ALib C++ Library
Library Version: 2510 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
alib::boxing::BoxTraits< TBoxable > Struct Template Reference

Description:

template<typename TBoxable>
struct alib::boxing::BoxTraits< TBoxable >

This template struct is used to define customized behavior for boxing C++ type TBoxable.

Default Boxing:

If this struct is not specialized for template type TBoxable, default boxing applies. With that, values and pointers of a type are boxed in the same way:

  • They are both boxed to a pointer of TBoxable if a value of the type does not "fit" into a box's Placeholder or if the type is not copy-constructible or not trivially destructible.
  • Otherwise, both are boxed as values, hence if a pointer is given to the constructor or assign operator= of class Box, indirection operator* is applied.


Custom Boxing With Specializations Of This Struct:

The default boxing briefly described above, can be manipulated by providing a specialization of this struct. All three entities of this default implementation have to be provided with such specializations:

  1. Type alias Mapping:
    This alias defines the type that a value of TBoxable is converted to when boxed.

    If special type NotBoxableTag is given, then boxing is disallowed for type TBoxed. In this case, only declarations of functions Write and Read need to be provided, as they are never invoked.

    The default implementation of this struct uses a second special type available, DefaultBoxingTag which denotes default boxing.

  2. Boolean constexpr value IsArray:
    If set to true, array-boxing is performed. In this case Mapping denotes the element type of the boxed C++ array.
  3. Static Method Write:
    This method is invoked for converting source values to mapped types. Often the default implementation given in the default version of this struct is applicable. In this case it can simply be copied to the specialization.

    Custom implementations may use one of the overloads of method Placeholder::Write or alternatively write to the union members of the placeholder directly.

  4. Static Method Read:
    This method is invoked for converting the placeholder data back to the boxed source type. Often the default implementation given in the default version of this struct is well suited. In this case it can simply be copied to the specialization.
    Custom implementations may use one of the overloads of method Placeholder::Read or alternatively read the union members of the placeholder directly.

    A type becomes not unboxable at the moment this function returns a different type than TBoxable.
    This may well be intended, and thus the specialized version of this struct may declare this method to return void. In this case a declaration of the method is enough, as it will never be invoked.
    With conditional specializations of this struct (see Programmer's Manual chapter 7.7 Tutorial: Conditional Customization), the return type might be likewise conditionally set. Such a return type then decides which of the types are unboxable and which are not.

Note
If a specialization uses default type mapping by providing
using   Mapping=  DefaultBoxingTag;
in theory, a mixture of default and custom boxing is in place! Note, that the authors of this library and documentation have not seen a use case for this, yet.


Helper Macros:

A set of macros for defining specializations exist. The use of the macro is recommended, as besides being less error-prone, their use makes the code more readable. Finally, chances are good that code that uses the macros remains compatible with future versions of module ALib Boxing.

All macros expect this struct's template type TBoxable as the first parameter, and most expect the mapped type as the second parameter.

For more information, see the reference documentation of the macros, which are:


Value Boxing and Nulled Pointers:

If a type is boxed as value (either with default boxing or custom boxing) and a nulled pointer to that type is boxed, method Placeholder::Clear is invoked instead of this struct's method Write.


Avoiding Seldom Compilation Errors:

For technical reasons, namely to avoid compilation problems, some conditional specialization is internally made, that declare method Read void. This is sometimes needed if a type is not returnable, even if that becomes never be boxed or unboxed. Such a situation might happen, for example, if class Box is part of a union.
The specialization is made for the following types of TBoxable:

  • C++ array types
    Those types are fetched by an overloaded constructor that does not (because it cannot) leverage this struct. Likewise, they cannot be unboxed in the usual fashion.
  • Function types (selected by std::is_function<TBoxable>::value).

If a dubious error message about method Read not being able to return a certain type occurs, even one that a user's code even "actively" tries to box or unbox, then it might be helpful to specialize this struct for such type, without providing implementations of Write and Read and with the latter to return void.


See also
More explanation and sample code is given in chapter 7. Customizing Boxing of the Programmer's Manual of module ALib Boxing.
Template Parameters
TBoxableThe source type to customize boxing for.

Definition at line 147 of file boxingtraits.inl.

Public Type Index:

using Mapping = DefaultBoxingTag
 

Public Static Field Index:

static constexpr bool IsArray = false
 Denotes whether type TBoxable is boxed as an array-type or not.
 

Public Static Method Index:

static std::conditional_t<!std::is_abstract< TBoxable >::value, TBoxable, TBoxable & > Read (const Placeholder &box)
 
static constexpr void Write (Placeholder &box, const TBoxable &value)
 

Type Definition Details:

◆ Mapping

template<typename TBoxable>
using alib::boxing::BoxTraits< TBoxable >::Mapping = DefaultBoxingTag

Defines the mapped type. Special designator types DefaultBoxingTag and NotBoxableTag may be given to denote corresponding behavior. The default implementation specifies designator type DefaultBoxingTag, which disables custom boxing.

Definition at line 154 of file boxingtraits.inl.

Field Details:

◆ IsArray

template<typename TBoxable>
bool alib::boxing::BoxTraits< TBoxable >::IsArray = false
staticconstexpr

Denotes whether type TBoxable is boxed as an array-type or not.

Definition at line 157 of file boxingtraits.inl.

Method Details:

◆ Read()

template<typename TBoxable>
std::conditional_t<!std::is_abstract< TBoxable >::value, TBoxable, TBoxable & > alib::boxing::BoxTraits< TBoxable >::Read ( const Placeholder & box)
inlinestatic

Used for unboxing a value, precisely reading the contents of field Box::data, which is given with output parameter box and creating a value of type TBoxable from that.
The default implementation of this struct implements this method as follows:

return box.Read<TBoxable>();

This implementation leverages the overloaded method Placeholder::Read and is often all that is needed with custom specializations.

If a different type than TBoxable is returned, then that source type is not unboxable. To intend such behavior, for example, because TBoxable is mapped to a reduced type and therefore unboxing is not possible, specializations may declare the return type to be void and omit a definition of this method.
With conditional customizations, also other return types may be given, which likewise denote an unboxable source type. A sample of that is given with Programmer's Manual chapter 7.7 Tutorial: Conditional Customization.

Parameters
boxThe Placeholder to unbox the data from
Returns
The unboxed object.

Definition at line 195 of file boxingtraits.inl.

Here is the call graph for this function:

◆ Write()

template<typename TBoxable>
constexpr void alib::boxing::BoxTraits< TBoxable >::Write ( Placeholder & box,
const TBoxable & value )
inlinestaticconstexpr

Used for boxing a value, precisely writing the boxable portion of a type into field Box::data, which is given with parameter box.
The default implementation of this struct implements this method as follows:

static constexpr void Write( Placeholder& box, const TBoxable& value ) {
box.Write( value );
}

This implementation leverages the overloads Placeholder::Write and is often all that is needed with custom specializations.

Parameters
boxThe placeholder of the destination box.
valueThe value to that is to be boxed.

Definition at line 169 of file boxingtraits.inl.

Here is the call graph for this function:

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