44template<
typename TNode>
55template<
typename TNode>
57 TNode* actual = begin;
59 TNode* next= actual->next();
75template<
typename TNode>
77 TNode* begin, TNode* end ) {
78 std::pair<TNode*,integer> result;
82 TNode* next= result.first->next();
90 recyclables.
pushFront( begin, result.first );
101template<
typename TAllocator,
typename TNode>
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] );
111 recyclables.
pushFront( &newElements[0], &newElements[qty-1] );
113 TNode* start= allocator().template Alloc<TNode>();
115 for(
integer i= 1; i < qty ; ++i ) {
116 end->next( allocator().
template Alloc<TNode>() );
125template<
typename TAllocator,
typename TNode>
129 allocator().Free(elem);
137template<
typename TAllocator,
typename TNode>
139 TNode* actual = begin;
141 TNode* next= actual->next();
143 allocator().Free(actual);
155template<
typename TAllocator,
typename TNode>
156std::pair<TNode*,integer>
disposeListImpl( TAllocator& allocator, TNode* begin, TNode* end ) {
157 std::pair<TNode*,integer> result;
161 TNode* next= result.first->next();
163 allocator().Free(result.first);
178template<
typename TNode,
typename TChunk>
181 size_t size=
sizeof(TChunk[1]) * count;
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));
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);
201 if( cntRecycledObjects <= 0 ) {
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) )
224template<
typename TAllocator,
typename TNode>
241 :
base( pAllocator ) {}
258 TNode* next= actual->next();
311 std::pair<TNode*, integer>
RecycleList(TNode* begin, TNode* end)
noexcept
332 template<
typename TChunk>
334 if constexpr ( TAllocator::allowsMemSplit() )
337 #if !defined(__MINGW32__)
340 base::AIF().template FreeArray(chunk, length );
348 template<
typename TChunk>
350 #if !defined(__MINGW32__)
353 base::AIF().template FreeArray(chunk, length );
366template<
typename TAllocator,
typename TNode>
371 template<
typename TAllocator1,
typename TNode1>
372 friend class RecyclerShared;
417 if( requiredRecyclables > 0 )
428template<
typename TAllocator,
typename TNode>
480 TNode*
Get() {
return !
sr.isEmpty() ?
sr.popFront() :
sr.AIF().template Alloc<TNode>(); }
495 std::pair<TNode*, integer>
RecycleList(TNode* begin, TNode* end)
noexcept
513 template<
typename TChunk>
515 if constexpr ( TAllocator::allowsMemSplit() )
518 sr.AIF().FreeArray(chunk, length );
525 template<
typename TChunk>
536template<
typename TAllocator,
typename TNode>
549 :
base( pAllocator ) {}
565 {
ALIB_WARNING(
"MONOMEM",
"Requested reservation of recyclables with non-recycling container.") }
585 std::pair<TNode*, integer>
RecycleList( TNode* begin, TNode* end )
noexcept
598 std::pair<TNode*, integer>
DisposeList( TNode* begin, TNode* end )
noexcept
608 template<
typename TChunk>
610 #if !defined(__MINGW32__)
613 base::AIF().template FreeArray(chunk, length );
621 template<
typename TChunk>
623 #if !defined(__MINGW32__)
626 base::AIF().template FreeArray(chunk, length );
637template<Recycling TRecycling>
652 template<
typename TAllocator,
typename TNode>
using HookType= void;
656 template<
typename TAllocator,
typename TNode>
using Type = RecyclerShared<TAllocator, TNode>;
657 template<
typename TAllocator,
typename TNode>
using HookType= SharedRecycler<TAllocator, TNode>;
661 template<
typename TAllocator,
typename TNode>
using Type= RecyclerVoid<TAllocator, TNode>;
662 template<
typename TAllocator,
typename TNode>
using HookType= void;
#define ALIB_WARNING(domain,...)
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
void Reserve(integer qty)
RecyclerShared(SharedRecycler< TAllocator, TNode > &hook) noexcept
void DisposeChunk(TChunk *chunk, size_t length) noexcept
void DisposeList(TNode *begin, TNode *end) noexcept
~RecyclerShared() noexcept
Destructor.
SharedRecycler< TAllocator, TNode > & sr
The reference to the list of recyclables.
void RecycleChunk(TChunk *chunk, size_t length) noexcept
RecyclerShared(RecyclerShared &&move) noexcept
integer Count() const 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 ©) noexcept=default
SharedRecycler(TAllocator &pAllocator) noexcept
integer Count() const 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)
void disposeListImpl(TAllocator &allocator, TNode *begin)
void recycleImpl(lang::SidiListHook< TNode > &recyclables, TNode *elem)
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.
@ None
< Denotes that no recycling should be performed.
@ Shared
< Denotes shared recycling.
ValueReference
Denotes if a value is interpreted as an absolute or relative number.
@ Absolute
Referring to an absolute value.
lang::integer integer
Type alias in namespace #"%alib".
containers::Recycling Recycling
Type alias in namespace #"%alib".
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.
integer Count() const noexcept
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 ©) 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 Type
The type chosen.
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.
TNode * first() const noexcept
void pushFront(TElement *elem) noexcept
SidiNodeBase< TNode > TNode
integer count(TNode *end=nullptr) const noexcept
void next(SidiNodeBase *p)