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
25struct NonCopyable {
26 NonCopyable(NonCopyable&) = delete;
27};
28
29struct NonDefaultCtor {
30 NonDefaultCtor(int) {}
31};
32
33struct Empty {};
34
35struct LessThan3 {
36 constexpr bool operator()(int i) const { return i < 3; }
37};
38
39struct EqualTo33 {
40 constexpr bool operator()(int i) const { return i == 33; }
41};
42
43struct Add3 {
44 constexpr int operator()(int i) const { return i + 3; }
45};
46
47// Tp is_object
48static_assert(std::is_invocable_v<decltype(std::views::repeat), int>);
49static_assert(!std::is_invocable_v<decltype(std::views::repeat), void>);
50
51// _Bound is semiregular, integer like or std::unreachable_sentinel_t
52static_assert(!std::is_invocable_v<decltype(std::views::repeat), int, Empty>);
53static_assert(!std::is_invocable_v<decltype(std::views::repeat), int, NonCopyable>);
54static_assert(!std::is_invocable_v<decltype(std::views::repeat), int, NonDefaultCtor>);
55static_assert(std::is_invocable_v<decltype(std::views::repeat), int, std::unreachable_sentinel_t>);
56
57// Tp is copy_constructible
58static_assert(!std::is_invocable_v<decltype(std::views::repeat), NonCopyable>);
59
60// Tp is move_constructible
61static_assert(std::is_invocable_v<decltype(std::views::repeat), MoveOnly>);
62
63// Test LWG4054 "Repeating a repeat_view should repeat the view"
64static_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.
69using RPV = std::ranges::repeat_view<const char*>;
70static_assert(std::same_as<decltype(std::views::repeat("foo", std::unreachable_sentinel)), RPV>); // OK
71static_assert(std::same_as<decltype(std::views::repeat(+"foo", std::unreachable_sentinel)), RPV>); // OK
72static_assert(std::same_as<decltype(std::views::repeat("foo")), RPV>); // OK since LWG4054
73static_assert(std::same_as<decltype(std::views::repeat(+"foo")), RPV>); // OK
74
75constexpr 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
129int main(int, char**) {
130 test();
131 static_assert(test());
132
133 return 0;
134}
135

source code of libcxx/test/std/ranges/range.factories/range.repeat.view/views_repeat.pass.cpp