CVB++ 15.0
variant_helper.hpp
1#pragma once
2
7
8#include <cassert>
9#include <typeinfo>
10#include <type_traits>
11
12#include "../../namespace.hpp"
13
14namespace Cvb
15{
16
17 CVB_BEGIN_INLINE_NS
18
19 namespace Shims
20 {
21 namespace Detail
22 {
23
25 template <bool V>
27
29 template <size_t V>
31
32#pragma region Max
33
34 namespace // NOLINT(cert-dcl59-cpp)
35 {
36
38 template <size_t... VALUES>
39 struct MaxImpl
40 {
41 static_assert(sizeof...(VALUES) == 0, "CVB: no empty alternative lists");
42 };
43
44 template <size_t VALUE>
45 struct MaxImpl<VALUE> : SizeT<VALUE>
46 {
47 };
48
49 template <size_t VALUE0, size_t VALUE1, size_t... REST>
50 struct MaxImpl<VALUE0, VALUE1, REST...>
51 {
52 static const constexpr size_t value =
53 VALUE1 < VALUE0 ? MaxImpl<VALUE0, REST...>::value : MaxImpl<VALUE1, REST...>::value;
54 };
55
56 } // namespace
57
59 template <size_t... VALUES>
60 static const constexpr size_t Max = MaxImpl<VALUES...>::value;
61
62#pragma endregion
63
64#pragma region NoneIs
65
66 namespace // NOLINT(cert-dcl59-cpp)
67 {
68
70 template <bool... VALUES>
71 struct NoneIsImpl;
72
73 template <>
74 struct NoneIsImpl<> : BoolT<true>
75 {
76 };
77
78 template <bool VALUE>
79 struct NoneIsImpl<VALUE> : BoolT<!VALUE>
80 {
81 };
82
83 template <bool VALUE, bool... REST>
84 struct NoneIsImpl<VALUE, REST...> : BoolT<!VALUE && NoneIsImpl<REST...>::value>
85 {
86 };
87
88 } // namespace
89
90 template <bool... VALUES>
91 static const constexpr bool NoneIs = NoneIsImpl<VALUES...>::value;
92
93#pragma endregion
94
95#pragma region IndexOf
96
97 namespace // NOLINT(cert-dcl59-cpp)
98 {
100 template <size_t V>
101 struct CappedIncrement : SizeT<V + 1>
102 {
103 };
104
105 template <>
106 struct CappedIncrement<size_t(-1)> : SizeT<size_t(-1)>
107 {
108 };
109
111 template <class T, class... REST>
112 struct IndexOfImpl;
113
114 template <class T>
115 struct IndexOfImpl<T> : SizeT<size_t(-1)>
116 {
117 };
118
119 template <class T, class... REST>
120 struct IndexOfImpl<T, T, REST...> : SizeT<0>
121 {
122 };
123
124 template <class T, class U, class... REST>
125 struct IndexOfImpl<T, U, REST...> : SizeT<CappedIncrement<IndexOfImpl<T, REST...>::value>::value>
126 {
127 };
128
129 } // namespace
130
132 template <class T, class... TS>
133 static const constexpr size_t IndexOf =
134 IndexOfImpl<typename std::remove_cv<typename std::remove_reference<T>::type>::type, TS...>::value;
135
137 template <class T, class... TS>
138 static const constexpr bool Contains = BoolT<IndexOf<T, TS...> != size_t(-1)>::value;
139
140#pragma endregion
141
142#pragma region IndexOfAssignable
143
144 namespace // NOLINT(cert-dcl59-cpp)
145 {
146
148 template <class T, class... REST>
149 struct IndexOfAssignableImpl;
150
151 template <class T>
152 struct IndexOfAssignableImpl<T> : SizeT<size_t(-1)>
153 {
154 };
155
156 template <class T, class U, class... REST>
157 struct IndexOfAssignableImpl<T, U, REST...>
158 {
159 static const constexpr size_t value =
160 std::is_assignable<U, T>::value ? 0 : CappedIncrement<IndexOfAssignableImpl<T, REST...>::value>::value;
161 };
162
163 } // namespace
164
167 template <class T, class... TS>
168 static const constexpr size_t IndexOfAssignable = IndexOfAssignableImpl<T, TS...>::value;
169
170#pragma endregion
171
172#pragma region TypeAt
173
174 namespace // NOLINT(cert-dcl59-cpp)
175 {
176
178 template <size_t I, class... TS>
179 struct TypeAtImpl;
180
181 template <class T, class... TS>
182 struct TypeAtImpl<0, T, TS...>
183 {
184 using type = T;
185 };
186
187 template <size_t I, class T, class... TS>
188 struct TypeAtImpl<I, T, TS...>
189 {
190 using type = typename TypeAtImpl<I - 1, TS...>::type;
191 };
192
193 } // namespace
194
196 template <size_t I, class... TS>
197 using TypeAt = typename TypeAtImpl<I, TS...>::type;
198
199#pragma endregion
200
201#pragma region VariantDestructor
202
204 struct VariantDestructor
205 {
206#pragma warning(push)
207#pragma warning(disable : 4100) // unreference paramete warning if type does not implement dtor
209 template <class T>
210 void operator()(T &value) const noexcept
211 {
212 value.~T();
213 }
214#pragma warning(pop)
215 };
216
217#pragma endregion
218
219#pragma region VariantCopier
220
222 class VariantCopier
223 {
224 void *data_;
225
226 public:
228 explicit VariantCopier(void *data) noexcept
229 : data_(data)
230 {
231 assert(data); // NOLINT(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
232 }
233
235 template <class T>
236 void operator()(const T &value) const
237 {
238 new (data_) T(value);
239 }
240 };
241
242#pragma endregion
243
244#pragma region VariantMover
245
247 class VariantMover
248 {
249 void *data_;
250
251 public:
253 explicit VariantMover(void *data) noexcept
254 : data_(data)
255 {
256 assert(data); // NOLINT(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
257 }
258
260 template <class T>
261 void operator()(T &&value) const
262 {
263 new (data_) T(std::forward<T>(value));
264 }
265 };
266
267#pragma endregion
268
269#pragma region VariantEqual
270
272 class VariantEqual
273 {
274 const void *data_;
275
276 public:
278 explicit VariantEqual(const void *data) noexcept
279 : data_(data)
280 {
281 assert(data); // NOLINT(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
282 }
283
285 template <class T>
286 bool operator()(const T &value) const noexcept
287 {
288 return *reinterpret_cast<const T *>(data_) == value;
289 }
290 };
291
292#pragma endregion
293
294#pragma region VariantLess
295
297 class VariantLess
298 {
299 const void *lhs_;
300
301 public:
303 explicit VariantLess(const void *data) noexcept
304 : lhs_(data)
305 {
306 assert(data); // NOLINT(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
307 }
308
310 template <class T>
311 bool operator()(const T &rhs) const noexcept
312 {
313 return *reinterpret_cast<const T *>(lhs_) < rhs;
314 }
315 };
316
317#pragma endregion
318
319 } // namespace Detail
320 } // namespace Shims
321
322 CVB_END_INLINE_NS
323
324} // namespace Cvb
T forward(T... args)
Namespace to for standard types that are not available in C++14.
Definition variant_helper.hpp:20
Root namespace for the Image Manager interface.
Definition c_bayer_to_rgb.h:17
Angle Max(Angle a, Angle b) noexcept
Returns the bigger of two angles.
Definition angle.hpp:495