21 constexpr PointerPair(
const void* p1,
const void* p2) :
P1(p1),
P2(p2) {}
71 #elif ALIB_SIZEOF_INTEGER != 4
74 #elif ALIB_SIZEOF_INTEGER != 8
82 int8_t
Array8 [2 *
sizeof(
void*) /
sizeof( int8_t )];
83 int16_t
Array16 [2 *
sizeof(
void*) /
sizeof( int16_t )];
86 int32_t
Array32 [2 *
sizeof(
void*) /
sizeof( int32_t )];
87 int64_t
Array64 [2 *
sizeof(
void*) /
sizeof( int64_t )];
89 #elif ALIB_SIZEOF_INTEGER != 4
90 int32_t
Array32 [2 *
sizeof(
void*) /
sizeof( int32_t )];
91 #elif ALIB_SIZEOF_INTEGER != 8
92 int64_t
Array64 [2 *
sizeof(
void*) /
sizeof( int64_t )];
119 #if ALIB_SIZEOF_INTEGER != 4
128 #elif ALIB_SIZEOF_INTEGER != 8
141 #if ALIB_SIZEOF_INTGAP == 2
148 #elif ALIB_SIZEOF_INTGAP == 4
149 #if ALIB_SIZEOF_INTEGER != 4
164 #elif ALIB_SIZEOF_INTGAP == 8
165 #if ALIB_SIZEOF_INTEGER != 8
177 #error "ALIB_SIZEOF_INTGAP not matched. Supported sizes are 2, 4 and 8."
212 std::array<char, 1>
C1;
213 std::array<char, 2>
C2;
214 std::array<char, 3>
C3;
215 std::array<char, 4>
C4;
216 std::array<char, 5>
C5;
217 std::array<char, 6>
C6;
218 std::array<char, 7>
C7;
219 std::array<char, 8>
C8;
220 #if ALIB_SIZEOF_INTEGER == 8
221 std::array<char, 9>
C9;
315 template<
typename TPo
inter>
318 template<
typename TP1,
typename TP2>
322 template<
typename TI>
323 requires std::is_integral_v<TI>
326 template<
typename TI1,
typename TI2>
327 requires (std::is_integral_v<TI1> && std::is_integral_v<TI2> )
335 template<
typename TArray,
typename TIntegral>
336 requires std::is_integral_v<TIntegral>
337 constexpr Placeholder(
const TArray* tpointer, TIntegral length )
349 template<
typename TReturn>
355 template<
typename TReturn>
376 template<
unsigned UsageLength>
378 static_assert( UsageLength > 0 && ( UsageLength <= 2 *
sizeof(
void*) ),
379 "Invalid usage length given" );
382 if constexpr( UsageLength >
sizeof(
void*) )
393 template<
typename TIntegral>
394 requires( std::is_integral_v<TIntegral> )
395 constexpr void Write(
const TIntegral& value ) {
397 if constexpr( std::is_signed_v<TIntegral>) {
399 if constexpr(
sizeof(TIntegral) == 1 )
Integrals.Int8 = int8_t (value);
400 else if constexpr(
sizeof(TIntegral) == 2 )
Integrals.Int16 = int16_t(value);
401 #if ALIB_SIZEOF_INTEGER == 4
403 else if constexpr(
sizeof(TIntegral) == 8 )
Integrals.Int64 = int64_t(value);
405 else if constexpr(
sizeof(TIntegral) == 4 )
Integrals.Int32 = int32_t(value);
409 if constexpr(
sizeof(TIntegral) == 1 )
Integrals.UInt8 = uint8_t (value);
410 else if constexpr(
sizeof(TIntegral) == 2 )
Integrals.UInt16= uint16_t(value);
411 #if ALIB_SIZEOF_INTEGER == 4
413 else if constexpr(
sizeof(TIntegral) == 8 )
Integrals.UInt64= uint64_t(value);
415 else if constexpr(
sizeof(TIntegral) == 4 )
Integrals.UInt32= uint32_t(value);
423 template<
typename TFloat>
424 requires( std::is_floating_point_v<TFloat> )
425 constexpr void Write(
const TFloat& value ) {
426 if constexpr( std::same_as<TFloat, float > )
FloatingPoints.Float = value;
427 else if constexpr( std::same_as<TFloat, double> )
FloatingPoints.Double= value;
441 template<
typename TTrivial>
442 requires( std::is_trivially_copyable_v<TTrivial>
443 && (
sizeof(TTrivial) <= 2 *
sizeof(
void*))
444 && !std::is_pointer_v<TTrivial>
445 && !std::is_integral_v<TTrivial>
446 && !std::is_floating_point_v<TTrivial> )
447 constexpr void Write(
const TTrivial& value ) {
449 if constexpr(
sizeof(TTrivial) == 1 )
Bytes.C1 = std::bit_cast<std::array<char, 1>>( value );
450 else if constexpr(
sizeof(TTrivial) == 2 )
Bytes.C2 = std::bit_cast<std::array<char, 2>>( value );
451 else if constexpr(
sizeof(TTrivial) == 3 )
Bytes.C3 = std::bit_cast<std::array<char, 3>>( value );
452 else if constexpr(
sizeof(TTrivial) == 4 )
Bytes.C4 = std::bit_cast<std::array<char, 4>>( value );
453 else if constexpr(
sizeof(TTrivial) == 5 )
Bytes.C5 = std::bit_cast<std::array<char, 5>>( value );
454 else if constexpr(
sizeof(TTrivial) == 6 )
Bytes.C6 = std::bit_cast<std::array<char, 6>>( value );
455 else if constexpr(
sizeof(TTrivial) == 7 )
Bytes.C7 = std::bit_cast<std::array<char, 7>>( value );
456 else if constexpr(
sizeof(TTrivial) == 8 )
Bytes.C8 = std::bit_cast<std::array<char, 8>>( value );
457 #if ALIB_SIZEOF_INTEGER == 8
458 else if constexpr(
sizeof(TTrivial) == 9 )
Bytes.C9 = std::bit_cast<std::array<char, 9>>( value );
459 else if constexpr(
sizeof(TTrivial) == 10 )
Bytes.C10= std::bit_cast<std::array<char, 10>>( value );
460 else if constexpr(
sizeof(TTrivial) == 11 )
Bytes.C11= std::bit_cast<std::array<char, 11>>( value );
461 else if constexpr(
sizeof(TTrivial) == 12 )
Bytes.C12= std::bit_cast<std::array<char, 12>>( value );
462 else if constexpr(
sizeof(TTrivial) == 13 )
Bytes.C13= std::bit_cast<std::array<char, 13>>( value );
463 else if constexpr(
sizeof(TTrivial) == 14 )
Bytes.C14= std::bit_cast<std::array<char, 14>>( value );
464 else if constexpr(
sizeof(TTrivial) == 15 )
Bytes.C15= std::bit_cast<std::array<char, 15>>( value );
465 else if constexpr(
sizeof(TTrivial) == 16 )
Bytes.C16= std::bit_cast<std::array<char, 16>>( value );
485 template<
typename T1,
typename T2>
486 requires( std::is_trivially_copyable_v<T1> && !std::is_pointer_v<T1>
487 && std::is_trivially_copyable_v<T2> && !std::is_pointer_v<T2>
488 && (
sizeof(T1) +
sizeof(T2) <= 2 *
sizeof(
void*) )
490 constexpr void Write(
const T1& v1,
const T2& v2 ) {
493 #pragma pack(push, 1)
500 static_assert(
sizeof(PackedTuple) ==
sizeof(T1) +
sizeof(T2),
501 "PackedTuple has unexpected padding!");
504 PackedTuple value { v1, v2 };
506 if constexpr(
sizeof(PackedTuple) == 1 )
Bytes.C1 = std::bit_cast<std::array<char, 1>>( value );
507 else if constexpr(
sizeof(PackedTuple) == 2 )
Bytes.C2 = std::bit_cast<std::array<char, 2>>( value );
508 else if constexpr(
sizeof(PackedTuple) == 3 )
Bytes.C3 = std::bit_cast<std::array<char, 3>>( value );
509 else if constexpr(
sizeof(PackedTuple) == 4 )
Bytes.C4 = std::bit_cast<std::array<char, 4>>( value );
510 else if constexpr(
sizeof(PackedTuple) == 5 )
Bytes.C5 = std::bit_cast<std::array<char, 5>>( value );
511 else if constexpr(
sizeof(PackedTuple) == 6 )
Bytes.C6 = std::bit_cast<std::array<char, 6>>( value );
512 else if constexpr(
sizeof(PackedTuple) == 7 )
Bytes.C7 = std::bit_cast<std::array<char, 7>>( value );
513 else if constexpr(
sizeof(PackedTuple) == 8 )
Bytes.C8 = std::bit_cast<std::array<char, 8>>( value );
514 #if ALIB_SIZEOF_INTEGER == 8
515 else if constexpr(
sizeof(PackedTuple) == 9 )
Bytes.C9 = std::bit_cast<std::array<char, 9>>( value );
516 else if constexpr(
sizeof(PackedTuple) == 10 )
Bytes.C10= std::bit_cast<std::array<char, 10>>( value );
517 else if constexpr(
sizeof(PackedTuple) == 11 )
Bytes.C11= std::bit_cast<std::array<char, 11>>( value );
518 else if constexpr(
sizeof(PackedTuple) == 12 )
Bytes.C12= std::bit_cast<std::array<char, 12>>( value );
519 else if constexpr(
sizeof(PackedTuple) == 13 )
Bytes.C13= std::bit_cast<std::array<char, 13>>( value );
520 else if constexpr(
sizeof(PackedTuple) == 14 )
Bytes.C14= std::bit_cast<std::array<char, 14>>( value );
521 else if constexpr(
sizeof(PackedTuple) == 15 )
Bytes.C15= std::bit_cast<std::array<char, 15>>( value );
522 else if constexpr(
sizeof(PackedTuple) == 16 )
Bytes.C16= std::bit_cast<std::array<char, 16>>( value );
535 template<
typename TPo
inter>
549 template<
typename TArray>
558 template<
typename TP1,
typename TP2>
576 template<
typename TPo
inter>
577 requires( !std::is_trivially_copyable_v<TPointer>
578 && (
sizeof(TPointer) <= 2 *
sizeof(
void*)) )
580 { std::memcpy( &
PointerPair.P1, &value,
sizeof(TPointer) ); }
594 template<
typename TMapped>
595 requires( !( std::is_trivially_copyable_v<TMapped>
596 && (
sizeof(TMapped) <= 2 *
sizeof(
void*)) )
597 && !std::is_pointer_v<TMapped>
599 TMapped
Read()
const {
return *
reinterpret_cast<const TMapped*
>( this ); }
606 template<
typename TPo
inter>
607 requires std::is_pointer_v<TPointer>
608 constexpr TPointer
Read()
const {
609 if constexpr (std::same_as<TPointer, void*>)
611 return reinterpret_cast<TPointer
>(
VoidP );
617 template<
typename TIntegral>
618 requires( std::is_integral_v<TIntegral> )
619 constexpr TIntegral
Read()
const {
621 if constexpr( std::is_signed_v<TIntegral>) {
623 if constexpr(
sizeof(TIntegral) == 1 )
return TIntegral(
Integrals.Int8 );
624 else if constexpr(
sizeof(TIntegral) == 2 )
return TIntegral(
Integrals.Int16);
625 #if ALIB_SIZEOF_INTEGER == 4
626 else if constexpr(
sizeof(TIntegral) == 4 )
return TIntegral(
Integrals.Int );
627 else if constexpr(
sizeof(TIntegral) == 8 )
return TIntegral(
Integrals.Int64);
629 else if constexpr(
sizeof(TIntegral) == 4 )
return TIntegral(
Integrals.Int32);
630 else if constexpr(
sizeof(TIntegral) == 8 )
return TIntegral(
Integrals.Int );
633 if constexpr(
sizeof(TIntegral) == 1 )
return TIntegral(
Integrals.UInt8 );
634 else if constexpr(
sizeof(TIntegral) == 2 )
return TIntegral(
Integrals.UInt16);
635 #if ALIB_SIZEOF_INTEGER == 4
636 else if constexpr(
sizeof(TIntegral) == 4 )
return TIntegral(
Integrals.UInt );
637 else if constexpr(
sizeof(TIntegral) == 8 )
return TIntegral(
Integrals.UInt64);
639 else if constexpr(
sizeof(TIntegral) == 4 )
return TIntegral(
Integrals.UInt32);
640 else if constexpr(
sizeof(TIntegral) == 8 )
return TIntegral(
Integrals.UInt );
647 template<
typename TFloat>
648 requires( std::is_floating_point_v<TFloat> )
649 constexpr TFloat
Read()
const {
650 if constexpr( std::same_as<TFloat, float > )
return TFloat(
FloatingPoints.Float );
651 else if constexpr( std::same_as<TFloat, double> )
return TFloat(
FloatingPoints.Double);
657 template<
typename TTrivial>
658 requires( std::is_trivially_copyable_v<TTrivial>
659 && (
sizeof(TTrivial) <= 2 *
sizeof(
void*))
660 && !std::is_pointer_v<TTrivial>
661 && !std::is_integral_v<TTrivial>
662 && !std::is_floating_point_v<TTrivial>
664 constexpr TTrivial
Read()
const {
666 if constexpr(
sizeof(TTrivial) == 1 )
return std::bit_cast<TTrivial>(
Bytes.C1);
667 else if constexpr(
sizeof(TTrivial) == 2 )
return std::bit_cast<TTrivial>(
Bytes.C2);
668 else if constexpr(
sizeof(TTrivial) == 3 )
return std::bit_cast<TTrivial>(
Bytes.C3);
669 else if constexpr(
sizeof(TTrivial) == 4 )
return std::bit_cast<TTrivial>(
Bytes.C4);
670 else if constexpr(
sizeof(TTrivial) == 5 )
return std::bit_cast<TTrivial>(
Bytes.C5);
671 else if constexpr(
sizeof(TTrivial) == 6 )
return std::bit_cast<TTrivial>(
Bytes.C6);
672 else if constexpr(
sizeof(TTrivial) == 7 )
return std::bit_cast<TTrivial>(
Bytes.C7);
673 else if constexpr(
sizeof(TTrivial) == 8 )
return std::bit_cast<TTrivial>(
Bytes.C8);
674 #if ALIB_SIZEOF_INTEGER == 8
675 else if constexpr(
sizeof(TTrivial) == 9 )
return std::bit_cast<TTrivial>(
Bytes.C9 );
676 else if constexpr(
sizeof(TTrivial) == 10 )
return std::bit_cast<TTrivial>(
Bytes.C10);
677 else if constexpr(
sizeof(TTrivial) == 11 )
return std::bit_cast<TTrivial>(
Bytes.C11);
678 else if constexpr(
sizeof(TTrivial) == 12 )
return std::bit_cast<TTrivial>(
Bytes.C12);
679 else if constexpr(
sizeof(TTrivial) == 13 )
return std::bit_cast<TTrivial>(
Bytes.C13);
680 else if constexpr(
sizeof(TTrivial) == 14 )
return std::bit_cast<TTrivial>(
Bytes.C14);
681 else if constexpr(
sizeof(TTrivial) == 15 )
return std::bit_cast<TTrivial>(
Bytes.C15);
682 else if constexpr(
sizeof(TTrivial) == 16 )
return std::bit_cast<TTrivial>(
Bytes.C16);
693 template<
typename TTrivial1,
typename TTrivial2>
694 requires( std::is_trivially_copyable_v<TTrivial1> && !std::is_pointer_v<TTrivial1>
695 && std::is_trivially_copyable_v<TTrivial2> && !std::is_pointer_v<TTrivial2>
696 && (
sizeof(TTrivial1) +
sizeof(TTrivial2) <= 2 *
sizeof(
void*) )
698 constexpr void Read(TTrivial1& v1, TTrivial2& v2)
const {
701 #pragma pack(push, 1)
708 static_assert(
sizeof(PT) ==
sizeof(TTrivial1) +
sizeof(TTrivial2),
709 "PackedTuple has unexpected padding!");
713 if constexpr(
sizeof(PT) == 1 ) {
const auto pt = std::bit_cast<PT>(
Bytes.C1); v1 = pt.v1; v2 = pt.v2; }
714 else if constexpr(
sizeof(PT) == 2 ) {
const auto pt = std::bit_cast<PT>(
Bytes.C2); v1 = pt.v1; v2 = pt.v2; }
715 else if constexpr(
sizeof(PT) == 3 ) {
const auto pt = std::bit_cast<PT>(
Bytes.C3); v1 = pt.v1; v2 = pt.v2; }
716 else if constexpr(
sizeof(PT) == 4 ) {
const auto pt = std::bit_cast<PT>(
Bytes.C4); v1 = pt.v1; v2 = pt.v2; }
717 else if constexpr(
sizeof(PT) == 5 ) {
const auto pt = std::bit_cast<PT>(
Bytes.C5); v1 = pt.v1; v2 = pt.v2; }
718 else if constexpr(
sizeof(PT) == 6 ) {
const auto pt = std::bit_cast<PT>(
Bytes.C6); v1 = pt.v1; v2 = pt.v2; }
719 else if constexpr(
sizeof(PT) == 7 ) {
const auto pt = std::bit_cast<PT>(
Bytes.C7); v1 = pt.v1; v2 = pt.v2; }
720 else if constexpr(
sizeof(PT) == 8 ) {
const auto pt = std::bit_cast<PT>(
Bytes.C8); v1 = pt.v1; v2 = pt.v2; }
721 #if ALIB_SIZEOF_INTEGER > 4
722 else if constexpr(
sizeof(PT) == 9 ) {
const auto pt = std::bit_cast<PT>(
Bytes.C9); v1 = pt.v1; v2 = pt.v2; }
723 else if constexpr(
sizeof(PT) == 10 ) {
const auto pt = std::bit_cast<PT>(
Bytes.C10); v1 = pt.v1; v2 = pt.v2; }
724 else if constexpr(
sizeof(PT) == 11 ) {
const auto pt = std::bit_cast<PT>(
Bytes.C11); v1 = pt.v1; v2 = pt.v2; }
725 else if constexpr(
sizeof(PT) == 12 ) {
const auto pt = std::bit_cast<PT>(
Bytes.C12); v1 = pt.v1; v2 = pt.v2; }
726 else if constexpr(
sizeof(PT) == 13 ) {
const auto pt = std::bit_cast<PT>(
Bytes.C13); v1 = pt.v1; v2 = pt.v2; }
727 else if constexpr(
sizeof(PT) == 14 ) {
const auto pt = std::bit_cast<PT>(
Bytes.C14); v1 = pt.v1; v2 = pt.v2; }
728 else if constexpr(
sizeof(PT) == 15 ) {
const auto pt = std::bit_cast<PT>(
Bytes.C15); v1 = pt.v1; v2 = pt.v2; }
729 else if constexpr(
sizeof(PT) == 16 ) {
const auto pt = std::bit_cast<PT>(
Bytes.C16); v1 = pt.v1; v2 = pt.v2; }
734static_assert(
sizeof(Placeholder) == 2 *
sizeof(std::size_t),
735 "Size of boxing::Placeholder is not two times the size of 'size_t'. "
736 "Compilation platform not supported." );
747template <
typename T1,
typename T2>
748requires ( std::is_trivially_copyable_v<T1>
749 && std::is_trivially_copyable_v<T2>
750 && (
sizeof(T1) +
sizeof(T2) <= 2 *
sizeof(
void*) )
765template <
typename T1,
typename T2>
766requires ( std::is_trivially_copyable_v<T1>
767 && std::is_trivially_copyable_v<T2>
768 && (
sizeof(T1) +
sizeof(T2) <= 2 *
sizeof(
void*) )
775template <
typename T,
typename U>
This namespace implements internals of namespace alib::boxing.
constexpr Pair< T1, T2 > MakePair(const T1 &t1, const T2 &t2)
lang::intGap_t intGap_t
Type alias in namespace alib.
lang::integer integer
Type alias in namespace alib.
lang::uintGap_t uintGap_t
Type alias in namespace alib.
boxing::Pair< T, U > Pair
Type alias in namespace alib.
characters::character character
Type alias in namespace alib.
lang::uinteger uinteger
Type alias in namespace alib.
constexpr PointerPairMutable(void *p1)
void * P2
The second pointer.
void * P1
The first pointer.
constexpr PointerPairMutable(void *p1, void *p2)
const void * P1
The first pointer.
const void * P2
The second pointer.
integer Length
The length of the array.
const void * Pointer
The pointer to the array.
constexpr StructArray(const void *p, integer l)
detail::PointerPair PointerPair
Collection of two const void pointers.
constexpr TIntegral Read() const
constexpr TFloat Read() const
constexpr void Write(const T1 &v1, const T2 &v2)
constexpr void Write(const TFloat &value)
detail::UnionFloatingPoints FloatingPoints
Collection of floating points of different sizes.
constexpr integer GetLength() const
integer Debugger_Integral
This union field was inserted only for debug display.
constexpr void Write(const TArray *pointer, integer length)
character * Debugger_String
This union field was inserted only for debug display.
detail::StructArray Array
Used when storing C++ arrays.
constexpr Placeholder()
Default constructor. Leaves everything uninitialized.
constexpr void Write(const TIntegral &value)
constexpr void Write(const TTrivial &value)
constexpr TTrivial Read() const
constexpr void Read(TTrivial1 &v1, TTrivial2 &v2) const
constexpr TPointer Read() const
constexpr void Write(const TPointer *pointer)
detail::UnionIntegrals Integrals
Collection of integrals of different sizes, placed next to each other.
TReturn * GetPointer2() const
detail::PointerPairMutable PointerPairMutable
Collection of two void pointers.
constexpr const void * GetVoidPointer() const
constexpr void Write(const TP1 *p1, const TP2 *p2)
TReturn * GetPointer() const
void * VoidP
Just a void pointer.
constexpr void SetPointer(void *value)
detail::UnionBytes Bytes
Byte arrays of different length.
std::array< char, 3 > C3
3 bytes.
std::array< char, 1 > C1
1 bytes.
std::array< char, 13 > C13
13 bytes.
std::array< char, 9 > C9
9 bytes.
std::array< char, 7 > C7
7 bytes.
std::array< char, 8 > C8
8 bytes.
std::array< char, 14 > C14
14 bytes.
std::array< char, 15 > C15
15 bytes.
std::array< char, 12 > C12
12 bytes.
std::array< char, 6 > C6
6 bytes.
std::array< char, 5 > C5
5 bytes.
std::array< char, 16 > C16
16 bytes.
std::array< char, 10 > C10
10 bytes.
std::array< char, 2 > C2
2 bytes.
std::array< char, 4 > C4
4 bytes.
std::array< char, 11 > C11
11 bytes.
float Float
A float value.
constexpr UnionFloatingPoints(float value)
float FloatArray[2 *sizeof(void *)/sizeof(float)]
Array of float. The Length is usually four on 64-bit platform, two on a 32-bit platform.
double Double
A double value.
double DoubleArray[2 *sizeof(void *)/sizeof(double)]
Array of double. The Length is usually two on 64-bit platform, one on a 32-bit platform.
constexpr UnionFloatingPoints(double value)
uint64_t UInt64
64-bit unsigned integral. Available only if platform is not of 64-bit.
int32_t Int32
32-bit signed integral. Available only if platform is not of 32-bit.
int8_t Int8
8-bit signed integral.
int16_t Array16[2 *sizeof(void *)/sizeof(int16_t)]
Array of 16-bit signed integrals of length 8 on 64-bit platform, 4 on a 32-bit platform.
constexpr UnionIntegrals(int32_t value)
constexpr UnionIntegrals(uint16_t value)
constexpr UnionIntegrals(integer value)
uint16_t UInt16
16-bit unsigned integral.
constexpr UnionIntegrals(uinteger value)
int32_t Array32[2 *sizeof(void *)/sizeof(int32_t)]
Array of 32-bit signed integrals of length 4 on a 64-bit platform. Not available on 32-bit platforms.
int64_t Int64
64-bit signed integral. Available only if platform is not of 64-bit.
constexpr UnionIntegrals(uint8_t value)
integer Int
Signed integral of platform-dependent size.
int64_t Array64[2 *sizeof(void *)/sizeof(int64_t)]
Array of 64-bit signed integrals of length 1 on a 32-bit platform. Not available on 64-bit platforms.
uinteger UInt
Unsigned integral of platform-dependent size.
uint8_t UInt8
8-bit unsigned integral.
int8_t Array8[2 *sizeof(void *)/sizeof(int8_t)]
Array of 8-bit signed integrals of length 16 on 64-bit platform, 8 on a 32-bit platform.
constexpr UnionIntegrals(uint32_t value)
constexpr UnionIntegrals(int16_t value)
uint32_t UInt32
32-bit unsigned integral. Available only if platform is not of 32-bit.
integer Array[2]
Array of 64-bit signed integrals of length two on 64-bit platform, one on a 32-bit platform.
uinteger UArray[2]
Array of 64-bit unsigned integrals of length two on 64-bit platform, one on a 32-bit platform.
constexpr UnionIntegrals(integer v1, integer v2)
int16_t Int16
16-bit signed integral.
constexpr UnionIntegrals(int8_t value)