135 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++14, c++17, c++2010 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_object48static_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_t52static_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_constructible58static_assert(!std::is_invocable_v<decltype(std::views::repeat), NonCopyable>);59 60// Tp is move_constructible61static_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>); // OK71static_assert(std::same_as<decltype(std::views::repeat(+"foo", std::unreachable_sentinel)), RPV>); // OK72static_assert(std::same_as<decltype(std::views::repeat("foo")), RPV>); // OK since LWG405473static_assert(std::same_as<decltype(std::views::repeat(+"foo")), RPV>); // OK74 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_view83 {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_view90 {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_view98 {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_view106 {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_view114 {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_view121 {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