340 lines · cpp
1// RUN: %clang_cc1 -std=c++20 -w %s2// RUN: %clang_cc1 -std=c++2c -w %s3// expected-no-diagnostics4 5namespace std {6template <typename _Tp, _Tp __v> struct integral_constant {7 static constexpr _Tp value = __v;8 using value_type = _Tp;9};10template <bool __v> using __bool_constant = integral_constant<bool, __v>;11template <typename> struct is_integral : integral_constant<bool, true> {};12template <typename> struct is_signed : integral_constant<bool, false> {};13template <typename _Tp, typename _Up = _Tp> _Up __declval(int);14template <typename _Tp> auto declval() -> decltype(__declval<_Tp>(0));15template <typename> struct make_unsigned {16 using type = int;17};18template <typename _Tp> struct decay {19 using type = _Tp;20};21template <int, typename _Iftrue, typename> struct conditional {22 using type = _Iftrue;23};24} // namespace std25namespace meta {26template <template <typename...> class> struct quote;27template <template <typename> class C, typename... Ts>28concept valid = requires { typename C<Ts...>; };29template <typename T>30concept trait = requires { typename T; };31template <typename T>32concept invocable = requires { typename quote<T::template invoke>; };33template <typename T>34concept integral = requires { T::value; };35template <trait T> using _t = T::type;36template <integral T> constexpr T::value_type _v = T::value;37template <bool B> using bool_ = std::integral_constant<bool, B>;38template <invocable Fn, typename... Args>39using invoke = Fn::template invoke<Args...>;40template <typename> struct id;41namespace detail {42template <template <typename> class, typename...> struct defer_;43template <template <typename> class C, typename... Ts>44 requires valid<C, Ts...>45struct defer_<C, Ts...> {46 using type = C<Ts...>;47};48} // namespace detail49template <template <typename> class C, typename... Ts>50struct defer : detail::defer_<C, Ts...> {};51template <template <typename...> class C> struct quote {52 template <typename... Ts> using invoke = _t<defer<C, Ts...>>;53};54namespace detail {55template <int> struct _cond {56 template <typename Then, typename> using invoke = Then;57};58template <> struct _cond<false>;59} // namespace detail60template <bool If, typename Then, typename Else>61using conditional_t = detail::_cond<If>::template invoke<Then, Else>;62namespace detail {63template <typename...> struct _if_;64template <typename If, typename Then, typename Else>65struct _if_<If, Then, Else> : std::conditional<_v<If>, Then, Else> {};66} // namespace detail67template <bool If, typename... Args>68using if_c = _t<detail::_if_<bool_<If>, Args...>>;69} // namespace meta70template <bool> void requires_();71template <typename A, typename B>72concept same_as = __is_same(B, A);73namespace ranges {74template <typename> struct view_closure;75template <typename T> using decay_t = meta::_t<std::decay<T>>;76enum cardinality { unknown };77template <cardinality> struct basic_view {};78} // namespace ranges79namespace std {80template <typename> struct vector {};81} // namespace std82namespace ranges {83struct {84 template <typename F, typename... Args>85 auto operator()(F f, Args... args) -> decltype(f(args...));86} invoke;87template <typename Fun, typename... Args>88using invoke_result_t =89 decltype(invoke(std::declval<Fun>(), std::declval<Args>()...));90namespace detail {91struct with_difference_type_;92template <typename T> using iter_value_t_ = T ::value_type;93} // namespace detail94template <typename R> using iter_value_t = detail::iter_value_t_<R>;95namespace detail {96template <typename I>97using iter_size_t =98 meta::_t<meta::conditional_t<std::is_integral<I>::value,99 std::make_unsigned<I>, meta::id<I>>>;100template <typename D>101concept signed_integer_like_impl_concept_ =102 std::integral_constant<bool, -D()>::value;103template <typename D>104concept signed_integer_like_ = signed_integer_like_impl_concept_<D>;105} // namespace detail106template <typename S, typename I>107concept sized_sentinel_for_requires_ =108 requires(S s, I i) { requires_<same_as<I, decltype(i - s)>>; };109template <typename S, typename I>110concept sized_sentinel_for = sized_sentinel_for_requires_<S, I>;111struct range_access {112 template <typename Rng>113 static auto begin_cursor(Rng rng) -> decltype(rng.begin_cursor());114 template <typename Cur, typename O>115 static auto distance_to(Cur pos, O other) -> decltype(pos.distance_to(other));116};117namespace detail {118template <typename S, typename C>119concept sized_sentinel_for_cursor_requires_ = requires(S s, C c) {120 requires_<signed_integer_like_<decltype(range_access::distance_to(c, s))>>;121};122template <typename S, typename C>123concept sized_sentinel_for_cursor = sized_sentinel_for_cursor_requires_<S, C>;124struct iterator_associated_types_base_ {125 typedef range_access value_type;126};127template <typename>128using iterator_associated_types_base = iterator_associated_types_base_;129} // namespace detail130template <typename>131struct basic_iterator : detail::iterator_associated_types_base<int> {};132template <typename Cur2, typename Cur>133 requires detail::sized_sentinel_for_cursor<Cur2, Cur>134void operator-(basic_iterator<Cur2>, basic_iterator<Cur>);135namespace _begin_ {136template <typename T>137concept has_member_begin_requires_ = requires(T t) { t; };138template <typename T>139concept has_member_begin = has_member_begin_requires_<T>;140struct _member_result_ {141 template <typename R>142 using invoke = decltype(static_cast<R (*)()>(nullptr)().begin());143};144struct _non_member_result_;145struct fn {146 template <typename R>147 using _result_t =148 meta::invoke<meta::conditional_t<has_member_begin<R>, _member_result_,149 _non_member_result_>,150 R>;151 template <typename R> _result_t<R> operator()(R);152};153} // namespace _begin_154_begin_::fn begin;155namespace _end_ {156template <typename>157concept has_member_end_requires_ = requires { begin; };158template <typename T>159concept has_member_end = has_member_end_requires_<T>;160struct _member_result_ {161 template <typename R>162 using invoke = decltype(static_cast<R (*)()>(nullptr)().end());163};164struct _non_member_result_;165struct fn {166 template <typename R>167 using _result_t =168 meta::invoke<meta::conditional_t<has_member_end<R>, _member_result_,169 _non_member_result_>,170 R>;171 template <typename R> _result_t<R> operator()(R);172};173} // namespace _end_174_end_::fn end;175template <typename Rng>176using iterator_t = decltype(begin(static_cast<Rng (*)()>(nullptr)()));177template <typename Rng>178using sentinel_t = decltype(end(static_cast<Rng (*)()>(nullptr)()));179template <typename T>180concept has_member_size_requires_ = requires(T t) { t.size(); };181template <typename T>182concept has_member_size = has_member_size_requires_<T>;183struct _other_result_;184struct _member_result_ {185 template <typename> using invoke = decltype(0);186 template <typename R>187 using _result_t = meta::invoke<188 meta::conditional_t<has_member_size<R>, _member_result_, _other_result_>,189 R>;190 template <typename R> _result_t<R> operator()(R r) { r.size(); }191} size;192template <typename Rng> using range_value_t = iter_value_t<iterator_t<Rng>>;193namespace detail {194template <cardinality Card>195std::integral_constant<cardinality, Card> test_cardinality(basic_view<Card> *);196}197template <typename Rng>198struct range_cardinality199 : meta::conditional_t<__is_same(Rng, Rng),200 decltype(detail::test_cardinality(201 static_cast<Rng *>(nullptr))),202 Rng> {};203template <typename T>204concept sized_range_requires_ = requires(T t) { size(t); };205template <typename T>206concept sized_range = sized_range_requires_<T>;207namespace detail {208template <int> struct dependent_ {209 template <typename T> using invoke = T;210};211} // namespace detail212template <typename Derived, cardinality Cardinality>213struct view_interface : basic_view<Cardinality> {214 template <bool B> using D = meta::invoke<detail::dependent_<B>, Derived>;215 Derived derived();216 template <bool True = true>217 requires sized_sentinel_for<sentinel_t<D<True>>, iterator_t<D<True>>>218 detail::iter_size_t<iterator_t<D<True>>> size() {219 derived().end() - derived().begin();220 }221};222struct {223 template <typename Fun> view_closure<Fun> operator()(Fun);224} make_view_closure;225struct view_closure_base {226 template <typename Rng, typename ViewFn>227 friend auto operator|(Rng rng, ViewFn vw) {228 return vw(rng);229 }230};231template <typename ViewFn> struct view_closure : view_closure_base, ViewFn {};232namespace detail {233template <typename Derived>234using begin_cursor_t =235 decay_t<decltype(range_access::begin_cursor(std::declval<Derived>()))>;236template <typename Derived>237using facade_iterator_t = basic_iterator<begin_cursor_t<Derived>>;238template <typename Derived>239using facade_sentinel_t =240 meta::if_c<same_as<Derived, Derived>, facade_iterator_t<Derived>, Derived>;241} // namespace detail242template <typename Derived, cardinality Cardinality>243struct view_facade : view_interface<Derived, Cardinality> {244 template <typename D = Derived> auto begin() -> detail::facade_iterator_t<D>;245 template <typename D = Derived> auto end() -> detail::facade_sentinel_t<D>;246};247template <typename Derived, cardinality Cardinality>248struct view_adaptor : view_facade<Derived, Cardinality> {249 auto begin_cursor() -> decltype(0);250};251namespace detail {252template <typename...> struct bind_back_fn_;253template <typename Fn, typename Arg> struct bind_back_fn_<Fn, Arg> {254 template <typename... CallArgs>255 invoke_result_t<Fn, CallArgs..., Arg> operator()(CallArgs...);256};257template <typename Fn, typename... Args>258using bind_back_fn = bind_back_fn_<Fn, Args...>;259} // namespace detail260struct {261 template <typename Fn, typename Arg1>262 detail::bind_back_fn<Fn, Arg1> operator()(Fn, Arg1);263} bind_back;264namespace detail {265struct to_container {266 template <typename> struct fn;267 template <typename, typename> struct closure;268};269template <typename, typename, typename R>270concept to_container_reserve = sized_range<R>;271template <typename MetaFn, typename Rng>272using container_t = meta::invoke<MetaFn, Rng>;273struct to_container_closure_base {274 template <typename Rng, typename MetaFn, typename Fn>275 friend auto operator|(Rng rng, to_container::closure<MetaFn, Fn> fn) {276 return fn(rng);277 }278};279template <typename, typename Fn>280struct to_container::closure : to_container_closure_base, Fn {};281template <typename MetaFn> struct to_container::fn {282 template <typename Rng> void impl(Rng, std::__bool_constant<false>);283 template <typename Rng> void impl(Rng rng, std::__bool_constant<true>) {284 size(rng);285 }286 template <typename Rng> container_t<MetaFn, Rng> operator()(Rng rng) {287 using cont_t = container_t<MetaFn, Rng>;288 using iter_t = Rng;289 using use_reserve_t =290 meta::bool_<to_container_reserve<cont_t, iter_t, Rng>>;291 impl(rng, use_reserve_t{});292 }293};294template <typename MetaFn, typename Fn>295using to_container_closure = to_container::closure<MetaFn, Fn>;296template <typename MetaFn>297using to_container_fn = to_container_closure<MetaFn, to_container::fn<MetaFn>>;298template <template <typename> class ContT> struct from_range {299 template <typename Rng>300 static auto from_rng_(long)301 -> meta::invoke<meta::quote<ContT>, range_value_t<Rng>>;302 template <typename Rng> using invoke = decltype(from_rng_<Rng>(0));303};304} // namespace detail305detail::to_container_fn<detail::from_range<std::vector>> to_vector;306template <typename Rng>307struct remove_if_view308 : view_adaptor<remove_if_view<Rng>, range_cardinality<Rng>::value> {};309struct filter_base_fn {310 template <typename Rng, typename Pred>311 remove_if_view<Rng> operator()(Rng, Pred);312 template <typename Pred> auto operator()(Pred pred) {313 return make_view_closure(bind_back(filter_base_fn{}, pred));314 }315} filter;316namespace detail {317struct promote_as_signed_;318template <typename I>319using iota_difference_t =320 meta::conditional_t<std::is_integral<I>::value, promote_as_signed_,321 with_difference_type_>;322} // namespace detail323template <typename, typename>324struct iota_view : view_facade<iota_view<int, int>, unknown> {325 struct cursor {326 auto distance_to(cursor) -> detail::iota_difference_t<int>;327 };328 cursor begin_cursor();329};330struct {331 template <typename From, typename To>332 requires(std::is_signed<From>::value == std::is_signed<To>::value)333 iota_view<From, To> operator()(From, To);334} iota;335} // namespace ranges336void foo() {337 ranges::iota(0, 1) | ranges::to_vector =338 ranges::iota(0, 1) | ranges::filter([] {}) | ranges::to_vector;339}340