// { dg-do run { target c++23 } } // { dg-add-options no_pch } #include #if __cpp_lib_ranges_repeat != 202207L # error "Feature-test macro __cpp_lib_ranges_repeat has wrong value in " #endif #include #include #include namespace ranges = std::ranges; namespace views = std::views; constexpr bool test01() { auto v = views::repeat(42); static_assert(ranges::random_access_range && !ranges::sized_range); auto i = ranges::begin(v); auto s = ranges::end(v); VERIFY( *i == 42 ); VERIFY( i[0] == 42 ); VERIFY( &i[0] == &i[1] ); VERIFY( &*i == &*(i+1) ); VERIFY( i != s ); auto j = i + 5, k = i + 12; VERIFY( k - i == 12 ); VERIFY( k - j == 7 ); VERIFY( i - j == -5 ); VERIFY( k > j ); VERIFY( j < k ); VERIFY( i + 5 == j ); VERIFY( i != j ); VERIFY( i + 5 <= j ); VERIFY( j - 5 >= i ); return true; } constexpr bool test02() { constexpr int bound = 20; auto v = views::repeat(42, bound); static_assert(ranges::random_access_range && ranges::sized_range); VERIFY( ranges::equal(v, views::repeat(42) | views::take(bound)) ); auto i = ranges::begin(v); auto s = ranges::end(v); VERIFY( *i == 42 ); VERIFY( i[0] == 42 ); VERIFY( &i[0] == &i[1] ); VERIFY( &*i == &*(i+1) ); VERIFY( i != s ); auto j = i + 5, k = i + 12; VERIFY( k - i == 12 ); VERIFY( k - j == 7 ); VERIFY( i - j == -5 ); VERIFY( k > j ); VERIFY( j < k ); VERIFY( i + 5 == j ); VERIFY( i != j ); VERIFY( i + 5 <= j ); VERIFY( j - 5 >= i ); VERIFY( ranges::size(v) == bound ); VERIFY( s - i == bound ); VERIFY( s - j == bound - (j - i) ); VERIFY( i + bound == s ); VERIFY( bound + i == s ); return true; } constexpr bool test03() { struct A { int n, m; }; auto v = ranges::repeat_view(std::piecewise_construct, std::tuple{1, 2}, std::tuple{3}); VERIFY( v[0].n == 1 ); VERIFY( v[0].m == 2 ); VERIFY( ranges::size(v) == 3 ); return true; } constexpr bool test04() { // Verify P2474R2 changes to views::take/drop. auto r = views::repeat(42); auto rt = r | views::take(10); static_assert(views::__detail::__is_repeat_view); VERIFY( ranges::equal(rt, views::repeat(42, 10)) ); auto rd = r | views::drop(10); static_assert(std::same_as); auto br = views::repeat(42, 37); auto brt = br | views::take(10); static_assert(std::same_as); VERIFY( ranges::equal(brt, views::repeat(42, 10)) ); auto brt100 = br | views::take(100); VERIFY( ranges::equal(brt100, br) ); auto brd = br | views::drop(10); static_assert(std::same_as); VERIFY( ranges::equal(brd, views::repeat(42, 27)) ); auto brd100 = br | views::drop(100); VERIFY( ranges::empty(brd100) ); return true; } void test05() { // LWG 3796 ranges::repeat_view r; } void test06() { struct move_only { move_only() { } move_only(move_only&&) { } }; // P2494R2 Relaxing range adaptors to allow for move only types static_assert( requires { views::repeat(move_only{}, 2); } ); } void test07() { // PR libstdc++/112453 auto t1 = std::views::repeat(std::make_unique(5)) | std::views::take(2); auto d1 = std::views::repeat(std::make_unique(5)) | std::views::drop(2); auto t2 = std::views::repeat(std::make_unique(5), 4) | std::views::take(2); auto d2 = std::views::repeat(std::make_unique(5), 4) | std::views::drop(2); } void test08() { // LWG 4053 - Unary call to std::views::repeat does not decay the argument using type = ranges::repeat_view; using type = decltype(views::repeat("foo", std::unreachable_sentinel)); using type = decltype(views::repeat(+"foo", std::unreachable_sentinel)); using type = decltype(views::repeat("foo")); using type = decltype(views::repeat(+"foo")); } void test09() { // LWG 4054 - Repeating a repeat_view should repeat the view auto v = views::repeat(views::repeat(5)); using type = decltype(v); using type = ranges::repeat_view>; VERIFY( v[0][0] == 5 ); } int main() { static_assert(test01()); static_assert(test02()); static_assert(test03()); static_assert(test04()); test05(); test06(); test07(); test08(); test09(); }