ALib C++ Library
Library Version: 2510 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
alib::boxing::Placeholder Union Reference

Description:

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

  • fundamental types,
  • "fitting" value types that are trivially copyable,
  • "fitting" value types that are not trivially copyable (not constexpr)
  • pointers and
  • arrays.

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 Boxing

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.

Constexpr Boxing

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.

See also

Definition at line 294 of file boxing/placeholder.inl.

Collaboration diagram for alib::boxing::Placeholder:
[legend]

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.
 
characterDebugger_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)
 

Field Details:

◆ Array

detail::StructArray alib::boxing::Placeholder::Array

Used when storing C++ arrays.

Definition at line 298 of file boxing/placeholder.inl.

◆ Bytes

detail::UnionBytes alib::boxing::Placeholder::Bytes

Byte arrays of different length.

Definition at line 301 of file boxing/placeholder.inl.

◆ Debugger_Integral

integer alib::boxing::Placeholder::Debugger_Integral

This union field was inserted only for debug display.

Definition at line 305 of file boxing/placeholder.inl.

◆ Debugger_String

character* alib::boxing::Placeholder::Debugger_String

This union field was inserted only for debug display.

Definition at line 304 of file boxing/placeholder.inl.

◆ FloatingPoints

detail::UnionFloatingPoints alib::boxing::Placeholder::FloatingPoints

Collection of floating points of different sizes.

Definition at line 300 of file boxing/placeholder.inl.

◆ Integrals

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.

◆ PointerPair

detail::PointerPair alib::boxing::Placeholder::PointerPair

Collection of two const void pointers.

Definition at line 296 of file boxing/placeholder.inl.

◆ PointerPairMutable

detail::PointerPairMutable alib::boxing::Placeholder::PointerPairMutable

Collection of two void pointers.

Definition at line 297 of file boxing/placeholder.inl.

◆ VoidP

void* alib::boxing::Placeholder::VoidP

Just a void pointer.

Definition at line 302 of file boxing/placeholder.inl.

Constructor(s) / Destructor Details:

◆ Placeholder()

alib::boxing::Placeholder::Placeholder ( )
inlineconstexpr

Default constructor. Leaves everything uninitialized.

Definition at line 309 of file boxing/placeholder.inl.

Method Details:

◆ Clear()

template<unsigned int UsageLength>
void alib::boxing::Placeholder::Clear ( )
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.

Template Parameters
UsageLengthThe number of bytes to clear.

Definition at line 378 of file boxing/placeholder.inl.

◆ GetLength()

integer alib::boxing::Placeholder::GetLength ( ) const
inlineconstexpr

Returns the length of a stored array (the second word stored).

Returns
The length stored.

Definition at line 365 of file boxing/placeholder.inl.

◆ GetPointer()

template<typename TReturn>
TReturn * alib::boxing::Placeholder::GetPointer ( ) const
inline

Returns a pointer of type TReturn.

Template Parameters
TReturnThe requested pointer type
Returns
The pointer stored.

Definition at line 349 of file boxing/placeholder.inl.

◆ GetPointer2()

template<typename TReturn>
TReturn * alib::boxing::Placeholder::GetPointer2 ( ) const
inline

Returns a pointer of type TReturn.

Template Parameters
TReturnThe requested pointer type
Returns
The pointer stored.

Definition at line 356 of file boxing/placeholder.inl.

◆ GetVoidPointer()

const void * alib::boxing::Placeholder::GetVoidPointer ( ) const
inlineconstexpr

Returns a pointer of type void*.

Returns
The pointer stored.

Definition at line 343 of file boxing/placeholder.inl.

◆ Read() [1/6]

template<typename TMapped>
requires ( !( std::is_trivially_copyable_v<TMapped> && (sizeof(TMapped) <= 2 * sizeof(void*)) ) && !std::is_pointer_v<TMapped> )
TMapped alib::boxing::Placeholder::Read ( ) const
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.

Template Parameters
TMappedThe value type to unbox.
Returns
The value stored.

Definition at line 602 of file boxing/placeholder.inl.

◆ Read() [2/6]

template<typename TPointer>
requires std::is_pointer_v<TPointer>
TPointer alib::boxing::Placeholder::Read ( ) const
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.

Template Parameters
TPointerThe pointer-type to unbox.
Returns
The value stored.

Definition at line 611 of file boxing/placeholder.inl.

◆ Read() [3/6]

template<typename TIntegral>
requires ( std::is_integral_v<TIntegral> )
TIntegral alib::boxing::Placeholder::Read ( ) const
inlineconstexpr

Templated method to read integral types from this placeholder.

Template Parameters
TIntegralThe integral type to unbox.
Returns
The value stored.

Definition at line 622 of file boxing/placeholder.inl.

◆ Read() [4/6]

template<typename TFloat>
requires ( std::is_floating_point_v<TFloat> )
TFloat alib::boxing::Placeholder::Read ( ) const
inlineconstexpr

Templated method to read integral types from this placeholder.

Template Parameters
TFloatThe integral type to unbox.
Returns
The value stored.

Definition at line 653 of file boxing/placeholder.inl.

◆ Read() [5/6]

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> )
TTrivial alib::boxing::Placeholder::Read ( ) const
inlineconstexpr

Templated method to read trivially copyable types that fits into the placeholder.

Template Parameters
TTrivialThe type to read from this placeholder.
Returns
The stored value.

Definition at line 668 of file boxing/placeholder.inl.

◆ Read() [6/6]

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*) ) )
void alib::boxing::Placeholder::Read ( TTrivial1 & v1,
TTrivial2 & v2 ) const
inlineconstexpr

Templated method that reads two trivially copyable types that jointly fit into the placeholder.

Template Parameters
TTrivial1The type of the first value to read from this placeholder.
TTrivial2The type of the second value to read from this placeholder.
Parameters
v1Output parameter. Receives the first value.
v2Output parameter. Receives the second value.

Definition at line 702 of file boxing/placeholder.inl.

◆ SetPointer()

void alib::boxing::Placeholder::SetPointer ( void * value)
inlineconstexpr

Sets a pointer of type char*.

Parameters
valueThe value to set.

Definition at line 361 of file boxing/placeholder.inl.

◆ Write() [1/8]

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*) ) )
void alib::boxing::Placeholder::Write ( const T1 & v1,
const T2 & v2 )
inlineconstexpr

Writes two values of arbitrary type into the placeholder. The method requires that:

  • Types T1 and T2 are trivially copyable
  • The types are no pointers
  • The sum of the types' sizes fit into the placeholder which is of 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.

Template Parameters
T1The type of the first value to store.
T2The type of the second value to store.
Parameters
v1The first value to store.
v2The second value to store.

Definition at line 493 of file boxing/placeholder.inl.

◆ Write() [2/8]

template<typename TArray>
void alib::boxing::Placeholder::Write ( const TArray * pointer,
integer length )
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.)

Template Parameters
TArrayThe pointer type.
Parameters
pointerThe pointer to store.
lengthThe array's length to store.

Definition at line 553 of file boxing/placeholder.inl.

Here is the call graph for this function:

◆ Write() [3/8]

template<typename TFloat>
requires ( std::is_floating_point_v<TFloat> )
void alib::boxing::Placeholder::Write ( const TFloat & value)
inlineconstexpr

This version of the overloaded method writes floating-point values.

Template Parameters
TFloatThe integral type to store.
Parameters
valueThe value to store.

Definition at line 428 of file boxing/placeholder.inl.

◆ Write() [4/8]

template<typename TIntegral>
requires ( std::is_integral_v<TIntegral> )
void alib::boxing::Placeholder::Write ( const TIntegral & value)
inlineconstexpr

This version of the overloaded method writes integral values.

Template Parameters
TIntegralThe integral type to store.
Parameters
valueThe value to store.

Definition at line 397 of file boxing/placeholder.inl.

◆ Write() [5/8]

template<typename TP1, typename TP2>
void alib::boxing::Placeholder::Write ( const TP1 * p1,
const TP2 * p2 )
inlineconstexpr

This version of the overloaded method is used for boxing two pointer types.

Template Parameters
TP1The type of the first pointer.
TP2The type of the second pointer.
Parameters
p1The first pointer to store.
p2The second pointer to store.

Definition at line 562 of file boxing/placeholder.inl.

Here is the call graph for this function:

◆ Write() [6/8]

template<typename TPointer>
requires ( !std::is_trivially_copyable_v<TPointer> && (sizeof(TPointer) <= 2 * sizeof(void*)) )
void alib::boxing::Placeholder::Write ( const TPointer & value)
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.

Template Parameters
TPointerThe type of the value to store.
Parameters
valueThe value to store.

Definition at line 582 of file boxing/placeholder.inl.

Here is the call graph for this function:

◆ Write() [7/8]

template<typename TPointer>
void alib::boxing::Placeholder::Write ( const TPointer * pointer)
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.

Template Parameters
TPointerThe pointer type.
Parameters
pointerThe pointer to store.

Definition at line 539 of file boxing/placeholder.inl.

Here is the call graph for this function:

◆ Write() [8/8]

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> )
void alib::boxing::Placeholder::Write ( const TTrivial & value)
inlineconstexpr

This version of the overloaded method requires type TTrivial to:

  • be trivially copyable,
  • be a non-pointer type,
  • that it fits into the placeholder which is of 2 * sizeof(void*), and
  • is not integral (handled with other overload).

This 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.

Template Parameters
TTrivialThe mapped type to store.
Parameters
valueThe value of type TTrivial to store.

Definition at line 450 of file boxing/placeholder.inl.


The documentation for this union was generated from the following file: