AMDiS  2.10
The Adaptive Multi-Dimensional Simulation Toolbox
TypeTraits.hpp
1 #pragma once
2 
3 #include <memory>
4 #include <type_traits>
5 
6 namespace AMDiS
7 {
9 
16  template <class T>
17  struct remove_cvref
18  {
19  using type = std::remove_cv_t<std::remove_reference_t<T>>;
20  };
21 
23  template <class T>
24  using remove_cvref_t = typename remove_cvref<T>::type;
25 
26  namespace Impl
27  {
28  template <class T>
29  struct UnderlyingType
30  {
31  using type = T;
32  };
33 
34  template <class T>
35  struct UnderlyingType<T&>
36  {
37  using type = typename UnderlyingType<T>::type;
38  };
39 
40  template <class T>
41  struct UnderlyingType<T*>
42  {
43  using type = typename UnderlyingType<T>::type;
44  };
45 
46  template <class T>
47  struct UnderlyingType<T* const>
48  {
49  using type = typename UnderlyingType<T>::type;
50  };
51 
52  template <class T>
53  struct UnderlyingType<std::reference_wrapper<T>>
54  {
55  using type = typename UnderlyingType<T>::type;
56  };
57 
58  template <class T>
59  struct UnderlyingType<std::shared_ptr<T>>
60  {
61  using type = typename UnderlyingType<T>::type;
62  };
63 
64  template <class T>
65  struct UnderlyingType<std::shared_ptr<T> const>
66  {
67  using type = typename UnderlyingType<T>::type;
68  };
69 
70  template <class T>
71  struct UnderlyingType<std::unique_ptr<T>>
72  {
73  using type = typename UnderlyingType<T>::type;
74  };
75 
76  template <class T>
77  struct UnderlyingType<std::unique_ptr<T> const>
78  {
79  using type = typename UnderlyingType<T>::type;
80  };
81  }
82 
84  template <class T>
85  using Underlying_t = typename Impl::UnderlyingType<T>::type;
86 
87 
88  // overload for l-values
89  template <class T>
90  T& underlying(T& value)
91  {
92  return value;
93  }
94 
95  // overload for l-value pointers
96  template <class T>
97  T& underlying(T* value)
98  {
99  return *value;
100  }
101 
102  // overload for plain r-values is deleted
103  template <class T>
104  T underlying(T&& value) = delete;
105 
106  // overload for reference-wrappers
107  template <class T>
108  T& underlying(std::reference_wrapper<T> const& value)
109  {
110  return value.get();
111  }
112 
113  // overload for shared_ptr
114  template <class T>
115  T& underlying(std::shared_ptr<T> const& value)
116  {
117  return *value;
118  }
119 
120  // overload for unique_ptr
121  template <class T>
122  T& underlying(std::unique_ptr<T> const& value)
123  {
124  return *value;
125  }
126 
127 
129  #define FWD(...) static_cast<decltype(__VA_ARGS__)>(__VA_ARGS__)
130 
132 #ifdef __GCC__
133  #define TYPEOF(...) __typeof__(__VA_ARGS__)
134 #else
135  #define TYPEOF(...) AMDiS::remove_cvref_t<decltype(__VA_ARGS__)>
136 #endif
137 
138 
140  #define VALUE(...) TYPEOF(__VA_ARGS__)::value
141 
142  // ---------------------------------------------------------------------------
143 
145  template <class... Ts>
146  struct Types {};
147 
148  template <class... Ts>
149  using Types_t = Types<remove_cvref_t<Ts>...>;
150 
151 
153  template <class T>
154  using owner = T;
155 
157  struct NoOp
158  {
159  template <class... T>
160  constexpr void operator()(T&&...) const { /* no nothing */ }
161  };
162 
164  template <class Obj>
165  auto makeUniquePtr(Obj&& obj)
166  {
167  return std::make_unique<TYPEOF(obj)>(FWD(obj));
168  }
169 
170  template <class Obj>
171  auto makeSharedPtr(Obj&& obj)
172  {
173  return std::make_shared<TYPEOF(obj)>(FWD(obj));
174  }
175 
176  template <bool... b>
177  using enable_if_all_t = std::enable_if_t<(b &&...)>;
178 
179 } // end namespace AMDiS
A functor with no operation.
Definition: TypeTraits.hpp:157
A variadic type list.
Definition: TypeTraits.hpp:146
Definition: AdaptBase.hpp:6
Remove cv and ref qualifiers of type T.
Definition: TypeTraits.hpp:17