testsuite: update mangling
[official-gcc.git] / gcc / testsuite / g++.dg / cpp2a / concepts-pr67148.C
blob97f80cfcfa861ed49bb8e35d2e4dee3118a88a31
1 // PR c++/67148
2 // { dg-do compile { target c++20 } }
3 // { dg-additional-options "-fconcepts-ts" }
5 namespace std
7   template<typename T>
8   T declval();
10   typedef unsigned int size_t;
11   typedef int ptrdiff_t;
12   typedef decltype(nullptr) nullptr_t;
13   template<typename _Tp, _Tp... _Idx>
14     struct integer_sequence
15     {
16       typedef _Tp value_type;
17       static constexpr size_t size() { return sizeof...(_Idx); }
18     };
20   template <class T, T Value>
21   struct integral_constant {
22     using type = integral_constant;
23     using value_type = T;
24     constexpr operator T() const { return Value; }
25     constexpr T operator()() const { return Value; }
26     static constexpr T value {Value};
27   };
28   template <class T, T Value>
29   constexpr T integral_constant<T, Value>::value;
30   using true_type = integral_constant<bool, true>;
31   using false_type = integral_constant<bool, false>;
33   template <class T, class U>
34   struct is_same : false_type {};
35   template <class T>
36   struct is_same<T,T> : true_type {};
38        
39 namespace meta
41     inline namespace v1
42     {
43         template <typename T>
44         using _t = typename T::type;
45         template <bool... Bools>
46         using and_c = std::is_same<std::integer_sequence<bool, Bools...>,
47                                    std::integer_sequence<bool, (Bools || true)...>>;
48     }
51 namespace stl2 { inline namespace v1 {
52 using std::declval;
53 namespace detail {
54 template <class...>
55 struct all_same : std::true_type {};
56 template <class T, class...Rest>
57 struct all_same<T, Rest...> :
58   meta::and_c<__is_same_as(T, Rest)...> {};
60 template <class...Ts>
61 concept bool Same() {
62   return detail::all_same<Ts...>::value;
64 template <class F, class...Args>
65 using ResultType = decltype(declval<F>()(declval<Args>()...));
66 template <class>
67 struct value_type {};
68 template <class T>
69 struct value_type<T*> {
70   using type = T;
72 template <class T>
73 using ValueType =
74   typename value_type<T>::type;
76 template <class F, class...Args>
77 concept bool Function() {
78   return requires (F& f, Args&&...args) {
79     f((Args&&)args...);
80     requires Same<decltype(f((Args&&)args...)), ResultType<F, Args...> >();
81   };
84 template <class, class...> struct __function : std::false_type {};
85 Function{F, ...Args} struct __function<F, Args...> : std::true_type {};
87 template <class F, class I1, class I2>
88 concept bool IndirectCallable() {
89   return Function<F, ValueType<I1>, ValueType<I2>>();
92 template <class F, class I1, class I2>
93 concept bool IndirectCallable2() {
94   return __function<F, ValueType<I1>, ValueType<I2>>::value;
97 namespace ext { namespace models {
98 template <class, class, class>
99 constexpr bool indirect_callable() { return false; }
100 IndirectCallable{F, I1, I2}
101 constexpr bool indirect_callable() { return true; }
103 template <class, class, class>
104 constexpr bool indirect_callable2() { return false; }
105 IndirectCallable2{F, I1, I2}
106 constexpr bool indirect_callable2() { return true; }
110 namespace models = stl2::ext::models;
112 template <class T = void>
113 struct plus {
114   T operator()(T, T) const;
117 static_assert((models::indirect_callable<::plus<int>, int*, int*>()));
118 static_assert((models::indirect_callable2<::plus<int>, int*, int*>()));
120 static_assert((models::indirect_callable<::plus<int>, int**, int*>())); // { dg-error "static assertion failed" }
121 static_assert((models::indirect_callable2<::plus<int>, int**, int*>())); // { dg-error "static assertion failed" }