xref: /llvm-project/libcxx/test/std/ranges/range.factories/range.repeat.view/views_repeat.pass.cpp (revision 0ecc1646cbbb1bdfce234a11bec33b8c64af29cb)
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 // template <class T>
12 // views::repeat(T &&) requires constructible_from<ranges::repeat_view<T>, T>;
13 
14 // template <class T, class Bound>
15 // views::repeat(T &&, Bound &&) requires constructible_from<ranges::repeat_view<T, Bound>, T, Bound>;
16 
17 #include <cassert>
18 #include <concepts>
19 #include <ranges>
20 #include <tuple>
21 #include <type_traits>
22 
23 #include "MoveOnly.h"
24 
25 struct NonCopyable {
26   NonCopyable(NonCopyable&) = delete;
27 };
28 
29 struct NonDefaultCtor {
NonDefaultCtorNonDefaultCtor30   NonDefaultCtor(int) {}
31 };
32 
33 struct Empty {};
34 
35 struct LessThan3 {
operator ()LessThan336   constexpr bool operator()(int i) const { return i < 3; }
37 };
38 
39 struct EqualTo33 {
operator ()EqualTo3340   constexpr bool operator()(int i) const { return i == 33; }
41 };
42 
43 struct Add3 {
operator ()Add344   constexpr int operator()(int i) const { return i + 3; }
45 };
46 
47 // Tp is_object
48 static_assert(std::is_invocable_v<decltype(std::views::repeat), int>);
49 static_assert(!std::is_invocable_v<decltype(std::views::repeat), void>);
50 
51 // _Bound is semiregular, integer like or std::unreachable_sentinel_t
52 static_assert(!std::is_invocable_v<decltype(std::views::repeat), int, Empty>);
53 static_assert(!std::is_invocable_v<decltype(std::views::repeat), int, NonCopyable>);
54 static_assert(!std::is_invocable_v<decltype(std::views::repeat), int, NonDefaultCtor>);
55 static_assert(std::is_invocable_v<decltype(std::views::repeat), int, std::unreachable_sentinel_t>);
56 
57 // Tp is copy_constructible
58 static_assert(!std::is_invocable_v<decltype(std::views::repeat), NonCopyable>);
59 
60 // Tp is move_constructible
61 static_assert(std::is_invocable_v<decltype(std::views::repeat), MoveOnly>);
62 
63 // Test LWG4054 "Repeating a repeat_view should repeat the view"
64 static_assert(std::is_same_v<decltype(std::views::repeat(std::views::repeat(42))),
65                              std::ranges::repeat_view<std::ranges::repeat_view<int>>>);
66 
67 // These cases are from LWG4053, but they are actually covered by the resolution of LWG4054,
68 // and the resolution of LWG4053 only affects CTAD.
69 using RPV = std::ranges::repeat_view<const char*>;
70 static_assert(std::same_as<decltype(std::views::repeat("foo", std::unreachable_sentinel)), RPV>);  // OK
71 static_assert(std::same_as<decltype(std::views::repeat(+"foo", std::unreachable_sentinel)), RPV>); // OK
72 static_assert(std::same_as<decltype(std::views::repeat("foo")), RPV>);                             // OK since LWG4054
73 static_assert(std::same_as<decltype(std::views::repeat(+"foo")), RPV>);                            // OK
74 
test()75 constexpr bool test() {
76   assert(*std::views::repeat(33).begin() == 33);
77   assert(*std::views::repeat(33, 10).begin() == 33);
78   static_assert(std::same_as<decltype(std::views::repeat(42)), std::ranges::repeat_view<int>>);
79   static_assert(std::same_as<decltype(std::views::repeat(42, 3)), std::ranges::repeat_view<int, int>>);
80   static_assert(std::same_as<decltype(std::views::repeat), decltype(std::ranges::views::repeat)>);
81 
82   // unbound && drop_view
83   {
84     auto r = std::views::repeat(33) | std::views::drop(3);
85     static_assert(!std::ranges::sized_range<decltype(r)>);
86     assert(*r.begin() == 33);
87   }
88 
89   // bound && drop_view
90   {
91     auto r = std::views::repeat(33, 8) | std::views::drop(3);
92     static_assert(std::ranges::sized_range<decltype(r)>);
93     assert(*r.begin() == 33);
94     assert(r.size() == 5);
95   }
96 
97   // unbound && take_view
98   {
99     auto r = std::views::repeat(33) | std::views::take(3);
100     static_assert(std::ranges::sized_range<decltype(r)>);
101     assert(*r.begin() == 33);
102     assert(r.size() == 3);
103   }
104 
105   // bound && take_view
106   {
107     auto r = std::views::repeat(33, 8) | std::views::take(3);
108     static_assert(std::ranges::sized_range<decltype(r)>);
109     assert(*r.begin() == 33);
110     assert(r.size() == 3);
111   }
112 
113   // bound && transform_view
114   {
115     auto r = std::views::repeat(33, 8) | std::views::transform(Add3{});
116     assert(*r.begin() == 36);
117     assert(r.size() == 8);
118   }
119 
120   // unbound && transform_view
121   {
122     auto r = std::views::repeat(33) | std::views::transform(Add3{});
123     assert(*r.begin() == 36);
124   }
125 
126   return true;
127 }
128 
main(int,char **)129 int main(int, char**) {
130   test();
131   static_assert(test());
132 
133   return 0;
134 }
135