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 for is_real_func and related traits
184  template<typename Function, typename T, typename = void>
186  using type = void;
187  };
188 
189  // Helper structure for is_real_func and related traits
190  template<typename Function, typename T>
192  <Function, T, _internal::void_t<decltype(std::declval<Function>()(T(0.0)))>> {
193  using type = decltype(std::declval<Function>()(T(0.0)));
194  };
195 
196 
197  // Helper structure for extracting information from Callables
198  template<class T>
199  struct func_helper : public func_helper<decltype(&T::operator())> {};
200 
201  template<class ReturnType, class... Args>
202  struct func_helper<ReturnType(Args...)> {
203 
204  using return_type = ReturnType;
205  using args_type = std::tuple<Args...>;
206  };
207 
208  template<class ReturnType, class... Args>
209  struct func_helper<ReturnType(*)(Args...)> {
210 
211  using return_type = ReturnType;
212  using args_type = std::tuple<Args...>;
213  };
214 
215  template<class Class, class ReturnType, class... Args>
216  struct func_helper<ReturnType(Class::*)(Args...) const> {
217 
218  using return_type = ReturnType;
219  using args_type = std::tuple<Args...>;
220  };
221  }
222 
223 
226  template<typename Function>
227  using is_real_func =
228  std::conditional_t<
229  is_real_type <
230  typename _internal::return_type_or_void<Function, real>::type
231  >::value,
232  std::true_type, std::false_type
233  >;
234 
235 
238  template<typename Function, typename T = bool>
240  typename std::enable_if_t<is_real_func<Function>::value, T>;
241 
242 
245  template<typename Function>
247 
248 }
249 
250 #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:188
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:240
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:246
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:233
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:199
Definition: core_traits.h:21
Definition: core_traits.h:185
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