Theoretica
A C++ numerical and automatic mathematical library
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 
14 namespace theoretica {
15 
16 
17  // Implement a simple void_t trait in C++14.
19  namespace _internal {
20  template<typename ...Args>
21  struct make_void { typedef void type; };
22  template<typename ...Args>
23  using void_t = typename make_void<Args...>::type;
24  }
25 
26 
29  template<typename Type>
30  struct is_real_type : std::is_floating_point<Type> {};
31 
34  template<>
35  struct is_real_type<real> : std::true_type {};
36 
37 
40  template<typename Structure, typename = _internal::void_t<>>
41  struct is_orderable : std::false_type{};
42 
43  // The @internal directive is used to avoid documenting this overload
45  template<typename Structure>
46  struct is_orderable
47  <Structure, _internal::void_t<
48  decltype(std::declval<Structure>() < std::declval<Structure>())>
49  > : std::true_type{};
50 
51 
54  template<typename Structure, typename = _internal::void_t<>>
55  struct is_indexable : std::false_type{};
56 
58  template<typename Structure>
59  struct is_indexable
60  <Structure, _internal::void_t<
61  decltype(std::declval<Structure>()[0])>
62  > : std::true_type{};
63 
64 
67  template<typename Structure, typename = _internal::void_t<>>
68  struct is_iterable : std::false_type{};
69 
71  template<typename Structure>
72  struct is_iterable
73  <Structure, _internal::void_t<
74  decltype(std::declval<Structure>().begin())>
75  > : std::true_type{};
76 
77 
80  template<typename Structure, typename = _internal::void_t<>>
81  struct is_vector : std::false_type{};
82 
83  template<typename Structure>
84  struct is_vector
85  <Structure, _internal::void_t<
86  decltype(std::declval<Structure>()[0]),
87  decltype(std::declval<Structure>().size())>
88  > : std::true_type{};
89 
90 
94  template<typename Structure, typename = _internal::void_t<>>
95  struct is_matrix : std::false_type{};
96 
98  template<typename Structure>
99  struct is_matrix
100  <Structure, _internal::void_t<
101  decltype(std::declval<Structure>()(0, 0)),
102  decltype(std::declval<Structure>().rows()),
103  decltype(std::declval<Structure>().cols())>
104  > : std::true_type{};
105 
106 
108  namespace _internal {
109 
111  template<typename Structure, typename = void>
113  using type = void;
114  };
115 
117  template<typename Structure>
119  <Structure, _internal::void_t<decltype(std::declval<Structure&>()[0])>> {
120  using type = std::remove_reference_t<decltype(std::declval<Structure>()[0])>;
121  };
122  }
123 
126  template<typename Structure>
128  typename _internal::vector_element_or_void<Structure>::type;
129 
130 
132  template<typename Structure>
134  std::remove_reference_t<decltype(std::declval<Structure>()[0])>;
135 
136 
138  template<typename Structure>
140  std::remove_reference_t<decltype(std::declval<Structure>()(0, 0))>;
141 
142 
145  template<typename Structure, typename Type>
147  : std::is_same<vector_element_t<Structure>, Type> {};
148 
149 
152  template<typename Structure>
154 
155 
159  template<typename Structure, typename T = bool>
160  using enable_matrix = std::enable_if_t<is_matrix<Structure>::value, T>;
161 
162 
166  template<typename Structure, typename T = bool>
167  using enable_vector = std::enable_if_t<is_vector<Structure>::value, T>;
168 
169 
171  template<typename Function>
173 
175  template<typename Function, typename... Args>
176  struct extract_func_args<Function(Args...)> {
177  using type = std::tuple<Args...>;
178  };
179 
180 
181  namespace _internal {
182 
183  // Helper structure to extract the first type of a variadic template
184  template<typename Arg, typename ...Other>
185  struct get_first {
186  using type = Arg;
187  };
188 
189  // Helper structure for is_real_func and related traits
190  template<typename Function, typename T, typename = void>
192  using type = void;
193  };
194 
195  // Helper structure for is_real_func and related traits
196  template<typename Function, typename T>
198  <Function, T, _internal::void_t<decltype(std::declval<Function>()(T(0.0)))>> {
199  using type = decltype(std::declval<Function>()(T(0.0)));
200  };
201 
202 
203  // Helper structure for extracting information from Callables
204  template<typename T>
205  struct func_helper : public func_helper<decltype(&T::operator())> {};
206 
207  template<typename ReturnType, typename ...Args>
208  struct func_helper<ReturnType(Args...)> {
209 
210  using return_type = ReturnType;
211  using args_type = std::tuple<Args...>;
212  using first_arg_type = typename get_first<Args...>::type;
213  };
214 
215  template<typename ReturnType, typename ...Args>
216  struct func_helper<ReturnType(*)(Args...)> {
217 
218  using return_type = ReturnType;
219  using args_type = std::tuple<Args...>;
220  using first_arg_type = typename get_first<Args...>::type;
221  };
222 
223  template<typename Class, typename ReturnType, typename ...Args>
224  struct func_helper<ReturnType(Class::*)(Args...) const> {
225 
226  using return_type = ReturnType;
227  using args_type = std::tuple<Args...>;
228  using first_arg_type = typename get_first<Args...>::type;
229  };
230  }
231 
232 
235  template<typename Function>
236  using is_real_func =
237  std::conditional_t<
238  is_real_type <
239  typename _internal::return_type_or_void<Function, real>::type
240  >::value,
241  std::true_type, std::false_type
242  >;
243 
244 
247  template<typename Function, typename T = bool>
249  typename std::enable_if_t<is_real_func<Function>::value, T>;
250 
251 
254  template<typename Function>
256 
257 }
258 
259 #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
typename std::enable_if_t< is_real_func< Function >::value, T > enable_real_func
Enable a certain function overload if the given type is a function taking as first argument a real nu...
Definition: core_traits.h:249
typename _internal::func_helper< Function >::return_type return_type_t
Extract the return type of a Callable object, such as a function pointer or lambda function.
Definition: core_traits.h:255
std::remove_reference_t< decltype(std::declval< Structure >()(0, 0))> matrix_element_t
Extract the type of a matrix (or any doubly indexable container) from its operator().
Definition: core_traits.h:140
std::remove_reference_t< decltype(std::declval< Structure >()[0])> vector_element_t
Extract the type of a vector (or any indexable container) from its operator[].
Definition: core_traits.h:134
std::enable_if_t< is_vector< Structure >::value, T > enable_vector
Enable a function overload if the template typename is considerable a vector.
Definition: core_traits.h:167
typename _internal::vector_element_or_void< Structure >::type vector_element_or_void_t
Extract the type of a vector (or any indexable container) from its operator[], returning void if the ...
Definition: core_traits.h:128
std::conditional_t< is_real_type< typename _internal::return_type_or_void< Function, real >::type >::value, std::true_type, std::false_type > is_real_func
Type trait to check whether the given function takes a real number as its first argument.
Definition: core_traits.h:242
std::enable_if_t< is_matrix< Structure >::value, T > enable_matrix
Enable a function overload if the template typename is considerable a matrix.
Definition: core_traits.h:160
Definition: core_traits.h:205
Definition: core_traits.h:185
Definition: core_traits.h:21
Definition: core_traits.h:191
Helper structure for vector_element_t.
Definition: core_traits.h:112
Extract the type of the arguments of a function.
Definition: core_traits.h:172
Type trait to check whether an indexable container has elements of the given type.
Definition: core_traits.h:147
Check whether a structure is indexable by a single integer index, by checking that it has the operato...
Definition: core_traits.h:55
Check whether a structure is iterable, by checking that it has a method begin().
Definition: core_traits.h:68
Check whether a structure is considerable a matrix, by checking that it has an operator(),...
Definition: core_traits.h:95
Check whether a structure is orderable, by checking that it has a comparison operator<().
Definition: core_traits.h:41
Type trait to check whether a type represents a real number.
Definition: core_traits.h:30
Check whether a structure is considerable a vector, by checking that it has an operator[] and a size(...
Definition: core_traits.h:81