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 
14 namespace qx
15 {
16 
17 // ---------------------------------------------------- std wrappers ---------------------------------------------------
18 
19 template<class T>
20 concept enumeration_c = std::is_enum_v<T>;
21 
22 template<class T>
23 concept arithmetic_c = std::is_arithmetic_v<T>;
24 
25 template<class T>
26 concept floating_point_c = std::is_floating_point_v<T>;
27 
28 template<class T>
29 concept integral_c = std::is_integral_v<T>;
30 
31 
32 
33 
34 template<class T>
35 concept is_iterator = requires(T) { typename T::iterator_category; };
36 
37 template<class T>
38 concept is_random_access_iterator =
39  is_iterator<T> && std::derived_from<typename T::iterator_category, std::random_access_iterator_tag>;
40 
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>;
44 };
45 
46 // won't work for base_args_t containing template template or type template parameters
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...>&)
50  {
51  }(derived);
52 };
53 
54 namespace details
55 {
56 
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*>;
61 };
62 
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*>;
67 };
68 
69 } // namespace details
70 
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>;
74 
75 } // namespace qx