xref: /llvm-project/libcxx/test/std/ranges/range.req/range.refinements/viewable_range.compile.pass.cpp (revision 71909de37495c82e31ae3a59f366f48e8fb66e54)
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
10 // UNSUPPORTED: libcpp-no-concepts
11 // UNSUPPORTED: gcc-10
12 // UNSUPPORTED: libcpp-has-no-incomplete-ranges
13 
14 // template<class R>
15 // concept viewable_range;
16 
17 #include <ranges>
18 #include <type_traits>
19 
20 #include "test_iterators.h"
21 #include "test_range.h"
22 
23 // The constraints we have in viewable_range are:
24 //  range<T>
25 //  view<remove_cvref_t<T>>
26 //  constructible_from<remove_cvref_t<T>, T>
27 //  borrowed_range<T>
28 //
29 // We test all the relevant combinations of satisfying/not satisfying those constraints.
30 
31 // viewable_range<T> is not satisfied for (range=false, view=*, constructible_from=*, borrowed_range=*)
32 struct T1 { };
33 static_assert(!std::ranges::range<T1>);
34 
35 static_assert(!std::ranges::viewable_range<T1>);
36 static_assert(!std::ranges::viewable_range<T1&>);
37 static_assert(!std::ranges::viewable_range<T1 const>);
38 static_assert(!std::ranges::viewable_range<T1 const&>);
39 
40 // viewable_range<T> is satisfied for (range=true, view=true, constructible_from=true, borrowed_range=true)
41 struct T2 : test_range<cpp20_input_iterator>, std::ranges::view_base {
42   T2(T2 const&) = default;
43 };
44 template<> constexpr bool std::ranges::enable_borrowed_range<T2> = true;
45 static_assert(std::ranges::range<T2>);
46 static_assert(std::ranges::view<T2>);
47 static_assert(std::constructible_from<T2, T2>);
48 static_assert(std::ranges::borrowed_range<T2>);
49 
50 static_assert(std::ranges::viewable_range<T2>);
51 static_assert(std::ranges::viewable_range<T2&>);
52 static_assert(std::ranges::viewable_range<T2 const>);
53 static_assert(std::ranges::viewable_range<T2 const&>);
54 
55 // viewable_range<T> is satisfied for (range=true, view=true, constructible_from=true, borrowed_range=false)
56 struct T3 : test_range<cpp20_input_iterator>, std::ranges::view_base {
57   T3(T3 const&) = default;
58 };
59 template<> constexpr bool std::ranges::enable_borrowed_range<T3> = false;
60 static_assert(std::ranges::range<T3>);
61 static_assert(std::ranges::view<T3>);
62 static_assert(std::constructible_from<T3, T3>);
63 static_assert(!std::ranges::borrowed_range<T3>);
64 
65 static_assert(std::ranges::viewable_range<T3>);
66 static_assert(std::ranges::viewable_range<T3&>);
67 static_assert(std::ranges::viewable_range<T3 const>);
68 static_assert(std::ranges::viewable_range<T3 const&>);
69 
70 // viewable_range<T> is not satisfied for (range=true, view=true, constructible_from=false, borrowed_range=true)
71 struct T4 : test_range<cpp20_input_iterator>, std::ranges::view_base {
72   T4(T4 const&) = delete;
73   T4(T4&&) = default;             // necessary to model view
74   T4& operator=(T4&&) = default;  // necessary to model view
75 };
76 static_assert(std::ranges::range<T4 const&>);
77 static_assert(std::ranges::view<std::remove_cvref_t<T4 const&>>);
78 static_assert(!std::constructible_from<std::remove_cvref_t<T4 const&>, T4 const&>);
79 static_assert(std::ranges::borrowed_range<T4 const&>);
80 
81 static_assert(!std::ranges::viewable_range<T4 const&>);
82 
83 // A type that satisfies (range=true, view=true, constructible_from=false, borrowed_range=false) can't be formed
84 
85 // viewable_range<T> is satisfied for (range=true, view=false, constructible_from=true, borrowed_range=true)
86 struct T5 : test_range<cpp20_input_iterator> { };
87 template<> constexpr bool std::ranges::enable_borrowed_range<T5> = true;
88 static_assert(std::ranges::range<T5>);
89 static_assert(!std::ranges::view<T5>);
90 static_assert(std::constructible_from<T5, T5>);
91 static_assert(std::ranges::borrowed_range<T5>);
92 
93 static_assert(std::ranges::viewable_range<T5>);
94 
95 // viewable_range<T> is not satisfied for (range=true, view=false, constructible_from=true, borrowed_range=false)
96 struct T6 : test_range<cpp20_input_iterator> { };
97 template<> constexpr bool std::ranges::enable_borrowed_range<T6> = false;
98 static_assert(std::ranges::range<T6>);
99 static_assert(!std::ranges::view<T6>);
100 static_assert(std::constructible_from<T6, T6>);
101 static_assert(!std::ranges::borrowed_range<T6>);
102 
103 static_assert(!std::ranges::viewable_range<T6>);
104 
105 // viewable_range<T> is satisfied for (range=true, view=false, constructible_from=false, borrowed_range=true)
106 struct T7 : test_range<cpp20_input_iterator> {
107   T7(T7 const&) = delete;
108 };
109 static_assert(std::ranges::range<T7&>);
110 static_assert(!std::ranges::view<std::remove_cvref_t<T7&>>);
111 static_assert(!std::constructible_from<std::remove_cvref_t<T7&>, T7&>);
112 static_assert(std::ranges::borrowed_range<T7&>);
113 
114 static_assert(std::ranges::viewable_range<T7&>);
115 
116 // A type that satisfies (range=true, view=false, constructible_from=false, borrowed_range=false) can't be formed
117 struct T8 : test_range<cpp20_input_iterator> {
118   T8(T8 const&) = delete;
119 };
120 static_assert(std::ranges::range<T8>);
121 static_assert(!std::ranges::view<T8>);
122 static_assert(!std::constructible_from<T8, T8>);
123 static_assert(!std::ranges::borrowed_range<T8>);
124 
125 static_assert(!std::ranges::viewable_range<T8>);
126 
127 // Test with a few degenerate types
128 static_assert(!std::ranges::viewable_range<void>);
129 static_assert(!std::ranges::viewable_range<int>);
130 static_assert(!std::ranges::viewable_range<int (*)(char)>);
131 static_assert(!std::ranges::viewable_range<int[]>);
132 static_assert(!std::ranges::viewable_range<int[10]>);
133 static_assert(!std::ranges::viewable_range<int(&)[]>); // unbounded array is not a range
134 static_assert( std::ranges::viewable_range<int(&)[10]>);
135