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
23 int buffer[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
24 struct View : std::ranges::view_base {
25 std::size_t size_ = 0;
ViewView26 constexpr View(std::size_t s) : size_(s) {}
beginView27 constexpr auto begin() const { return buffer; }
endView28 constexpr auto end() const { return buffer + size_; }
29 };
30
31 struct SizedNonConst : std::ranges::view_base {
32 using iterator = forward_iterator<int*>;
33 std::size_t size_ = 0;
SizedNonConstSizedNonConst34 constexpr SizedNonConst(std::size_t s) : size_(s) {}
beginSizedNonConst35 constexpr auto begin() const { return iterator{buffer}; }
endSizedNonConst36 constexpr auto end() const { return iterator{buffer + size_}; }
sizeSizedNonConst37 constexpr std::size_t size() { return size_; }
38 };
39
40 struct StrangeSizeView : std::ranges::view_base {
beginStrangeSizeView41 constexpr auto begin() const { return buffer; }
endStrangeSizeView42 constexpr auto end() const { return buffer + 8; }
43
sizeStrangeSizeView44 constexpr auto size() { return 5; }
sizeStrangeSizeView45 constexpr auto size() const { return 6; }
46 };
47
test()48 constexpr 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
main(int,char **)94 int main(int, char**) {
95 test();
96 static_assert(test());
97
98 return 0;
99 }
100