11 #include <type_traits>
20 concept enumeration_c = std::is_enum_v<T>;
23 concept arithmetic_c = std::is_arithmetic_v<T>;
26 concept floating_point_c = std::is_floating_point_v<T>;
29 concept integral_c = std::is_integral_v<T>;
35 concept is_iterator = requires(T) {
typename T::iterator_category; };
38 concept is_random_access_iterator =
39 is_iterator<T> && std::derived_from<typename T::iterator_category, std::random_access_iterator_tag>;
41 template<
class T,
class return_t,
class... args_t>
42 concept callable_c = requires(T t, args_t&&... args) {
43 { t(std::forward<args_t>(args)...) } -> std::convertible_to<return_t>;
47 template<
class derived_t,
template<
class... base_args_t>
class base_t, class... partial_specialization_args_t>
48 concept derived_from_template_c = requires(
const derived_t& derived) {
49 []<
class... base_args_t>(
const base_t<partial_specialization_args_t..., base_args_t...>&)
57 template<
class range_t,
class T>
58 concept is_iterator_arrow_operator_of_t_type = requires(range_t t) {
59 { t.begin().operator->() } -> std::convertible_to<const T*>;
60 { t.end().operator->() } -> std::convertible_to<const T*>;
63 template<
class range_t,
class T>
64 concept is_iterator_t_pointer = requires(range_t t) {
65 { t.begin() } -> std::convertible_to<const T*>;
66 { t.end() } -> std::convertible_to<const T*>;
71 template<
class range_t,
class T>
72 concept range_of_t_c =
73 details::is_iterator_arrow_operator_of_t_type<range_t, T> || details::is_iterator_t_pointer<range_t, T>;