11 #include <type_traits>
18 concept is_enumeration = std::is_enum_v<T>;
21 concept enumeration_c = is_enumeration<T>;
24 concept is_iterator = requires(T) {
typename T::iterator_category; };
27 concept is_random_access_iterator =
28 is_iterator<T> && std::derived_from<typename T::iterator_category, std::random_access_iterator_tag>;
30 template<
class T,
class return_t,
class... args_t>
31 concept callable_c = requires(T t, args_t&&... args) {
33 t(std::forward<args_t>(args)...)
34 } -> std::convertible_to<return_t>;
38 template<
class derived_t,
template<
class... base_args_t>
class base_t, class... partial_specialization_args_t>
39 concept derived_from_template_c = requires(
const derived_t& derived) {
40 []<
class... base_args_t>(
const base_t<partial_specialization_args_t..., base_args_t...>&)
48 template<
class range_t,
class T>
49 concept is_iterator_arrow_operator_of_t_type = requires(range_t t) {
51 t.begin().operator->()
52 } -> std::convertible_to<const T*>;
55 } -> std::convertible_to<const T*>;
58 template<
class range_t,
class T>
59 concept is_iterator_t_pointer = requires(range_t t) {
62 } -> std::convertible_to<const T*>;
65 } -> std::convertible_to<const T*>;
70 template<
class range_t,
class T>
71 concept range_of_t_c =
72 details::is_iterator_arrow_operator_of_t_type<range_t, T> || details::is_iterator_t_pointer<range_t, T>;