8#ifndef HPP_ALIB_MONOMEM_DETAIL_RECYCLER
9#define HPP_ALIB_MONOMEM_DETAIL_RECYCLER 1
13#include "alib/lang/sidilist.hpp"
30template<
typename TNode>
41template<
typename TNode>
44 TNode* actual = begin;
47 TNode* next= actual->next();
63template<
typename TNode>
65 TNode* begin, TNode* end )
67 std::pair<TNode*,integer> result;
72 TNode* next= result.first->next();
80 recyclables.
pushFront( begin, result.first );
91template<
typename TAllocator,
typename TNode>
97 if constexpr ( TAllocator::allowsMemSplit() )
100 TNode* newElements= allocator().template AllocArray<TNode>(qty);
101 for(
auto i= qty - 2; i >= 0 ; --i )
102 newElements[i].next( &newElements[i + 1] );
104 recyclables.
pushFront( &newElements[0], &newElements[qty-1] );
108 TNode* start= allocator().template Alloc<TNode>();
110 for(
auto i= 1; i < qty ; ++i )
112 end->next( allocator().
template Alloc<TNode>() );
123template<
typename TAllocator,
typename TNode>
127 allocator().Free(elem);
135template<
typename TAllocator,
typename TNode>
138 TNode* actual = begin;
141 TNode* next= actual->next();
143 allocator().Free(actual);
156template<
typename TAllocator,
typename TNode>
157std::pair<TNode*,integer>
disposeListImpl( TAllocator& allocator, TNode* begin, TNode* end )
159 std::pair<TNode*,integer> result;
164 TNode* next= result.first->next();
166 allocator().Free(result.first);
182template<
typename TNode,
typename TChunk>
186 size_t size=
sizeof(TChunk[1]) * count;
189 if constexpr(
alignof(TNode) >
alignof(TChunk[1]) )
191 mem =
reinterpret_cast<void*
>((size_t(chunk) +
alignof(TNode) - 1) & ~(
alignof(TNode) -1));
192 size-= size_t(
reinterpret_cast<char*
>(mem) -
reinterpret_cast<char*
>(chunk));
196 ALIB_DBG(
size_t cntRecycledObjects= 0; )
197 while(size >
sizeof(TNode))
199 recyclables.
pushFront(
reinterpret_cast<TNode*
>( mem ) );
201 mem =
reinterpret_cast<char*
>(mem) +
sizeof(TNode);
202 size -=
sizeof (TNode);
208 if( cntRecycledObjects <= 0 )
214 "De-allocated chunk size is smaller than node size.\n"
215 " Chunk object: Type: <" << typeChunk <<
">\n"
216 " Size, Count, Alignment: " <<
sizeof(TChunk[1]) <<
" * " << count <<
" = "
217 << (
sizeof(TChunk[1]) * count) <<
" bytes, alignment: "
218 <<
alignof(TChunk[1]) <<
"\n"
219 " Recyclable Type: <" << typeNode <<
">\n"
220 " Size, Alignment: " <<
sizeof(TNode) <<
" bytes, alignment: " <<
alignof(TNode) <<
"\n"
221 "Note: If this recycler is used with a <containers::HashTable>, this message may be eliminated\n"
222 " by reserving a reasonable initial bucket size." )
224 ALIB_WARNING( cntRecycledObjects > 0,
"MONOMEM/RECYCLER",
225 "De-allocated chunk size is smaller than node size." )
239template<
typename TAllocator,
typename TNode>
257 :
base( pAllocator ) {}
270 move.recyclables.
reset();
279 TNode* next= actual->next();
320 :
base::AI().template Alloc<TNode>(); }
335 std::pair<TNode*, integer>
RecycleList(TNode* begin, TNode* end)
noexcept
356 template<
typename TChunk>
359 if constexpr ( TAllocator::allowsMemSplit() )
362 #if !defined(__MINGW32__)
363 base::AI().FreeArray(chunk, length );
365 base::AI().template FreeArray(chunk, length );
373 template<
typename TChunk>
376#if !defined(__MINGW32__)
377 base::AI().FreeArray(chunk, length );
379 base::AI().template FreeArray(chunk, length );
392template<
typename TAllocator,
typename TNode>
397 template<
typename TAllocator1,
typename TNode1>
446 if( requiredRecyclables > 0 )
457template<
typename TAllocator,
typename TNode>
511 {
return !
sr.isEmpty() ?
sr.popFront()
512 :
sr.AI().template Alloc<TNode>(); }
527 std::pair<TNode*, integer>
RecycleList(TNode* begin, TNode* end)
noexcept
545 template<
typename TChunk>
548 if constexpr ( TAllocator::allowsMemSplit() )
551 sr.AI().FreeArray(chunk, length );
558 template<
typename TChunk>
569template<
typename TAllocator,
typename TNode>
583 :
base( pAllocator ) {}
599 {
ALIB_WARNING(
"MONOMEM",
"Requested reservation of recyclables with non-recycling container.") }
619 std::pair<TNode*, integer>
RecycleList( TNode* begin, TNode* end )
noexcept
632 std::pair<TNode*, integer>
DisposeList( TNode* begin, TNode* end )
noexcept
642 template<
typename TChunk>
645#if !defined(__MINGW32__)
646 base::AI().FreeArray(chunk, length );
648 base::AI().template FreeArray(chunk, length );
656 template<
typename TChunk>
659#if !defined(__MINGW32__)
660 base::AI().FreeArray(chunk, length );
662 base::AI().template FreeArray(chunk, length );
673template<Recycling TRecycling>
689 template<
typename TAllocator,
typename TNode>
using HookType= void;
694 template<
typename TAllocator,
typename TNode>
using Type = RecyclerShared<TAllocator, TNode>;
695 template<
typename TAllocator,
typename TNode>
using HookType= SharedRecycler<TAllocator, TNode>;
700 template<
typename TAllocator,
typename TNode>
using Type= RecyclerVoid<TAllocator, TNode>;
701 template<
typename TAllocator,
typename TNode>
using HookType= void;
RecyclerShared(SharedRecycler< TAllocator, TNode > &hook) noexcept
lang::AllocatorInterface< TAllocator > AI() const noexcept
void Reserve(integer qty)
void DisposeList(TNode *begin, TNode *end) noexcept
void Recycle(TNode *elem) noexcept
TAllocator & GetAllocator() const noexcept
static constexpr bool IsRecycling() noexcept
~RecyclerShared() noexcept
Destructor.
integer Count() const noexcept
void Reset() noexcept
Does nothing. Shared recyclers can't be reset.
std::pair< TNode *, integer > RecycleList(TNode *begin, TNode *end) noexcept
RecyclerShared(const RecyclerShared ©) noexcept=default
void RecycleChunk(TChunk *chunk, size_t length) noexcept
RecyclerShared(RecyclerShared &&move) noexcept
void DisposeChunk(TChunk *chunk, size_t length) noexcept
void DisposeList(TNode *begin) noexcept
void RecycleList(TNode *begin) noexcept
SharedRecycler< TAllocator, TNode > & sr
The reference to the list of recyclables.
lang::AllocatorMember< TAllocator > allocBase
Shortcut to a base class.
SharedRecycler() noexcept
Constructor taking no allocator, used with HeapAllocator.
integer Count() const noexcept
void Reset() noexcept
Reset. Deletes all recyclables with the allocator.
~SharedRecycler() noexcept
Destructor. Deletes all recyclables with the allocator.
SharedRecycler(TAllocator &pAllocator) noexcept
void Reserve(integer qty, lang::ValueReference reference)
ALIB_API NAString & GetShort(NAString &target)
#define ALIB_WARNING(...)
#define ALIB_ASSERT_MODULE(modulename)
#define ALIB_WARNINGS_RESTORE
#define ALIB_WARNINGS_ALLOW_UNSAFE_BUFFER_USAGE
void reserveImpl(TAllocator &allocator, lang::SidiListHook< TNode > &recyclables, integer qty)
void recycleListImpl(lang::SidiListHook< TNode > &recyclables, TNode *begin)
void recycleChunkImpl(lang::SidiListHook< TNode > &recyclables, TChunk *chunk, size_t count)
void disposeImpl(TAllocator &allocator, TNode *elem)
void disposeListImpl(TAllocator &allocator, TNode *begin)
void recycleImpl(lang::SidiListHook< TNode > &recyclables, TNode *elem)
@ Private
< Denotes private recycling. This is usaully the default value.
@ None
< Denotes that no recycling should be performed.
@ Shared
< Denotes shared recycling.
static ALIB_FORCE_INLINE void Destruct(T &object)
ValueReference
Denotes if a value is interpreted as an absolute or relative number.
@ Absolute
Referring to an absolute value.
NLocalString< 4096 > NString4K
Type alias name for TLocalString<nchar,8192>.
lang::integer integer
Type alias in namespace alib.
~RecyclerPrivate() noexcept
Destructor. Frees all recyclables with the allocator.
lang::AllocatorInterface< TAllocator > AI() const noexcept
void DisposeList(TNode *begin, TNode *end) noexcept
RecyclerPrivate() noexcept=default
Parameterless constructor. Used with type HeapAllocator.
void Recycle(TNode *elem) noexcept
TAllocator & GetAllocator() const noexcept
static constexpr bool IsRecycling() noexcept
lang::SidiListHook< TNode > recyclables
The list of recyclables.
integer Count() const noexcept
void Reset() noexcept
Resets this recycler. Frees all recyclables with the allocator.
std::pair< TNode *, integer > RecycleList(TNode *begin, TNode *end) noexcept
void Reserve(integer qty) noexcept
RecyclerPrivate(const RecyclerPrivate ©) noexcept
void RecycleChunk(TChunk *chunk, size_t length) noexcept
lang::AllocatorMember< TAllocator > base
The base type.
void DisposeChunk(TChunk *chunk, size_t length) noexcept
RecyclerPrivate(RecyclerPrivate &&move) noexcept
void DisposeList(TNode *begin) noexcept
void RecycleList(TNode *begin) noexcept
constexpr integer Count() const noexcept
std::pair< TNode *, integer > DisposeList(TNode *begin, TNode *end) noexcept
void Recycle(TNode *elem) noexcept
void Reserve(integer) noexcept
Does nothing. In debug-compilations a warning is raised.
static constexpr bool IsRecycling() noexcept
void Reset() noexcept
Does nothing. Shared recyclers can't be reset.
std::pair< TNode *, integer > RecycleList(TNode *begin, TNode *end) noexcept
RecyclerVoid()=default
Parameterless constructor. Used with type HeapAllocator.
lang::AllocatorMember< TAllocator > base
The base type.
void DisposeChunk(TChunk *chunk, size_t length) noexcept
RecyclerVoid(TAllocator &pAllocator) noexcept
constexpr void RecycleChunk(TChunk *chunk, size_t length) noexcept
void DisposeList(TNode *begin) noexcept
void RecycleList(TNode *begin) noexcept
void Type
The type chosen.
void HookType
The hook type. Only used with shared recycling, otherwise void.
AllocatorInterface< TAllocator > AI() const noexcept
AllocatorMember()=delete
Deleted default constructor. (The allocator has to be given with construction)
TAllocator & GetAllocator() const noexcept
TElement * popFront() noexcept
void reset() noexcept
Resets this list to zero elements.
void pushFront(TElement *elem) noexcept
integer count(TElement *end=nullptr) const noexcept
TElement * first() const noexcept
bool isEmpty() const noexcept
void next(SidiNodeBase *p)