1 // PR c++/70685 2 // { dg-do compile { target c++14 } } 3 4 namespace std { 5 template <typename _Tp, _Tp __v> struct A { static constexpr _Tp value = __v; 6 }; 7 typedef A<bool, false> false_type; 8 template <bool, typename _Iftrue, typename> using conditional_t = _Iftrue; 9 namespace hana { 10 template <typename> struct is_default : false_type {}; 11 template <typename> struct tag_of; 12 struct deleted_implementation; 13 namespace detail { 14 namespace operators { 15 template <typename> struct adl {}; 16 } 17 } 18 template <typename> struct B; 19 template <int v> struct G : std::A<int, v> {}; 20 template <typename T, T v> G<v> integral_c; 21 template <int i> using int_ = G<i>; 22 template <int i> int_<i> int_c; 23 template <typename> struct C; 24 template <typename Tag> struct D { operatorD25 template <typename... X> auto operator()(X... x) { 26 return C<Tag>::apply(x...); 27 } 28 }; 29 template <typename Tag> D<Tag> make; 30 template <typename> struct unpack_impl; 31 struct Foldable { 32 using Tag = int; 33 static constexpr int value = is_default<unpack_impl<Tag>>::value; 34 }; 35 struct range_tag; 36 auto make_range = make<range_tag>; 37 template <typename> struct sum_impl; 38 template <typename> struct F; 39 template <typename M = B<int>> F<M> sum; 40 template <typename T, T, T To> 41 struct range : detail::operators::adl<range<T, 0, To>> {}; 42 template <typename T, T From, T To> struct tag_of<range<T, From, To>> { 43 using type = range_tag; 44 }; 45 template <> struct C<range_tag> { 46 template <typename From, typename To> static auto apply(From, To) { 47 using T = int; 48 constexpr T from(From::value); 49 constexpr T to(To::value); 50 return range<T, from, to>{}; 51 } 52 }; 53 template <> struct sum_impl<range_tag> { 54 template <typename I> static constexpr I sum_helper(I m, I n) { 55 if (m == n) 56 return 0; 57 return sum_helper(0, 0); 58 } 59 template <typename T, T from, T to> static auto apply(range<T, from, to>) { 60 integral_c<T, sum_helper(from, to - 1)>; 61 } 62 }; 63 template <typename> struct F { 64 template <typename Xs> auto operator()(Xs xs) { 65 using S = typename tag_of<Xs>::type; 66 using Sum = 67 conditional_t<Foldable::value, sum_impl<S>, deleted_implementation>; 68 Sum::apply(xs); 69 } 70 }; 71 } 72 auto __hana_tmp_22 = 73 (hana::sum<>(hana::make_range(hana::int_c<-3>, hana::int_c<-2>)), 74 hana::sum<>(hana::make_range(hana::int_c<3>, hana::int_c<7>)), 75 hana::int_c<6>); 76 } 77