11 #include <type_traits>
21 concept enumeration_c = std::is_enum_v<T>;
24 concept arithmetic_c = std::is_arithmetic_v<T>;
30 concept is_iterator =
requires(T) {
typename T::iterator_category; };
33 concept is_random_access_iterator =
34 is_iterator<T> && std::derived_from<typename T::iterator_category, std::random_access_iterator_tag>;
36 template<
class T,
class return_t,
class... args_t>
37 concept callable_c =
requires(T t, args_t&&... args) {
38 { t(std::forward<args_t>(args)...) } -> std::convertible_to<return_t>;
42 template<
class derived_t,
template<
class... base_args_t>
class base_t, class... partial_specialization_args_t>
43 concept derived_from_template_c =
requires(
const derived_t& derived) {
44 []<
class... base_args_t>(
const base_t<partial_specialization_args_t..., base_args_t...>&)
52 template<
class range_t,
class T>
53 concept is_iterator_arrow_operator_of_t_type =
requires(range_t t) {
54 { t.begin().operator->() } -> std::convertible_to<const T*>;
55 { t.end().operator->() } -> std::convertible_to<const T*>;
58 template<
class range_t,
class T>
59 concept is_iterator_t_pointer =
requires(range_t t) {
60 { t.begin() } -> std::convertible_to<const T*>;
61 { t.end() } -> std::convertible_to<const T*>;
66 template<
class range_t,
class T>
67 concept range_of_t_c =
68 details::is_iterator_arrow_operator_of_t_type<range_t, T> || details::is_iterator_t_pointer<range_t, T>;
74 template<
class T,
class variant_t>
77 template<
class T,
class... args_t>
78 struct is_in_variant<T, std::variant<args_t...>> : std::disjunction<std::is_same<T, args_t>...>
84 template<
class T,
class variant_t>
requires(same_variadic_args_v< args_t... >) const expr auto coalesce(args_t &&... args)
Coalesce function, C# a ?? b analogue.