ALib C++ Framework
by
Library Version: 2605 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
recycling.hpp
Go to the documentation of this file.
1//==================================================================================================
2/// \file
3/// This header-file is part of module \alib_containers of the \aliblong.
4///
5/// Copyright 2013-2026 A-Worx GmbH, Germany.
6/// Published under #"mainpage_license".
7//==================================================================================================
8ALIB_EXPORT namespace alib { namespace containers {
9
10//==================================================================================================
11/// This enumeration contains three elements, which denote the type of node-recycling that a
12/// container instantiation is deemed to perform. One of these elements is to be set as the value
13/// for a corresponding template parameter named \p{TRecycling} found in container types
14/// of this module.
15///
16/// In the case #"%Shared" is given, the container type will expose a type definition named
17/// \b "SharedRecyclerType", which can be used to define the external shared recycler object.
18/// This object has then to be passed to the constructor of the container instance.
19///
20/// \see
21/// Chapter #"alib_contmono_intro_recycling" of the Programmer's Manual
22/// for this \alibmod.
23//==================================================================================================
24enum class Recycling {
25 None , ///<< Denotes that no recycling should be performed.
26 Private, ///<< Denotes private recycling. This is usaully the default value.
27 Shared , ///<< Denotes shared recycling.
28};
29
30
31} // namespace alib[::containers]
32
33/// Type alias in namespace #"%alib".
35
36} // namespace [alib]
37
40
41/// Stores an element for recycling.
42/// @param recyclables The recycling stack.
43/// @param elem The element to recycle.
44template<typename TNode>
45void recycleImpl( lang::SidiListHook<TNode>& recyclables, TNode* elem )
46{
47 lang::Destruct(*elem);
48 recyclables.pushFront( elem );
49}
50
51
52/// Stores a list of elements for recycling (from the \p{begin} element to the last one).
53/// @param recyclables The recycling stack.
54/// @param begin The first element of the list store, must not be \c nullptr.
55template<typename TNode>
56void recycleListImpl( lang::SidiListHook<TNode>& recyclables, TNode* begin ) {
57 TNode* actual = begin;
58 for (;;) {
59 TNode* next= actual->next();
60 lang::Destruct(*actual);
61 if (next == nullptr)
62 break;
63 actual= next;
64 }
65
66 recyclables.pushFront( begin, actual );
67}
68
69/// Stores a list of elements for recycling. Both given nodes have to exist.
70/// @param recyclables The recycling stack.
71/// @param begin The first element of the list store.
72/// @param end The first element not to be recycled.
73/// @return A pair of values. The first is a pointer to the last node recycled, and the second
74/// provides the number of nodes recycled.
75template<typename TNode>
76std::pair<TNode*,integer> recycleListImpl( lang::SidiListHook<TNode>& recyclables,
77 TNode* begin, TNode* end ) {
78 std::pair<TNode*,integer> result;
79 result.second= 1;
80 result.first = begin;
81 for (;;) {
82 TNode* next= result.first->next();
83 lang::Destruct(*result.first);
84 if (next == end)
85 break;
86 ++result.second;
87 result.first= next;
88 }
89
90 recyclables.pushFront( begin, result.first );
91 return result;
92}
93
94/// Reserves the given \p{qty} of recyclables. If the allocator used returns \c true with
95/// method #"Allocator::allowsMemSplit" (like like #"%MonoAllocator" does), then one
96/// chunk is allocated and cut into pieces.<br>
97/// Otherwise, common allocations are performed
98/// @param allocator The allocator to use.
99/// @param recyclables The recycling stack.
100/// @param qty The quantity of elements to reserve.
101template<typename TAllocator, typename TNode>
102void reserveImpl( TAllocator& allocator, lang::SidiListHook<TNode>& recyclables, integer qty ) {
103 if (qty <= 0)
104 return;
105
106 if constexpr ( TAllocator::allowsMemSplit() ) {
107 TNode* newElements= allocator().template AllocArray<TNode>(qty);
108 for( integer i= qty - 2; i >= 0 ; --i )
109 newElements[i].next( &newElements[i + 1] );
110
111 recyclables.pushFront( &newElements[0], &newElements[qty-1] );
112 } else {
113 TNode* start= allocator().template Alloc<TNode>();
114 TNode* end = start;
115 for( integer i= 1; i < qty ; ++i ) {
116 end->next( allocator().template Alloc<TNode>() );
117 end= end->next();
118 }
119 recyclables.pushFront( start, end );
120} }
121
122/// Frees an element (no recycling).
123/// @param allocator The allocator to use.
124/// @param elem The element to recycle.
125template<typename TAllocator, typename TNode>
126void disposeImpl( TAllocator& allocator, TNode* elem )
127{
128 lang::Destruct(*elem);
129 allocator().Free(elem);
130}
131
132
133/// Deletes the given list.
134/// This shared recycler does not free the node, but recycles them.
135/// @param allocator The allocator to use.
136/// @param begin The first element of the list to free.
137template<typename TAllocator, typename TNode>
138void disposeListImpl( TAllocator& allocator, TNode* begin ) {
139 TNode* actual = begin;
140 for (;;) {
141 TNode* next= actual->next();
142 lang::Destruct(*actual);
143 allocator().Free(actual);
144 if (next == nullptr)
145 return;
146 actual= next;
147} }
148
149/// Deletes a list of elements for recycling. Both given nodes have to exist.
150/// @param allocator The allocator to use.
151/// @param begin The first element of the list to free.
152/// @param end The first element not to be freed.
153/// @return A pair of values. The first is a pointer to the last node deleted, and the second
154/// provides the number of nodes deleted.
155template<typename TAllocator, typename TNode>
156std::pair<TNode*,integer> disposeListImpl( TAllocator& allocator, TNode* begin, TNode* end ) {
157 std::pair<TNode*,integer> result;
158 result.second= 1;
159 result.first= begin;
160 for (;;) {
161 TNode* next= result.first->next();
162 lang::Destruct(*result.first);
163 allocator().Free(result.first);
164 if (next == end)
165 return result;
166 ++result.second;
167 result.first= next;
168} }
169
170/// Recycles a chunk of memory that is \e not of the node type.
171/// Such recycling is useful for example, in combination with hash tables, which usually
172/// allocate a "bucket array" that grows over time. In this case, the former smaller bucket
173/// array may be passed to this method to recycle it as future node elements.
174/// @tparam TChunk The type of the external chunk.
175/// @param recyclables The recycling stack.
176/// @param chunk The recyclable chunk's address.
177/// @param count The number of objects. (For non-array types, \c 1 is to be given.)
178template<typename TNode, typename TChunk>
179void recycleChunkImpl( lang::SidiListHook<TNode>& recyclables, TChunk* chunk, size_t count ) {
180 void* mem = chunk;
181 size_t size= sizeof(TChunk[1]) * count;
182
183 // align beginning of buffer (if necessary)
184 if constexpr( alignof(TNode) > alignof(TChunk[1]) ) {
185 auto alignedAddr= (reinterpret_cast<size_t>(chunk) + alignof(TNode) - 1)
186 & ~(static_cast<size_t>(alignof(TNode)) - 1U);
187 mem = reinterpret_cast<void*>(alignedAddr);
188 size-= size_t(static_cast<char*>(mem) - reinterpret_cast<char*>(chunk));
189 }
190
191 // create recyclables
192 ALIB_DBG( size_t cntRecycledObjects= 0; )
193 while(size > sizeof(TNode)) {
194 recyclables.pushFront( static_cast<TNode*>( mem ) );
195 mem = static_cast<char*>(mem) + sizeof(TNode);
196 size -= sizeof (TNode);
197 ALIB_DBG( ++cntRecycledObjects; )
198 }
199
200 #if ALIB_DEBUG
201 if( cntRecycledObjects <= 0 ) {
202 ALIB_WARNING( "MONOMEM/RECYCLER",
203 "De-allocated chunk size is smaller than node size.\n"
204 " Chunk object: Type: <{}>\n"
205 " Size, Count, Alignment: {} * {} = {} bytes, alignment: {}\n"
206 " Recyclable Type: <{}>\n"
207 " Size, Alignment: {} bytes, alignment: {}\n"
208 "Note: If this recycler is used with a <containers::HashTable>, this message may be\n"
209 " eliminated by reserving a reasonable initial bucket size.",
210 &typeid(TChunk), sizeof(TChunk[1]), count, sizeof(TChunk[1]) * count,
211 alignof(TChunk[1]), &typeid(TNode), sizeof(TNode), alignof(TNode) )
212 }
213 #endif
214}
215
216#include "ALib.Lang.CIMethods.H"
217
218/// Implements internal recycling interface. Used by container types of module \alib_containers_nl that
219/// use private recycling (when their template parameter \p{TRecycling} evaluates to
220/// #"Recycling::Private").
221///
222/// @tparam TAllocator The allocator to store and use.
223/// @tparam TNode The type to recycle. Has to be derived of #"SidiNodeBase".
224template<typename TAllocator, typename TNode>
226 protected:
227 /// The base type.
229
230 /// The list of recyclables.
232
233 public:
234 /// Parameterless constructor. Used with type #"%HeapAllocator".
235 RecyclerPrivate() noexcept =default;
236
237 /// Constructor taking an allocator.
238 /// @param pAllocator The allocator to use.
239 explicit
240 RecyclerPrivate( TAllocator& pAllocator ) noexcept
241 : base( pAllocator ) {}
242
243 /// Copy constructor. Does not copy the recycle node, but clears this one.
244 /// @param copy The object to copy.
245 RecyclerPrivate( const RecyclerPrivate& copy ) noexcept
246 : base( copy ) {}
247
248 /// Move constructor. Grabs the recyclables from the moved one and sets moved to nulled.
249 /// @param move The private recycler to move.
251 : base( move )
252 , recyclables(move) { move.recyclables.reset(); }
253
254 /// Destructor. Frees all recyclables with the allocator.
255 ~RecyclerPrivate() noexcept {
256 TNode* actual = recyclables.first();
257 while (actual) {
258 TNode* next= actual->next();
259 base::AIF().Free(actual);
260 actual= next;
261 } }
262
263 /// Resets this recycler. Frees all recyclables with the allocator.
264 void Reset() noexcept {
265 if(recyclables.first()) {
267 recyclables.reset();
268 } }
269
270 /// @return Returns the allocator received with construction.
271 TAllocator& GetAllocator() const noexcept { return base::GetAllocator(); }
272
273 /// @return The allocator interface of the allocator received with construction.
275
276 /// @return Returns \c true to indicate that this is not a non-recycling version.
277 static constexpr bool IsRecycling() noexcept { return true; }
278
279 /// Counts the number of recyclables.<br>
280 /// Attention: This method runs in linear time.
281 /// @return The number of available elements.
282 [[nodiscard]]
283 integer Count() const noexcept { return recyclables.count(); }
284
285
286 /// Reserves the given number of recyclables.
287 /// @param qty The number of new recyclables to allocate.
288 void Reserve( integer qty ) noexcept { reserveImpl( base::GetAllocator(), recyclables, qty); }
289
290 /// Returns a recycled object or allocates a new one.
291 /// @return A recycled or allocated element.
292 [[nodiscard]]
293 TNode* Get() {
294 return !recyclables.isEmpty() ? recyclables.popFront()
295 : base::AIF().template Alloc<TNode>();
296 }
297
298 /// Stores an element for recycling.
299 /// @param elem The element to store.
300 void Recycle( TNode* elem ) noexcept { recycleImpl( recyclables, elem ); }
301
302 /// Stores a list of elements for recycling (from the \p{begin} element to the last one).
303 /// @param begin The first element of the list store, must not be \c nullptr.
304 void RecycleList( TNode* begin ) noexcept { recycleListImpl( recyclables, begin ); }
305
306 /// Stores a list of elements for recycling. Both given nodes have to exist.
307 /// @param begin The first element of the list to recycle.
308 /// @param end The first element not to be recycled.
309 /// @return A pair of values. The first is a pointer to the last node recycled, and the second
310 /// provides the number of nodes recycled.
311 std::pair<TNode*, integer> RecycleList(TNode* begin, TNode* end) noexcept
312 { return recycleListImpl( recyclables, begin, end ); }
313
314 /// Deletes the given list.
315 /// This shared recycler does not free the node, but recycles them.
316 /// @param begin The first element of the list to free.
317 void DisposeList( TNode* begin ) noexcept { disposeListImpl( base::GetAllocator(), begin ); }
318
319 /// Deletes a list of elements for recycling. Both given nodes have to exist.
320 /// @param begin The first element of the list to free.
321 /// @param end The first element not to be freed.
322 void DisposeList( TNode* begin, TNode* end ) noexcept
323 { disposeListImpl( base::GetAllocator(), begin, end ); }
324
325
326 /// Converts a given chunk of memory, previously allocated with the same allocator that
327 /// this type uses, into recyclable node objects.<br>
328 /// This is only done if #"Allocator::allowsMemSplit;*" returns \c true.
329 /// @tparam TChunk The type of array that is to be cut into node elements.
330 /// @param chunk The chunk array to convert into nodes
331 /// @param length The length of the chunk array (pass \c 1 if the chunk is not an array type).
332 template<typename TChunk>
333 void RecycleChunk(TChunk* chunk, size_t length ) noexcept {
334 if constexpr ( TAllocator::allowsMemSplit() )
335 recycleChunkImpl( recyclables, chunk, length );
336 else
337 #if !defined(__MINGW32__)
338 base::AIF().FreeArray(chunk, length );
339 #else
340 base::AIF().template FreeArray(chunk, length );
341 #endif
342 }
343
344 /// Frees the given memory. Note that the shared recycler calls #"RecycleChunk" with this method.
345 /// @tparam TChunk The type of array that is to be freed.
346 /// @param chunk The chunk array to convert into nodes
347 /// @param length The length of the chunk array (pass \c 1 if the chunk is not an array type).
348 template<typename TChunk>
349 void DisposeChunk(TChunk* chunk, size_t length ) noexcept {
350 #if !defined(__MINGW32__)
351 base::AIF().FreeArray(chunk, length );
352 #else
353 base::AIF().template FreeArray(chunk, length );
354 #endif
355 }
356};
357
358/// This is the type exposed to users of the \alib containers in case shared recycling is
359/// chosen, for example, with #"List::SharedRecyclerType;*" or
360/// #"HashTable::SharedRecyclerType;*".<br>
361/// A user has to pass an instance of this type to the constructor of the container.
362/// Constructors that accept this type do not accept an allocator instance, as this is embedded
363/// already here.
364/// @tparam TAllocator The allocator to store and use.
365/// @tparam TNode The node type to recycle.
366template<typename TAllocator, typename TNode>
367class SharedRecycler : public lang::AllocatorMember<TAllocator>
368 , protected lang::SidiListHook<TNode>
369{
370 protected:
371 template<typename TAllocator1, typename TNode1>
372 friend class RecyclerShared;
373
374 /// Shortcut to a base class.
376
377 /// Shortcut to a base class.
379
380
381 public:
382 /// Constructor taking no allocator, used with #"%HeapAllocator".
383 SharedRecycler () noexcept
384 : lang::AllocatorMember<TAllocator>() {}
385
386 /// Constructor taking an allocator.
387 /// @param pAllocator The allocator to use.
388 SharedRecycler ( TAllocator& pAllocator ) noexcept
389 : allocBase( pAllocator ) {}
390
391 /// Destructor. Deletes all recyclables with the allocator.
392 ~SharedRecycler() noexcept { Reset(); }
393
394 /// Reset. Deletes all recyclables with the allocator.
395 void Reset() noexcept {
396 TNode* actual = this->first();
397 while (actual) {
398 TNode* next= actual->next();
399 allocBase::AIF().Free(actual);
400 actual= next;
401 }
402 this->reset();
403 }
404
405 /// Counts the number of recyclables.
406 /// @return The number of recycled container elements available.
407 integer Count() const noexcept { return this->count(); }
408
409 /// Reserves space for at least the given number of recyclables.
410 /// @param qty The expected number or increase of elements to be stored in the containers
411 /// that share this recycler.
412 /// @param reference Denotes whether \p{expected} is meant as an absolute size or an increase .
413 void Reserve( integer qty, lang::ValueReference reference ) {
414 auto requiredRecyclables= ( qty - (reference == lang::ValueReference::Absolute ? Count()
415 : 0 ) );
416
417 if( requiredRecyclables > 0 )
418 reserveImpl( allocBase::GetAllocator(), *this, requiredRecyclables );
419 }
420};
421
422/// Implements internal recycling interface. Used by container types of module \alib_containers_nl that
423/// use shared recycling (when their template parameter \p{TRecycling} evaluates to
424/// #"Recycling::Shared").
425///
426/// @tparam TAllocator The allocator to store and use.
427/// @tparam TNode The type to recycle. Has to be derived of #"SidiNodeBase".
428template<typename TAllocator, typename TNode>
430 protected:
431 /// The reference to the list of recyclables.
433
434 public:
435
436 /// Constructor taking an allocator and the hook.
437 /// @param hook The external, shared recycling list.
439 : sr(hook) {}
440
441
442 /// Copy constructor. Copies the reference to the shared recycler.
443 /// @param copy The private recycler to copy.
444 RecyclerShared( const RecyclerShared& copy ) noexcept =default;
445
446 /// Move constructor. Just copies the reference but leaves original intact. (We don't care)
447 /// @param move The private recycler to move.
449 : sr(move.sr) {}
450
451 /// Destructor.
452 ~RecyclerShared() noexcept {}
453
454 /// Does nothing. Shared recyclers can't be reset.
455 void Reset() noexcept {}
456
457 /// @return Returns the allocator received with construction.
458 TAllocator& GetAllocator() const noexcept { return sr.GetAllocator(); }
459
460 /// @return The allocator interface of the allocator received with construction.
461 lang::AllocatorInterface<TAllocator> AIF() const noexcept { return sr.GetAllocator()(); }
462
463
464 /// @return Returns \c true to indicate that this is not a non-recycling version.
465 static constexpr bool IsRecycling() noexcept { return true; }
466
467 /// Counts the number of recyclables.<br>
468 /// Attention: This method runs in linear time.
469 /// @return The number of available elements.
470 [[nodiscard]]
471 integer Count() const noexcept { return sr.count(); }
472
473 /// Reserves the given number of recyclables.
474 /// @param qty The number of new recyclables to allocate.
475 void Reserve( integer qty ) { reserveImpl( sr.GetAllocator(), sr, qty); }
476
477 /// Returns a recycled object or allocates a new one.
478 /// @return A recycled or allocated element.
479 [[nodiscard]]
480 TNode* Get() { return !sr.isEmpty() ? sr.popFront() : sr.AIF().template Alloc<TNode>(); }
481
482 /// Stores an element for recycling.
483 /// @param elem The element to store.
484 void Recycle( TNode* elem ) noexcept { recycleImpl( sr, elem ); }
485
486 /// Stores a list of elements for recycling (from the \p{begin} element to the last one).
487 /// @param begin The first element of the list store, must not be \c nullptr.
488 void RecycleList( TNode* begin ) noexcept { recycleListImpl( sr, begin ); }
489
490 /// Stores a list of elements for recycling. Both given nodes have to exist.
491 /// @param begin The first element of the list to recycle.
492 /// @param end The first element not to be recycled.
493 /// @return A pair of values. The first is a pointer to the last node recycled, and the second
494 /// provides the number of nodes recycled.
495 std::pair<TNode*, integer> RecycleList(TNode* begin, TNode* end) noexcept
496 { return recycleListImpl( sr, begin, end ); }
497
498 /// Does not free, but recycles instead.
499 /// @param begin The first element of the list to free.
500 void DisposeList( TNode* begin ) noexcept { recycleListImpl( sr, begin ); }
501
502 /// Does not free, but recycles instead.
503 /// @param begin The first element of the list to free.
504 /// @param end The first element not to be freed.
505 void DisposeList( TNode* begin, TNode* end ) noexcept { recycleListImpl( sr, begin, end ); }
506
507 /// Converts a given chunk of memory, previously allocated with the same allocator that
508 /// this type uses, into recyclable node objects.<br>
509 /// This is only done if #"Allocator::allowsMemSplit;*" returns \c true.
510 /// @tparam TChunk The type of array that is to be cut into node elements.
511 /// @param chunk The chunk array to convert into nodes
512 /// @param length The length of the chunk array (pass \c 1 if the chunk is not an array type).
513 template<typename TChunk>
514 void RecycleChunk(TChunk* chunk, size_t length ) noexcept {
515 if constexpr ( TAllocator::allowsMemSplit() )
516 recycleChunkImpl( sr, chunk, length );
517 else
518 sr.AIF().FreeArray(chunk, length );
519 }
520
521 /// This shared recycler calls #"RecycleChunk" with this method.
522 /// @tparam TChunk The type of array that is to be freed.
523 /// @param chunk The chunk array to convert into nodes
524 /// @param length The length of the chunk array (pass \c 1 if the chunk is not an array type).
525 template<typename TChunk>
526 void DisposeChunk(TChunk* chunk, size_t length ) noexcept { RecycleChunk( chunk, length ); }
527};
528
529
530/// Implements internal recycling interface. Used by container types of module \alib_containers_nl
531/// that omit recycling (when their template parameter \p{TRecycling} evaluates to
532/// #"Recycling::None").
533///
534/// @tparam TAllocator The allocator to store and use.
535/// @tparam TNode The type to recycle. Has to be derived of #"SidiNodeBase".
536template<typename TAllocator, typename TNode>
538 protected:
539 /// The base type.
541
542 public:
543 /// Parameterless constructor. Used with type #"%HeapAllocator".
545
546 /// Defaulted default constructor.
547 /// @param pAllocator The allocator to use.
548 RecyclerVoid( TAllocator& pAllocator ) noexcept
549 : base( pAllocator ) {}
550
551 /// Does nothing. Shared recyclers can't be reset.
552 void Reset() noexcept {}
553
554 /// @return Returns \c false to indicate that this is a non-recycling version.
555 static constexpr bool IsRecycling() noexcept { return false; }
556
557 /// This recycler just returns \c 0.
558 /// Attention: With other implementations, this method may run in linear time.
559 /// @return \c 0, which in this case is always the number of available elements.
560 [[nodiscard]]
561 constexpr integer Count() const noexcept { return 0; }
562
563 /// Does nothing. In debug-compilations a #"alib_mod_assert;warning is raised".
564 void Reserve( integer ) noexcept
565 { ALIB_WARNING("MONOMEM","Requested reservation of recyclables with non-recycling container.") }
566
567 /// Allocates a new one.
568 /// @return An allocated element.
569 [[nodiscard]]
570 TNode* Get() { return base::AIF().template Alloc<TNode>(); }
571
572 /// Frees an element.
573 /// @param elem The element to store.
574 void Recycle( TNode* elem ) noexcept { disposeImpl( base::GetAllocator(), elem ); }
575
576 /// Frees the list.
577 /// @param begin The first element of the list store, must not be \c nullptr.
578 void RecycleList( TNode* begin ) noexcept { disposeListImpl( base::GetAllocator(), begin ); }
579
580 /// Frees the list (as this is a non-recycling recycler).
581 /// @param begin The first element of the list recycled.
582 /// @param end The first element not to be recycled.
583 /// @return A pair of values. The first is a pointer to the last node deleted, and the second
584 /// provides the number of nodes deleted.
585 std::pair<TNode*, integer> RecycleList( TNode* begin, TNode* end ) noexcept
586 { return disposeListImpl( base::GetAllocator(), begin, end ); }
587
588
589 /// Deletes a list of elements (from the \p{begin} element to the last one).
590 /// @param begin The first element of the list recycle, must not be \c nullptr.
591 void DisposeList( TNode* begin ) noexcept { disposeListImpl( base::GetAllocator(), begin ); }
592
593 /// Deletes a list of elements for recycling. Both given nodes have to exist.
594 /// @param begin The first element of the list to free.
595 /// @param end The first element not to be freed.
596 /// @return A pair of values. The first is a pointer to the last node deleted, and the second
597 /// provides the number of nodes deleted.
598 std::pair<TNode*, integer> DisposeList( TNode* begin, TNode* end ) noexcept
599 { return disposeListImpl( base::GetAllocator(), begin, end ); }
600
601 /// With other recyclers, this method
602 /// converts a given chunk of memory, previously allocated with the same allocator that
603 /// this type uses, into recyclable node objects.<br>
604 /// This recycler just frees the object.
605 /// @tparam TChunk The type of array that is to be cut into node elements.
606 /// @param chunk The chunk array to convert into nodes
607 /// @param length The length of the chunk array (pass \c 1 if the chunk is not an array type).
608 template<typename TChunk>
609 constexpr void RecycleChunk( TChunk* chunk, size_t length ) noexcept {
610 #if !defined(__MINGW32__)
611 base::AIF().FreeArray(chunk, length );
612 #else
613 base::AIF().template FreeArray(chunk, length );
614 #endif
615 }
616
617 /// Frees the given memory. Note that the shared recycler calls #"RecycleChunk" with this method.
618 /// @tparam TChunk The type of array that is to be freed.
619 /// @param chunk The chunk array to convert into nodes
620 /// @param length The length of the chunk array (pass \c 1 if the chunk is not an array type).
621 template<typename TChunk>
622 void DisposeChunk(TChunk* chunk, size_t length ) noexcept {
623 #if !defined(__MINGW32__)
624 base::AIF().FreeArray(chunk, length );
625 #else
626 base::AIF().template FreeArray(chunk, length );
627 #endif
628 }
629
630}; // struct RecyclerVoid
631
632/// Helper-struct that chooses the right recycler type depending on template parameter
633/// \p{TRecycling}. Specializations exists for each element in enumeration
634/// #"Recycling".
635/// @tparam TRecycling The sort of recycling, as given with template parameter of container types
636/// with the same name.
637template<Recycling TRecycling>
639 #if DOXYGEN
640 /// The type chosen.
641 using Type= void;
642
643 /// The hook type. Only used with shared recycling, otherwise <c>void</c>.
644 using HookType= void;
645 #endif
646};
647#if !DOXYGEN
648template<>
650{
651 template<typename TAllocator, typename TNode> using Type= RecyclerPrivate<TAllocator, TNode>;
652 template<typename TAllocator, typename TNode> using HookType= void;
653};
654
655template<> struct RecyclingSelector<Recycling::Shared> {
656 template<typename TAllocator, typename TNode> using Type = RecyclerShared<TAllocator, TNode>;
657 template<typename TAllocator, typename TNode> using HookType= SharedRecycler<TAllocator, TNode>;
658};
659
660template<> struct RecyclingSelector<Recycling::None> {
661 template<typename TAllocator, typename TNode> using Type= RecyclerVoid<TAllocator, TNode>;
662 template<typename TAllocator, typename TNode> using HookType= void;
663};
664#endif
665
666#include "ALib.Lang.CIMethods.H"
667} // namespace [alib::containers::detail]
#define ALIB_WARNING(domain,...)
#define ALIB_EXPORT
#define ALIB_DBG(...)
static constexpr bool IsRecycling() noexcept
std::pair< TNode *, integer > RecycleList(TNode *begin, TNode *end) noexcept
void DisposeList(TNode *begin) noexcept
void RecycleList(TNode *begin) noexcept
RecyclerShared(SharedRecycler< TAllocator, TNode > &hook) noexcept
void DisposeChunk(TChunk *chunk, size_t length) noexcept
void DisposeList(TNode *begin, TNode *end) noexcept
SharedRecycler< TAllocator, TNode > & sr
The reference to the list of recyclables.
void RecycleChunk(TChunk *chunk, size_t length) noexcept
RecyclerShared(RecyclerShared &&move) noexcept
void Reset() noexcept
Does nothing. Shared recyclers can't be reset.
lang::AllocatorInterface< TAllocator > AIF() const noexcept
void Recycle(TNode *elem) noexcept
TAllocator & GetAllocator() const noexcept
RecyclerShared(const RecyclerShared &copy) noexcept=default
SharedRecycler(TAllocator &pAllocator) noexcept
lang::AllocatorMember< TAllocator > allocBase
Shortcut to a base class.
~SharedRecycler() noexcept
Destructor. Deletes all recyclables with the allocator.
void Reset() noexcept
Reset. Deletes all recyclables with the allocator.
void Reserve(integer qty, lang::ValueReference reference)
lang::SidiListHook< TNode > hookBase
Shortcut to a base class.
SharedRecycler() noexcept
Constructor taking no allocator, used with #"%HeapAllocator".
Detail namespace of module ALib Containers.
void reserveImpl(TAllocator &allocator, lang::SidiListHook< TNode > &recyclables, integer qty)
void recycleListImpl(lang::SidiListHook< TNode > &recyclables, TNode *begin)
Definition recycling.hpp:56
void disposeListImpl(TAllocator &allocator, TNode *begin)
void recycleImpl(lang::SidiListHook< TNode > &recyclables, TNode *elem)
Definition recycling.hpp:45
void recycleChunkImpl(lang::SidiListHook< TNode > &recyclables, TChunk *chunk, size_t count)
void disposeImpl(TAllocator &allocator, TNode *elem)
@ Private
< Denotes private recycling. This is usaully the default value.
Definition recycling.hpp:26
@ None
< Denotes that no recycling should be performed.
Definition recycling.hpp:25
@ Shared
< Denotes shared recycling.
Definition recycling.hpp:27
void Destruct(T &object)
Definition tmp.hpp:82
ValueReference
Denotes if a value is interpreted as an absolute or relative number.
@ Absolute
Referring to an absolute value.
Definition alox.cpp:14
lang::integer integer
Type alias in namespace #"%alib".
Definition integers.hpp:149
containers::Recycling Recycling
Type alias in namespace #"%alib".
Definition recycling.hpp:34
void Reset() noexcept
Resets this recycler. Frees all recyclables with the allocator.
void DisposeList(TNode *begin, TNode *end) noexcept
void DisposeList(TNode *begin) noexcept
lang::AllocatorMember< TAllocator > base
The base type.
void DisposeChunk(TChunk *chunk, size_t length) noexcept
std::pair< TNode *, integer > RecycleList(TNode *begin, TNode *end) noexcept
RecyclerPrivate() noexcept=default
Parameterless constructor. Used with type #"%HeapAllocator".
void Recycle(TNode *elem) noexcept
lang::AllocatorInterface< TAllocator > AIF() const noexcept
void RecycleChunk(TChunk *chunk, size_t length) noexcept
~RecyclerPrivate() noexcept
Destructor. Frees all recyclables with the allocator.
TAllocator & GetAllocator() const noexcept
lang::SidiListHook< TNode > recyclables
The list of recyclables.
void Reserve(integer qty) noexcept
void RecycleList(TNode *begin) noexcept
RecyclerPrivate(RecyclerPrivate &&move) noexcept
static constexpr bool IsRecycling() noexcept
RecyclerPrivate(const RecyclerPrivate &copy) noexcept
lang::AllocatorMember< TAllocator > base
The base type.
std::pair< TNode *, integer > RecycleList(TNode *begin, TNode *end) noexcept
void DisposeList(TNode *begin) noexcept
void RecycleList(TNode *begin) noexcept
std::pair< TNode *, integer > DisposeList(TNode *begin, TNode *end) noexcept
RecyclerVoid()
Parameterless constructor. Used with type #"%HeapAllocator".
void Reset() noexcept
Does nothing. Shared recyclers can't be reset.
void DisposeChunk(TChunk *chunk, size_t length) noexcept
constexpr void RecycleChunk(TChunk *chunk, size_t length) noexcept
void Recycle(TNode *elem) noexcept
void Reserve(integer) noexcept
Does nothing. In debug-compilations a #"alib_mod_assert;warning is raised".
RecyclerVoid(TAllocator &pAllocator) noexcept
constexpr integer Count() const noexcept
static constexpr bool IsRecycling() noexcept
void HookType
The hook type. Only used with shared recycling, otherwise void.
TAllocator & GetAllocator() const noexcept
AllocatorInterface< TAllocator > AIF() const noexcept
void reset() noexcept
Resets this list to zero elements.
Definition sidilist.hpp:209
TNode * first() const noexcept
Definition sidilist.hpp:214
void pushFront(TElement *elem) noexcept
Definition sidilist.hpp:218
SidiNodeBase< TNode > TNode
Definition sidilist.hpp:179
integer count(TNode *end=nullptr) const noexcept
Definition sidilist.hpp:301
void next(SidiNodeBase *p)
Definition sidilist.hpp:92