// { 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>();
}
