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