4#ifndef _Stroika_Foundation_Common_Concept_h_
5#define _Stroika_Foundation_Common_Concept_h_ 1
7#include "Stroika/Foundation/StroikaPreComp.h"
18#include "Stroika/Foundation/Common/Common.h"
19#include "Stroika/Foundation/Common/ConceptsBase.h"
78 template <
typename F,
typename... Args>
80 {
noexcept (f (args...)) };
92 template <
typename F,
typename R,
typename... Args>
93 concept invocable_r = invocable<F, Args...> && convertible_to<invoke_result_t<F, Args...>, R>;
94 static_assert (
invocable_r<
decltype ([] (int) {
return ""; }),
const char*,
int>);
95 static_assert (
invocable_r<
decltype ([] (
char*,
char*) {}),
void,
char*,
char*>);
100 requires { []<
typename Rep,
typename Period> (type_identity<chrono::duration<Rep, Period>>) {}(type_identity<T> ()); };
101 static_assert (not IDuration<float>);
104 template <
typename T>
106 requires { []<
typename CLOCK,
typename DURATION> (type_identity<chrono::time_point<CLOCK, DURATION>>) {}(type_identity<T> ()); };
107 static_assert (not ITimePoint<float>);
121 template <
typename T,
typename... U>
127 template <
typename T>
134 template <
typename...>
146 template <
class _Ty1,
class _Ty2>
148 { __x == __y } -> Boolean_testable;
149 { __x != __y } -> Boolean_testable;
151 static_assert (not equality_comparable_with<nullopt_t, optional<int>>);
156 template <
typename OT>
157 concept IOptional = same_as<remove_cvref_t<OT>, optional<typename OT::value_type>>;
158 static_assert (IOptional<optional<int>>);
159 static_assert (not IOptional<int>);
162#if qCompilerAndStdLib_template_concept_matcher_requires_Buggy
163 template <
typename T1,
typename T2 =
void>
164 struct is_shared_ptr_ : false_type {};
165 template <
typename T1>
166 struct is_shared_ptr_<shared_ptr<T1>> : true_type {};
167 template <
typename T1,
typename T2 =
void>
168 struct is_pair_ : false_type {};
169 template <
typename T1,
typename T2>
170 struct is_pair_<pair<T1, T2>> : true_type {};
171 template <
typename... ARGS>
172 struct is_variant_ : false_type {};
173 template <
typename... ARGS>
174 struct is_variant_<variant<ARGS...>> : true_type {};
181 template <
typename T>
183#if qCompilerAndStdLib_template_concept_matcher_requires_Buggy
184 Private_::is_pair_<T>::value
188 []<
typename T1,
typename T2> (pair<T1, T2>) {}(t)
197 template <
typename T>
199#if qCompilerAndStdLib_template_concept_matcher_requires_Buggy
200 Private_::is_shared_ptr_<T>::value
205 []<
typename T1> (shared_ptr<T1>) {}(t)
214 template <
typename T,
size_t N>
215 concept has_tuple_element =
requires (T t) {
216 typename tuple_element_t<N, remove_const_t<T>>;
217 { get<N> (t) } -> convertible_to<const tuple_element_t<N, T>&>;
226 template <
typename T>
227 concept ITuple = !is_reference_v<T> &&
requires (T t) {
228 typename tuple_size<T>::type;
229 requires derived_from<tuple_size<T>, integral_constant<size_t, tuple_size_v<T>>>;
230 } && []<
size_t... N> (index_sequence<N...>) {
return (Private_::has_tuple_element<T, N> && ...); }(make_index_sequence<tuple_size_v<T>> ());
235 template <
typename T>
237#if qCompilerAndStdLib_template_concept_matcher_requires_Buggy
238 Private_::is_variant_<T>::value
242 []<
typename... TYPES> (variant<TYPES...>) {}(t)
257 template <
typename T>
259 template <
typename TEST_ARGUMENT>
260 using Test = conditional_t<convertible_to<TEST_ARGUMENT, T>, true_type, false_type>;
270 template <
typename T>
272 template <
typename TEST_ARGUMENT>
273 using Test = conditional_t<constructible_from<TEST_ARGUMENT, T>, true_type, false_type>;
287 template <
typename T>
289 { t.size () } -> convertible_to<size_t>;
293 template <
typename T>
294 concept HasEq_ =
requires (T t) {
295 { t == t } -> convertible_to<bool>;
297 template <
typename T>
298 constexpr inline bool HasEq_v_ = HasEq_<T>;
299 template <
typename T,
typename U>
300 constexpr inline bool HasEq_v_<pair<T, U>> = HasEq_v_<T> and HasEq_v_<U>;
301 template <
typename... Ts>
302 constexpr inline bool HasEq_v_<tuple<Ts...>> = (HasEq_v_<Ts> and ...);
303 template <
typename T>
304 constexpr bool HasUsableEqualToOptimization ()
310 if constexpr (Private_::HasEq_v_<T>) {
311 struct EqualToEmptyTester_ : equal_to<T> {
315 return sizeof (EqualToEmptyTester_) ==
sizeof (
int);
325 template <
typename T>
340 template <
typename T>
344 template <
typename T,
typename =
void>
345 struct ExtractValueType {
348 template <IHasValueType T>
349 struct ExtractValueType<T> {
350 using type =
typename T::value_type;
352 template <
typename T>
353 struct ExtractValueType<const T*,
void> {
356 template <
typename T>
357 struct ExtractValueType<T*,
void> {
371 template <
typename T>
377 template <
typename T>
389 template <
bool B,
typename T>
391 static constexpr bool value = B;
394 template <
typename HEAD,
typename... TAIL>
395 struct Select : conditional_t<HEAD::value, HEAD, Select<TAIL...>> {};
396 template <
typename T>
400 template <
bool B,
typename T>
401 struct Select<Case<B, T>> {
403 static_assert (B,
"!");
406 template <
typename HEAD,
typename... TAIL>
407 using Select_t =
typename Select<HEAD, TAIL...>::type;
416#include "Concepts.inl"
Concept: trivial shorthand for variadic same_as A or same_as B, or ...
concept true if integral or floating-point type 'T'.
check T has had remove_cvref_t called on it (e.g. ICVRefTd<const string&> is string)
Concept checks if the given type T has a const size() method which can be called to return a size_t.
Concept checks if the given type T has a value_type (type) member.
like std::invocable concept, except also requires the invocation doesn't raise exceptions
return true iff argument type T, is std::pair<a,b> for some a/b types
return true iff argument type T, is std::shared_ptr<A> for some A types
Concept ITuple<T> check if T is a tuple.
detect if T is a std::variant<> type.
handy re-usable concept, with the obvious meaning, and strangely omitted from std-c++ (though used in...
like convertible_to, but also handling cases where T has an explicit CTOR taking From
equality_comparable_with, but less strict - just checks if it can be equality compared!
Concept: std::is_trivially_copyable_v.
typename Private_::ExtractValueType< remove_cvref_t< T > >::type ExtractValueType_t
Extract the type of elements in a container, or returned by an iterator (value_type) or void it there...