This is the central class of ALib Boxing . By using template meta programming, an object of this class can be created by passing just 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 in detail per "boxable type".
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 header file alib/compatibility/std_boxing_functional.hpp as documented with namespace alib::compatibility::std.
Definition at line 38 of file box.inl.
|
| Box () noexcept |
|
| Box (Box &&) noexcept=default |
| Trivial default move constructor.
|
|
| Box (const Box &) noexcept=default |
| Trivial default copy constructor.
|
|
template<typename TBoxable > |
constexpr | Box (const TBoxable &src) noexcept |
|
| Box (TypeCode typeCode, const Placeholder &placeholder) noexcept |
|
| ~Box () noexcept=default |
| Trivial default destructor.
|
|
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_API 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_API 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_API 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_API | operator bool () const |
|
bool | operator!= (const Box &rhs) const |
|
ALIB_API bool | operator< (Box const &rhs) const |
|
ALIB_API bool | operator<= (Box const &rhs) const |
|
Box & | operator= (Box &&) noexcept=default |
|
Box & | operator= (const Box &) noexcept=default |
|
ALIB_API bool | operator== (Box const &rhs) const |
|
ALIB_API bool | operator> (Box const &rhs) const |
|
bool | operator>= (Box const &rhs) const |
|
const std::type_info & | TypeID () const |
|
template<typename TUnboxable > |
const TUnboxable | Unbox () const |
|
template<typename TElementType > |
TElementType * | UnboxArray () const |
|
wchar | UnboxCharacter () const |
|
template<typename TElementType > |
TElementType & | UnboxElement (integer idx) const |
|
ALIB_API double | UnboxFloatingPoint () const |
|
integer | UnboxLength () const |
|
template<typename TUnboxable > |
TUnboxable | UnboxMutable () const |
|
integer | UnboxSignedIntegral () const |
|
uinteger | UnboxUnsignedIntegral () const |
|
template<typename TBoxable >
Box |
( |
const TBoxable & | src | ) |
|
|
inlineconstexprnoexcept |
Constructor using template meta programming to fetch any type of C++ value.
Internally, this constructor is implemented using a set of different constructors which are selected by the compiler using std::enable_if
conditions.
Types derived from class Box itself are boxed by coping 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 >()...)) 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 1229 of file box.inl.
template<typename TFDecl , typename... TArgs>
decltype(std::declval< typename TFDecl::Signature >()(std::declval< Box & >(), std::declval< TArgs >()...)) 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 assertion 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 1175 of file box.inl.
template<typename TFDecl >
TFDecl::Signature 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 IsCharacter |
( |
| ) |
const |
|
inline |
Tests if this box contains one of types char
, wchar_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 four different character types.
- Returns
true
if this box contains a character type, false
otherwise.
Definition at line 652 of file box.inl.
bool 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 575 of file box.inl.
template<typename TBoxable >
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 to test 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 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 593 of file box.inl.
template<typename TUnboxable >
const TUnboxable Unbox |
( |
| ) |
const |
|
inline |
Returns the contents of this box converted to type TBoxable. By default this is done by invoking template method Placeholder::Read on field data. This behavior might be customized by specializing structT_Boxer".
With debug-builds, the actual type of this object is
\ref ALIB_ASSERT_ERROR "asserted" to equal the templated return type.
\note
With debug-builds, it is \ref ALIB_ASSERT_ERROR "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
-
TUnboxable | The type to unbox. If it is not unboxable, a compile-time assertion is given. |
- Returns
- The unboxed value of type TUnboxable .
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 1018 of file box.inl.