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 aworx::lib::compatibility::std.
Definition at line 33 of file box.inl.
|
constexpr | Box () noexcept |
|
| Box (Box &&) noexcept=default |
|
| Box (const Box &) noexcept=default |
|
template<typename TBoxable > |
constexpr | Box (const TBoxable &src) noexcept |
|
| ~Box () noexcept=default |
|
size_t | ArrayElementSize () const |
|
template<typename TFDecl , typename... TArgs> |
decltype( | Call (TArgs &&... args) conststd::declval< typename TFDecl::Signature >()(std::declval< Box & >(), std::declval< TArgs >()...)) |
|
template<typename TFDecl , typename... TArgs> |
decltype( | Call (TArgs &&... args) std::declval< typename TFDecl::Signature >()(std::declval< Box & >(), std::declval< TArgs >()...)) |
|
template<typename TFDecl , typename... TArgs> |
decltype( | CallDirect (typename TFDecl::Signature function, TArgs &&... args) conststd::declval< typename TFDecl::Signature >()(std::declval< Box & >(), std::declval< TArgs >()...)) |
|
template<typename TFDecl , typename... TArgs> |
decltype( | CallDirect (typename TFDecl::Signature function, TArgs &&... args) std::declval< typename TFDecl::Signature >()(std::declval< Box & >(), std::declval< TArgs >()...)) |
|
ALIB_API void | Clone (monomem::MonoAllocator &memory) |
|
Placeholder & | Data () |
|
const Placeholder & | Data () const |
|
const detail::VTable * | DbgGetVTable () const |
|
const std::type_info & | ElementTypeID () const |
|
template<typename TFDecl > |
TFDecl::Signature | GetFunction (Reach searchScope, bool isInvocation=false) const |
|
unsigned int | GetPlaceholderUsageLength () const |
|
ALIB_API size_t | Hashcode () const |
|
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 |
|
constexpr 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 . |
decltype( 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 variadic further 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 1131 of file box.inl.
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 IsSignedIntegral |
( |
| ) |
const |
|
inline |
Tests if this 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 570 of file box.inl.
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 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 588 of file box.inl.
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 rational for why ALib is generally using signed types for array lengths, is given here.
- Returns
- The length of the boxed object.
Definition at line 975 of file box.inl.