aboutsummaryrefslogtreecommitdiff
path: root/clang/test/SemaCXX/GH161671.cpp
blob: de09e548d91f24dccebfa5af8e2e122cdb116d12 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
// RUN: %clang_cc1 -std=c++20 -w %s
// RUN: %clang_cc1 -std=c++2c -w %s
// expected-no-diagnostics

namespace std {
template <typename _Tp, _Tp __v> struct integral_constant {
  static constexpr _Tp value = __v;
  using value_type = _Tp;
};
template <bool __v> using __bool_constant = integral_constant<bool, __v>;
template <typename> struct is_integral : integral_constant<bool, true> {};
template <typename> struct is_signed : integral_constant<bool, false> {};
template <typename _Tp, typename _Up = _Tp> _Up __declval(int);
template <typename _Tp> auto declval() -> decltype(__declval<_Tp>(0));
template <typename> struct make_unsigned {
  using type = int;
};
template <typename _Tp> struct decay {
  using type = _Tp;
};
template <int, typename _Iftrue, typename> struct conditional {
  using type = _Iftrue;
};
} // namespace std
namespace meta {
template <template <typename...> class> struct quote;
template <template <typename> class C, typename... Ts>
concept valid = requires { typename C<Ts...>; };
template <typename T>
concept trait = requires { typename T; };
template <typename T>
concept invocable = requires { typename quote<T::template invoke>; };
template <typename T>
concept integral = requires { T::value; };
template <trait T> using _t = T::type;
template <integral T> constexpr T::value_type _v = T::value;
template <bool B> using bool_ = std::integral_constant<bool, B>;
template <invocable Fn, typename... Args>
using invoke = Fn::template invoke<Args...>;
template <typename> struct id;
namespace detail {
template <template <typename> class, typename...> struct defer_;
template <template <typename> class C, typename... Ts>
  requires valid<C, Ts...>
struct defer_<C, Ts...> {
  using type = C<Ts...>;
};
} // namespace detail
template <template <typename> class C, typename... Ts>
struct defer : detail::defer_<C, Ts...> {};
template <template <typename...> class C> struct quote {
  template <typename... Ts> using invoke = _t<defer<C, Ts...>>;
};
namespace detail {
template <int> struct _cond {
  template <typename Then, typename> using invoke = Then;
};
template <> struct _cond<false>;
} // namespace detail
template <bool If, typename Then, typename Else>
using conditional_t = detail::_cond<If>::template invoke<Then, Else>;
namespace detail {
template <typename...> struct _if_;
template <typename If, typename Then, typename Else>
struct _if_<If, Then, Else> : std::conditional<_v<If>, Then, Else> {};
} // namespace detail
template <bool If, typename... Args>
using if_c = _t<detail::_if_<bool_<If>, Args...>>;
} // namespace meta
template <bool> void requires_();
template <typename A, typename B>
concept same_as = __is_same(B, A);
namespace ranges {
template <typename> struct view_closure;
template <typename T> using decay_t = meta::_t<std::decay<T>>;
enum cardinality { unknown };
template <cardinality> struct basic_view {};
} // namespace ranges
namespace std {
template <typename> struct vector {};
} // namespace std
namespace ranges {
struct {
  template <typename F, typename... Args>
  auto operator()(F f, Args... args) -> decltype(f(args...));
} invoke;
template <typename Fun, typename... Args>
using invoke_result_t =
    decltype(invoke(std::declval<Fun>(), std::declval<Args>()...));
namespace detail {
struct with_difference_type_;
template <typename T> using iter_value_t_ = T ::value_type;
} // namespace detail
template <typename R> using iter_value_t = detail::iter_value_t_<R>;
namespace detail {
template <typename I>
using iter_size_t =
    meta::_t<meta::conditional_t<std::is_integral<I>::value,
                                 std::make_unsigned<I>, meta::id<I>>>;
template <typename D>
concept signed_integer_like_impl_concept_ =
    std::integral_constant<bool, -D()>::value;
template <typename D>
concept signed_integer_like_ = signed_integer_like_impl_concept_<D>;
} // namespace detail
template <typename S, typename I>
concept sized_sentinel_for_requires_ =
    requires(S s, I i) { requires_<same_as<I, decltype(i - s)>>; };
template <typename S, typename I>
concept sized_sentinel_for = sized_sentinel_for_requires_<S, I>;
struct range_access {
  template <typename Rng>
  static auto begin_cursor(Rng rng) -> decltype(rng.begin_cursor());
  template <typename Cur, typename O>
  static auto distance_to(Cur pos, O other) -> decltype(pos.distance_to(other));
};
namespace detail {
template <typename S, typename C>
concept sized_sentinel_for_cursor_requires_ = requires(S s, C c) {
  requires_<signed_integer_like_<decltype(range_access::distance_to(c, s))>>;
};
template <typename S, typename C>
concept sized_sentinel_for_cursor = sized_sentinel_for_cursor_requires_<S, C>;
struct iterator_associated_types_base_ {
  typedef range_access value_type;
};
template <typename>
using iterator_associated_types_base = iterator_associated_types_base_;
} // namespace detail
template <typename>
struct basic_iterator : detail::iterator_associated_types_base<int> {};
template <typename Cur2, typename Cur>
  requires detail::sized_sentinel_for_cursor<Cur2, Cur>
void operator-(basic_iterator<Cur2>, basic_iterator<Cur>);
namespace _begin_ {
template <typename T>
concept has_member_begin_requires_ = requires(T t) { t; };
template <typename T>
concept has_member_begin = has_member_begin_requires_<T>;
struct _member_result_ {
  template <typename R>
  using invoke = decltype(static_cast<R (*)()>(nullptr)().begin());
};
struct _non_member_result_;
struct fn {
  template <typename R>
  using _result_t =
      meta::invoke<meta::conditional_t<has_member_begin<R>, _member_result_,
                                       _non_member_result_>,
                   R>;
  template <typename R> _result_t<R> operator()(R);
};
} // namespace _begin_
_begin_::fn begin;
namespace _end_ {
template <typename>
concept has_member_end_requires_ = requires { begin; };
template <typename T>
concept has_member_end = has_member_end_requires_<T>;
struct _member_result_ {
  template <typename R>
  using invoke = decltype(static_cast<R (*)()>(nullptr)().end());
};
struct _non_member_result_;
struct fn {
  template <typename R>
  using _result_t =
      meta::invoke<meta::conditional_t<has_member_end<R>, _member_result_,
                                       _non_member_result_>,
                   R>;
  template <typename R> _result_t<R> operator()(R);
};
} // namespace _end_
_end_::fn end;
template <typename Rng>
using iterator_t = decltype(begin(static_cast<Rng (*)()>(nullptr)()));
template <typename Rng>
using sentinel_t = decltype(end(static_cast<Rng (*)()>(nullptr)()));
template <typename T>
concept has_member_size_requires_ = requires(T t) { t.size(); };
template <typename T>
concept has_member_size = has_member_size_requires_<T>;
struct _other_result_;
struct _member_result_ {
  template <typename> using invoke = decltype(0);
  template <typename R>
  using _result_t = meta::invoke<
      meta::conditional_t<has_member_size<R>, _member_result_, _other_result_>,
      R>;
  template <typename R> _result_t<R> operator()(R r) { r.size(); }
} size;
template <typename Rng> using range_value_t = iter_value_t<iterator_t<Rng>>;
namespace detail {
template <cardinality Card>
std::integral_constant<cardinality, Card> test_cardinality(basic_view<Card> *);
}
template <typename Rng>
struct range_cardinality
    : meta::conditional_t<__is_same(Rng, Rng),
                          decltype(detail::test_cardinality(
                              static_cast<Rng *>(nullptr))),
                          Rng> {};
template <typename T>
concept sized_range_requires_ = requires(T t) { size(t); };
template <typename T>
concept sized_range = sized_range_requires_<T>;
namespace detail {
template <int> struct dependent_ {
  template <typename T> using invoke = T;
};
} // namespace detail
template <typename Derived, cardinality Cardinality>
struct view_interface : basic_view<Cardinality> {
  template <bool B> using D = meta::invoke<detail::dependent_<B>, Derived>;
  Derived derived();
  template <bool True = true>
    requires sized_sentinel_for<sentinel_t<D<True>>, iterator_t<D<True>>>
  detail::iter_size_t<iterator_t<D<True>>> size() {
    derived().end() - derived().begin();
  }
};
struct {
  template <typename Fun> view_closure<Fun> operator()(Fun);
} make_view_closure;
struct view_closure_base {
  template <typename Rng, typename ViewFn>
  friend auto operator|(Rng rng, ViewFn vw) {
    return vw(rng);
  }
};
template <typename ViewFn> struct view_closure : view_closure_base, ViewFn {};
namespace detail {
template <typename Derived>
using begin_cursor_t =
    decay_t<decltype(range_access::begin_cursor(std::declval<Derived>()))>;
template <typename Derived>
using facade_iterator_t = basic_iterator<begin_cursor_t<Derived>>;
template <typename Derived>
using facade_sentinel_t =
    meta::if_c<same_as<Derived, Derived>, facade_iterator_t<Derived>, Derived>;
} // namespace detail
template <typename Derived, cardinality Cardinality>
struct view_facade : view_interface<Derived, Cardinality> {
  template <typename D = Derived> auto begin() -> detail::facade_iterator_t<D>;
  template <typename D = Derived> auto end() -> detail::facade_sentinel_t<D>;
};
template <typename Derived, cardinality Cardinality>
struct view_adaptor : view_facade<Derived, Cardinality> {
  auto begin_cursor() -> decltype(0);
};
namespace detail {
template <typename...> struct bind_back_fn_;
template <typename Fn, typename Arg> struct bind_back_fn_<Fn, Arg> {
  template <typename... CallArgs>
  invoke_result_t<Fn, CallArgs..., Arg> operator()(CallArgs...);
};
template <typename Fn, typename... Args>
using bind_back_fn = bind_back_fn_<Fn, Args...>;
} // namespace detail
struct {
  template <typename Fn, typename Arg1>
  detail::bind_back_fn<Fn, Arg1> operator()(Fn, Arg1);
} bind_back;
namespace detail {
struct to_container {
  template <typename> struct fn;
  template <typename, typename> struct closure;
};
template <typename, typename, typename R>
concept to_container_reserve = sized_range<R>;
template <typename MetaFn, typename Rng>
using container_t = meta::invoke<MetaFn, Rng>;
struct to_container_closure_base {
  template <typename Rng, typename MetaFn, typename Fn>
  friend auto operator|(Rng rng, to_container::closure<MetaFn, Fn> fn) {
    return fn(rng);
  }
};
template <typename, typename Fn>
struct to_container::closure : to_container_closure_base, Fn {};
template <typename MetaFn> struct to_container::fn {
  template <typename Rng> void impl(Rng, std::__bool_constant<false>);
  template <typename Rng> void impl(Rng rng, std::__bool_constant<true>) {
    size(rng);
  }
  template <typename Rng> container_t<MetaFn, Rng> operator()(Rng rng) {
    using cont_t = container_t<MetaFn, Rng>;
    using iter_t = Rng;
    using use_reserve_t =
        meta::bool_<to_container_reserve<cont_t, iter_t, Rng>>;
    impl(rng, use_reserve_t{});
  }
};
template <typename MetaFn, typename Fn>
using to_container_closure = to_container::closure<MetaFn, Fn>;
template <typename MetaFn>
using to_container_fn = to_container_closure<MetaFn, to_container::fn<MetaFn>>;
template <template <typename> class ContT> struct from_range {
  template <typename Rng>
  static auto from_rng_(long)
      -> meta::invoke<meta::quote<ContT>, range_value_t<Rng>>;
  template <typename Rng> using invoke = decltype(from_rng_<Rng>(0));
};
} // namespace detail
detail::to_container_fn<detail::from_range<std::vector>> to_vector;
template <typename Rng>
struct remove_if_view
    : view_adaptor<remove_if_view<Rng>, range_cardinality<Rng>::value> {};
struct filter_base_fn {
  template <typename Rng, typename Pred>
  remove_if_view<Rng> operator()(Rng, Pred);
  template <typename Pred> auto operator()(Pred pred) {
    return make_view_closure(bind_back(filter_base_fn{}, pred));
  }
} filter;
namespace detail {
struct promote_as_signed_;
template <typename I>
using iota_difference_t =
    meta::conditional_t<std::is_integral<I>::value, promote_as_signed_,
                        with_difference_type_>;
} // namespace detail
template <typename, typename>
struct iota_view : view_facade<iota_view<int, int>, unknown> {
  struct cursor {
    auto distance_to(cursor) -> detail::iota_difference_t<int>;
  };
  cursor begin_cursor();
};
struct {
  template <typename From, typename To>
    requires(std::is_signed<From>::value == std::is_signed<To>::value)
  iota_view<From, To> operator()(From, To);
} iota;
} // namespace ranges
void foo() {
  ranges::iota(0, 1) | ranges::to_vector =
      ranges::iota(0, 1) | ranges::filter([] {}) | ranges::to_vector;
}