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.