53 #define ALIB_TEMPINTERNAL_STATIC_TYPE_CHECKS_BOXING(TBoxable, valueBoxing) \
54 using TVal = ALIB_TVALUE(TBoxable); \
56 constexpr bool isVolatile = std::is_volatile_v<std::remove_pointer_t<TBoxable>>; \
57 constexpr bool isPointer = std::is_pointer<TBoxable>::value; \
58 constexpr bool isValue = !isPointer; \
59 constexpr bool valIsString = IsStringType<TVal>; \
60 constexpr bool isCustomizedTV= IsCustomized<TVal>; \
61 constexpr bool isCustomizedTP= IsCustomized<TPtr>; \
62 constexpr bool isBlockedTV = std::same_as<NotBoxableTag, \
63 typename BoxTraits<TVal>::Mapping>; \
64 constexpr bool isBlockedTP = std::same_as<NotBoxableTag, \
65 typename BoxTraits<TPtr>::Mapping>; \
67 ALIB_STATIC_DENY( GeneralBoxingRule1, !valueBoxing && isVolatile, \
68 "Types boxed as pointers cannot be boxed if volatile." ); \
70 ALIB_STATIC_DENY( GeneralBoxingRule4, isPointer && valIsString, \
71 "String types must not be given as pointers." ); \
73 ALIB_STATIC_DENY( CustomBoxingRule3, isBlockedTV && isValue, \
74 "Customized boxing forbids boxing this value type: " \
75 "'BoxTraits<T>::Type == NotBoxable'!" ); \
77 ALIB_STATIC_DENY( CustomBoxingRule4, isBlockedTP && isPointer, \
78 "Customized boxing forbids boxing this pointer type: " \
79 "'BoxTraits<T*>::Type == NotBoxable'!" ); \
81 ALIB_STATIC_DENY( CustomBoxingRule5, isBlockedTV && !isCustomizedTP && isPointer, \
82 "Customized boxing forbids boxing value type T (BoxTraits<T>::Type == NotBoxable), while " \
83 "no customization for this pointer type T* was given." ); \
85 ALIB_STATIC_DENY( CustomBoxingRule6, isBlockedTP && !isCustomizedTV && isValue, \
86 "Customized boxing forbids boxing pointer type T* " \
87 "(BoxTraits<T*>::Type == NotBoxable), while no customization for this value type T was " \
91 #define ALIB_TEMPINTERNAL_STATIC_TYPE_CHECKS_UNBOXING(TUnboxable) \
92 using TVal = ALIB_TVALUE(TUnboxable); \
94 constexpr bool isConst = std::is_const_v <std::remove_pointer_t<TUnboxable>>; \
95 constexpr bool isVolatile = std::is_volatile_v<std::remove_pointer_t<TUnboxable>>; \
96 constexpr bool isPointer = std::is_pointer<TUnboxable>::value; \
97 constexpr bool isValue = !isPointer; \
98 constexpr bool valuesFit = sizeof(std::conditional_t<std::same_as<void,TVal>,void*,TVal>)\
99 <= sizeof(Placeholder); \
100 constexpr bool isCopyConstr = std::is_copy_constructible<TVal>::value; \
101 constexpr bool isTrivDest = std::is_trivially_destructible<TVal>::value; \
102 constexpr bool isCustomizedTV= IsCustomized<TVal>; \
103 constexpr bool isCustomizedTP= IsCustomized<TPtr>; \
104 constexpr bool isDefault = !(isCustomizedTV || isCustomizedTP); \
105 constexpr bool isBlockedTV = std::same_as<NotBoxableTag, \
106 typename BoxTraits<TVal>::Mapping>; \
107 constexpr bool isBlockedTP = std::same_as<NotBoxableTag, \
108 typename BoxTraits<TPtr>::Mapping>; \
109 constexpr bool isLockedTV = IsLocked<TVal>; \
110 constexpr bool isLockedTP = IsLocked<TPtr>; \
113 ALIB_STATIC_DENY( GeneralBoxingRule2, isConst, \
114 "Type qualifier 'const' not allowed with template type TUnboxable. Types boxed as values" \
115 " are always unboxed mutable, types boxed as pointers are always unboxed constant." ); \
117 ALIB_STATIC_DENY( GeneralBoxingRule3, isVolatile, \
118 "Type qualifier 'volatile' not allowed with template type TUnboxable" ); \
121 ALIB_STATIC_DENY( DefaultBoxingRule1, isDefault && isValue && !valuesFit, \
122 "This type cannot be unboxed by value: " \
123 "By default, values that do not fit into boxes are boxed as pointers." ); \
125 ALIB_STATIC_DENY( DefaultBoxingRule2, \
126 isDefault && isValue && (!isCopyConstr || !isTrivDest), \
127 "This type cannot be unboxed by value: " \
128 "By default, types that are not copy-constructible or not trivially destructible, " \
129 "are boxed as pointers." ); \
131 ALIB_STATIC_DENY( DefaultBoxingRule3, \
132 isDefault && isPointer && valuesFit && isCopyConstr && isTrivDest, \
133 "This type cannot be unboxed as pointer: Default boxing of types that fit " \
134 "into boxes and are copy-constructible and trivially destructible, " \
135 "is performed by value." ); \
139 ALIB_STATIC_DENY( CustomBoxingRule1, isCustomizedTV && !isCustomizedTP && isPointer, \
140 "This pointer type T* cannot be unboxed, because custom boxing is defined for " \
141 "value type T, while no custom boxing is defined for pointer type T*." ); \
143 ALIB_STATIC_DENY( CustomBoxingRule2, !isCustomizedTV && isCustomizedTP && isValue, \
144 "This value type T cannot be unboxed, because custom boxing is defined for " \
145 "pointer type T*, while no custom boxing is defined for value type T." ); \
149 ALIB_STATIC_DENY( CustomBoxingRule3, isBlockedTV && isValue, \
150 "Customized boxing forbids unboxing (and even boxing) this value type: " \
151 "'BoxTraits<T>::Type == NotBoxable'!" ); \
153 ALIB_STATIC_DENY( CustomBoxingRule4, isBlockedTP && isPointer, \
154 "Customized boxing forbids unboxing (and even boxing) this pointer type: " \
155 "'BoxTraits<T*>::Type == NotBoxable'!" ); \
157 ALIB_STATIC_DENY( CustomBoxingRule5, isBlockedTV && !isCustomizedTP && isPointer, \
158 "Customized boxing forbids unboxing (and even boxing) value type T " \
159 "(BoxTraits<T>::Type == NotBoxable), while no customization for this pointer type T* " \
162 ALIB_STATIC_DENY( CustomBoxingRule6, isBlockedTP && !isCustomizedTV && isValue, \
163 "Customized boxing forbids unboxing (and even boxing) pointer type T* " \
164 "(BoxTraits<T*>::Type == NotBoxable), while no customization for this value type T was" \
168 ALIB_STATIC_DENY( CustomBoxingRule7, isLockedTV && isValue, \
169 "Customized boxing forbids unboxing this value type: " \
170 "'BoxTraits<T>::Read' returns a different type." ); \
172 ALIB_STATIC_DENY( CustomBoxingRule8, isLockedTP && isPointer, \
173 "Customized boxing forbids unboxing this pointer type: " \
174 "'BoxTraits<T*>::Read' returns a different type." ); \
176 ALIB_STATIC_DENY( CustomBoxingRule9, isLockedTV && !isCustomizedTP && isPointer, \
177 "Customized boxing forbids unboxing value type T " \
178 "('BoxTraits<T>::Read' returns a different type), while no customization for this pointer " \
179 "type T* was given." ); \
181 ALIB_STATIC_DENY( CustomBoxingRule10, isLockedTP && !isCustomizedTV && isValue, \
182 "Customized boxing forbids unboxing pointer type T* " \
183 "('BoxTraits<T*>::Read' returns a different type), while no customization for this value " \
184 "type T was given." ); \
193 template<
typename TBoxable>
196 using TCV= std::remove_cv_t<TBoxable>;
198 if constexpr (std::same_as<typename BoxTraits<TCV>::Mapping,
DefaultBoxingTag>)
210 constexpr void initPH(
const T& src)
noexcept
233 ,
data (placeholder) {}
246 template <
typename TBoxable>
247 inline constexpr Box(
const TBoxable& src )
noexcept;
252 constexpr Box(
const std::nullptr_t& ) noexcept :
vtable(
nullptr) {}
256 requires std::is_array_v<T>
257 constexpr Box( T& src )
noexcept
259 using TElem= std::remove_cv_t<std::remove_pointer_t<std::decay_t<T>>>;
263 : std::extent<T>::value;
269 requires ( std::is_base_of<Box, std::remove_cv_t<T>>::value )
270 constexpr Box(
const T& src ) noexcept
272 ,
data ( src.data ) {}
278 requires ( IsStringType<std::remove_cv_t<T>> )
279 constexpr Box(
const T& src )
noexcept {
281 ALIB_TEMPINTERNAL_STATIC_TYPE_CHECKS_BOXING(T,
true)
282 if constexpr ( characters::ArrayTraits <T,
nchar>::Access == characters::Policy::Implicit )
285 data = Placeholder( characters::ArrayTraits<std::remove_cv_t<T>,
nchar>::Buffer( src ),
286 characters::ArrayTraits<std::remove_cv_t<T>,
nchar>::Length( src ) );
291 data = Placeholder( characters::ArrayTraits<std::remove_cv_t<T>,
wchar>::Buffer( src ),
292 characters::ArrayTraits<std::remove_cv_t<T>,
wchar>::Length( src ) );
297 data = Placeholder( characters::ArrayTraits<std::remove_cv_t<T>,
xchar>::Buffer( src ),
298 characters::ArrayTraits<std::remove_cv_t<T>,
xchar>::Length( src ) );
305 requires ( !std::is_pointer_v<T>
306 && !IsStringType<std::remove_cv_t<T>>
307 && ( IsCustomized<std::decay_t<T> >
308 || ( !IsCustomized<std::decay_t<T>*> && IsStdPH<T> ) )
310 constexpr Box(
const T& src )
noexcept {
311 ALIB_TEMPINTERNAL_STATIC_TYPE_CHECKS_BOXING(T,
true)
318 requires( !std::is_pointer_v<T>
319 && !IsStringType<std::remove_cv_t<T>>
320 && !std::is_array_v<T>
321 && !std::is_base_of_v<
Box, T>
322 && !IsCustomized<std::decay_t<T> >
323 && ( IsCustomized<std::remove_cv_t<T> >
324 || ( !IsCustomized<std::decay_t<T>*> && !IsStdPH<T> )
325 || ( IsCustomized<std::decay_t<T>*> )
328 constexpr
Box( const T& src ) noexcept {
329 ALIB_TEMPINTERNAL_STATIC_TYPE_CHECKS_BOXING(T,
true)
336 requires ( std::is_pointer_v<T>
339 ( IsCustomized<std::remove_cv_t<T>>
342 constexpr
Box( const T& src ) noexcept {
343 ALIB_TEMPINTERNAL_STATIC_TYPE_CHECKS_BOXING(T,
false)
350 requires ( std::is_pointer_v<T>
352 && !IsStringType<std::remove_cv_t<T>>
354 ( IsCustomized<std::remove_cv_t<T>>
358 constexpr
Box( const T& src ) noexcept {
359 ALIB_TEMPINTERNAL_STATIC_TYPE_CHECKS_BOXING(T,
false)
362 if ( src )
initPH( *src );
363 else
data = Placeholder( sizeof(TV) <= sizeof(
integer)
369 #undef ALIB_TEMPINTERNAL_STATIC_TYPE_CHECKS_BOXING
370 #undef ALIB_TM_IS_DEFAULT_BOXING
410 template<
typename TBoxable>
414 template<
typename TBoxable>
428 template<
typename TBoxable>
429 requires ( !std::same_as<TBoxable, void>
433 ALIB_TEMPINTERNAL_STATIC_TYPE_CHECKS_UNBOXING(TBoxable)
437 template<
typename TBoxable>
438 requires std::same_as<TBoxable, void>
442 #if !ALIB_FEAT_BOXING_BIJECTIVE_INTEGRALS || DOXYGEN
513 #if !ALIB_FEAT_BOXING_BIJECTIVE_CHARACTERS || DOXYGEN
586 template<
typename TElementType>
589 return vtable &&
typeid(TElementType) ==
vtable->ElementType;
633 template<
typename TValue>
637 ALIB_TEMPINTERNAL_STATIC_TYPE_CHECKS_UNBOXING(TValue)
641 "Cannot unbox string-type <{}> from mapped type <{}>.", &
typeid(TValue), &
vtable->Type )
670 template<
typename TValue>
671 requires ( !std::is_pointer_v<TValue>
675 ALIB_TEMPINTERNAL_STATIC_TYPE_CHECKS_UNBOXING(TValue)
679 "Cannot unbox type <{}> from mapped type <{}>.", &
typeid(TValue), &
vtable->Type )
701 template<
typename TPo
inter>
702 requires ( std::is_pointer_v<TPointer>
704 const std::remove_pointer_t<TPointer>*
Unbox()
const
706 ALIB_TEMPINTERNAL_STATIC_TYPE_CHECKS_UNBOXING(TPointer)
710 "Cannot unbox type <{}> from mapped type <{}>.", &
typeid(TPointer), &
vtable->Type )
715 #undef ALIB_TEMPINTERNAL_STATIC_TYPE_CHECKS_UNBOXING
724 template <
typename TPo
inter>
725 requires std::is_pointer_v<TPointer>
728 {
return const_cast<std::remove_const_t<TPointer>
>(
Unbox<TPointer>() ); }
770 return vtable->PlaceholderUsage;
796 data.Array.Pointer=
nullptr;
797 data.Array.Length = 0;
843 return vtable->ElementType;
866 template <
typename TElementType>
871 "Box::UnboxArray() invoked on box of non-array type <{}>.", &
vtable->Type )
874 "BOXING: Cannot unbox array type<{}[]> from mapped type<{}[]>.",
875 &
typeid(TElementType*), &
vtable->ElementType )
878 return data.GetPointer<TElementType>();
896 return data.GetLength();
910 template <
typename TElementType>
914 "Box is void (no contents). Unboxing is undefined behavior." )
916 "Box::UnboxElement() invoked on box of non-array type <{}>.", &
vtable->Type )
919 "BOXING: Cannot unbox array element type <{}> from mapped type <{}[]>.",
920 &
typeid(TElementType), &
vtable->ElementType )
923 "Box::UnboxElement<{}>(): Index out of bounds.", &
typeid(TElementType))
927 return *(
data.GetPointer<TElementType>() + idx );
974 template <
typename TFDecl>
977 ,
bool isInvocation =
false )
const;
979 template <
typename TFDecl>
981 ALIB_DBG( ,
bool isInvocation =
false) )
const
988 auto result=
vtable->Functions.Get<TFDecl>(
ALIB_DBG(isInvocation) );
1037 template <
typename TFDecl,
typename... TArgs>
1038 decltype( std::declval<typename TFDecl::Signature>()( std::declval<Box&>(), std::declval<TArgs>()... ) )
1042 if( func !=
nullptr )
1043 return reinterpret_cast<typename TFDecl::Signature
>(func)
1044 ( *
this, std::forward<TArgs>(args)... );
1047 return decltype( std::declval<typename TFDecl::Signature>()( std::declval<Box&>(),
1048 std::declval<TArgs>()... )) ();
1061 template <
typename TFDecl,
typename... TArgs>
1062 decltype( std::declval<typename TFDecl::Signature>()( std::declval<Box&>(), std::declval<TArgs>()... ) )
1063 CallDirect(typename TFDecl::Signature function, TArgs&&... args)
const
1066 "Box not initialized (does not contain value). Function call not allowed." )
1067 return reinterpret_cast<typename TFDecl::Signature
>(function)
1068 ( *
this, std::forward<TArgs>(args)... );
1087 template <
typename TFDecl,
typename... TArgs>
1088 decltype( std::declval<typename TFDecl::Signature>()( std::declval<Box&>(), std::declval<TArgs>()... ) )
1092 "Box not initialized (does not contain value). Function call not allowed." )
1094 if( func !=
nullptr )
1095 return reinterpret_cast<typename TFDecl::Signature
>(func)
1096 ( *
this, std::forward<TArgs>(args)... );
1098 return decltype( std::declval<typename TFDecl::Signature>()( std::declval<Box&>(),
1099 std::declval<TArgs>()... )) ();
1113 template <
typename TFDecl,
typename... TArgs>
1114 decltype( std::declval<typename TFDecl::Signature>()( std::declval<Box&>(), std::declval<TArgs>()... ) )
1115 CallDirect(typename TFDecl::Signature function, TArgs &&... args)
1118 "Box not initialized (does not contain value). Function call not allowed." )
1119 return reinterpret_cast<typename TFDecl::Signature
>( function )
1120 ( *
this, std::forward<TArgs>(args)... );
1137 return ! ((*this) == rhs);
1171 return !( (*this) < rhs);
1179 explicit operator bool()
const;
1252template<
typename TFDecl,
typename TMapped,
bool TIsArray= false>
1258 ->Functions.template Get<TFDecl>(
false),
1259 "BOXING",
"Doubly defined function" )
1262 ->
Functions.template Set<TFDecl>( function );
1290template<
typename TFDecl>
ALIB_DLL bool operator>(Box const &rhs) const
TElementType & UnboxElement(integer idx) const
uinteger UnboxUnsignedIntegral() const
const detail::VTable * DbgGetVTable() const
uinteger TypeCode
The type of type codes received with ExportType.
bool IsUnsignedIntegral() const
const std::remove_pointer_t< TPointer > * Unbox() const
ALIB_DLL double UnboxFloatingPoint() const
ALIB_DLL bool IsNotNull() const
Placeholder data
The data that we encapsulate.
const std::type_info & ElementTypeID() const
Box(TypeCode typeCode, const Placeholder &placeholder) noexcept
integer UnboxSignedIntegral() const
bool operator!=(const Box &rhs) const
bool IsFloatingPoint() const
unsigned int GetPlaceholderUsageLength() const
TypeCode ExportType() const
void Import(TypeCode typeCode)
constexpr void initPH(const T &src) noexcept
decltype(std::declval< typename TFDecl::Signature >()(std::declval< Box & >(), std::declval< TArgs >()...)) CallDirect(typename TFDecl::Signature function, TArgs &&... args) const
bool IsSameType(const Box &other) const
ALIB_DLL void Clone(MonoAllocator &memory)
bool operator>=(Box const &rhs) const
Placeholder ExportValue() const
void Import(TypeCode typeCode, const Placeholder &placeholder)
decltype(std::declval< typename TFDecl::Signature >()(std::declval< Box & >(), std::declval< TArgs >()...)) Call(TArgs &&... args) const
constexpr Box(const TBoxable &src) noexcept
TPointer UnboxMutable() const
size_t ArrayElementSize() const
const std::type_info & TypeID() const
const Placeholder & Data() const
ALIB_DLL bool operator<(Box const &rhs) const
TElementType * UnboxArray() const
static constexpr detail::VTable * getVTable()
integer UnboxLength() const
ALIB_DLL bool operator==(Box const &rhs) const
bool IsSignedIntegral() const
ALIB_DLL bool operator<=(Box const &rhs) const
wchar UnboxCharacter() const
TFDecl::Signature GetFunction(Reach searchScope, bool isInvocation=false) const
ALIB_DLL size_t Hashcode() const
#define ALIB_ASSERT_ERROR(cond, domain,...)
ALIB_DLL void DbgCheckRegistration(detail::VTable *vtable, bool increaseUsageCounter)
FunctionTable DEFAULT_FUNCTIONS
The default box-functions set.
void BootstrapRegisterDefault(typename TFDecl::Signature function)
void BootstrapRegister(typename TFDecl::Signature function)
Reach
Denotes the reach of something.
@ Global
Denotes global reach.
characters::wchar wchar
Type alias in namespace alib.
lang::integer integer
Type alias in namespace alib.
monomem::TMonoAllocator< lang::HeapAllocator > MonoAllocator
characters::nchar nchar
Type alias in namespace alib.
boxing::Box Box
Type alias in namespace alib.
characters::xchar xchar
Type alias in namespace alib.
lang::uinteger uinteger
Type alias in namespace alib.
static std::conditional_t<!std::is_abstract< TBoxable >::value, TBoxable, TBoxable & > Read(const Placeholder &box)
static constexpr bool IsArray
Denotes whether type TBoxable is boxed as an array-type or not.
static constexpr detail::VTable * Get()
The custom function hash.
FunctionTable Functions
Box-functions attached with BootstrapRegister.
static constexpr Policy Access
static TStringSource Construct(const TChar *array, integer length)
static constexpr Policy Construction