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
|
// { dg-do compile { target c++20 } }
// { dg-additional-options "-fconcepts-ts" }
typedef int size_t;
template <typename _Tp> struct A { static constexpr _Tp value = 1; };
template <typename _Tp> _Tp declval();
template <typename _From, typename _To> struct __is_convertible_helper {
template <typename, typename> static A<bool> __test(int);
typedef decltype(__test<_From, _To>(0)) type;
};
template <typename, typename>
struct is_convertible : __is_convertible_helper<int, int>::type {};
template <typename> struct remove_reference;
template <typename _Tp> struct remove_reference<_Tp &> { typedef _Tp type; };
struct base;
struct general;
template <typename _Tp, _Tp...> struct B;
template <typename _Tp, _Tp> using make_integer_sequence = B<int>;
template <size_t... _Idx> using index_sequence = B<size_t, _Idx...>;
template <size_t _Num>
using make_index_sequence = make_integer_sequence<size_t, _Num>;
template <bool...> struct and_c_impl { static constexpr bool value = true; };
template <bool...> constexpr bool and_c() { return and_c_impl<>::value; }
template <class X, class Y> concept bool cpt_Convertible() {
return is_convertible<X, Y>::value;
}
template <class T> using uncvref_t = typename remove_reference<T>::type;
struct Plus;
using index_t = int;
template <class> bool cpt_Index;
template <class... Extents>
requires and_c<cpt_Index<Extents>()...>() class Dimensionality;
namespace detail_concept {
template <class> bool match_dimensionality;
template <class... Extents>
constexpr bool match_dimensionality<Dimensionality<Extents...>> = true;
}
template <class X> concept bool cpt_Dimensionality() {
return detail_concept::match_dimensionality<X>;
}
template <class X> concept bool cpt_Shaped() { return requires(X x){{x};}; }
template <class X> concept bool cpt_Dimensioned() { return cpt_Shaped<X>(); }
template <class... Extents>
requires and_c<cpt_Index<Extents>()...>() class Dimensionality {
public:
static constexpr size_t num_dimensions = sizeof...(Extents);
};
template <index_t...> using DimensionalityC = Dimensionality<>;
template <class> struct dimensionality_type_impl;
template <cpt_Dimensioned X> struct dimensionality_type_impl<X> {
using type = uncvref_t<decltype(declval<X>().dimensionality())>;
};
template <cpt_Dimensioned X>
using dimensionality_type = typename dimensionality_type_impl<X>::type;
template <class Functor, class... Expressibles>
requires requires(Functor functor, Expressibles... expressibles) {
map_expressions_impl(functor, expressibles...);
}
decltype(auto) map_impl(Functor, Expressibles...);
void cpt_ContinualScalar();
template <class> concept bool cpt_Scalar() { return cpt_ContinualScalar; }
template <class X> concept bool cpt_FlatEvaluator() {
return requires(X x){{x}->cpt_Scalar;};
}
template <class, class> bool k_evaluator_impl;
template <size_t... Indexes, class Evaluator>
constexpr bool k_evaluator_impl<index_sequence<Indexes...>, Evaluator> = true;
template <class X, size_t K> concept bool cpt_KEvaluator() {
return k_evaluator_impl<make_index_sequence<K>, X>;
}
template <class X, size_t K> concept bool cpt_KCompatibleEvaluator() {
return cpt_KEvaluator<X, K>();
}
template <class X> concept bool cpt_Structure() {
return cpt_Convertible<X, base>();
}
template <cpt_Dimensionality Dimensionality, cpt_Structure,
cpt_KCompatibleEvaluator<Dimensionality::num_dimensions> Evaluator>
class NumericArrayExpression;
namespace detail_concept {
template <class> bool match_numeric_array_expression;
template <cpt_Dimensionality Dimensionality,
cpt_Structure Structure,
cpt_KCompatibleEvaluator<Dimensionality::num_dimensions> Evaluator>
constexpr bool match_numeric_array_expression<
NumericArrayExpression<Dimensionality, Structure, Evaluator>> = true;
}
template <class X> concept bool cpt_NumericArrayExpression() {
return detail_concept::match_numeric_array_expression<X>;
}
namespace expression_traits {
namespace detail_expression_traits {
template <class...> struct first_numeric_array_expression_impl;
template <cpt_NumericArrayExpression ExpressionFirst, class... ExpressionsRest>
struct first_numeric_array_expression_impl<ExpressionFirst,
ExpressionsRest...> {
using type = ExpressionFirst;
};
}
template <class... Expressions>
using first_numeric_array_expression =
typename detail_expression_traits::first_numeric_array_expression_impl<
Expressions...>::type;
template <class... Expressions>
using first_expression_dimensionality =
dimensionality_type<first_numeric_array_expression<Expressions...>>;
}
template <cpt_Dimensionality Dimensionality, cpt_Structure,
cpt_KCompatibleEvaluator<Dimensionality::num_dimensions> Evaluator>
class NumericArrayExpression {
public:
NumericArrayExpression(Dimensionality, Evaluator) {}
Dimensionality &dimensionality();
};
template <cpt_Structure Structure, cpt_Dimensionality Dimensionality,
cpt_KCompatibleEvaluator<Dimensionality::num_dimensions> Evaluator>
auto make_numeric_array_expression(Dimensionality dimensionality,
Evaluator evaluator) {
return NumericArrayExpression<Dimensionality, Structure, Evaluator>(
dimensionality, evaluator);
}
template <size_t, class Functor, class... Evaluators>
auto make_map_evaluator_impl(Functor) requires
and_(cpt_FlatEvaluator<Evaluators>()...);
template <class Functor, class... Expressions>
requires
requires(Expressions... expressions,
expression_traits::first_expression_dimensionality<Expressions...>
dimensionality) {
make_map_evaluator_impl<decltype(dimensionality)::num_dimensions>(
expressions...);
}
decltype(auto) map_expressions_impl(Functor, Expressions...);
template <class Functor, class... Expressibles> concept bool cpt_Mappable() {
return requires(Functor functor, Expressibles... expressibles) {
map_impl(functor, expressibles...);
};
}
void ____C_A_T_C_H____T_E_S_T____8() {
auto e1 = make_numeric_array_expression<general>(DimensionalityC<>(), [] {});
using E1 = decltype(e1);
cpt_Mappable<Plus, E1>();
}
|