ALib C++ Library
Library Version: 2511 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
boxes.cpp
1//##################################################################################################
2// ALib C++ Library
3//
4// Copyright 2013-2025 A-Worx GmbH, Germany
5// Published under 'Boost Software License' (a free software license, see LICENSE.txt)
6//##################################################################################################
7#include "alib_precompile.hpp"
8#if !defined(ALIB_C20_MODULES) || ((ALIB_C20_MODULES != 0) && (ALIB_C20_MODULES != 1))
9# error "Symbol ALIB_C20_MODULES has to be given to the compiler as either 0 or 1"
10#endif
11#if ALIB_C20_MODULES
12 module;
13#endif
14//========================================= Global Fragment ========================================
16#include <cstring>
17
18//============================================== Module ============================================
19#if ALIB_C20_MODULES
20 module ALib.Boxing;
21 import ALib.Lang;
22#if ALIB_MONOMEM
23# include "ALib.Monomem.H"
24#endif
25#else
26# include "ALib.Lang.H"
27#if ALIB_MONOMEM
28# include "ALib.Monomem.H"
29#endif
30# include "ALib.Boxing.H"
31#endif
32//========================================== Implementation ========================================
33
34//##################################################################################################
35// static assertions for the platform
36//##################################################################################################
37static_assert( sizeof(alib::integer ) == sizeof(alib::uinteger ), "Error in ALib type definitions" );
38static_assert( sizeof(alib::integer ) == sizeof(std::size_t ), "Error in ALib type definitions" );
39static_assert(std::is_signed< alib::integer>::value == std::is_signed<std::ptrdiff_t >::value, "Error in ALib type definitions" );
40static_assert(std::is_signed< alib::integer>::value != std::is_signed<std::size_t >::value, "Error in ALib type definitions" );
41static_assert(std::is_signed<alib::uinteger>::value == std::is_signed<std::size_t >::value, "Error in ALib type definitions" );
42static_assert(std::is_signed<alib::uinteger>::value != std::is_signed<std::ptrdiff_t >::value, "Error in ALib type definitions" );
43
44
45
46namespace alib { namespace boxing {
47
48#if ALIB_DEBUG && !DOXYGEN
49namespace detail {
50 // This is used by boxing::Bootstrap to do runtime-check for compatibility of boxing
51 // and long double values.
52 // It was put here to prevent the compiler to optimize and remove the code.
53 extern long double LONGDOUBLE_WRITE_TEST_MEM[2];
54extern void dbgLongDoubleTrueLengthSet();
55extern bool dbgLongDoubleTrueLengthTest();
56}
57#endif
58
59#if !DOXYGEN
60
61namespace {
62integer flattenCount(const Box* boxArray, integer length) {
63 integer ctdFlattened= 0;
64 for( integer i= 0; i < length ; ++i ) {
65 const Box& box= boxArray[i];
66
67 if( box.IsType<boxing::TBoxes<lang::HeapAllocator>*>() ) {
68 const auto* boxes= box.Unbox<boxing::TBoxes<lang::HeapAllocator>*>();
69 ctdFlattened+= flattenCount( boxes->data(), integer(boxes->size()) );
70 continue;
71 }
72 #if ALIB_MONOMEM
73 if( box.IsType<boxing::TBoxes<MonoAllocator>*>() ) {
74 const auto* boxes= box.Unbox<boxing::TBoxes<MonoAllocator>*>();
75 ctdFlattened+= flattenCount( boxes->data(), integer(boxes->size()) );
76 continue;
77 }
78 if( box.IsType<boxing::TBoxes<PoolAllocator>*>() ) {
79 const auto* boxes= box.Unbox<boxing::TBoxes<PoolAllocator>*>();
80 ctdFlattened+= flattenCount( boxes->data(), integer(boxes->size()) );
81 continue;
82 }
83 #endif
84
85 if( box.IsArrayOf<Box>() ) {
86 ctdFlattened+= flattenCount( box.UnboxArray<Box>(), box.UnboxLength() );
87 continue;
88 }
89
90 ++ctdFlattened;
91 }
92
93 return ctdFlattened;
94}
95
96template<typename TAllocator>
97void flattenInsert(typename TBoxes<TAllocator>::iterator& it, const Box* boxArray, integer length) {
98 for( integer i= 0; i < length ; ++i ) {
99 const Box& box= boxArray[i];
100
101 if( box.IsType<boxing::TBoxes<lang::HeapAllocator>*>() ) {
102 const auto* boxes= box.Unbox<boxing::TBoxes<lang::HeapAllocator>*>();
103 flattenInsert<TAllocator>( it, boxes->data(), integer(boxes->size()) );
104 continue;
105 }
106 #if ALIB_MONOMEM
107 if( box.IsType<boxing::TBoxes<MonoAllocator>*>() ) {
108 const auto* boxes= box.Unbox<boxing::TBoxes<MonoAllocator>*>();
109 flattenInsert<TAllocator>( it, boxes->data(), integer(boxes->size()) );
110 continue;
111 }
112 if( box.IsType<boxing::TBoxes<PoolAllocator>*>() ) {
113 const auto* boxes= box.Unbox<boxing::TBoxes<PoolAllocator>*>();
114 flattenInsert<TAllocator>( it, boxes->data(), integer(boxes->size()) );
115 continue;
116 }
117 #endif
118
119 if( box.IsArrayOf<Box>() ) {
120 flattenInsert<TAllocator>( it, box.UnboxArray<Box>(), box.UnboxLength() );
121 continue;
122 }
123
124 new( &*it ) Box( box );
125 ++it;
126} }
127
128} // anonymous namespace
129
130
131template<typename TAllocator>
132void TBoxes<TAllocator>::AddArray( const Box* boxArray, integer length ) {
133 // 1. Count the number of boxes if "recursively flattened"
134 integer ctdFlattened= flattenCount( boxArray, length );
135
136 // 2. create space in vector
137 auto it= vectorBase::insert(vectorBase::end(), size_t(ctdFlattened), Box() );
138
139 // 3. insert recursively all boxes found (flatten)
140 flattenInsert<TAllocator>( it, boxArray, length);
141
142 ALIB_ASSERT( it == vectorBase::end(), "BOXING" )
143}
144
145template ALIB_DLL void TBoxes< lang::HeapAllocator>::AddArray( const Box* boxArray, integer length );
146#if ALIB_MONOMEM
147template ALIB_DLL void TBoxes<MonoAllocator>::AddArray( const Box* boxArray, integer length );
148#endif
149
150
151#endif // #if DOXYGEN
152
153}} // namespace [alib::boxing]
integer UnboxLength() const
Definition box.inl:842
void AddArray(const Box *boxArray, integer length)
#define ALIB_DLL
Definition alib.inl:503
#define ALIB_ASSERT(cond, domain)
Definition alib.inl:1065
This namespace implements internals of namespace alib::boxing.
Definition vtable.cpp:43
lang::integer integer
Type alias in namespace alib.
Definition integers.inl:149
boxing::Box Box
Type alias in namespace alib.
Definition box.inl:1149
lang::uinteger uinteger
Type alias in namespace alib.
Definition integers.inl:152