qxLib
concepts.h
Go to the documentation of this file.
1 /**
2 
3  @file concepts.h
4  @author Khrapov
5  @date 2.11.2021
6  @copyright © Nick Khrapov, 2021. All right reserved.
7 
8 **/
9 #pragma once
10 
11 #include <type_traits>
12 #include <utility>
13 #include <variant>
14 
15 namespace qx
16 {
17 
18 // ---------------------------------------------------- std wrappers ---------------------------------------------------
19 
20 template<class T>
21 concept enumeration_c = std::is_enum_v<T>;
22 
23 template<class T>
24 concept arithmetic_c = std::is_arithmetic_v<T>;
25 
26 
27 
28 
29 template<class T>
30 concept is_iterator = requires(T) { typename T::iterator_category; };
31 
32 template<class T>
33 concept is_random_access_iterator =
34  is_iterator<T> && std::derived_from<typename T::iterator_category, std::random_access_iterator_tag>;
35 
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>;
39 };
40 
41 // won't work for base_args_t containing template template or type template parameters
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...>&)
45  {
46  }(derived);
47 };
48 
49 namespace details
50 {
51 
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*>;
56 };
57 
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*>;
62 };
63 
64 } // namespace details
65 
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>;
69 
70 
71 namespace details
72 {
73 
74 template<class T, class variant_t>
76 
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>...>
79 {
80 };
81 
82 } // namespace details
83 
84 template<class T, class variant_t>
85 concept in_variant_c = details::is_in_variant<T, variant_t>::value;
86 
87 } // namespace qx
requires(same_variadic_args_v< args_t... >) const expr auto coalesce(args_t &&... args)
Coalesce function, C# a ?? b analogue.
Definition: coalesce.inl:57