45template<
typename TNode>
56template<
typename TNode>
59 TNode* actual = begin;
62 TNode* next= actual->next();
78template<
typename TNode>
80 TNode* begin, TNode* end )
82 std::pair<TNode*,integer> result;
87 TNode* next= result.first->next();
95 recyclables.
pushFront( begin, result.first );
106template<
typename TAllocator,
typename TNode>
112 if constexpr ( TAllocator::allowsMemSplit() )
114 TNode* newElements= allocator().template AllocArray<TNode>(qty);
115 for(
integer i= qty - 2; i >= 0 ; --i )
116 newElements[i].next( &newElements[i + 1] );
118 recyclables.
pushFront( &newElements[0], &newElements[qty-1] );
122 TNode* start= allocator().template Alloc<TNode>();
124 for(
integer i= 1; i < qty ; ++i )
126 end->next( allocator().
template Alloc<TNode>() );
136template<
typename TAllocator,
typename TNode>
140 allocator().Free(elem);
148template<
typename TAllocator,
typename TNode>
151 TNode* actual = begin;
154 TNode* next= actual->next();
156 allocator().Free(actual);
169template<
typename TAllocator,
typename TNode>
170std::pair<TNode*,integer>
disposeListImpl( TAllocator& allocator, TNode* begin, TNode* end )
172 std::pair<TNode*,integer> result;
177 TNode* next= result.first->next();
179 allocator().Free(result.first);
195template<
typename TNode,
typename TChunk>
199 size_t size=
sizeof(TChunk[1]) * count;
202 if constexpr(
alignof(TNode) >
alignof(TChunk[1]) )
204 mem =
reinterpret_cast<void*
>((size_t(chunk) +
alignof(TNode) - 1) & ~(
alignof(TNode) -1));
205 size-= size_t(
reinterpret_cast<char*
>(mem) -
reinterpret_cast<char*
>(chunk));
209 ALIB_DBG(
size_t cntRecycledObjects= 0; )
210 while(size >
sizeof(TNode))
212 recyclables.
pushFront(
reinterpret_cast<TNode*
>( mem ) );
213 mem =
reinterpret_cast<char*
>(mem) +
sizeof(TNode);
214 size -=
sizeof (TNode);
219 if( cntRecycledObjects <= 0 )
222 "De-allocated chunk size is smaller than node size.\n"
223 " Chunk object: Type: <{}>\n"
224 " Size, Count, Alignment: {} * {} = {} bytes, alignment: {}\n"
225 " Recyclable Type: <{}>\n"
226 " Size, Alignment: {} bytes, alignment: {}\n"
227 "Note: If this recycler is used with a <containers::HashTable>, this message may be\n"
228 " eliminated by reserving a reasonable initial bucket size.",
229 &
typeid(TChunk),
sizeof(TChunk[1]), count,
sizeof(TChunk[1]) * count,
230 alignof(TChunk[1]), &
typeid(TNode),
sizeof(TNode),
alignof(TNode) )
243template<
typename TAllocator,
typename TNode>
261 :
base( pAllocator ) {}
274 move.recyclables.
reset();
283 TNode* next= actual->next();
324 :
base::AI().template Alloc<TNode>(); }
339 std::pair<TNode*, integer>
RecycleList(TNode* begin, TNode* end)
noexcept
360 template<
typename TChunk>
363 if constexpr ( TAllocator::allowsMemSplit() )
366 #if !defined(__MINGW32__)
367 base::AI().FreeArray(chunk, length );
369 base::AI().template FreeArray(chunk, length );
377 template<
typename TChunk>
380#if !defined(__MINGW32__)
381 base::AI().FreeArray(chunk, length );
383 base::AI().template FreeArray(chunk, length );
396template<
typename TAllocator,
typename TNode>
401 template<
typename TAllocator1,
typename TNode1>
402 friend class RecyclerShared;
450 if( requiredRecyclables > 0 )
461template<
typename TAllocator,
typename TNode>
515 {
return !
sr.isEmpty() ?
sr.popFront()
516 :
sr.AI().template Alloc<TNode>(); }
531 std::pair<TNode*, integer>
RecycleList(TNode* begin, TNode* end)
noexcept
549 template<
typename TChunk>
552 if constexpr ( TAllocator::allowsMemSplit() )
555 sr.AI().FreeArray(chunk, length );
562 template<
typename TChunk>
573template<
typename TAllocator,
typename TNode>
587 :
base( pAllocator ) {}
603 {
ALIB_WARNING(
"MONOMEM",
"Requested reservation of recyclables with non-recycling container.") }
623 std::pair<TNode*, integer>
RecycleList( TNode* begin, TNode* end )
noexcept
636 std::pair<TNode*, integer>
DisposeList( TNode* begin, TNode* end )
noexcept
646 template<
typename TChunk>
649#if !defined(__MINGW32__)
650 base::AI().FreeArray(chunk, length );
652 base::AI().template FreeArray(chunk, length );
660 template<
typename TChunk>
663#if !defined(__MINGW32__)
664 base::AI().FreeArray(chunk, length );
666 base::AI().template FreeArray(chunk, length );
677template<Recycling TRecycling>
693 template<
typename TAllocator,
typename TNode>
using HookType= void;
698 template<
typename TAllocator,
typename TNode>
using Type = RecyclerShared<TAllocator, TNode>;
699 template<
typename TAllocator,
typename TNode>
using HookType= SharedRecycler<TAllocator, TNode>;
704 template<
typename TAllocator,
typename TNode>
using Type= RecyclerVoid<TAllocator, TNode>;
705 template<
typename TAllocator,
typename TNode>
using HookType= void;
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
lang::AllocatorInterface< TAllocator > AI() const 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.
void Recycle(TNode *elem) noexcept
TAllocator & GetAllocator() const noexcept
RecyclerShared(const RecyclerShared ©) noexcept=default
SharedRecycler(TAllocator &pAllocator) noexcept
integer Count() const noexcept
~SharedRecycler() noexcept
Destructor. Deletes all recyclables with the allocator.
lang::SidiListHook< TNode > hookBase
Shortcut to a base class.
void Reset() noexcept
Reset. Deletes all recyclables with the allocator.
void Reserve(integer qty, lang::ValueReference reference)
SharedRecycler() noexcept
Constructor taking no allocator, used with HeapAllocator.
lang::AllocatorMember< TAllocator > allocBase
Shortcut to a base class.
#define ALIB_WARNING(domain,...)
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 > AI() 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
void Reset() noexcept
Does nothing. Shared recyclers can't be reset.
void DisposeChunk(TChunk *chunk, size_t length) noexcept
RecyclerVoid()=default
Parameterless constructor. Used with type HeapAllocator.
constexpr void RecycleChunk(TChunk *chunk, size_t length) noexcept
void Recycle(TNode *elem) noexcept
void Reserve(integer) noexcept
Does nothing. In debug-compilations a 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.
AllocatorInterface< TAllocator > AI() const noexcept
TAllocator & GetAllocator() const noexcept
AllocatorMember()=delete
Deleted default constructor. (The allocator has to be given with construction)
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)