8#ifndef HPP_ALIB_BOXING_BOX
9#define HPP_ALIB_BOXING_BOX 1
11#if !defined(HPP_ALIB_BOXING_BOXING)
12# error "ALib sources with ending '.inl' must not be included from outside."
15#if ALIB_DEBUG && !defined(HPP_ALIB_LANG_DBGTYPEDEMANGLER)
19namespace alib {
namespace boxing {
64 #define ALIB_TEMPINTERNAL_STATIC_TYPE_CHECKS_BOXING(TBoxable, TClean) \
65 using TVal = typename std::remove_pointer<ATMP_RCVR(TBoxable)>::type; \
67 constexpr bool valueBoxing = !ATMP_IS_PTR(TClean); \
68 constexpr bool isVolatile = std::is_volatile<ATMP_RP(TBoxable)>::value; \
69 constexpr bool isPointer = std::is_pointer<TBoxable>::value; \
70 constexpr bool isValue = !isPointer; \
71 constexpr bool isCustomizedTV= TT_IsCustomized<TVal>::value; \
72 constexpr bool isCustomizedTP= TT_IsCustomized<TPtr>::value; \
73 constexpr bool isBlockedTV = ATMP_EQ( detail::TNotBoxable, typename T_Boxer<TVal>::Mapping::Type ); \
74 constexpr bool isBlockedTP = ATMP_EQ( detail::TNotBoxable, typename T_Boxer<TPtr>::Mapping::Type ); \
76 ALIB_STATIC_DENY( GeneralBoxingRule1, !valueBoxing && isVolatile, \
77 "Types boxed as pointers can not be boxed if volatile." ); \
79 ALIB_STATIC_DENY( CustomBoxingRule3, isBlockedTV && isValue, \
80 "Customized boxing forbids boxing this value type: " \
81 "'T_Boxer<T>::Type == NotBoxable'!" ); \
83 ALIB_STATIC_DENY( CustomBoxingRule4, isBlockedTP && isPointer, \
84 "Customized boxing forbids boxing this pointer type: " \
85 "'T_Boxer<T*>::Type == NotBoxable'!" ); \
87 ALIB_STATIC_DENY( CustomBoxingRule5, isBlockedTV && !isCustomizedTP && isPointer, \
88 "Customized boxing forbids boxing value type T (T_Boxer<T>::Type == NotBoxable), while " \
89 "no customization for this pointer type T* was given." ); \
91 ALIB_STATIC_DENY( CustomBoxingRule6, isBlockedTP && !isCustomizedTV && isValue, \
92 "Customized boxing forbids boxing pointer type T* " \
93 "(T_Boxer<T*>::Type == NotBoxable), while no customization for this value type T was " \
98 #define ALIB_TEMPINTERNAL_STATIC_TYPE_CHECKS_UNBOXING(TUnboxable) \
99 using T = ATMP_RCVR(TUnboxable); \
100 using TVal = typename std::remove_pointer<T>::type; \
101 using TPtr = TVal*; \
102 constexpr bool isConst = std::is_const <ATMP_RP(TUnboxable)>::value; \
103 constexpr bool isVolatile = std::is_volatile<ATMP_RP(TUnboxable)>::value; \
104 constexpr bool isPointer = std::is_pointer<TUnboxable>::value; \
105 constexpr bool isValue = !isPointer; \
106 constexpr bool valuesFit = sizeof(ATMP_IF_T_F(ATMP_EQ(void,TVal), void*,TVal)) \
107 <= sizeof(Placeholder); \
108 constexpr bool isConstructible= std::is_copy_constructible<TVal>::value; \
109 constexpr bool isTriviallyDest= std::is_trivially_destructible<TVal>::value; \
110 constexpr bool isCustomizedTV = TT_IsCustomized<TVal>::value; \
111 constexpr bool isCustomizedTP = TT_IsCustomized<TPtr>::value; \
112 constexpr bool isDefault = !(isCustomizedTV || isCustomizedTP); \
113 constexpr bool isBlockedTV = ATMP_EQ( detail::TNotBoxable, typename T_Boxer<TVal>::Mapping::Type ); \
114 constexpr bool isBlockedTP = ATMP_EQ( detail::TNotBoxable, typename T_Boxer<TPtr>::Mapping::Type ); \
115 constexpr bool isLockedTV = TT_IsLocked<TVal>::value; \
116 constexpr bool isLockedTP = TT_IsLocked<TPtr>::value; \
119 ALIB_STATIC_DENY( GeneralBoxingRule2, isConst, \
120 "Type qualifier 'const' not allowed with template type TUnboxable. Types boxed as values"\
121 " are always unboxed mutable, types boxed as pointers are always unboxed constant." ); \
123 ALIB_STATIC_DENY( GeneralBoxingRule3, isVolatile, \
124 "Type qualifier 'volatile' not allowed with template type TUnboxable" ); \
127 ALIB_STATIC_DENY( DefaultBoxingRule1, isDefault && isValue && !valuesFit, \
128 "This type can not be unboxed by value: " \
129 "By default, values that do not fit into boxes are boxed as pointers." ); \
131 ALIB_STATIC_DENY( DefaultBoxingRule2, \
132 isDefault && isValue && (!isConstructible || !isTriviallyDest), \
133 "This type can not be unboxed by value: " \
134 "By default, types that are not copy constructible or not trivially destructible, " \
135 "are boxed as pointers." ); \
137 ALIB_STATIC_DENY( DefaultBoxingRule3, \
138 isDefault && isPointer && valuesFit && isConstructible && isTriviallyDest, \
139 "This type can not be unboxed as pointer: Default boxing of types that fit " \
140 "into boxes and are copy constructible and trivially destructible, " \
141 "is performed by value." ); \
145 ALIB_STATIC_DENY( CustomBoxingRule1, isCustomizedTV && !isCustomizedTP && isPointer, \
146 "This pointer type T* can not be unboxed, because custom boxing is defined for " \
147 "value type T, while no custom boxing is defined for pointer type T*." ); \
149 ALIB_STATIC_DENY( CustomBoxingRule2, !isCustomizedTV && isCustomizedTP && isValue, \
150 "This value type T can not be unboxed, because custom boxing is defined for " \
151 "pointer type T*, while no custom boxing is defined for value type T." ); \
155 ALIB_STATIC_DENY( CustomBoxingRule3, isBlockedTV && isValue, \
156 "Customized boxing forbids unboxing (and even boxing) this value type: " \
157 "'T_Boxer<T>::Type == NotBoxable'!" ); \
159 ALIB_STATIC_DENY( CustomBoxingRule4, isBlockedTP && isPointer, \
160 "Customized boxing forbids unboxing (and even boxing) this pointer type: " \
161 "'T_Boxer<T*>::Type == NotBoxable'!" ); \
163 ALIB_STATIC_DENY( CustomBoxingRule5, isBlockedTV && !isCustomizedTP && isPointer, \
164 "Customized boxing forbids unboxing (and even boxing) value type T " \
165 "(T_Boxer<T>::Type == NotBoxable), while no customization for this pointer type T* " \
168 ALIB_STATIC_DENY( CustomBoxingRule6, isBlockedTP && !isCustomizedTV && isValue, \
169 "Customized boxing forbids unboxing (and even boxing) pointer type T* " \
170 "(T_Boxer<T*>::Type == NotBoxable), while no customization for this value type T was" \
174 ALIB_STATIC_DENY( CustomBoxingRule7, isLockedTV && isValue, \
175 "Customized boxing forbids unboxing this value type: " \
176 "'T_Boxer<T>::Read' returns a different type." ); \
178 ALIB_STATIC_DENY( CustomBoxingRule8, isLockedTP && isPointer, \
179 "Customized boxing forbids unboxing this pointer type: " \
180 "'T_Boxer<T*>::Read' returns a different type." ); \
182 ALIB_STATIC_DENY( CustomBoxingRule9, isLockedTV && !isCustomizedTP && isPointer, \
183 "Customized boxing forbids unboxing value type T " \
184 "('T_Boxer<T>::Read' returns a different type), while no customization for this pointer "\
185 "type T* was given." ); \
187 ALIB_STATIC_DENY( CustomBoxingRule10, isLockedTP && !isCustomizedTV && isValue, \
188 "Customized boxing forbids unboxing pointer type T* " \
189 "('T_Boxer<T*>::Read' returns a different type), while no customization for this value " \
190 "type T was given." ); \
194 #if defined(ALIB_DOX)
202 template<
typename TBoxable,
bool NoStaticAsserts= false>
208 template<
typename TBoxable>
269 #if defined(ALIB_DOX)
282 template <
typename TBoxable>
302 || std::is_same<
ATMP_RECVP(T),
wchar_t >::value
303 || std::is_same<
ATMP_RECVP(T),
char16_t>::value
304 || std::is_same<
ATMP_RECVP(T),
char32_t>::value
337 && ( ( !TT_IsCustomized<
ATMP_RCVR(T)*>::value
338 &&
sizeof(Placeholder) >=
sizeof(
ATMP_RCVP(T))
339 && std::is_copy_constructible <
ATMP_RCVP(T)>::value
340 && std::is_trivially_destructible<
ATMP_RCVP(T)>::value )
341 || TT_IsCustomized<
ATMP_RCVR(T) >::value )
357 && !TT_IsCustomized <
ATMP_RCVR(T) >::value
358 && !TT_IsCustomized <
ATMP_RCVR(T)*>::value
360 && ( (
sizeof(Placeholder) <
sizeof(
ATMP_RCVP(T)))
361 || !std::is_copy_constructible <
ATMP_RCVP(T)>::value
362 || !std::is_trivially_destructible<
ATMP_RCVP(T)>::value ) )
372 && !TT_IsCustomized <
ATMP_RCVR(T) >::value
382 && !TT_IsCustomized <
ATMP_RCVR(T) >::value
383 && TT_IsCustomized <
ATMP_RCVR(T)*>::value
413 && !std::is_const<T>::value
424 && std::is_const<
ATMP_RP(T)>::value
428 ,
data ( T_Boxer <T>::Write(
srcP ) )
465 && !TT_IsCustomized<
ATMP_RCVR(T) >::value
466 && ( TT_IsCustomized<
ATMP_RCVP(T) >::value
467 || (
sizeof(Placeholder) >=
sizeof(
ATMP_RCVP(T) )
468 && std::is_copy_constructible <
ATMP_RCVP(T)>::value
469 && std::is_trivially_destructible<
ATMP_RCVP(T)>::value ) )
480 ?
sizeof(Placeholder)
489 #undef ALIB_TEMPINTERNAL_STATIC_TYPE_CHECKS_BOXING
490 #undef ALIB_TM_IS_DEFAULT_BOXING
516 #if defined(ALIB_DOX)
538 template<
typename TBoxable>
544 template<
typename TBoxable>
551 template<
typename TBoxable>
561 #if !ALIB_FEAT_BOXING_BIJECTIVE_INTEGRALS || defined(ALIB_DOX)
638 #if !ALIB_FEAT_BOXING_BIJECTIVE_CHARACTERS || defined(ALIB_DOX)
723 template<
typename TElementType>
766 #if defined(ALIB_DOX)
785 template<
typename TUnboxable>
790 template <
typename TUnboxable>
808 #undef ALIB_TEMPINTERNAL_STATIC_TYPE_CHECKS_UNBOXING
811 #if defined(ALIB_DOX)
821 template<
typename TUnboxable>
826 template <
typename TUnboxable>
947 template <
typename TElementType>
952 "Box::UnboxArray() invoked on box of non-array type <",
998 template <
typename TElementType>
1003 "Box::UnboxElement() invoked on box of non-array type <",
1013 ">(): Index out of bounds.")
1022 #if defined(ALIB_DOX)
1068 template <
typename TFDecl>
1073 template <
typename TFDecl>
1134 decltype( std::declval<typename TFDecl::Signature>()( std::declval<Box&>(), std::declval<TArgs>()... ) )
1138 if(
func !=
nullptr )
1139 return reinterpret_cast<typename TFDecl::Signature
>(
func)
1140 ( *
this, std::forward<TArgs>(
args)... );
1143 return decltype( std::declval<typename TFDecl::Signature>()( std::declval<Box&>(),
1144 std::declval<TArgs>()... )) ();
1160 decltype( std::declval<typename TFDecl::Signature>()( std::declval<Box&>(), std::declval<TArgs>()... ) )
1164 "Box not initialized (does not contain value). Function call not allowed." )
1166 ( *
this, std::forward<TArgs>(
args)... );
1188 decltype( std::declval<typename TFDecl::Signature>()( std::declval<Box&>(), std::declval<TArgs>()... ) )
1192 "Box not initialized (does not contain value). Function call not allowed." )
1194 if(
func !=
nullptr )
1195 return reinterpret_cast<typename TFDecl::Signature
>(
func)
1196 ( *
this, std::forward<TArgs>(
args)... );
1198 return decltype( std::declval<typename TFDecl::Signature>()( std::declval<Box&>(),
1199 std::declval<TArgs>()... )) ();
1216 decltype( std::declval<typename TFDecl::Signature>()( std::declval<Box&>(), std::declval<TArgs>()... ) )
1220 "Box not initialized (does not contain value). Function call not allowed." )
1222 ( *
this, std::forward<TArgs>(
args)... );
1243 return ! ((*this) == rhs);
1285 return !( (*this) < rhs);
1295 explicit operator bool()
const;
1341#if defined(ALIB_DOX)
1342namespace alib {
namespace boxing {
1346#if defined(ALIB_DOX)
decltype(std::declval< typename TFDecl::Signature >()(std::declval< Box & >(), std::declval< TArgs >()...)) CallDirect(typename TFDecl::Signature function, TArgs &&... args) const
uinteger UnboxUnsignedIntegral() const
Box(Box &&) noexcept=default
ALIB_API bool operator<(Box const &rhs) const
size_t ArrayElementSize() const
TElementType * UnboxArray() const
ALIB_API bool IsNotNull() const
constexpr Box(const TBoxable &src) noexcept
wchar UnboxCharacter() const
bool operator>=(Box const &rhs) const
integer UnboxLength() const
TElementType & UnboxElement(integer idx) const
bool IsFloatingPoint() const
bool IsSameType(const Box &other) const
TFDecl::Signature GetFunction(Reach searchScope, bool isInvocation=false) const
TUnboxable UnboxMutable() const
bool IsUnsignedIntegral() const
ALIB_API size_t Hashcode() const
bool IsSignedIntegral() const
unsigned int GetPlaceholderUsageLength() const
ALIB_API bool operator<=(Box const &rhs) const
Box(const Box &) noexcept=default
ALIB_API double UnboxFloatingPoint() const
bool operator!=(const Box &rhs) const
decltype(std::declval< typename TFDecl::Signature >()(std::declval< Box & >(), std::declval< TArgs >()...)) Call(TArgs &&... args) const
const detail::VTable * DbgGetVTable() const
const std::type_info & TypeID() const
const std::type_info & ElementTypeID() const
const Placeholder & Data() const
integer UnboxSignedIntegral() const
ALIB_API bool operator>(Box const &rhs) const
ALIB_API bool operator==(Box const &rhs) const
const TUnboxable Unbox() const
static detail::VTable * getVTable()
ALIB_API void Clone(monomem::MonoAllocator &memory)
ALIB_API const char * Get()
#define ATMP_IF_T_F( Cond, T, F)
#define ATMP_ISOF( T, TBase)
#define ALIB_WARNINGS_RESTORE
#define ALIB_FORCE_INLINE
#define ATMP_EQ( T, TEqual)
#define ALIB_ASSERT_ERROR(cond,...)
#define ALIB_WARNINGS_ALLOW_UNSAFE_BUFFER_USAGE
#define ATMP_SELECT_IF_1TP(TParam, ...)
#define ATMP_T_IF(T, Cond)
ALIB_API void DbgCheckRegistration(detail::VTable *vtable, bool increaseUsageCounter)
FunctionTable DEFAULT_FUNCTIONS
const alib::boxing::Box & Type
@ Global
Denotes global reach.
lang::uinteger uinteger
Type alias in namespace alib.
characters::wchar wchar
Type alias in namespace alib.
lang::integer integer
Type alias in namespace alib.
static void Write(Placeholder &target, const TBoxable &value)
TFDecl::Signature Get(bool isInvocation) const
const std::type_info & Type
const unsigned int PlaceholderUsage
const MappingType Mapping
const std::type_info & ElementType
constexpr TReturn * Pointer() const
constexpr integer Length() const
ALIB_WARNINGS_RESTORE constexpr void Clear()