ALib C++ Library
Library Version: 2402 R1
Documentation generated by doxygen
Loading...
Searching...
No Matches
boxes.inl
Go to the documentation of this file.
1/** ************************************************************************************************
2 * \file
3 * This header file is part of module \alib_boxing of the \aliblong.
4 *
5 * \emoji :copyright: 2013-2024 A-Worx GmbH, Germany.
6 * Published under \ref mainpage_license "Boost Software License".
7 **************************************************************************************************/
8#ifndef HPP_ALIB_BOXING_BOXES
9#define HPP_ALIB_BOXING_BOXES 1
10
11#if !defined(HPP_ALIB_BOXING_BOXING)
12# error "ALib sources with ending '.inl' must not be included from outside."
13#endif
14
15
16#if !defined (_GLIBCXX_VECTOR) && !defined(_VECTOR_)
17# include <vector>
18#endif
19
20#if ALIB_MONOMEM
21namespace alib { namespace monomem { class MonoAllocator; }}
22
23namespace alib { namespace boxing { namespace detail {
24
25//
26/**
27 * This detail namespace function just calls \alib{monomem;MonoAllocator::Alloc} with the given
28 * parameters. The use of this function avoids the need to include headers of module
29 * \alib_monomem, by headers of module \alib_boxing_nl.
30 * @param allocator The allocator to use.
31 * @param size The requested size.
32 * @param alignment The requested alignment
33 * @return The allocated piece of memory.
34 */
35ALIB_API char* monoAlloc( monomem::MonoAllocator& allocator, size_t size, size_t alignment);
36
37
38/** ************************************************************************************************
39 * Implementation of <c>std::allocator</c> used with class \alib{boxing;Boxes}.
40 * This allocator takes an optional pointer to type \alib{monomem;MonoAllocator}.
41 * If this pointer is \e nulled, then standard allocation is used.
42 *
43 * \note The internals of this type implementing the interface required by <c>std::allocator</c>
44 * are not documented.
45 *
46 * @tparam T The type of objects to be allocated.
47 **************************************************************************************************/
48template<typename T>
50{
51#if !defined(ALIB_DOX)
52 using size_type = size_t ;
53 using difference_type= ptrdiff_t ;
54 using value_type = T ;
55 using is_always_equal= std::false_type;
56
57 // deprecated types
58 #if ALIB_CPP_STANDARD == 17
59 size_t max_size() const noexcept { return static_cast<size_t>(-1) / 2; }
60 #endif
61
62 monomem::MonoAllocator* allocator;
63 constexpr BoxesAllocator() : allocator(nullptr) {}
64 constexpr BoxesAllocator( const BoxesAllocator& ) noexcept =default;
65 constexpr BoxesAllocator( BoxesAllocator&& ) noexcept =default;
66 template<typename U> BoxesAllocator( U& origin ) : allocator(origin.allocator) {}
67 constexpr BoxesAllocator( monomem::MonoAllocator* pAllocator)
68 : allocator(pAllocator) {}
69
70 template<typename T2>
71 bool operator==( const alib::boxing::detail::BoxesAllocator<T2>& rhs ) noexcept
72 { return allocator == rhs.allocator; }
73
74 template<typename T2>
75 bool operator!=( const alib::boxing::detail::BoxesAllocator<T2>& rhs ) noexcept
76 { return (allocator != rhs.allocator); }
77
78 [[nodiscard]]
79 T* allocate( size_t n, const void* = nullptr )
80 {
81 if( allocator == nullptr )
82 return reinterpret_cast<T*>( std::malloc( sizeof(T) * n ) );
83
84 return reinterpret_cast<T*>( detail::monoAlloc( *allocator,
85 sizeof(T[1]) * n, alignof(T[]) ) );
86 }
87
88 void deallocate( T* p , std::size_t )
89 {
90 if( allocator == nullptr )
91 std::free( p );
92 }
93
94#endif
95}; // struct BoxesAllocator
96
97}}} // namespace [alib::boxing::detail]
98
99
100#endif
101
102namespace alib { namespace boxing {
103/** ************************************************************************************************
104 * A vector of objects of type \alib{boxing;Box}.
105 * Specializes class \c std::vector<Box> (publicly) with a constructor and methods to add a
106 * variable amount of arbitrary values with one invocation.
107 *
108 * If another \b %Boxes object or an array of boxes, or boxed versions of such, are added, this
109 * container is "flattened", so that instead of the container, the boxes are added. Such flatting
110 * is performed recursively.
111 *
112 * \see
113 * Chapter \ref alib_boxing_boxes "11. Variadic Function Arguments and Class Boxes"
114 * of the Programmer's Manual of module \alib_boxing.
115 **************************************************************************************************/
116class Boxes
117 #if ALIB_MONOMEM
118 : public std::vector<Box, detail::BoxesAllocator<Box>>
119 #else
120 : public std::vector<Box>
121 #endif
122{
123 public:
124 /** ****************************************************************************************
125 * Defaulted default constructor.
126 ******************************************************************************************/
127 Boxes() = default;
128
129 /** ****************************************************************************************
130 * Deleted copy constructor.
131 ******************************************************************************************/
132 Boxes( Boxes& ) = delete;
133
134 /** ****************************************************************************************
135 * Deleted copy assignment operator.
136 * @return Nothing (deleted).
137 ******************************************************************************************/
138 Boxes& operator=( Boxes& ) = delete;
139
140 #if ALIB_MONOMEM
141 /** ************************************************************************************
142 * Constructor accepting a monotonic allocator.<br>
143 * Note: This constructor is available only if module \alib_monomem is included in the
144 * \alibdist.
145 *
146 * @param monoAllocator The allocator to use with the underlying <c>std::vector</c>.
147 **************************************************************************************/
149 : vector<Box, detail::BoxesAllocator<Box>>( detail::BoxesAllocator<Box>(monoAllocator) )
150 {}
151 #endif
152
153 /** ****************************************************************************************
154 * Empty method. Needed to allow adding empty variadic template parameter packs.
155 * @return A reference to this object.
156 ******************************************************************************************/
158 {
159 return *this;
160 }
161
162 /** ****************************************************************************************
163 * Adds one box for each given variadic argument.
164 *
165 * @tparam TBoxables The types of the variadic arguments.
166 * @param args The variadic arguments. Each argument is converted into one box to be
167 * appended.
168 * @return A reference to this object.
169 ******************************************************************************************/
170 template <typename... TBoxables>
171 Boxes& Add( TBoxables&&... args )
172 {
173 Box boxes[sizeof...(args)]= { std::forward<TBoxables>( args )... };
174 AddArray( boxes, sizeof...(args) );
175
176 return *this;
177 }
178
179 /** ****************************************************************************************
180 * Adds one boxt.
181 *
182 * @param box The box to append.
183 * @return A reference to this object.
184 ******************************************************************************************/
185 Boxes& Add(const Box& box )
186 {
187 AddArray( &box, 1 );
188
189 return *this;
190 }
191
192 /** ****************************************************************************************
193 * Adds an array of boxes.
194 *
195 * @tparam TExtend The size of the given array of boxes.
196 * @param boxArray The array of boxes.
197 * @return A reference to this object.
198 ******************************************************************************************/
199 template<size_t TExtend>
200 Boxes& Add( const Box(& boxArray)[TExtend] )
201 {
202 AddArray( boxArray, TExtend );
203 return *this;
204 }
205
206 /** ****************************************************************************************
207 * Adds all elements of the given other \b %Boxes object.
208 *
209 * @param boxes Another container of boxes to add.
210 * @return A reference to this object.
211 ******************************************************************************************/
212 Boxes& Add( const Boxes& boxes )
213 {
214 AddArray( boxes.data(), static_cast<integer>(boxes.size()) );
215 return *this;
216 }
217
218 /** ****************************************************************************************
219 * Adds an array of boxes. Array elements of types \b %Boxes itself and boxed arrays of
220 * class \b %Box are recursively "flattened".
221 *
222 * This method is internally used by all overloads of #Add.
223 *
224 * @param boxArray Pointer to the start of the array of boxes.
225 * @param length The number of boxes contained in \p{boxArray}.
226 ******************************************************************************************/
227 ALIB_API void AddArray( const Box* boxArray, integer length );
228
229
230 /** ****************************************************************************************
231 * Inline operator that simply aliases method #Add.
232 *
233 * @param src The value to be boxed and added.
234 * @return Returns a mutable reference to \c this.
235 *****************************************************************************************/
236 template <typename TBoxable>
237 Boxes& operator+=( TBoxable&& src )
238 {
239 return Add( src );
240 }
241
242 /** ****************************************************************************************
243 * Inline operator that simply aliases method #Add.
244 *
245 * @param src The value to be boxed and added.
246 * @return Returns a mutable reference to \c this.
247 *****************************************************************************************/
248 template <typename TBoxable>
249 Boxes& operator<<( TBoxable&& src )
250 {
251 return Add( src );
252 }
253
254 /** ****************************************************************************************
255 * Returns the quantity of elements stored in ths container.
256 * @return The element count.
257 *****************************************************************************************/
258 integer Size() const
259 {
260 return static_cast<integer>( size() );
261 }
262
263 /** ****************************************************************************************
264 * Invokes the corresponding parent's method \c std::vector::reserve.
265 *
266 * @param newCapacity The new, higher capacity of the vector.
267 ******************************************************************************************/
268 void Reserve(integer newCapacity)
269 {
270 reserve( static_cast<size_t>( newCapacity ) );
271 }
272
273 /** ****************************************************************************************
274 * Invokes \alib{boxing;Box::Call} with each box in this list.
275 * The result of the invocations of the box-functions is ignored.
276 *
277 * @tparam TFDecl The function type to call.
278 * Needs to be specified with invocations of this method.
279 * @tparam TArgs Types of the variadic arguments \p{args}.
280 * Do not need to be specified.
281 * @param args Variadic arguments forwarded to the functions.
282 ******************************************************************************************/
283 template <typename TFDecl, typename... TArgs>
284 void CallAll(TArgs&&... args) const
285 {
286 for( auto& box : *this )
287 box.Call<TFDecl>( std::forward<TArgs>(args)... );
288 }
289
290 /** ****************************************************************************************
291 * Non-constant version of method #CallAll, which likewise chooses the non-constant version
292 * of \alib{boxing;Box::Call} and hence this method is usable with functions that only
293 * accept mutable (aka not constant) boxes.<br>
294 * Technically, the only difference between this method and \b CallAll is that the latter
295 * is declared \c const.
296 *
297 * @tparam TFDecl The function type to call.
298 * Needs to be specified with invocations of this method.
299 * @tparam TArgs Types of the variadic arguments \p{args} .
300 * @param args Variadic arguments forwarded to the functions.
301 ******************************************************************************************/
302 template <typename TFDecl, typename... TArgs>
303 void CallAll(TArgs&&... args)
304 {
305 for( auto& box : *this )
306 box.Call<TFDecl>( std::forward<TArgs>(args)... );
307 }
308
309 #if ALIB_MONOMEM
310 /** ****************************************************************************************
311 * Same as \ref CallAll "CallAll<FClone>", but uses method \alib{boxing;Box::Clone},
312 * which internally invokes \alib{boxing;FClone}.
313 *
314 * Using this version leads to shorter code, because method \b Box::Clone is not inlined.
315 *
316 * \par Availability
317 * This method is available only if module \alib_monomem is included in the \alibdist.
318 *
319 * @param memory A monotonic allocator used for storing cloned data.
320 ******************************************************************************************/
322 void CloneAll(monomem::MonoAllocator& memory);
323 #endif
324
325}; // class Boxes
326
327
328
329
330}} // namespace [alib::boxing]
331
332#endif // HPP_ALIB_BOXING_BOXES
void CallAll(TArgs &&... args)
Definition boxes.inl:303
Boxes & Add(const Boxes &boxes)
Definition boxes.inl:212
Boxes(Boxes &)=delete
integer Size() const
Definition boxes.inl:258
Boxes & Add(const Box(&boxArray)[TExtend])
Definition boxes.inl:200
void Reserve(integer newCapacity)
Definition boxes.inl:268
Boxes & Add(const Box &box)
Definition boxes.inl:185
void CallAll(TArgs &&... args) const
Definition boxes.inl:284
Boxes & Add(TBoxables &&... args)
Definition boxes.inl:171
Boxes & operator<<(TBoxable &&src)
Definition boxes.inl:249
ALIB_API void CloneAll(monomem::MonoAllocator &memory)
Definition boxing.cpp:216
ALIB_API void AddArray(const Box *boxArray, integer length)
Boxes(monomem::MonoAllocator *monoAllocator)
Definition boxes.inl:148
Boxes & operator+=(TBoxable &&src)
Definition boxes.inl:237
Boxes & operator=(Boxes &)=delete
#define ALIB_API
Definition alib.hpp:538
#define ALIB_MONOMEM
Definition alib.hpp:177
ALIB_API char * monoAlloc(monomem::MonoAllocator &allocator, size_t size, size_t alignment)
Definition boxes.cpp:46
Definition alib.cpp:57
boxing::Box Box
Type alias in namespace alib.
lang::integer integer
Type alias in namespace alib.
Definition integers.hpp:286