xref: /llvm-project/libcxx/test/std/ranges/range.adaptors/range.zip/size.pass.cpp (revision b8cb1dc9ea87faa8e8e9ab7a31710a8c0bb8b084)
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