Loading [MathJax]/extensions/tex2jax.js
Theoretica
Mathematical Library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Macros Pages
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 considerable a matrix. The std::enable_if structure
153 // is used, with type T which defaults to bool.
154 template<typename Structure, typename T = bool>
155 using enable_matrix = std::enable_if_t<is_matrix<Structure>::value, T>;
156
157
158 // Enable a function overload if the template typename
159 // is considerable a vector. 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_vector = std::enable_if_t<is_vector<Structure>::value, T>;
163
164
165 // Extract the type of the arguments of a function.
166 template<typename Function>
167 struct extract_func_args;
168
169 template<typename Function, typename... Args>
170 struct extract_func_args<Function(Args...)> {
171 using type = std::tuple<Args...>;
172 };
173
174
175 namespace _internal {
176
177 // Helper structure to extract the first type of a variadic template
178 template<typename Arg, typename ...Other>
179 struct get_first {
180 using type = Arg;
181 };
182
183 // Helper structure for is_real_func and related traits
184
185 template<typename Function, typename T, typename = void>
186 struct return_type_or_void {
187 using type = void;
188 };
189
190 // Helper structure for is_real_func and related traits
191 template<typename Function, typename T>
192 struct return_type_or_void
193 <Function, T, _internal::void_t<decltype(std::declval<Function>()(T(0.0)))>> {
194 using type = decltype(std::declval<Function>()(T(0.0)));
195 };
196
197
198 // Helper structure for extracting information from Callables
199 template<typename T>
200 struct func_helper : public func_helper<decltype(&T::operator())> {};
201
202
203 template<typename ReturnType, typename ...Args>
204 struct func_helper<ReturnType(Args...)> {
205
206 using return_type = ReturnType;
207 using args_type = std::tuple<Args...>;
208 using first_arg_type = typename get_first<Args...>::type;
209 };
210
211 template<typename ReturnType, typename ...Args>
212 struct func_helper<ReturnType(*)(Args...)> {
213
214 using return_type = ReturnType;
215 using args_type = std::tuple<Args...>;
216 using first_arg_type = typename get_first<Args...>::type;
217 };
218
219 template<typename Class, typename ReturnType, typename ...Args>
220 struct func_helper<ReturnType(Class::*)(Args...) const> {
221
222 using return_type = ReturnType;
223 using args_type = std::tuple<Args...>;
224 using first_arg_type = typename get_first<Args...>::type;
225 };
226 }
227
228
229 // Type trait to check whether the given function takes
230 // a real number as its first argument.
231 template<typename Function>
232 using is_real_func =
233 std::conditional_t<
234 is_real_type <
235 typename _internal::return_type_or_void<Function, real>::type
236 >::value,
237 std::true_type, std::false_type
238 >;
239
240
241 // Enable a certain function overload if the given type
242 // is a function taking as first argument a real number
243 template<typename Function, typename T = bool>
244 using enable_real_func =
245 typename std::enable_if_t<is_real_func<Function>::value, T>;
246
247
248 // Extract the return type of a Callable object, such as a function
249 // pointer or lambda function.
250 template<typename Function>
251 using return_type_t = typename _internal::func_helper<Function>::return_type;
252
253}
254
255#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:198