Utopia  2
Framework for studying models of complex & adaptive systems.
type_traits.hh
Go to the documentation of this file.
1 
2 #ifndef UTOPIA_CORE_TYPETRAITS_HH
3 #define UTOPIA_CORE_TYPETRAITS_HH
4 
5 #include <cmath>
6 #include <iomanip>
7 #include <iostream> // needed for operator<< overloads
8 #include <limits>
9 #include <type_traits>
10 #include <vector>
11 #include <tuple>
12 #include <utility>
13 #include <string>
14 #include <sstream> // needed for making string representations of arb. types
15 #include <string_view>
16 
17 #include <boost/hana/ext/std/tuple.hpp>
18 #include <boost/hana/for_each.hpp>
19 #include <boost/hana/tuple.hpp>
20 
21 #include <armadillo>
22 
23 /*
24  * Implementation logic: prototype with two template parameters, <T, std::void_t<>>
25  * holding boolean member that is false, and
26  * specialization with <T, std::void_t<some, conditions, defining, concept>>
27  * holding booleaen member which is true.
28 */
29 
30 namespace Utopia
31 {
32 namespace Utils
33 {
39 template < typename T, typename U = std::void_t<> >
41 {
42  using type = T;
43 };
44 
51 template < typename T >
53  T,
54  std::enable_if_t< std::is_pointer_v< T >, std::void_t<> > >
55 {
57 };
58 
64 template < typename T >
66 
73 template < typename T >
74 struct remove_pointer< T,
75  std::enable_if_t< std::is_array_v< T >, std::void_t<> > >
76 {
77  using type =
79 };
80 
88 template < typename T >
90 {
91  using type =
92  std::remove_cv_t< remove_pointer_t< std::remove_reference_t< T > > >;
93 };
94 
96 template < typename T >
98 
103 template < typename T >
104 struct is_string : public std::false_type
105 {
106 };
107 
111 template < typename... Ts >
112 struct is_string< std::basic_string< Ts... > > : public std::true_type
113 {
114 };
115 
119 template< typename... Ts>
120 struct is_string<std::basic_string_view<Ts...>> : public std::true_type{};
121 
125 template <>
126 struct is_string< const char* > : public std::true_type
127 {
128 };
129 
133 template <>
134 struct is_string< char* > : public std::true_type
135 {
136 };
137 
139 template < typename T >
140 constexpr inline bool is_string_v = is_string< T >::value;
141 
148 template < typename T, typename = std::void_t<> >
149 struct is_iterable : std::false_type
150 {
151 };
152 
159 template < typename T >
160 struct is_iterable< T, std::void_t< typename T::iterator > > : std::true_type
161 {
162 };
163 
165 template < typename T >
166 inline constexpr bool is_iterable_v = is_iterable< T >::value;
167 
174 template < class T, class U = std::void_t<> >
175 struct is_container : public std::false_type
176 {
177 };
178 
180 template < typename T >
181 inline constexpr bool is_container_v = is_container< T >::value;
182 
189 template < typename T >
190 struct is_container< T,
191  std::void_t< std::enable_if_t<
192  is_iterable_v< remove_qualifier_t< T > > and
193  not is_string_v< remove_qualifier_t< T > >,
194  int > > > : public std::true_type
195 {
196 }; // FIXME: there is something inconsistent in the **usage** of this
197  // metafunction that requires the use of `remove_qualifier` in order to keep
198  // the tests functional. The cause is not the metafunction itself, but its
199  // use. Fix this when possible at some point.
200 
209 template < typename T, typename = std::void_t<> >
210 struct is_associative_container : std::false_type
211 {
212 };
213 
222 template < typename T >
224  T,
225  std::void_t< std::enable_if_t< is_container_v< T >, int >,
226  typename T::key_type,
227  typename T::key_compare > > : std::true_type
228 {
229 };
230 
232 template < typename T >
233 inline constexpr bool is_associative_container_v =
235 
244 template < typename T, typename = std::void_t<> >
245 struct is_unordered_associative_container : std::false_type
246 {
247 };
248 
257 template < typename T >
259  T,
260  std::void_t< std::enable_if_t< is_container_v< T >, int >,
261  typename T::key_type,
262  typename T::value_type,
263  typename T::hasher > > : std::true_type
264 {
265 };
266 
268 template < typename T >
271 
279 template < typename T, typename = std::void_t<> >
280 struct is_linear_container : std::false_type
281 {
282 };
283 
291 template < typename T >
293  T,
294  std::void_t<
295  std::enable_if_t< not is_associative_container_v< T > and
296  not is_unordered_associative_container_v< T > and
297  is_container_v< T >,
298  int > > > : std::true_type
299 {
300 };
301 
307 template < typename T >
309 
315 template < typename T, typename = std::void_t<> >
316 struct is_random_access_container : std::false_type
317 {
318 };
319 
325 template < typename T >
327  T,
328  std::void_t< std::enable_if_t<
329  is_linear_container_v< T > and
330  std::is_convertible_v< typename std::iterator_traits<
331  typename T::iterator >::iterator_category,
332  std::random_access_iterator_tag > > > >
333  : std::true_type
334 {
335 };
336 
338 template < typename T >
339 inline constexpr bool is_random_access_container_v =
341 
347 template < typename T, typename U = std::void_t<> >
348 struct has_vertex_descriptor : std::false_type
349 {
350 };
351 
356 template < typename T >
357 struct has_vertex_descriptor< T, std::void_t< typename T::vertex_descriptor > >
358  : std::true_type
359 {
360 };
361 
363 template < typename T >
364 inline constexpr bool has_vertex_descriptor_v =
366 
372 template < typename T, typename U = std::void_t<> >
373 struct has_edge_descriptor : std::false_type
374 {
375 };
376 
381 template < typename T >
382 struct has_edge_descriptor< T, std::void_t< typename T::edge_descriptor > >
383  : std::true_type
384 {
385 };
386 
388 template < typename T >
390 
396 template < typename T, typename U = std::void_t<> >
397 struct is_graph : std::false_type
398 {
399 };
400 
407 template < typename T >
408 struct is_graph<
409  T,
410  std::void_t< std::enable_if_t< has_edge_descriptor_v< T > and
411  has_vertex_descriptor_v< T >,
412  int > > > : std::true_type
413 {
414 };
415 
417 template < typename T >
418 inline constexpr bool is_graph_v = is_graph< T >::value;
419 
430 template < typename T >
431 struct get_size
432  : std::integral_constant<
433  std::size_t,
434  std::numeric_limits< std::size_t >::max() > // scalar have an
435  // unrealistic size ->
436  // distinguish from size 1
437  // array/tuple...
438 {
439 };
440 
442 template < typename T, std::size_t N >
443 struct get_size< std::array< T, N > > : std::integral_constant< std::size_t, N >
444 {
445 };
446 
448 template < typename... Ts >
449 struct get_size< std::tuple< Ts... > >
450  : std::integral_constant< std::size_t, sizeof...(Ts) >
451 {
452 };
453 
455 template < typename A, typename B >
456 struct get_size< std::pair< A, B > > : std::integral_constant< std::size_t, 2 >
457 {
458 };
459 
461 template < typename... Ts >
462 struct get_size< boost::hana::tuple< Ts... > >
463  : std::integral_constant< std::size_t, sizeof...(Ts) >
464 {
465 };
466 
468 template < arma::uword N, arma::uword M >
469 struct get_size< arma::mat::fixed< N, M > >
470  : std::integral_constant< std::size_t, N * M >
471 {
472 };
473 
475 template < arma::uword N, arma::uword M >
476 struct get_size< arma::imat::fixed< N, M > >
477  : std::integral_constant< std::size_t, N * M >
478 {
479 };
480 
482 template < arma::uword N, arma::uword M >
483 struct get_size< arma::s32_mat::fixed< N, M > >
484  : std::integral_constant< std::size_t, N * M >
485 {
486 };
487 
489 template < arma::uword N, arma::uword M >
490 struct get_size< arma::u32_mat::fixed< N, M > >
491  : std::integral_constant< std::size_t, N * M >
492 {
493 };
494 
496 template < arma::uword N, arma::uword M >
497 struct get_size< arma::umat::fixed< N, M > >
498  : std::integral_constant< std::size_t, N * M >
499 {
500 };
501 
503 template < arma::uword N, arma::uword M >
504 struct get_size< arma::fmat::fixed< N, M > >
505  : std::integral_constant< std::size_t, N * M >
506 {
507 };
508 
510 template < arma::uword N >
511 struct get_size< arma::vec::fixed< N > >
512  : std::integral_constant< std::size_t, N >
513 {
514 };
515 
517 template < arma::uword N >
518 struct get_size< arma::ivec::fixed< N > >
519  : std::integral_constant< std::size_t, N >
520 {
521 };
522 
524 template < arma::uword N >
525 struct get_size< arma::s32_vec::fixed< N > >
526  : std::integral_constant< std::size_t, N >
527 {
528 };
529 
531 template < arma::uword N >
532 struct get_size< arma::uvec::fixed< N > >
533  : std::integral_constant< std::size_t, N >
534 {
535 };
536 
538 template < arma::uword N >
539 struct get_size< arma::u32_vec::fixed< N > >
540  : std::integral_constant< std::size_t, N >
541 {
542 };
543 
545 template < arma::uword N >
546 struct get_size< arma::fvec::fixed< N > >
547  : std::integral_constant< std::size_t, N >
548 {
549 };
550 
552 template < arma::uword N >
553 struct get_size< arma::rowvec::fixed< N > >
554  : std::integral_constant< std::size_t, N >
555 {
556 };
557 
559 template < arma::uword N >
560 struct get_size< arma::irowvec::fixed< N > >
561  : std::integral_constant< std::size_t, N >
562 {
563 };
564 
566 template < arma::uword N >
567 struct get_size< arma::s32_rowvec::fixed< N > >
568  : std::integral_constant< std::size_t, N >
569 {
570 };
571 
573 template < arma::uword N >
574 struct get_size< arma::u32_rowvec::fixed< N > >
575  : std::integral_constant< std::size_t, N >
576 {
577 };
578 
580 template < arma::uword N >
581 struct get_size< arma::urowvec::fixed< N > >
582  : std::integral_constant< std::size_t, N >
583 {
584 };
585 
587 template < arma::uword N >
588 struct get_size< arma::frowvec::fixed< N > >
589  : std::integral_constant< std::size_t, N >
590 {
591 };
592 
593 // Shorthand for get_size<T>::value
594 template < typename T >
595 inline constexpr std::size_t get_size_v = get_size< T >::value;
596 
606 template < typename T, typename U = std::void_t<> >
607 struct is_array_like : std::false_type
608 {
609 };
610 
620 template < typename T >
622  T,
623  std::void_t<
624  std::enable_if_t< get_size_v< T > !=
625  std::numeric_limits< std::size_t >::max() and
626  is_container_v< T > >,
627  int > > : std::true_type
628 {
629 };
630 
632 template < typename T >
634 
643 template < typename T, std::size_t s >
644 struct has_static_size_base : std::true_type
645 {
646 };
647 
655 template < typename T >
656 struct has_static_size_base< T, std::numeric_limits< std::size_t >::max() >
657  : std::false_type
658 {
659 };
660 
668 template < typename T >
669 struct has_static_size : has_static_size_base< T, get_size_v< T > >
670 {
671 };
672 
674 template < typename T >
676 
683 template < typename T, typename X = std::void_t<> >
685 {
686  public:
687  static constexpr bool value = false;
688 };
689 
696 template < typename T >
698  T,
699  std::void_t< std::enable_if_t< std::is_class_v< std::decay_t< T > >, T > > >
700 {
701 
702  struct Fallback
703  {
704  void
706  };
707 
708  struct Derived
709  : T
710  , Fallback
711  {
712  };
713 
714  template < typename U, U >
715  struct Check;
716 
717  typedef char True[1]; // typedef for an array of size one.
718  typedef char False[2]; // typedef for an array of size two.
719 
720  template < typename S >
721  static constexpr True&
722  f(...);
723 
724  template < typename S >
725  static constexpr False&
726  f(Check< void (Fallback::*)(), &S::operator() >*);
727 
728  public:
729  static constexpr bool value = (sizeof(f< Derived >(nullptr)) == 1);
730 };
731 
733 template < typename T >
735 
741 struct Nothing
742 {
743 };
744 
745 }
746 }
747 
748 #endif
Check if a type T is callable, i.e., if it has.
Definition: type_traits.hh:685
static constexpr bool value
Definition: type_traits.hh:687
constexpr bool has_vertex_descriptor_v
Shorthand for has_vertex_descriptor<T>::value.
Definition: type_traits.hh:364
constexpr bool is_graph_v
Shorthand for is_graph<T>::value.
Definition: type_traits.hh:418
constexpr bool is_associative_container_v
Shorthand for is_associative_container<T>::value.
Definition: type_traits.hh:233
constexpr bool is_callable_v
Shorthand for is_callable<T>::value.
Definition: type_traits.hh:734
constexpr bool is_random_access_container_v
shorthand for is_linear_container<T>::value
Definition: type_traits.hh:339
constexpr bool is_container_v
Shorthand for 'is_container::value.
Definition: type_traits.hh:181
constexpr std::size_t get_size_v
Definition: type_traits.hh:595
typename remove_pointer< T >::type remove_pointer_t
Shorthand for 'typename remove_pointer<T>::type'.
Definition: type_traits.hh:65
constexpr bool has_static_size_v
Shorthand for has_static_size::value.
Definition: type_traits.hh:675
constexpr bool is_linear_container_v
Shorthand for is_linear_container<T>::value.
Definition: type_traits.hh:308
constexpr bool has_edge_descriptor_v
shothand for has_edge_descriptor<T>::value
Definition: type_traits.hh:389
constexpr bool is_unordered_associative_container_v
Shorthand for is_unordered_associative_container<T>::value.
Definition: type_traits.hh:269
constexpr bool is_iterable_v
shorthand for is_iterable<T>::value
Definition: type_traits.hh:166
typename remove_qualifier< T >::type remove_qualifier_t
Shorthand for 'typename remove_qualifier::value'.
Definition: type_traits.hh:97
constexpr bool is_array_like_v
Shorthand for is_array_like<T>::value.
Definition: type_traits.hh:633
constexpr bool is_string_v
Shorthand for 'is_string<T>::value'.
Definition: type_traits.hh:140
Definition: agent.hh:11
Definition: parallel.hh:235
Represent a type that does nothing and represents nothing, hence can be used in metaprogramming whene...
Definition: type_traits.hh:742
Return the size of a Type T containing other types at compile time. If no object for which an overloa...
Definition: type_traits.hh:438
Check if a type T has a edge descriptor.
Definition: type_traits.hh:374
Determine if type T is 'tuplelike'. This is not intended to be used explicitly, refer to 'has_static_...
Definition: type_traits.hh:645
Determine if type T is tuple_like, i.e., has a compile time constant size which is smaller than std::...
Definition: type_traits.hh:670
Check if a type T has a vertex descriptor.
Definition: type_traits.hh:349
Check if a given type is homogeneous and has a size which is a compile time constant....
Definition: type_traits.hh:608
Check if a type T is an associative container type, i.e. a container type T that defines T::key_type ...
Definition: type_traits.hh:211
Check if a type is a container type, which does not include string types.
Definition: type_traits.hh:176
Check if some type T is a graph by checking if it has edge - and vertex_descriptors.
Definition: type_traits.hh:398
Check if a type T is iterable, i.e., if it defines T::iterable.
Definition: type_traits.hh:150
Check if a type T is a linear container. A linear container for us is any type T that is a container ...
Definition: type_traits.hh:281
Check if a type T is a random access container, i.e., any container type T that has an iterator tagge...
Definition: type_traits.hh:317
Check if a type T is a string-like type, i.e. std::basic_string, const char*, char*,...
Definition: type_traits.hh:105
Check if a type T is an unordered associative container type, i.e. a container type T that defines T:...
Definition: type_traits.hh:246
typename remove_pointer< std::remove_all_extents_t< T > >::type type
Definition: type_traits.hh:78
typename remove_pointer< std::remove_pointer_t< T > >::type type
Definition: type_traits.hh:56
Helper function for removing pointer qualifiers from a type recursivly This is the recursion base cas...
Definition: type_traits.hh:41
T type
Definition: type_traits.hh:42
Function for removing the qualifiers from a type T. Qualifiers are 'const', 'volative',...
Definition: type_traits.hh:90
std::remove_cv_t< remove_pointer_t< std::remove_reference_t< T > > > type
Definition: type_traits.hh:92