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 // UNSUPPORTED: libcpp-has-no-incomplete-ranges
11
12 // constexpr auto size() requires(sized_range<Views>&&...)
13 // constexpr auto size() const requires(sized_range<const Views>&&...)
14
15 #include <ranges>
16
17 #include <cassert>
18 #include <tuple>
19 #include <utility>
20
21 #include "test_iterators.h"
22 #include "types.h"
23
24 int buffer[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
25 struct View : std::ranges::view_base {
26 std::size_t size_ = 0;
ViewView27 constexpr View(std::size_t s) : size_(s) {}
beginView28 constexpr auto begin() const { return buffer; }
endView29 constexpr auto end() const { return buffer + size_; }
30 };
31
32 struct SizedNonConst : std::ranges::view_base {
33 using iterator = forward_iterator<int*>;
34 std::size_t size_ = 0;
SizedNonConstSizedNonConst35 constexpr SizedNonConst(std::size_t s) : size_(s) {}
beginSizedNonConst36 constexpr auto begin() const { return iterator{buffer}; }
endSizedNonConst37 constexpr auto end() const { return iterator{buffer + size_}; }
sizeSizedNonConst38 constexpr std::size_t size() { return size_; }
39 };
40
41 struct StrangeSizeView : std::ranges::view_base {
beginStrangeSizeView42 constexpr auto begin() const { return buffer; }
endStrangeSizeView43 constexpr auto end() const { return buffer + 8; }
44
sizeStrangeSizeView45 constexpr auto size() { return 5; }
sizeStrangeSizeView46 constexpr auto size() const { return 6; }
47 };
48
test()49 constexpr bool test() {
50 {
51 // single range
52 std::ranges::zip_view v(View(8));
53 assert(v.size() == 8);
54 assert(std::as_const(v).size() == 8);
55 }
56
57 {
58 // multiple ranges same type
59 std::ranges::zip_view v(View(2), View(3));
60 assert(v.size() == 2);
61 assert(std::as_const(v).size() == 2);
62 }
63
64 {
65 // multiple ranges different types
66 std::ranges::zip_view v(std::views::iota(0, 500), View(3));
67 assert(v.size() == 3);
68 assert(std::as_const(v).size() == 3);
69 }
70
71 {
72 // const-view non-sized range
73 std::ranges::zip_view v(SizedNonConst(2), View(3));
74 assert(v.size() == 2);
75 static_assert(std::ranges::sized_range<decltype(v)>);
76 static_assert(!std::ranges::sized_range<decltype(std::as_const(v))>);
77 }
78
79 {
80 // const/non-const has different sizes
81 std::ranges::zip_view v(StrangeSizeView{});
82 assert(v.size() == 5);
83 assert(std::as_const(v).size() == 6);
84 }
85
86 {
87 // underlying range not sized
88 std::ranges::zip_view v(InputCommonView{buffer});
89 static_assert(!std::ranges::sized_range<decltype(v)>);
90 static_assert(!std::ranges::sized_range<decltype(std::as_const(v))>);
91 }
92 return true;
93 }
94
main(int,char **)95 int main(int, char**) {
96 test();
97 static_assert(test());
98
99 return 0;
100 }
101