Theoretica
Scientific Computing
Loading...
Searching...
No Matches
core_traits.h
Go to the documentation of this file.
1
5
6#ifndef THEORETICA_CORE_TRAITS_H
7#define THEORETICA_CORE_TRAITS_H
8
9#include <type_traits>
10#include <tuple>
11#include "constants.h"
12
13
14namespace theoretica {
15
16
17 // Implement a simple void_t trait in C++14.
18 namespace _internal {
19
20 template<typename ...Args>
21 struct make_void { typedef void type; };
22
23 template<typename ...Args>
24 using void_t = typename make_void<Args...>::type;
25 }
26
27
28 template<typename Type>
29 struct is_real_type : std::is_floating_point<Type> {};
30
31 // Type trait to check whether a type represents
32 // a real number.
33 template<>
34 struct is_real_type<real> : std::true_type {};
35
36
37 // Check whether a structure is orderable,
38 // by checking that it has a comparison operator<().
39 template<typename Structure, typename = _internal::void_t<>>
40 struct is_orderable : std::false_type{};
41
42 // The \internal directive is used to avoid documenting this overload
43 template<typename Structure>
44 struct is_orderable
45 <Structure, _internal::void_t<
46 decltype(std::declval<Structure>() < std::declval<Structure>())>
47 > : std::true_type{};
48
49
50 // Check whether a structure is indexable by a single integer index,
51 // by checking that it has the operator[](0).
52 template<typename Structure, typename = _internal::void_t<>>
53 struct is_indexable : std::false_type{};
54
55 template<typename Structure>
56 struct is_indexable
57 <Structure, _internal::void_t<
58 decltype(std::declval<Structure>()[0])>
59 > : std::true_type{};
60
61
62 // Check whether a structure is iterable,
63 // by checking that it has a method begin().
64 template<typename Structure, typename = _internal::void_t<>>
65 struct is_iterable : std::false_type{};
66
67 template<typename Structure>
68 struct is_iterable
69 <Structure, _internal::void_t<
70 decltype(std::declval<Structure>().begin())>
71 > : std::true_type{};
72
73
74 // Check whether a structure is considerable a vector,
75 // by checking that it has an operator[] and a size() method.
76 template<typename Structure, typename = _internal::void_t<>>
77 struct is_vector : std::false_type{};
78
79 template<typename Structure>
80 struct is_vector
81 <Structure, _internal::void_t<
82 decltype(std::declval<Structure>()[0]),
83 decltype(std::declval<Structure>().size())>
84 > : std::true_type{};
85
86
87 // Check whether a structure is considerable a matrix,
88 // by checking that it has an operator(), a rows() method
89 // and a cols() method.
90 template<typename Structure, typename = _internal::void_t<>>
91 struct is_matrix : std::false_type{};
92
93 template<typename Structure>
94 struct is_matrix
95 <Structure, _internal::void_t<
96 decltype(std::declval<Structure>()(0, 0)),
97 decltype(std::declval<Structure>().rows()),
98 decltype(std::declval<Structure>().cols())>
99 > : std::true_type{};
100
101
102 namespace _internal {
103
104 // Helper structure for vector_element_t
105 template<typename Structure, typename = void>
106 struct vector_element_or_void {
107 using type = void;
108 };
109
110 // Helper structure for vector_element_t
111
112 template<typename Structure>
113 struct vector_element_or_void
114 <Structure, _internal::void_t<decltype(std::declval<Structure&>()[0])>> {
115 using type = std::remove_reference_t<decltype(std::declval<Structure>()[0])>;
116 };
117 }
118
119 // Extract the type of a vector (or any indexable container) from its operator[],
120 // returning void if the type has no operator[].
121 template<typename Structure>
122 using vector_element_or_void_t =
123 typename _internal::vector_element_or_void<Structure>::type;
124
125
126 // Extract the type of a vector (or any indexable container) from its operator[].
127 template<typename Structure>
128 using vector_element_t =
129 std::remove_reference_t<decltype(std::declval<Structure>()[0])>;
130
131
132 // Extract the type of a matrix (or any doubly indexable container) from its operator().
133 template<typename Structure>
134 using matrix_element_t =
135 std::remove_reference_t<decltype(std::declval<Structure>()(0, 0))>;
136
137
138 // Type trait to check whether an indexable container
139 // has elements of the given type.
140 template<typename Structure, typename Type>
141 struct has_type_elements
142 : std::is_same<vector_element_t<Structure>, Type> {};
143
144
145 // Type trait to check whether an indexable container
146 // has real elements.
147 template<typename Structure>
148 using has_real_elements = is_real_type<vector_element_t<Structure>>;
149
150
151 // Enable a function overload if the template typename
152 // is a real number type. The std::enable_if structure is used,
153 // with type T which defaults to bool.
154 template<typename Type, typename T = bool>
155 using enable_real = std::enable_if_t<is_real_type<Type>::value, T>;
156
157
158 // Enable a function overload if the template typename
159 // is considerable a matrix. The std::enable_if structure
160 // is used, with type T which defaults to bool.
161 template<typename Structure, typename T = bool>
162 using enable_matrix = std::enable_if_t<is_matrix<Structure>::value, T>;
163
164
165 // Enable a function overload if the template typename
166 // is considerable a vector. The std::enable_if structure
167 // is used, with type T which defaults to bool.
168 template<typename Structure, typename T = bool>
169 using enable_vector = std::enable_if_t<is_vector<Structure>::value, T>;
170
171
172 // Disable a function overload if the template typename
173 // is considerable a vector. The std::enable_if structure
174 // is used, with type T which defaults to bool.
175 template<typename Structure, typename T = bool>
176 using disable_vector = std::enable_if_t<!is_vector<Structure>::value, T>;
177
178
179 namespace _internal {
180
181 // Helper structure to extract the first type of a variadic template
182 template<typename Arg, typename ...Other>
183 struct get_first {
184 using type = Arg;
185 };
186
187 // Helper structure for is_real_func and related traits
188 template<typename Function, typename T, typename = void>
189 struct return_type_or_void {
190 using type = void;
191 };
192
193 // Helper structure for is_real_func and related traits
194 template<typename Function, typename T>
195 struct return_type_or_void
196 <Function, T, _internal::void_t<decltype(std::declval<Function>()(T(0.0)))>> {
197 using type = decltype(std::declval<Function>()(T(0.0)));
198 };
199
200
201 // Helper structure for extracting information from Callables
202 template <typename T> struct func_helper;
203
204 template <typename R, typename... Args>
205 struct func_helper<R(Args...)> {
206
207 // Return type of the function
208 using return_type = R;
209
210 // Tuple of argument types
211 using args_tuple = std::tuple<Args...>;
212
213 // Type of the first argument
214 using first_arg_type = typename get_first<Args...>::type;
215
216 // Arity of the function (number of arguments)
217 static constexpr std::size_t arity = sizeof...(Args);
218 };
219
220 template <typename R, typename... Args>
221 struct func_helper<R(*)(Args...)> : func_helper<R(Args...)> {};
222
223 template <typename C, typename R, typename... Args>
224 struct func_helper<R(C::*)(Args...) const> : func_helper<R(Args...)> {};
225
226 template <typename T>
227 struct func_helper : func_helper<decltype(&T::operator())> {};
228
229 }
230
231
232 // Type trait to check whether the given function takes
233 // a real number as its first argument.
234 template<typename Function>
235 using is_real_func =
236 std::conditional_t<
237 is_real_type <
238 typename _internal::return_type_or_void<Function, real>::type
239 >::value,
240 std::true_type, std::false_type
241 >;
242
243
244 // Enable a certain function overload if the given type
245 // is a function taking as first argument a real number
246 template<typename Function, typename T = bool>
247 using enable_real_func =
248 typename std::enable_if_t<is_real_func<Function>::value, T>;
249
250
251 // Extract the return type of a Callable object, such as a function
252 // pointer or lambda function.
253 template<typename Function>
254 using return_type_t = typename _internal::func_helper<Function>::return_type;
255
256}
257
258#endif
Mathematical constants and default algorithm parameters.
Main namespace of the library which contains all functions and objects.
Definition algebra.h:27
double real
A real number, defined as a floating point type.
Definition constants.h:207
Vector make_error()
Create a vector representing an error state, with all NaN values.
Definition algebra.h:103