CVB++ 15.0
block_helper_ref_value.hpp
1#pragma once
2
3#include "../../shims/stdtype_traits.hpp"
4
5#include "detail_block.hpp"
6
7namespace Cvb
8{
9 CVB_BEGIN_INLINE_NS
10
11 namespace // NOLINT(cert-dcl59-cpp)
12 {
16 template <template <class, size_t> class CRefValue>
18 {
23 template <size_t I, class Ty, size_t K, std::enable_if_t<less<I, K>::value, int> = 0>
24 static CVB_FORCE_INLINE void set(CRefValue<Ty, K> &refVal, const Ty *val) noexcept
25 {
26 refVal.pointers_[I] = const_cast<Ty *>(val); // NOLINT(cppcoreguidelines-pro-type-const-cast)
27 // we have to const_cast here, as the stored pointers must be
28 // mutable as we set them here and for RefValue.
29 }
30 };
31
35 template <template <class, size_t> class RValue>
37 {
42 template <size_t I, class Ty, size_t K, std::enable_if_t<less<I, K>::value, int> = 0>
43 static CVB_FORCE_INLINE void set(RValue<Ty, K> &refVal, Ty *val) noexcept
44 {
45 refVal.pointers_[I] = val;
46 }
47 };
48 } // namespace
49
55 template <class T, size_t K>
56 class ConstRefValue final
57 {
58 static_assert(K > 0, "Cvb: ConstRefValue must hold at least one element.");
59
60 template <class Ty, class ACCESSTRAIT>
61 friend class Block;
62 template <template <class, size_t> class CRefValue>
63 friend struct ConstRefValueSetter;
64
65 std::array<T *, K> pointers_;
66
67 /*
68 * \brief Default Ctor creating invalid object.
69 */
70 ConstRefValue()
71 {
72 for (auto &ptr : pointers_)
73 {
74 ptr = nullptr;
75 }
76 }
77
78 public:
79 using ComponentType = T;
80
87 template <class... TT>
88 explicit ConstRefValue(const TT &...refs)
89 : pointers_({const_cast<T *>(&refs)...}) // NOLINT(cppcoreguidelines-pro-type-const-cast)
90 // we have to const_cast here, as the stored pointers must be mutable
91 // through the setters and for RefValue.
92 {
93 static_assert(sizeof...(TT) == K, "Cvb: Number of parameters must equal the number of elements.");
94 }
95
96 ConstRefValue(const ConstRefValue &other) noexcept = default;
97 ConstRefValue &operator=(const ConstRefValue &other) noexcept = default;
98 ConstRefValue(ConstRefValue &&other) noexcept = default;
99 ConstRefValue &operator=(ConstRefValue &&other) noexcept = default;
100 ~ConstRefValue() = default;
101
102 private:
103 template <class Ty, size_t... I>
104 Ty Cast(std::index_sequence<I...>) const noexcept
105 {
106 using expander = int[]; // NOLINT(cppcoreguidelines-avoid-c-arrays) fold expression support for pre C++17
107 // standards.. for explanation see Block::FillPixelValueElements
108
109 Ty value{};
110 expander{0, ((void)set<I>(value, *pointers_[I]), 0)...};
111 return value;
112 }
113
114 public:
121 template <class Ty>
122 Ty Cast() const noexcept
123 {
124 return Cast<Ty>(std::make_index_sequence<K>());
125 }
126
132 T X() const noexcept
133 {
134 return *pointers_[0];
135 }
136
142 template <size_t N = K, std::enable_if_t<less<1, N>::value, int> = 0>
143 T Y() const noexcept
144 {
145 return *pointers_[1];
146 }
147
153 template <size_t N = K, std::enable_if_t<less<2, N>::value, int> = 0>
154 T Z() const noexcept
155 {
156 return *pointers_[2];
157 }
158
164 template <size_t N = K, std::enable_if_t<less<3, N>::value, int> = 0>
165 T W() const noexcept
166 {
167 return *pointers_[3];
168 }
169
176 T operator[](size_t i) const noexcept
177 {
178 assert(i < K);
179
180 return *pointers_[i];
181 }
182
188 static constexpr size_t NumValues() noexcept
189 {
190 return K;
191 }
192 };
193
199 template <class T, size_t K>
200 class RefValue final
201 {
202 /*
203 * This class could theoretically inherit from ConstRefValue,
204 * but as that would require adding a virtual destructor to ConstRefValue
205 * to ensure correct handling of deletion of pointers to these classes,
206 * both classes are implemented as concrete classes.
207 *
208 * The caveat of adding a virtual destructor is, that it requires constructing
209 * a vtable which seems to disable inlining and therefore hurts the performance.
210 */
211
212 static_assert(K > 0, "Cvb: RefValue must hold at least one element.");
213
214 template <class Ty, class ACCESSTRAIT>
215 friend class Block;
216 template <template <class, size_t> class RValue>
217 friend struct RefValueSetter;
218
219 std::array<T *, K> pointers_;
220
221 /*
222 * \brief Default Ctor creating invalid object.
223 */
224 RefValue()
225 {
226 for (auto &ptr : pointers_)
227 {
228 ptr = nullptr;
229 }
230 }
231
232 public:
233 using ComponentType = T;
234
240 template <class... TT>
241 explicit RefValue(TT &...refs)
242 : pointers_({const_cast<T *>(&refs)...}) // NOLINT(cppcoreguidelines-pro-type-const-cast)
243 // we have to const_cast here, as the stored pointers must be
244 // mutable through the setters and for RefValue.
245 {
246 }
247
248 RefValue(const RefValue &other) noexcept = default;
249 RefValue &operator=(const RefValue &other) noexcept = default;
250 RefValue(RefValue &&other) noexcept = default;
251 RefValue &operator=(RefValue &&other) noexcept = default;
252 ~RefValue() = default;
253
254 private:
255 template <class Ty, size_t... I>
256 RefValue<T, K> &Assign(const Ty &other, std::index_sequence<I...>) noexcept
257 {
258 using expander = int[]; // NOLINT(cppcoreguidelines-avoid-c-arrays) fold expression support for pre C++17
259 // standards.. for explanation see Block::FillPixelValueElements
260
261 expander{0, ((void)(*pointers_[I] = get<I>(other)), 0)...};
262 return *this;
263 }
264
265 public:
275 template <class Ty>
276 RefValue<T, K> &operator=(const Ty &other) noexcept
277 {
278 return Assign(other, std::make_index_sequence<K>()); // NOLINT(cppcoreguidelines-c-copy-assignment-signature)
279 }
280
289 template <size_t N>
290 RefValue<T, K> &operator=(const T (&list)[N]) noexcept // NOLINT(cppcoreguidelines-avoid-c-arrays)
291 {
292 static_assert(N == K, "Cvb: The initializer list must contain K elements.");
293
294 for (int i = 0; i < N; ++i)
295 {
296 *pointers_[i] = list[i];
297 }
298 return *this;
299 }
300
301 private:
302 template <class Ty, size_t... I>
303 Ty Cast(std::index_sequence<I...>) const noexcept
304 {
305 using expander = int[]; // NOLINT(cppcoreguidelines-avoid-c-arrays) fold expression support for pre C++17
306 // standards.. for explanation see Block::FillPixelValueElements
307
308 Ty value{};
309 expander{0, ((void)set<I>(value, *pointers_[I]), 0)...};
310 return value;
311 }
312
313 public:
320 template <class Ty>
321 Ty Cast() const noexcept
322 {
323 return Cast<Ty>(std::make_index_sequence<K>());
324 }
325
331 T X() const noexcept
332 {
333 return *pointers_[0];
334 }
335
341 T &X() noexcept
342 {
343 return *pointers_[0];
344 }
345
351 template <size_t N = K, std::enable_if_t<less<1, N>::value, int> = 0>
352 T Y() const noexcept
353 {
354 return *pointers_[1];
355 }
356
362 template <size_t N = K, std::enable_if_t<less<1, N>::value, int> = 0>
363 T &Y() noexcept
364 {
365 return *pointers_[1];
366 }
367
373 template <size_t N = K, std::enable_if_t<less<2, N>::value, int> = 0>
374 T Z() const noexcept
375 {
376 return *pointers_[2];
377 }
378
384 template <size_t N = K, std::enable_if_t<less<2, N>::value, int> = 0>
385 T &Z() noexcept
386 {
387 return *pointers_[2];
388 }
389
395 template <size_t N = K, std::enable_if_t<less<3, N>::value, int> = 0>
396 T W() const noexcept
397 {
398 return *pointers_[3];
399 }
400
406 template <size_t N = K, std::enable_if_t<less<3, N>::value, int> = 0>
407 T &W() noexcept
408 {
409 return *pointers_[3];
410 }
411
418 T operator[](size_t i) const noexcept
419 {
420 assert(i < K);
421
422 return *pointers_[i];
423 }
424
431 T &operator[](size_t i) noexcept
432 {
433 assert(i < K);
434
435 return *pointers_[i];
436 }
437
443 static constexpr const size_t NumValues() noexcept
444 {
445 return K;
446 }
447 };
448
461 template <size_t I, class T, size_t K, std::enable_if_t<less<I, K>::value, int> = 0>
462 auto get(const RefValue<T, K> &refVal) noexcept -> decltype(refVal[I])
463 {
464 return refVal[I];
465 }
466
479 template <size_t I, class T, size_t K, std::enable_if_t<less<I, K>::value, int> = 0>
480 auto get(const ConstRefValue<T, K> &refVal) noexcept -> decltype(refVal[I])
481 {
482 return refVal[I];
483 }
484
497 template <size_t I, class T, size_t K, std::enable_if_t<less<I, K>::value, int> = 0>
498 void set(RefValue<T, K> &refVal, const T &val) noexcept
499 {
500 refVal[I] = val;
501 }
502
515
520 template <size_t I, class Ty, size_t K>
521 CVB_FORCE_INLINE void internal_set(RefValue<Ty, K> &refVal, Ty *val) noexcept
522 {
523 assert(val != nullptr);
524
525 RefValueSetter<RefValue>::template set<I>(refVal, val);
526 }
527
539
544 template <size_t I, class Ty, size_t K>
545 CVB_FORCE_INLINE void internal_set(ConstRefValue<Ty, K> &refVal, const Ty *val) noexcept
546 {
547 assert(val != nullptr);
548
549 ConstRefValueSetter<ConstRefValue>::template set<I>(refVal, val);
550 }
551
552 CVB_END_INLINE_NS
553} // namespace Cvb
T X() const noexcept
Get const value of the first (x) value.
Definition block_helper_ref_value.hpp:132
ConstRefValue(const TT &...refs)
Constructor from reference values.
Definition block_helper_ref_value.hpp:88
T W() const noexcept
Get const value of the fourth (w) value.
Definition block_helper_ref_value.hpp:165
Ty Cast() const noexcept
Cast to any type, for which a set<size_t>(Ty) function exists.
Definition block_helper_ref_value.hpp:122
T Z() const noexcept
Get const value of the third (z) value.
Definition block_helper_ref_value.hpp:154
static constexpr size_t NumValues() noexcept
Get number of values stored in this ConstRefValue.
Definition block_helper_ref_value.hpp:188
T operator[](size_t i) const noexcept
Element access.
Definition block_helper_ref_value.hpp:176
auto get(const ConstRefValue< T, K > &refVal) noexcept -> decltype(refVal[I])
Get's the I-th element of the ConstRefValue<T,K>.
Definition block_helper_ref_value.hpp:480
T Y() const noexcept
Get const value of the second (y) value.
Definition block_helper_ref_value.hpp:143
CVB_FORCE_INLINE void internal_set(ConstRefValue< Ty, K > &refVal, const Ty *val) noexcept
Set's the I-th pointer in the ConstRefValue<T,K> refVal.
Definition block_helper_ref_value.hpp:545
void set(RefValue< T, K > &refVal, const T &val) noexcept
Set's the value of the I-th element in the RefValue<T,K> refVal.
Definition block_helper_ref_value.hpp:498
T X() const noexcept
Get const value of the first (x) value.
Definition block_helper_ref_value.hpp:331
T & Y() noexcept
Get reference to the second (y) value.
Definition block_helper_ref_value.hpp:363
RefValue(TT &...refs)
Constructor from reference values.
Definition block_helper_ref_value.hpp:241
T W() const noexcept
Get const value of the fourth (w) value.
Definition block_helper_ref_value.hpp:396
Ty Cast() const noexcept
Cast to any type, for which a set<size_t>(Ty) function exists.
Definition block_helper_ref_value.hpp:321
CVB_FORCE_INLINE void internal_set(RefValue< Ty, K > &refVal, Ty *val) noexcept
Set's the I-th pointer in the RefValue<T,K> refVal.
Definition block_helper_ref_value.hpp:521
T & X() noexcept
Get reference to the first (x) value.
Definition block_helper_ref_value.hpp:341
T Z() const noexcept
Get const value of the third (z) value.
Definition block_helper_ref_value.hpp:374
RefValue< T, K > & operator=(const T(&list)[N]) noexcept
Assignment from a N-element initializer list or array. The values pointed to by this class are overwr...
Definition block_helper_ref_value.hpp:290
T & W() noexcept
Get reference to the fourth (w) value.
Definition block_helper_ref_value.hpp:407
T operator[](size_t i) const noexcept
Element access.
Definition block_helper_ref_value.hpp:418
T & Z() noexcept
Get reference to the third (z) value.
Definition block_helper_ref_value.hpp:385
T & operator[](size_t i) noexcept
Mutable element access.
Definition block_helper_ref_value.hpp:431
T Y() const noexcept
Get const value of the second (y) value.
Definition block_helper_ref_value.hpp:352
static constexpr const size_t NumValues() noexcept
Get number of values stored in this RefValue.
Definition block_helper_ref_value.hpp:443
RefValue< T, K > & operator=(const Ty &other) noexcept
Assignment from any type, for which get<size_t>(Ty) function exists. The values pointed to by this cl...
Definition block_helper_ref_value.hpp:276
auto get(const RefValue< T, K > &refVal) noexcept -> decltype(refVal[I])
Get's the I-th element of the RefValue<T,K>.
Definition block_helper_ref_value.hpp:462
Root namespace for the Image Manager interface.
Definition c_bayer_to_rgb.h:17
Helper class for setting the pointers, as friending template functions is not really stable.
Definition block_helper_ref_value.hpp:18
static CVB_FORCE_INLINE void set(CRefValue< Ty, K > &refVal, const Ty *val) noexcept
Set's the I-th pointer in the RefValue<T,K> refVal.
Definition block_helper_ref_value.hpp:24
Helper class for setting the pointers, as friending template functions is not really stable.
Definition block_helper_ref_value.hpp:37
static CVB_FORCE_INLINE void set(RValue< Ty, K > &refVal, Ty *val) noexcept
Set's the I-th pointer in the ConstRefValue<T,K> refVal.
Definition block_helper_ref_value.hpp:43