A protected member of this union is contained in class Box to store information on a boxed object. This member is passed as an argument to static methods Write and Read of type-traits struct BoxTraits, which implement boxing and unboxing.
This union declares different inner structs and unions and contains one corresponding member of each. This sorts the union fields into different groups, which his also helpful when debugging instances of type box.
The overall size of this union is two times the size of std::size_t
, hence 16 bytes on a 64-bit and 8 bytes on a 32-bit system.
Virtually any sort of data might be written into the union. With non-injective boxing, what means that two or more types are boxed to the same target type, the format that type uses has to be implemented by all Write and Read methods of any specialization of BoxTraits. Otherwise, undefined behavior occurs.
This type offers two sets of templated overloaded methods, named Write and Read. In addition to be overloaded, the methods use C++20 concepts to be selected by the compiler only for certain template types.
The methods cover boxing and unboxing of the most frequent types like
constexpr
)For these types, the default implementation of BoxTraits::Write and Read, as given for example with macro ALIB_BOXING_CUSTOMIZE_TYPE_MAPPING often is all that is needed.
Custom implementations of boxing and unboxing may read from and write to the union data directly.
In this case, a "continuous" use of the available data is suggested. At least, gaps in writing should be initialized with a value (e.g., 0
). The rationale for this is that the default implementations of box-functions FHashcode and FEquals use only the first N relevant bytes. If now, gaps are not written, they contain "random" data, what would cause a failure of these default functions.
By the same token, if the customization of a non-array type writes a different length than C++ operator sizeof
reports for the mapped type, then also SizeTraits has to be specialized for that type, so that the method Box::GetPlaceholderUsageLength reports the right value. Note that furthermore method Clear, which is used when boxing nulled pointers, only clears as much data in this struct as reported by SizeTraits.
While this library defines constexpr
-boxing for all fundamental types and for most library types of other ALib Modules, still such customization is considered "expert use" as the gain to do it for custom types is marginal. The biggest benefit of constexpr
boxing, lies in the fact that - if also a customized VTable is provided - such types can be located in global and static instances of class Box.
Definition at line 294 of file boxing/placeholder.inl.
Public Field Index: | |
detail::StructArray | Array |
Used when storing C++ arrays. | |
detail::UnionBytes | Bytes |
Byte arrays of different length. | |
integer | Debugger_Integral |
This union field was inserted only for debug display. | |
character * | Debugger_String |
This union field was inserted only for debug display. | |
detail::UnionFloatingPoints | FloatingPoints |
Collection of floating points of different sizes. | |
detail::UnionIntegrals | Integrals |
Collection of integrals of different sizes, placed next to each other. | |
detail::PointerPair | PointerPair |
Collection of two const void pointers. | |
detail::PointerPairMutable | PointerPairMutable |
Collection of two void pointers. | |
void * | VoidP |
Just a void pointer. | |
Public Method Index: | |
constexpr | Placeholder () |
Default constructor. Leaves everything uninitialized. | |
template<unsigned int UsageLength> | |
constexpr void | Clear () |
constexpr integer | GetLength () const |
template<typename TReturn> | |
TReturn * | GetPointer () const |
template<typename TReturn> | |
TReturn * | GetPointer2 () const |
constexpr const void * | GetVoidPointer () const |
template<typename TMapped> requires ( !( std::is_trivially_copyable_v<TMapped> && (sizeof(TMapped) <= 2 * sizeof(void*)) ) && !std::is_pointer_v<TMapped> ) | |
TMapped | Read () const |
template<typename TPointer> requires std::is_pointer_v<TPointer> | |
constexpr TPointer | Read () const |
template<typename TIntegral> requires ( std::is_integral_v<TIntegral> ) | |
constexpr TIntegral | Read () const |
template<typename TFloat> requires ( std::is_floating_point_v<TFloat> ) | |
constexpr TFloat | Read () const |
template<typename TTrivial> requires ( std::is_trivially_copyable_v<TTrivial> && (sizeof(TTrivial) <= 2 * sizeof(void*)) && !std::is_pointer_v<TTrivial> && !std::is_integral_v<TTrivial> && !std::is_floating_point_v<TTrivial> ) | |
constexpr TTrivial | Read () const |
template<typename TTrivial1, typename TTrivial2> requires ( std::is_trivially_copyable_v<TTrivial1> && !std::is_pointer_v<TTrivial1> && std::is_trivially_copyable_v<TTrivial2> && !std::is_pointer_v<TTrivial2> && ( sizeof(TTrivial1) + sizeof(TTrivial2) <= 2 * sizeof(void*) ) ) | |
constexpr void | Read (TTrivial1 &v1, TTrivial2 &v2) const |
constexpr void | SetPointer (void *value) |
template<typename T1, typename T2> requires ( std::is_trivially_copyable_v<T1> && !std::is_pointer_v<T1> && std::is_trivially_copyable_v<T2> && !std::is_pointer_v<T2> && ( sizeof(T1) + sizeof(T2) <= 2 * sizeof(void*) ) ) | |
constexpr void | Write (const T1 &v1, const T2 &v2) |
template<typename TArray> | |
constexpr void | Write (const TArray *pointer, integer length) |
template<typename TFloat> requires ( std::is_floating_point_v<TFloat> ) | |
constexpr void | Write (const TFloat &value) |
template<typename TIntegral> requires ( std::is_integral_v<TIntegral> ) | |
constexpr void | Write (const TIntegral &value) |
template<typename TP1, typename TP2> | |
constexpr void | Write (const TP1 *p1, const TP2 *p2) |
template<typename TPointer> requires ( !std::is_trivially_copyable_v<TPointer> && (sizeof(TPointer) <= 2 * sizeof(void*)) ) | |
void | Write (const TPointer &value) |
template<typename TPointer> | |
constexpr void | Write (const TPointer *pointer) |
template<typename TTrivial> requires ( std::is_trivially_copyable_v<TTrivial> && (sizeof(TTrivial) <= 2 * sizeof(void*)) && !std::is_pointer_v<TTrivial> && !std::is_integral_v<TTrivial> && !std::is_floating_point_v<TTrivial> ) | |
constexpr void | Write (const TTrivial &value) |
detail::StructArray alib::boxing::Placeholder::Array |
Used when storing C++ arrays.
Definition at line 298 of file boxing/placeholder.inl.
detail::UnionBytes alib::boxing::Placeholder::Bytes |
Byte arrays of different length.
Definition at line 301 of file boxing/placeholder.inl.
integer alib::boxing::Placeholder::Debugger_Integral |
This union field was inserted only for debug display.
Definition at line 305 of file boxing/placeholder.inl.
character* alib::boxing::Placeholder::Debugger_String |
This union field was inserted only for debug display.
Definition at line 304 of file boxing/placeholder.inl.
detail::UnionFloatingPoints alib::boxing::Placeholder::FloatingPoints |
Collection of floating points of different sizes.
Definition at line 300 of file boxing/placeholder.inl.
detail::UnionIntegrals alib::boxing::Placeholder::Integrals |
Collection of integrals of different sizes, placed next to each other.
Definition at line 299 of file boxing/placeholder.inl.
detail::PointerPair alib::boxing::Placeholder::PointerPair |
Collection of two const
void
pointers.
Definition at line 296 of file boxing/placeholder.inl.
detail::PointerPairMutable alib::boxing::Placeholder::PointerPairMutable |
Collection of two void
pointers.
Definition at line 297 of file boxing/placeholder.inl.
void* alib::boxing::Placeholder::VoidP |
Just a void pointer.
Definition at line 302 of file boxing/placeholder.inl.
|
inlineconstexpr |
Default constructor. Leaves everything uninitialized.
Definition at line 309 of file boxing/placeholder.inl.
|
inlineconstexpr |
Clears this box data.
It has to be ensured that all the memory used by a mapped type is cleared. For example, the default implementations of box-functions FHashcode and FEquals are using the relevant bytes of this placeholder, and those must not be of random value.
For efficiency reasons, the rest should not be cleared.
UsageLength | The number of bytes to clear. |
Definition at line 378 of file boxing/placeholder.inl.
|
inlineconstexpr |
Returns the length of a stored array (the second word stored).
Definition at line 365 of file boxing/placeholder.inl.
|
inline |
Returns a pointer of type TReturn.
TReturn | The requested pointer type |
Definition at line 349 of file boxing/placeholder.inl.
|
inline |
Returns a pointer of type TReturn.
TReturn | The requested pointer type |
Definition at line 356 of file boxing/placeholder.inl.
|
inlineconstexpr |
Returns a pointer of type void*
.
Definition at line 343 of file boxing/placeholder.inl.
|
inline |
Templated read method for value types that fit into this placeholder, which are not pointers, and furthermore which are not trivially copyable.
The value is dereferenced from the start of the placeholder memory using reinterpret_cast
. With that, this overload is never constexpr
and thus not marked so.
TMapped | The value type to unbox. |
Definition at line 602 of file boxing/placeholder.inl.
|
inlineconstexpr |
Templated method to read pointer types from this placeholder. The pointer is changed to the desired type using reinterpret_cast
. Only if void*
is requested, this method can be constexpr
.
TPointer | The pointer-type to unbox. |
Definition at line 611 of file boxing/placeholder.inl.
|
inlineconstexpr |
Templated method to read integral types from this placeholder.
TIntegral | The integral type to unbox. |
Definition at line 622 of file boxing/placeholder.inl.
|
inlineconstexpr |
Templated method to read integral types from this placeholder.
TFloat | The integral type to unbox. |
Definition at line 653 of file boxing/placeholder.inl.
|
inlineconstexpr |
Templated method to read trivially copyable types that fits into the placeholder.
TTrivial | The type to read from this placeholder. |
Definition at line 668 of file boxing/placeholder.inl.
|
inlineconstexpr |
Templated method that reads two trivially copyable types that jointly fit into the placeholder.
TTrivial1 | The type of the first value to read from this placeholder. |
TTrivial2 | The type of the second value to read from this placeholder. |
v1 | Output parameter. Receives the first value. |
v2 | Output parameter. Receives the second value. |
Definition at line 702 of file boxing/placeholder.inl.
|
inlineconstexpr |
Sets a pointer of type char*
.
value | The value to set. |
Definition at line 361 of file boxing/placeholder.inl.
|
inlineconstexpr |
Writes two values of arbitrary type into the placeholder. The method requires that:
2 * sizeof(void*)
.This version packs the two given values with no gap into a tuple and then writes that tuple using std::bit_cast
. This way, this method may be used with constexpr
use cases that enable constant boxes, which in seldom cases may be required. Furthermore, this way, values boxed like this fulfil one requirement to produce reliable hash values.
T1 | The type of the first value to store. |
T2 | The type of the second value to store. |
v1 | The first value to store. |
v2 | The second value to store. |
Definition at line 493 of file boxing/placeholder.inl.
|
inlineconstexpr |
This version of the overloaded method is used for boxing C++ array types. The type and length of the array is stored in the field Array of the data union.
Note that for unboxing custom types from C++ array types, a custom implementation of BoxTraits::Read is needed. Such an implementation reads the pointer and length directly from this struct. (I.e. there is no overloaded method Read available for arrays.)
TArray | The pointer type. |
pointer | The pointer to store. |
length | The array's length to store. |
Definition at line 553 of file boxing/placeholder.inl.
|
inlineconstexpr |
This version of the overloaded method writes floating-point values.
TFloat | The integral type to store. |
value | The value to store. |
Definition at line 428 of file boxing/placeholder.inl.
|
inlineconstexpr |
This version of the overloaded method writes integral values.
TIntegral | The integral type to store. |
value | The value to store. |
Definition at line 397 of file boxing/placeholder.inl.
|
inlineconstexpr |
This version of the overloaded method is used for boxing two pointer types.
TP1 | The type of the first pointer. |
TP2 | The type of the second pointer. |
p1 | The first pointer to store. |
p2 | The second pointer to store. |
Definition at line 562 of file boxing/placeholder.inl.
|
inline |
This version of the overloaded method is selected when the type TPointer is not trivially copyable, still fits into the placeholder of size 2 * sizeof(void*)
, and furthermore does not directly match other overloaded versions.
The copying is performed using memcpy
. This is necessary to avoid de-referencing type-punned pointers which would break the strict-aliasing rule when compiling the code with higher optimization levels. Note that modern compilers like GCC usually optimize the invocation of memcpy
out.
This version is not constexpr
and thus may not be used to create constant boxes, which in seldom cases may be required.
TPointer | The type of the value to store. |
value | The value to store. |
Definition at line 582 of file boxing/placeholder.inl.
|
inlineconstexpr |
This version of the overloaded method is used for boxing C++ pointer types.
Note that for unboxing custom types from C++ array types, a custom implementation of BoxTraits::Read is needed. Such an implementation reads the pointer and length directly from this struct. In other words, there is no overloaded method Read available for array types.
TPointer | The pointer type. |
pointer | The pointer to store. |
Definition at line 539 of file boxing/placeholder.inl.
|
inlineconstexpr |
This version of the overloaded method requires type TTrivial to:
2 * sizeof(void*)
, andThis version copies the value using std::bit_cast
. This way, this method may be used with constexpr
use cases that enable constant boxes, which in seldom cases may be required.
TTrivial | The mapped type to store. |
value | The value of type TTrivial to store. |
Definition at line 450 of file boxing/placeholder.inl.