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// REQUIRES: std-at-least-c++23
10
11// <ranges>
12
13// template<class R, class P>
14// join_with_view(R&&, P&&) -> join_with_view<views::all_t<R>, views::all_t<P>>;
15//
16// template<input_range R>
17// join_with_view(R&&, range_value_t<range_reference_t<R>>)
18// -> join_with_view<views::all_t<R>, single_view<range_value_t<range_reference_t<R>>>>;
19
20#include <ranges>
21
22#include <deque>
23#include <type_traits>
24
25#include "test_iterators.h"
26
27struct View : std::ranges::view_base {
28 using It = cpp20_input_iterator<std::deque<int>*>;
29
30 View() = default;
31 It begin() const;
32 sentinel_wrapper<It> end() const;
33};
34
35static_assert(std::ranges::input_range<View>);
36static_assert(std::ranges::view<View>);
37
38struct Pattern : std::ranges::view_base {
39 Pattern() = default;
40 forward_iterator<int*> begin();
41 forward_iterator<int*> end();
42};
43
44static_assert(std::ranges::forward_range<Pattern>);
45static_assert(std::ranges::view<Pattern>);
46
47// A range that is not a view
48struct Range {
49 using It = cpp20_input_iterator<std::deque<int>*>;
50
51 Range() = default;
52 It begin() const;
53 sentinel_wrapper<It> end() const;
54};
55
56static_assert(std::ranges::input_range<Range>);
57static_assert(!std::ranges::view<Range>);
58
59// A pattern that is not a view
60struct RangePattern {
61 RangePattern() = default;
62 forward_iterator<int*> begin();
63 forward_iterator<int*> end();
64};
65
66static_assert(std::ranges::forward_range<RangePattern>);
67static_assert(!std::ranges::view<RangePattern>);
68
69void test_range_and_pattern_deduction_guide() {
70 { // Both `v` and `pat` model `std::ranges::view`.
71 {
72 View v;
73 Pattern pat;
74 std::ranges::join_with_view view(v, pat);
75 static_assert(std::is_same_v<decltype(view), std::ranges::join_with_view<View, Pattern>>);
76 }
77 {
78 View v;
79 std::ranges::join_with_view view(v, Pattern{});
80 static_assert(std::is_same_v<decltype(view), std::ranges::join_with_view<View, Pattern>>);
81 }
82 {
83 Pattern pat;
84 std::ranges::join_with_view view(View{}, pat);
85 static_assert(std::is_same_v<decltype(view), std::ranges::join_with_view<View, Pattern>>);
86 }
87 {
88 std::ranges::join_with_view view(View{}, Pattern{});
89 static_assert(std::is_same_v<decltype(view), std::ranges::join_with_view<View, Pattern>>);
90 }
91 }
92
93 { // Only `pat` models `std::ranges::view`.
94 {
95 Range v;
96 Pattern pat;
97 std::ranges::join_with_view view(v, pat);
98 static_assert(std::is_same_v<decltype(view), std::ranges::join_with_view<std::ranges::ref_view<Range>, Pattern>>);
99 }
100 {
101 Range v;
102 std::ranges::join_with_view view(v, Pattern{});
103 static_assert(std::is_same_v<decltype(view), std::ranges::join_with_view<std::ranges::ref_view<Range>, Pattern>>);
104 }
105 {
106 Pattern pat;
107 std::ranges::join_with_view view(Range{}, pat);
108 static_assert(
109 std::is_same_v<decltype(view), std::ranges::join_with_view<std::ranges::owning_view<Range>, Pattern>>);
110 }
111 {
112 std::ranges::join_with_view view(Range{}, Pattern{});
113 static_assert(
114 std::is_same_v<decltype(view), std::ranges::join_with_view<std::ranges::owning_view<Range>, Pattern>>);
115 }
116 }
117
118 { // Only `v` models `std::ranges::view`.
119 {
120 View v;
121 RangePattern pat;
122 std::ranges::join_with_view view(v, pat);
123 static_assert(
124 std::is_same_v<decltype(view), std::ranges::join_with_view<View, std::ranges::ref_view<RangePattern>>>);
125 }
126 {
127 View v;
128 std::ranges::join_with_view view(v, RangePattern{});
129 static_assert(
130 std::is_same_v<decltype(view), std::ranges::join_with_view<View, std::ranges::owning_view<RangePattern>>>);
131 }
132 {
133 RangePattern pat;
134 std::ranges::join_with_view view(View{}, pat);
135 static_assert(
136 std::is_same_v<decltype(view), std::ranges::join_with_view<View, std::ranges::ref_view<RangePattern>>>);
137 }
138 {
139 std::ranges::join_with_view view(View{}, RangePattern{});
140 static_assert(
141 std::is_same_v<decltype(view), std::ranges::join_with_view<View, std::ranges::owning_view<RangePattern>>>);
142 }
143 }
144
145 { // Both `v` and `pat` don't model `std::ranges::view`.
146 {
147 Range r;
148 RangePattern pat;
149 std::ranges::join_with_view view(r, pat);
150 static_assert(std::is_same_v<
151 decltype(view),
152 std::ranges::join_with_view<std::ranges::ref_view<Range>, std::ranges::ref_view<RangePattern>>>);
153 }
154 {
155 Range r;
156 std::ranges::join_with_view view(r, RangePattern{});
157 static_assert(std::is_same_v<
158 decltype(view),
159 std::ranges::join_with_view<std::ranges::ref_view<Range>, std::ranges::owning_view<RangePattern>>>);
160 }
161 {
162 RangePattern pat;
163 std::ranges::join_with_view view(Range{}, pat);
164 static_assert(std::is_same_v<
165 decltype(view),
166 std::ranges::join_with_view<std::ranges::owning_view<Range>, std::ranges::ref_view<RangePattern>>>);
167 }
168 {
169 std::ranges::join_with_view view(Range{}, RangePattern{});
170 static_assert(
171 std::is_same_v<
172 decltype(view),
173 std::ranges::join_with_view<std::ranges::owning_view<Range>, std::ranges::owning_view<RangePattern>>>);
174 }
175 }
176}
177
178void test_range_and_element_deduction_guide() {
179 { // Element is lvalue
180 int elem = 0;
181
182 {
183 View v;
184 std::ranges::join_with_view view(v, elem);
185 static_assert(std::is_same_v<decltype(view), std::ranges::join_with_view<View, std::ranges::single_view<int>>>);
186 }
187 {
188 std::ranges::join_with_view view(View{}, elem);
189 static_assert(std::is_same_v<decltype(view), std::ranges::join_with_view<View, std::ranges::single_view<int>>>);
190 }
191 {
192 Range r;
193 std::ranges::join_with_view view(r, elem);
194 static_assert(
195 std::is_same_v<decltype(view),
196 std::ranges::join_with_view<std::ranges::ref_view<Range>, std::ranges::single_view<int>>>);
197 }
198 {
199 std::ranges::join_with_view view(Range{}, elem);
200 static_assert(
201 std::is_same_v<decltype(view),
202 std::ranges::join_with_view<std::ranges::owning_view<Range>, std::ranges::single_view<int>>>);
203 }
204 }
205
206 { // Element is rvalue
207 {
208 View v;
209 std::ranges::join_with_view view(v, 1);
210 static_assert(std::is_same_v<decltype(view), std::ranges::join_with_view<View, std::ranges::single_view<int>>>);
211 }
212 {
213 std::ranges::join_with_view view(View{}, 1);
214 static_assert(std::is_same_v<decltype(view), std::ranges::join_with_view<View, std::ranges::single_view<int>>>);
215 }
216 {
217 Range r;
218 std::ranges::join_with_view view(r, 1);
219 static_assert(
220 std::is_same_v<decltype(view),
221 std::ranges::join_with_view<std::ranges::ref_view<Range>, std::ranges::single_view<int>>>);
222 }
223 {
224 std::ranges::join_with_view view(Range{}, 1);
225 static_assert(
226 std::is_same_v<decltype(view),
227 std::ranges::join_with_view<std::ranges::owning_view<Range>, std::ranges::single_view<int>>>);
228 }
229 }
230}
231

source code of libcxx/test/std/ranges/range.adaptors/range.join.with/range.join.with.view/ctad.compile.pass.cpp