AMDiS 2.10
The Adaptive Multi-Dimensional Simulation Toolbox
TypeTraits.hpp
1#pragma once
2
3#include <memory>
4#include <type_traits>
5
6namespace AMDiS
7{
9
16 template <class T>
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>
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:158
A variadic type list.
Definition: TypeTraits.hpp:146
Remove cv and ref qualifiers of type T.
Definition: TypeTraits.hpp:18