ALib C++ Library
Library Version: 2510 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];
54 extern void dbgLongDoubleTrueLengthSet();
55 extern bool dbgLongDoubleTrueLengthTest();
56}
57#endif
58
59#if !DOXYGEN
60
61namespace {
62integer flattenCount(const Box* boxArray, integer length)
63{
64 integer ctdFlattened= 0;
65 for( integer i= 0; i < length ; ++i )
66 {
67 const Box& box= boxArray[i];
68
69 if( box.IsType<boxing::TBoxes<lang::HeapAllocator>*>() )
70 {
71 const auto* boxes= box.Unbox<boxing::TBoxes<lang::HeapAllocator>*>();
72 ctdFlattened+= flattenCount( boxes->data(), integer(boxes->size()) );
73 continue;
74 }
75 #if ALIB_MONOMEM
76 if( box.IsType<boxing::TBoxes<MonoAllocator>*>() )
77 {
78 const auto* boxes= box.Unbox<boxing::TBoxes<MonoAllocator>*>();
79 ctdFlattened+= flattenCount( boxes->data(), integer(boxes->size()) );
80 continue;
81 }
82 if( box.IsType<boxing::TBoxes<PoolAllocator>*>() )
83 {
84 const auto* boxes= box.Unbox<boxing::TBoxes<PoolAllocator>*>();
85 ctdFlattened+= flattenCount( boxes->data(), integer(boxes->size()) );
86 continue;
87 }
88 #endif
89
90 if( box.IsArrayOf<Box>() )
91 {
92 ctdFlattened+= flattenCount( box.UnboxArray<Box>(), box.UnboxLength() );
93 continue;
94 }
95
96 ++ctdFlattened;
97 }
98
99 return ctdFlattened;
100}
101
102template<typename TAllocator>
103void flattenInsert(typename TBoxes<TAllocator>::iterator& it, const Box* boxArray, integer length)
104{
105 for( integer i= 0; i < length ; ++i )
106 {
107 const Box& box= boxArray[i];
108
109 if( box.IsType<boxing::TBoxes<lang::HeapAllocator>*>() )
110 {
111 const auto* boxes= box.Unbox<boxing::TBoxes<lang::HeapAllocator>*>();
112 flattenInsert<TAllocator>( it, boxes->data(), integer(boxes->size()) );
113 continue;
114 }
115 #if ALIB_MONOMEM
116 if( box.IsType<boxing::TBoxes<MonoAllocator>*>() )
117 {
118 const auto* boxes= box.Unbox<boxing::TBoxes<MonoAllocator>*>();
119 flattenInsert<TAllocator>( it, boxes->data(), integer(boxes->size()) );
120 continue;
121 }
122 if( box.IsType<boxing::TBoxes<PoolAllocator>*>() )
123 {
124 const auto* boxes= box.Unbox<boxing::TBoxes<PoolAllocator>*>();
125 flattenInsert<TAllocator>( it, boxes->data(), integer(boxes->size()) );
126 continue;
127 }
128 #endif
129
130 if( box.IsArrayOf<Box>() )
131 {
132 flattenInsert<TAllocator>( it, box.UnboxArray<Box>(), box.UnboxLength() );
133 continue;
134 }
135
136 new( &*it ) Box( box );
137 ++it;
138 }
139}
140
141} // anonymous namespace
142
143
144template<typename TAllocator>
145void TBoxes<TAllocator>::AddArray( const Box* boxArray, integer length )
146{
147 // 1. Count the number of boxes if "recursively flattened"
148 integer ctdFlattened= flattenCount( boxArray, length );
149
150 // 2. create space in vector
151 auto it= vectorBase::insert(vectorBase::end(), size_t(ctdFlattened), Box() );
152
153 // 3. insert recursively all boxes found (flatten)
154 flattenInsert<TAllocator>( it, boxArray, length);
155
156 ALIB_ASSERT( it == vectorBase::end(), "BOXING" )
157}
158
159template ALIB_DLL void TBoxes< lang::HeapAllocator>::AddArray( const Box* boxArray, integer length );
160#if ALIB_MONOMEM
161template ALIB_DLL void TBoxes<MonoAllocator>::AddArray( const Box* boxArray, integer length );
162#endif
163
164
165#endif // #if DOXYGEN
166
167}} // namespace [alib::boxing]
integer UnboxLength() const
Definition box.inl:893
void AddArray(const Box *boxArray, integer length)
#define ALIB_DLL
Definition alib.inl:496
#define ALIB_ASSERT(cond, domain)
Definition alib.inl:1048
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:1216
lang::uinteger uinteger
Type alias in namespace alib.
Definition integers.inl:152