Loading...
Searching...
No Matches
util.h
Go to the documentation of this file.
1#ifndef _BBM_CONCEPTS_UTIL_H_
2#define _BBM_CONCEPTS_UTIL_H_
3
4#include <tuple>
5
6/***********************************************************************/
7/*! \file util.h
8
9 \brief Additional basic helper concepts.
10************************************************************************/
11
12namespace bbm {
13 namespace concepts {
14
15 /**********************************************************************/
16 /*! \brief Concept wrapper around a type trait: check if T meets the type TRAIT<T,ARGS...>
17 **********************************************************************/
18 template<typename T, template<typename...> typename TRAIT, typename... ARGS>
19 concept trait_wrapper = TRAIT<T, ARGS...>::value;
20
21 /*********************************************************************/
22 /* \brief true if type trait exists for a type
23 *********************************************************************/
24 template<template<typename...> typename TRAIT, typename... ARGS>
25 concept valid_trait = std::same_as<TRAIT<ARGS...>, TRAIT<ARGS...>>;
26
27 /*********************************************************************/
28 /*! \brief true if type is the same as any of the listed types
29 *********************************************************************/
30 template<typename T, typename... U>
31 concept same_as_any = (std::same_as<T, U> || ...);
32
33 /*********************************************************************/
34 /*! \brief true if type is the same as all of the listed types
35 *********************************************************************/
36 template<typename T, typename... U>
37 concept same_as_all = (std::same_as<T, U> && ...);
38
39 /*********************************************************************/
40 /*! \brief assignable_to: reverse of std::assignable_from
41 *********************************************************************/
42 template<typename RHS, typename LHS>
43 concept assignable_to = requires(RHS&& r, LHS l)
44 {
45 { l = std::forward<RHS>(r) };
46 };
47
48 /*********************************************************************/
49 /*! @{ \name basic math operator concepts
50 *********************************************************************/
51 template<typename T>
52 concept has_addition = requires(T a)
53 {
54 { a+a } -> assignable_to<T>; // T+T
55 { a+1 } -> assignable_to<T>; // T+scalar
56 { a+=a }; // T+=T
57 { a+=1 }; // T+=scalar
58 };
59
60 template<typename T>
61 concept has_subtraction = requires(T a)
62 {
63 { a-a } -> assignable_to<T>; // T-T
64 { a-1 } -> assignable_to<T>; // T-scalar
65 { a-=a }; // T-=T
66 { a-=1 }; // T-=scalar
67 };
68
69 template<typename T>
70 concept has_multiplication = requires(T a)
71 {
72 { a*a } -> assignable_to<T>; // T*T
73 { a*1 } -> assignable_to<T>; // T*scalar
74 { a*=a }; // T*=T
75 { a*=1 }; // T*=scalar
76 };
77
78 template<typename T>
79 concept has_division = requires(T a)
80 {
81 { a/a } -> assignable_to<T>; // T/T
82 { a/1 } -> assignable_to<T>; // T/scalar
83 { a/=a }; // T/=T
84 { a/=1 }; // T/=scalar
85 };
86
87 template<typename T>
88 concept has_modulo = requires(T a)
89 {
90 { a%a } -> assignable_to<T>; // T%T
91 { a%1 } -> assignable_to<T>; // T%scalar
92 { a%=a }; // T%=T
93 { a%=1 }; // T%=scalar
94 };
95
96 template<typename T>
98 //! @}
99
100
101 /**********************************************************************/
102 /*! @{ \name increment/decrement operators
103 **********************************************************************/
104 template<typename T>
105 concept has_increment = requires(T a)
106 {
107 { a++ };
108 { ++a };
109 };
110
111 template<typename T>
112 concept has_decrement = requires(T a)
113 {
114 { a-- };
115 { --a };
116 };
117 //! @}
118
119
120 /**********************************************************************/
121 /*! \brief bit operators
122 **********************************************************************/
123 template<typename T>
124 concept has_bit_operators = requires(T a)
125 {
126 { a | a } -> assignable_to<T>;
127 { a & a } -> assignable_to<T>;
128 { a ^ a } -> assignable_to<T>;
129 { ~a } -> assignable_to<T>;
130 { a |= a };
131 { a &= a };
132 { a ^= a };
133 };
134
135 /**********************************************************************/
136 /*! \brief logical operators
137 **********************************************************************/
138 template<typename T>
139 concept has_logical_operators = requires(T a)
140 {
141 { a || a } -> assignable_to<T>;
142 { a && a } -> assignable_to<T>;
143 { !a } -> assignable_to<T>;
144 };
145
146 /**********************************************************************/
147 /*! @{ \name dereference/arrow operations
148 **********************************************************************/
149 template<typename T>
150 concept has_dereference = requires(T a)
151 {
152 { *a };
153 };
154
155 template<typename T>
156 concept has_arrow = requires(T a)
157 {
158 { a.operator->() };
159 };
160 //! @}
161
162 /**********************************************************************/
163 /*! \brief constructible_from_tuple concept
164 **********************************************************************/
165 template<typename T, typename TUP>
166 concept constructible_from_tuple = requires
167 {
168 { std::make_from_tuple<T>( std::declval<TUP>() ) };
169 };
170
171 /**********************************************************************/
172 /*! \brief std::get supported
173 **********************************************************************/
174 template<typename T>
175 concept gettable = requires(T a)
176 {
177 { std::get<0>(a) };
178 { std::tuple_size<std::decay_t<T>>::value };
179 };
180
181 /**********************************************************************/
182 /*! \brief Check if lambda/functor takes a set of arguments.
183 **********************************************************************/
184 template<typename L, typename... ARGS>
185 concept lambda = requires(L lambda, ARGS... args)
186 {
187 { lambda(args...) };
188 };
189
190 } // end concepts namespace
191} // end bbm namespace
192
193
194#endif /* _BBM_CONCEPTS_UTIL_H_ */
assignable_to: reverse of std::assignable_from
Definition: util.h:43
constructible_from_tuple concept
Definition: util.h:166
std::get supported
Definition: util.h:175
Definition: util.h:52
Definition: util.h:156
Definition: util.h:97
bit operators
Definition: util.h:124
Definition: util.h:112
Definition: util.h:150
Definition: util.h:79
Definition: util.h:105
logical operators
Definition: util.h:139
Definition: util.h:88
Definition: util.h:61
Check if lambda/functor takes a set of arguments.
Definition: util.h:185
true if type is the same as all of the listed types
Definition: util.h:37
true if type is the same as any of the listed types
Definition: util.h:31
Concept wrapper around a type trait: check if T meets the type TRAIT<T,ARGS...>
Definition: util.h:19
Definition: util.h:25
Definition: aggregatebsdf.h:29
decltype(auto) value(T &&t)
return the value of an attribute, or if not an attribute the object
Definition: attribute_value.h:20