2 // { dg-do compile { target c++20 } }
3 // { dg-additional-options "-fconcepts-ts" }
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
16 typedef _Tp value_type;
17 static constexpr size_t size() { return sizeof...(_Idx); }
20 template <class T, T Value>
21 struct integral_constant {
22 using type = integral_constant;
24 constexpr operator T() const { return Value; }
25 constexpr T operator()() const { return Value; }
26 static constexpr T value {Value};
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 {};
36 struct is_same<T,T> : true_type {};
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)...>>;
51 namespace stl2 { inline namespace v1 {
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)...> {};
62 return detail::all_same<Ts...>::value;
64 template <class F, class...Args>
65 using ResultType = decltype(declval<F>()(declval<Args>()...));
69 struct value_type<T*> {
74 typename value_type<T>::type;
76 template <class F, class...Args>
77 concept bool Function() {
78 return requires (F& f, Args&&...args) {
80 requires Same<decltype(f((Args&&)args...)), ResultType<F, Args...> >();
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>
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" }