ALib C++ Library
Library Version: 2402 R1
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 !defined(ALIB_DOX)
10# if !defined(HPP_ALIB_BOXING_BOXING)
11# include "alib/boxing/boxing.hpp"
12# endif
13# if ALIB_MONOMEM && !defined(HPP_ALIB_MONOMEM_MONOALLOCATOR)
15# endif
16#endif // !defined(ALIB_DOX)
17
19
20namespace alib { namespace boxing {
21
22#if ALIB_DEBUG && !defined(ALIB_DOX)
23 // This is used by boxing::Bootstrap to do runtime-check for compatibility of boxing
24 // and long double values.
25 // It was put here to prevent the compiler to optimize and remove the code.
26 extern long double dbgLongDoubleWriteTestMem[2];
27 long double dbgLongDoubleWriteTestMem[2];
28 extern void dbgLongDoubleTrueLengthSet();
29 void dbgLongDoubleTrueLengthSet()
30 {
31 memset( dbgLongDoubleWriteTestMem, 0x3E, 2 * ALIB_SIZEOF_LONGDOUBLE_REPORTED);
32 }
33 extern bool dbgLongDoubleTrueLengthTest();
34 bool dbgLongDoubleTrueLengthTest()
35 {
36 const char* mem= reinterpret_cast<const char*>( dbgLongDoubleWriteTestMem );
37 return mem[ALIB_SIZEOF_LONGDOUBLE_WRITTEN - 1] != 0x3E
38 && mem[ALIB_SIZEOF_LONGDOUBLE_WRITTEN ] == 0x3E;
39 }
40#endif
41
42
43#if ALIB_MONOMEM
45[[nodiscard]]
46char* detail::monoAlloc( monomem::MonoAllocator& allocator, size_t size, size_t alignment)
47{
48 return allocator.Alloc( size, alignment );
49}
50#endif
51
52#if !defined(ALIB_DOX)
53
54namespace {
55integer flattenCount(const Box* boxArray, integer length)
56{
57 integer qtyFlattened= 0;
58 for( integer i= 0; i < length ; ++i )
59 {
60 const Box& box= boxArray[i];
61
62 if( box.IsType<Boxes*>() )
63 {
64 const Boxes* boxes= box.Unbox<Boxes*>();
65 qtyFlattened+= flattenCount( boxes->data(), static_cast<integer>(boxes->size()) );
66 continue;
67 }
68
69 if( box.IsArrayOf<Box>() )
70 {
71 qtyFlattened+= flattenCount( box.UnboxArray<Box>(), box.UnboxLength() );
72 continue;
73 }
74
75 ++qtyFlattened;
76 }
77
78 return qtyFlattened;
79}
80
81void flattenInsert(Boxes::iterator& it, const Box* boxArray, integer length)
82{
83 for( integer i= 0; i < length ; ++i )
84 {
85 const Box& box= boxArray[i];
86
87 if( box.IsType<Boxes*>() )
88 {
89 const Boxes* boxes = box.Unbox<Boxes*>();
90 flattenInsert( it, boxes->data(), static_cast<integer>(boxes->size()) );
91 continue;
92 }
93
94 if( box.IsArrayOf<Box>() )
95 {
96 flattenInsert( it, box.UnboxArray<Box>(), box.UnboxLength() );
97 continue;
98 }
99
100 new( &*it ) Box( box );
101 ++it;
102 }
103}
104
105} // anonymous namespace
106
107
108
109void Boxes::AddArray( const Box* boxArray, integer length )
110{
111 // 1. Count the number of boxes if "recursively flattened"
112 // (We copy the anonymous method flattenCount() from above, to avoid JSR, which is unlikely
113 // anyhow)
114 integer qtyFlattened= 0;
115 for( integer i= 0; i < length ; ++i )
116 {
117 const Box& box= boxArray[i];
118
119 if( box.IsType<Boxes*>() )
120 {
121 const Boxes* boxes= box.Unbox<Boxes*>();
122 qtyFlattened+= flattenCount( boxes->data(), static_cast<integer>(boxes->size()) );
123 continue;
124 }
125
126 if( box.IsArrayOf<Box>() )
127 {
128 qtyFlattened+= flattenCount( box.UnboxArray<Box>(), box.UnboxLength() );
129 continue;
130 }
131
132 ++qtyFlattened;
133 }
134
135 // 2. create space in vector
136 auto it= insert(end(), static_cast<size_t>(qtyFlattened), Box() );
137
138 // 3. insert recursively all boxes found (flatten)
139 // (We copy the anonymous method flattenInsert() from above, to avoid JSR, which is unlikely
140 // anyhow)
141 for( integer i= 0; i < length ; ++i )
142 {
143 const Box& box= boxArray[i];
144
145 if( box.IsType<Boxes*>() )
146 {
147 const Boxes* boxes = box.Unbox<Boxes*>();
148 flattenInsert( it, boxes->data(), static_cast<integer>(boxes->size()) );
149 continue;
150 }
151
152 if( box.IsArrayOf<Box>() )
153 {
154 flattenInsert( it, box.UnboxArray<Box>(), box.UnboxLength() );
155 continue;
156 }
157
158 new( &*it ) Box( box );
159 ++it;
160 }
161
162 ALIB_ASSERT( it == end() )
163}
164
165
166#endif // #if defined(ALIB_DOX)
167
168}} // namespace [alib::boxing]
TElementType * UnboxArray() const
Definition box.inl:948
integer UnboxLength() const
Definition box.inl:979
bool IsType() const
bool IsArrayOf() const
Definition box.inl:724
const TUnboxable Unbox() const
ALIB_API void AddArray(const Box *boxArray, integer length)
ALIB_FORCE_INLINE char * Alloc(size_t size, size_t alignment)
#define ALIB_WARNINGS_RESTORE
Definition alib.hpp:715
#define ALIB_API
Definition alib.hpp:538
#define ALIB_WARNINGS_ALLOW_UNSAFE_BUFFER_USAGE
Definition alib.hpp:644
#define ALIB_ASSERT(cond)
Definition alib.hpp:983
#define ALIB_SIZEOF_LONGDOUBLE_REPORTED
Definition prepro.dox:29
#define ALIB_SIZEOF_LONGDOUBLE_WRITTEN
Definition prepro.dox:30
ALIB_API char * monoAlloc(monomem::MonoAllocator &allocator, size_t size, size_t alignment)
Definition boxes.cpp:46
Definition alib.cpp:57
boxing::Boxes Boxes
Type alias in namespace alib.
boxing::Box Box
Type alias in namespace alib.
lang::integer integer
Type alias in namespace alib.
Definition integers.hpp:286