ALib C++ Library
Library Version: 2412 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
boxes.cpp
1// #################################################################################################
2// ALib C++ Library
3//
4// Copyright 2013-2024 A-Worx GmbH, Germany
5// Published under 'Boost Software License' (a free software license, see LICENSE.txt)
6// #################################################################################################
8
9#if !DOXYGEN
10# include "alib/boxing/boxing.hpp"
11# if ALIB_MONOMEM
13# endif
14#endif // !DOXYGEN
15
17
18namespace alib { namespace boxing {
19
20#if ALIB_DEBUG && !DOXYGEN
21 // This is used by boxing::Bootstrap to do runtime-check for compatibility of boxing
22 // and long double values.
23 // It was put here to prevent the compiler to optimize and remove the code.
24 extern long double dbgLongDoubleWriteTestMem[2];
25 long double dbgLongDoubleWriteTestMem[2];
26 extern void dbgLongDoubleTrueLengthSet();
27 void dbgLongDoubleTrueLengthSet()
28 {
29 memset( dbgLongDoubleWriteTestMem, 0x3E, 2 * ALIB_SIZEOF_LONGDOUBLE_REPORTED);
30 }
31 extern bool dbgLongDoubleTrueLengthTest();
32 bool dbgLongDoubleTrueLengthTest()
33 {
34 const char* mem= reinterpret_cast<const char*>( dbgLongDoubleWriteTestMem );
35 return mem[ALIB_SIZEOF_LONGDOUBLE_WRITTEN - 1] != 0x3E
36 && mem[ALIB_SIZEOF_LONGDOUBLE_WRITTEN ] == 0x3E;
37 }
38#endif
39
40
41#if !DOXYGEN
42
43namespace {
44integer flattenCount(const Box* boxArray, integer length)
45{
46 integer ctdFlattened= 0;
47 for( integer i= 0; i < length ; ++i )
48 {
49 const Box& box= boxArray[i];
50
51 if( box.IsType<boxing::TBoxes<lang::HeapAllocator>*>() )
52 {
53 const auto* boxes= box.Unbox<boxing::TBoxes<lang::HeapAllocator>*>();
54 ctdFlattened+= flattenCount( boxes->data(), static_cast<integer>(boxes->size()) );
55 continue;
56 }
57 #if ALIB_MONOMEM
58 if( box.IsType<boxing::TBoxes<MonoAllocator>*>() )
59 {
60 const auto* boxes= box.Unbox<boxing::TBoxes<MonoAllocator>*>();
61 ctdFlattened+= flattenCount( boxes->data(), static_cast<integer>(boxes->size()) );
62 continue;
63 }
64 if( box.IsType<boxing::TBoxes<PoolAllocator>*>() )
65 {
66 const auto* boxes= box.Unbox<boxing::TBoxes<PoolAllocator>*>();
67 ctdFlattened+= flattenCount( boxes->data(), static_cast<integer>(boxes->size()) );
68 continue;
69 }
70 #endif
71
72 if( box.IsArrayOf<Box>() )
73 {
74 ctdFlattened+= flattenCount( box.UnboxArray<Box>(), box.UnboxLength() );
75 continue;
76 }
77
78 ++ctdFlattened;
79 }
80
81 return ctdFlattened;
82}
83
84template<typename TAllocator>
85void flattenInsert(typename TBoxes<TAllocator>::iterator& it, const Box* boxArray, integer length)
86{
87 for( integer i= 0; i < length ; ++i )
88 {
89 const Box& box= boxArray[i];
90
91 if( box.IsType<boxing::TBoxes<lang::HeapAllocator>*>() )
92 {
93 const auto* boxes= box.Unbox<boxing::TBoxes<lang::HeapAllocator>*>();
94 flattenInsert<TAllocator>( it, boxes->data(), static_cast<integer>(boxes->size()) );
95 continue;
96 }
97 #if ALIB_MONOMEM
98 if( box.IsType<boxing::TBoxes<MonoAllocator>*>() )
99 {
100 const auto* boxes= box.Unbox<boxing::TBoxes<MonoAllocator>*>();
101 flattenInsert<TAllocator>( it, boxes->data(), static_cast<integer>(boxes->size()) );
102 continue;
103 }
104 if( box.IsType<boxing::TBoxes<PoolAllocator>*>() )
105 {
106 const auto* boxes= box.Unbox<boxing::TBoxes<PoolAllocator>*>();
107 flattenInsert<TAllocator>( it, boxes->data(), static_cast<integer>(boxes->size()) );
108 continue;
109 }
110 #endif
111
112 if( box.IsArrayOf<Box>() )
113 {
114 flattenInsert<TAllocator>( it, box.UnboxArray<Box>(), box.UnboxLength() );
115 continue;
116 }
117
118 new( &*it ) Box( box );
119 ++it;
120 }
121}
122
123} // anonymous namespace
124
125
126template<typename TAllocator>
127void TBoxes<TAllocator>::AddArray( const Box* boxArray, integer length )
128{
129 // 1. Count the number of boxes if "recursively flattened"
130 integer ctdFlattened= flattenCount( boxArray, length );
131
132 // 2. create space in vector
133 auto it= vectorBase::insert(vectorBase::end(), size_t(ctdFlattened), Box() );
134
135 // 3. insert recursively all boxes found (flatten)
136 flattenInsert<TAllocator>( it, boxArray, length);
137
138 ALIB_ASSERT( it == vectorBase::end() )
139}
140
141template ALIB_API void TBoxes< lang::HeapAllocator>::AddArray( const Box* boxArray, integer length );
142#if ALIB_MONOMEM
143template ALIB_API void TBoxes<MonoAllocator>::AddArray( const Box* boxArray, integer length );
144#endif
145
146
147#endif // #if DOXYGEN
148
149}} // namespace [alib::boxing]
integer UnboxLength() const
Definition box.inl:1018
void AddArray(const Box *boxArray, integer length)
#define ALIB_WARNINGS_RESTORE
Definition alib.hpp:849
#define ALIB_API
Definition alib.hpp:639
#define ALIB_WARNINGS_ALLOW_UNSAFE_BUFFER_USAGE
Definition alib.hpp:760
#define ALIB_ASSERT(cond)
Definition alib.hpp:1270
#define ALIB_SIZEOF_LONGDOUBLE_REPORTED
Definition prepro.md:29
#define ALIB_SIZEOF_LONGDOUBLE_WRITTEN
Definition prepro.md:30
Definition alib.cpp:69
boxing::Box Box
Type alias in namespace alib.
lang::integer integer
Type alias in namespace alib.
Definition integers.hpp:273