This is the central class of ALib Boxing . By making extensive use of template programming and keyword requires
on overloaded constructors, an object of this class can be created by passing instances of (almost) any C++ type to the constructor. The passed value will be "boxed" within the instance of this class.
Then, the instances of this class support type checking, value extraction ("unboxing") and the invocation of "virtual methods". All features are customizable via type traits, and thus the built-in defaulted behavior for a custom type can be changed.
A thorough introduction to and documentation of all aspects of ALib Boxing is given with Programmer's Manual ALib Boxing.
Functors In Namespace std
Functors std::hash
, std::equal_to,
and std::less
are specialized for this type with the inclusion of the header-file ALib.Boxing.StdFunctors.H.
Definition at line 28 of file box.inl.
|
| Box () noexcept |
|
template<typename TBoxable> |
constexpr | Box (const TBoxable &src) noexcept |
|
| Box (TypeCode typeCode, const Placeholder &placeholder) noexcept |
|
size_t | ArrayElementSize () const |
|
template<typename TFDecl, typename... TArgs> |
decltype(std::declval< typename TFDecl::Signature >()(std::declval< Box & >(), std::declval< TArgs >()...)) | Call (TArgs &&... args) |
|
template<typename TFDecl, typename... TArgs> |
decltype(std::declval< typename TFDecl::Signature >()(std::declval< Box & >(), std::declval< TArgs >()...)) | Call (TArgs &&... args) const |
|
template<typename TFDecl, typename... TArgs> |
decltype(std::declval< typename TFDecl::Signature >()(std::declval< Box & >(), std::declval< TArgs >()...)) | CallDirect (typename TFDecl::Signature function, TArgs &&... args) |
|
template<typename TFDecl, typename... TArgs> |
decltype(std::declval< typename TFDecl::Signature >()(std::declval< Box & >(), std::declval< TArgs >()...)) | CallDirect (typename TFDecl::Signature function, TArgs &&... args) const |
|
ALIB_DLL void | Clone (MonoAllocator &memory) |
|
Placeholder & | Data () |
|
const Placeholder & | Data () const |
|
const detail::VTable * | DbgGetVTable () const |
|
const std::type_info & | ElementTypeID () const |
|
TypeCode | ExportType () const |
|
Placeholder | ExportValue () const |
|
template<typename TFDecl> |
TFDecl::Signature | GetFunction (Reach searchScope, bool isInvocation=false) const |
|
unsigned int | GetPlaceholderUsageLength () const |
|
ALIB_DLL size_t | Hashcode () const |
|
void | Import (TypeCode typeCode) |
|
void | Import (TypeCode typeCode, const Placeholder &placeholder) |
|
bool | IsArray () const |
|
template<typename TElementType> |
bool | IsArrayOf () const |
|
bool | IsCharacter () const |
|
bool | IsEnum () const |
|
bool | IsFloatingPoint () const |
|
ALIB_DLL bool | IsNotNull () const |
|
bool | IsNull () const |
|
bool | IsPointer () const |
|
bool | IsSameType (const Box &other) const |
|
bool | IsSignedIntegral () const |
|
template<typename TBoxable> |
bool | IsType () const |
|
bool | IsUnsignedIntegral () const |
|
ALIB_DLL | operator bool () const |
|
bool | operator!= (const Box &rhs) const |
|
ALIB_DLL bool | operator< (Box const &rhs) const |
|
ALIB_DLL bool | operator<= (Box const &rhs) const |
|
ALIB_DLL bool | operator== (Box const &rhs) const |
|
ALIB_DLL bool | operator> (Box const &rhs) const |
|
bool | operator>= (Box const &rhs) const |
|
const std::type_info & | TypeID () const |
|
template<typename TValue>
requires IsUnboxableStringType<TValue> |
TValue | Unbox () const |
|
template<typename TValue>
requires ( !std::is_pointer_v<TValue> && !IsUnboxableStringType<TValue> ) |
TValue | Unbox () const |
|
template<typename TPointer>
requires ( std::is_pointer_v<TPointer> && !IsUnboxableStringType<TPointer> ) |
const std::remove_pointer_t< TPointer > * | Unbox () const |
|
template<typename TElementType> |
TElementType * | UnboxArray () const |
|
wchar | UnboxCharacter () const |
|
template<typename TElementType> |
TElementType & | UnboxElement (integer idx) const |
|
ALIB_DLL double | UnboxFloatingPoint () const |
|
integer | UnboxLength () const |
|
template<typename TPointer>
requires std::is_pointer_v<TPointer> |
TPointer | UnboxMutable () const |
|
integer | UnboxSignedIntegral () const |
|
uinteger | UnboxUnsignedIntegral () const |
|
template<typename TBoxable>
alib::boxing::Box::Box |
( |
const TBoxable & | src | ) |
|
|
inlineconstexprnoexcept |
Constructor to fetch any type of object.
Internally, this constructor is implemented using a set of different constructors which are selected by the compiler using keyword requires
.
Types derived from class Box itself are boxed by copying the internal values of the box. This means that boxing objects of derived types is similar to "downcasting" the object to class Box.
- Template Parameters
-
TBoxable | Any C++ type to be boxed. |
- Parameters
-
src | The src value or pointer type T . |
template<typename TFDecl, typename... TArgs>
decltype(std::declval< typename TFDecl::Signature >()(std::declval< Box & >(), std::declval< TArgs >()...)) alib::boxing::Box::Call |
( |
TArgs &&... | args | ) |
|
|
inline |
Same as method Call, but usable with interfaces that only accept a mutable (aka not constant) box. Technically, the only difference between this method and Call is that the latter is declared const
.
- Note
- The only built-in boxing function that requires a mutable reference to a box, is function FClone. This modifies the contents of a box by performing deep copies, with the goal to extent the lifecylce of boxes.
- Template Parameters
-
TFDecl | The function type to call. Has to be explicitly specified. |
TArgs | Types of the variadic arguments args. Do not need to be specified. |
- Parameters
-
args | Variadic arguments forwarded to the function. |
- Returns
- Nothing in case that TReturn is void, otherwise the result of the invocation, respectively
TReturn()
if the requested function type was not found for this Box.
Definition at line 1089 of file box.inl.
template<typename TFDecl, typename... TArgs>
decltype(std::declval< typename TFDecl::Signature >()(std::declval< Box & >(), std::declval< TArgs >()...)) alib::boxing::Box::Call |
( |
TArgs &&... | args | ) |
const |
|
inline |
Invokes a function registered for boxes of the mapped type. The function declaration is provided with the first template parameter TFDecl. The further variadic template parameters do not need to be specified. They specify the types of the called function's parameters and are matched against the function signature given with the declaration. If the types of the given function arguments do not correspond to the types of the box-function called, a compile-time error is raised.
- Note
- Precisely, the variadic template types denote the function arguments starting from the second, as the first argument is always a reference to the box that this method was invoked on.
If no corresponding function was registered for the mapped type, then a default function, that is applicable to any mapped type is searched. If neither is found, a default value of the return type of the function is returned.
With debug-builds, an error is raised if the function type is not known at all to ALib Boxing. This is true, if an implementation was neither registered with any other mapped type, nor registered as a default.
- See also
- Description of method GetFunction to implement two use cases:
- Repetitive invocation of the same function.
- Avoidance of default functions
-
A non-constant overload exists, for the seldom case the reference to this box that is passed to the function, needs to be of non-constant type.
- Template Parameters
-
TFDecl | The function type to call. Has to be explicitly specified. |
TArgs | Types of the variadic arguments args. Do not need to be specified. |
- Parameters
-
args | Variadic arguments forwarded to the function. |
- Returns
- Nothing in case that TReturn is void, otherwise the result of the invocation, respectively
TReturn()
if the requested function type was not found for this Box.
Definition at line 1039 of file box.inl.
template<typename TFDecl>
TFDecl::Signature alib::boxing::Box::GetFunction |
( |
Reach | searchScope, |
|
|
bool | isInvocation = false ) const |
|
inline |
Searches an implementation of a box-function identified by template parameter TFDecl, which has to be implemented according the rules of function declarations.
If found, a non-nulled function pointer is returned, otherwise a nulled one.
On success, the function can be invoked by passing the returned pointer to method CallDirect. This approach avoids further searches that are otherwise to be performed with multiple invocations of method Call.
If parameter defaults equals Reach::Local, functions specific to the mapped type of this box (registered using BootstrapRegister) are searched. If Reach::Global is given, then a defaulted function (registered using BootstrapRegisterDefault) is searched, if no specific function was found.
- Note
- Reach::Local can be used to detect specific behavior and to avoid the use of default functions. This can be useful if the default implementation of a function is just not applicable in a certain situation.
-
A second use case of this method are situations where multiple invocations of the same function are to be done, on just one or on several boxes of the same mapped type:
assert( box1.IsSameType( box2 ) );
auto* func= box1.GetFunction<FMyFunc>( Reach::Global );
if( func != nullptr )
for( int i= 0; i< 10; ++i )
{
box1.CallDirect<FMyFunc>( func, i );
box2.CallDirect<FMyFunc>( func, i );
}
- Template Parameters
-
- Parameters
-
searchScope | Reach::Local chooses type-specific functions only, while. Reach::Global includes default functions in the search. |
isInvocation | Available only in debug compilations. If true , a counter associated with an implementation found is increaed to provide statistics. Defaults to false and should not be given. |
- Returns
- The function implementation.
nullptr
in case that no function is available.
bool alib::boxing::Box::IsCharacter |
( |
| ) |
const |
|
inline |
Tests if this box contains one of types char
, wchar_t
, char8_t
, char16_t
, or char32_t
.
With default library compilation that disables symbol ALIB_FEAT_BOXING_BIJECTIVE_CHARACTERS, this method will be inlined and simply returns IsType<wchar>()
.
Otherwise, this method will not be inlined and tests for all five different character types.
- Returns
true
if this box contains a character type, false
otherwise.
Definition at line 524 of file box.inl.
bool alib::boxing::Box::IsSignedIntegral |
( |
| ) |
const |
|
inline |
Tests if this box contains a signed integral type (one of the C++ fundamental types of different sizes).
With compilation that disables ALIB_FEAT_BOXING_BIJECTIVE_INTEGRALS, this method will be inlined and simply returns IsType<integer>()
.
Otherwise this method will not be inlined and tests for the five different integer sizes (int8_t
, int16_t
, int32_t
, int64_t
, and intGap_t).
- Returns
true
if this box contains a signed integral type, false
otherwise.
Definition at line 455 of file box.inl.
template<typename TBoxable>
bool alib::boxing::Box::IsType |
( |
| ) |
const |
Checks if this box stores a value of type TBoxable.
If template parameter TBoxable it is not unboxable, a compile-time assertion is given, with specific guidance why the type must not be unboxed and for that reason must not even be tested for.
Special type void
may be given for testing if this box does contain a value at all. A box does not contain a value, after
- default construction,
- construction with keyword
nullptr
, or
- assignment of keyword
nullptr
.
For more information on the "void state" of boxes, see manual chapter 12.1 Void And Nulled Boxes.
- Template Parameters
-
TBoxable | The boxable type guessed. |
- Returns
true
if this box stores a value that is convertible to type TBoxable, false
otherwise.
bool alib::boxing::Box::IsUnsignedIntegral |
( |
| ) |
const |
|
inline |
Tests if this box contains an unsigned integral type (one of the C++ fundamental type of different sizes).
With default library compilation that disables ALIB_FEAT_BOXING_BIJECTIVE_INTEGRALS, this method will be inlined and simply returns IsType<uinteger>()
.
Otherwise this method will not be inlined and tests for the five different integer sizes (uint8_t
, uint16_t
, uint32_t
, uint64_t
, and uintGap_t).
- Returns
true
if this box contains an unsigned integral type, false
otherwise.
Definition at line 470 of file box.inl.
template<typename TValue>
requires ( !std::is_pointer_v<TValue> && !IsUnboxableStringType<TValue> )
TValue alib::boxing::Box::Unbox |
( |
| ) |
const |
|
inline |
Creates a value of type TBoxable from the contents of this box . By default, this is done by invoking the template method Placeholder::Read on field data. This behavior might be customized by specializing type trait BoxTraits.
This overload of the method accepts only (non-const) value types. For details on unboxing values and pointers, see chapter 6.5 Constant vs. Mutable Box Contents of the Programmer's Manual of this module ALib Boxing.
With debug-builds, it is asserted that given TBoxable is mapped to the type stored, so that IsType returned true
for TBoxable. In release compilations, no checks are performed!
- Template Parameters
-
TValue | The value-type to unbox. If it is not unboxable, a compile-time assertion is raised. |
- Returns
- The unboxed value.
Definition at line 673 of file box.inl.
template<typename TPointer>
requires ( std::is_pointer_v<TPointer> && !IsUnboxableStringType<TPointer> )
const std::remove_pointer_t< TPointer > * alib::boxing::Box::Unbox |
( |
| ) |
const |
|
inline |
Returns a pointer to a constant instance of type TPointer that this box stored. By default, this is done by invoking the template method Placeholder::Read on field data. This behavior might be customized by specializing type trait BoxTraits.
This overload of the method accepts only (non-const) pointer-types. For details on unboxing values and pointers, see chapter 6.5 Constant vs. Mutable Box Contents of the Programmer's Manual of this module ALib Boxing.
With debug-builds, it is asserted that given TBoxable is mapped to the type stored, so that IsType returned true
for TBoxable. In release compilations, no checks are performed!
- Template Parameters
-
TPointer | The pointer-type to unbox. If it is not unboxable, a compile-time assertion is raised. |
- Returns
- The unboxed pointer to a constant instance of TPointer.
Definition at line 704 of file box.inl.
wchar alib::boxing::Box::UnboxCharacter |
( |
| ) |
const |
|
inline |
Unboxes one of the types char
, wchar_t
, char8_t
, char16_t
, or char32_t
and converts it to wchar.
With default library compilation that disables ALIB_FEAT_BOXING_BIJECTIVE_CHARACTERS, this method will be inlined and simply returns Unbox<wchar>()
.
Otherwise, this method will not be inlined and tests for the five different character types before unboxing.
- Returns
- The stored character.
Definition at line 539 of file box.inl.
integer alib::boxing::Box::UnboxLength |
( |
| ) |
const |
|
inline |
Returns the length of a boxed Array. While in theory, the length applies only to arrays, in debug-compilations, no run-time type check is performed. This way, mapped types that use the second "word" of the placeholder to store a value of type integer
, may also use this function.
In the latter case, the name of this method might be misleading and therefore, it is recommended to use Data().integer[1] to denote that a custom interpretation of the placeholder is performed. The compilation result is the same.
Some quick rationale for why ALib is generally using signed types for array lengths, is given here.
- Returns
- The length of the boxed object.
Definition at line 893 of file box.inl.