1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
10
11// constexpr auto size() requires(sized_range<Views>&&...)
12// constexpr auto size() const requires(sized_range<const Views>&&...)
13
14#include <ranges>
15
16#include <cassert>
17#include <tuple>
18#include <utility>
19
20#include "test_iterators.h"
21#include "types.h"
22
23int buffer[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
24struct View : std::ranges::view_base {
25 std::size_t size_ = 0;
26 constexpr View(std::size_t s) : size_(s) {}
27 constexpr auto begin() const { return buffer; }
28 constexpr auto end() const { return buffer + size_; }
29};
30
31struct SizedNonConst : std::ranges::view_base {
32 using iterator = forward_iterator<int*>;
33 std::size_t size_ = 0;
34 constexpr SizedNonConst(std::size_t s) : size_(s) {}
35 constexpr auto begin() const { return iterator{buffer}; }
36 constexpr auto end() const { return iterator{buffer + size_}; }
37 constexpr std::size_t size() { return size_; }
38};
39
40struct StrangeSizeView : std::ranges::view_base {
41 constexpr auto begin() const { return buffer; }
42 constexpr auto end() const { return buffer + 8; }
43
44 constexpr auto size() { return 5; }
45 constexpr auto size() const { return 6; }
46};
47
48constexpr bool test() {
49 {
50 // single range
51 std::ranges::zip_view v(View(8));
52 assert(v.size() == 8);
53 assert(std::as_const(v).size() == 8);
54 }
55
56 {
57 // multiple ranges same type
58 std::ranges::zip_view v(View(2), View(3));
59 assert(v.size() == 2);
60 assert(std::as_const(v).size() == 2);
61 }
62
63 {
64 // multiple ranges different types
65 std::ranges::zip_view v(std::views::iota(0, 500), View(3));
66 assert(v.size() == 3);
67 assert(std::as_const(v).size() == 3);
68 }
69
70 {
71 // const-view non-sized range
72 std::ranges::zip_view v(SizedNonConst(2), View(3));
73 assert(v.size() == 2);
74 static_assert(std::ranges::sized_range<decltype(v)>);
75 static_assert(!std::ranges::sized_range<decltype(std::as_const(v))>);
76 }
77
78 {
79 // const/non-const has different sizes
80 std::ranges::zip_view v(StrangeSizeView{});
81 assert(v.size() == 5);
82 assert(std::as_const(v).size() == 6);
83 }
84
85 {
86 // underlying range not sized
87 std::ranges::zip_view v(InputCommonView{buffer});
88 static_assert(!std::ranges::sized_range<decltype(v)>);
89 static_assert(!std::ranges::sized_range<decltype(std::as_const(v))>);
90 }
91 return true;
92}
93
94int main(int, char**) {
95 test();
96 static_assert(test());
97
98 return 0;
99}
100

source code of libcxx/test/std/ranges/range.adaptors/range.zip/size.pass.cpp