Library: adapt LinkedElements to use the new StdFactory adaptor

This is the first validation of the new design:
the policy to take ownership can be reimplemented simply
by delegating to the adaptor for a C++ standard allocator
This commit is contained in:
Fischlurch 2024-05-26 23:54:32 +02:00
parent 8ca3c61c6f
commit cf80a292c1
5 changed files with 42 additions and 72 deletions

View file

@ -53,24 +53,8 @@ namespace lib {
const size_t EXTENT_SIZ = 256;
const size_t OVERHEAD = 2 * sizeof(void*);
const size_t STORAGE_SIZ = EXTENT_SIZ - OVERHEAD;
using HeapAlloc = std::allocator<std::byte>;
using Alloc = std::allocator_traits<HeapAlloc>;
HeapAlloc heap;
void*
allocate (size_t bytes) ////////////////////////OOO obsolete ... find a way to relocate this as custom allocator within LinkedElements!!!
{
return Alloc::allocate (heap, bytes);
}
void
destroy (void* storage)
{
Alloc::destroy (heap, static_cast<std::byte *> (storage));
}
/**
* Special allocator-policy for lib::LinkedElements
* - does not allow to allocate new elements
@ -86,7 +70,7 @@ namespace lib {
*/
template<class X>
void
destroy (X* elm)
dispose (X* elm)
{
REQUIRE (elm);
elm->~X();

View file

@ -64,7 +64,7 @@
namespace lib {
namespace allo { /** Concepts and Adapter for custom memory management */
namespace allo {///< Concepts and Adaptors for custom memory management
/////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1366 : define Allocator Concepts here
/// TODO the following Concepts can be expected here (with C++20)
@ -110,16 +110,16 @@ namespace lib {
template<class ALOT, typename...ARGS>
typename ALOT::pointer
construct (typename ALOT::alocator_type& allo, ARGS&& ...args)
construct (typename ALOT::allocator_type& allo, ARGS&& ...args)
{
auto loc = ALOT::allocate (allocator_, 1);
ALOT::construct (allocator_, loc, std::forward<ARGS>(args)...);
auto loc = ALOT::allocate (allo, 1);
ALOT::construct (allo, loc, std::forward<ARGS>(args)...);
return loc;
}
template<class ALOT, typename...ARGS>
template<class ALOT>
void
destroy (typename ALOT::alocator_type& allo, typename ALOT::pointer elm)
destroy (typename ALOT::allocator_type& allo, typename ALOT::pointer elm)
{
ALOT::destroy (allo, elm);
ALOT::deallocate (allo, elm, 1);

View file

@ -1,5 +1,5 @@
/*
LINKED-ELEMENTS.hpp - configurable intrusive single linked list template
LINKED-ELEMENTS.hpp - configurable intrusive single linked list template
Copyright (C) Lumiera.org
2012, Hermann Vosseler <Ichthyostega@web.de>
@ -39,8 +39,8 @@
**
** @note this linked list container is _intrusive_ and thus needs the help
** of the element type, which must *provide a pointer member* `next`.
** Consequently, each such node element can't be member in
** multiple collections at the same time
** Consequently, each such node element can not be member in
** several collections at the same time (unless they share all elements)
** @note as usual, any iterator relies on the continued existence and
** unaltered state of the container. There is no sanity check.
** @warning this container is deliberately not threadsafe
@ -50,7 +50,7 @@
** this node element when going out of scope.
**
** @see LinkedElements_test
** @see llist.h
** @see allocator-handle.hpp
** @see ScopedCollection
** @see itertools.hpp
*/
@ -80,38 +80,24 @@ namespace lib {
namespace linked_elements { ///< allocation policies for the LinkedElements list container
/**
* Policy for LinkedElements: taking ownership
* and possibly creating heap allocated Nodes
* Policy for LinkedElements: taking ownership and
* possibly creating new Nodes through a custom allocator.
* @tparam ALO a C++ standard conformant allocator
* @note is util::MoveOnly to enforce ownership
* on behalf of LinkedElements
*/
struct OwningHeapAllocated
: util::MoveOnly
template<class ALO>
struct OwningAllocated
: lib::allo::StdFactory<ALO>
, util::MoveOnly
{
typedef void* CustomAllocator;
using lib::allo::StdFactory<ALO>::StdFactory;
/** this policy discards elements
* by deallocating them from heap
*/
template<class X>
void
destroy (X* elm)
{
delete elm;
}
/** this policy creates new elements
* simply by heap allocation */
template<class TY, typename...ARGS>
TY&
create (ARGS&& ...args)
{
return *new TY (std::forward<ARGS> (args)...);
}
using CustomAllocator = ALO;
};
template<class N>
using OwningHeapAllocated = OwningAllocated<std::allocator<N>>;
@ -120,7 +106,7 @@ namespace lib {
/**
* Policy for LinkedElements: never create or destroy
* any elements, only allow to add already existing nodes.
* @note any added node needs to provide a \c next pointer
* @note any added node needs to provide a `next` pointer
* field, which is used ("intrusively") for managing
* the list datastructure. But besides that, the
* node element won't be altered or discarded
@ -133,8 +119,8 @@ namespace lib {
/** this policy doesn't take ownership
* and thus never discards anything
*/
void
destroy (void*)
void
dispose (void*)
{
/* does nothing */
}
@ -181,18 +167,18 @@ namespace lib {
* within the cluster will be bulk de-allocated
* when the cluster as such goes out of scope.
*/
void
destroy (void*)
void
dispose (void*)
{
/* does nothing */
}
template<class TY, typename...ARGS>
TY&
TY*
create (ARGS&& ...args)
{
return cluster_.create<TY> (std::forward<ARGS> (args)...);
return & cluster_.create<TY> (std::forward<ARGS> (args)...);
}
};
@ -222,7 +208,7 @@ namespace lib {
*/
template
< class N ///< node class or Base/Interface class for nodes
, class ALO = linked_elements::OwningHeapAllocated
, class ALO = linked_elements::OwningHeapAllocated<N>
>
class LinkedElements
: ALO
@ -233,7 +219,7 @@ namespace lib {
public:
~LinkedElements()
{
{
clear();
}
@ -290,7 +276,7 @@ namespace lib {
N* elm = head_;
head_ = head_->next;
try {
ALO::destroy(elm);
ALO::dispose (elm);
}
ERROR_LOG_AND_IGNORE (progress, "Clean-up of element in LinkedElements list")
}
@ -332,7 +318,7 @@ namespace lib {
TY&
emplace (ARGS&& ...args)
{
return push (ALO::template create<TY> (std::forward<ARGS> (args)...));
return push (* ALO::template create<TY> (std::forward<ARGS> (args)...));
}

View file

@ -28,6 +28,7 @@
#include "lib/test/run.hpp"
#include "lib/test/test-helper.hpp"
#include "lib/test/diagnostic-output.hpp"/////////////TODO
#include "lib/util.hpp"
#include "lib/allocation-cluster.hpp"
@ -486,7 +487,7 @@ namespace test{
elements.emplace<Num<3>> (4,5);
elements.emplace<Num<6>> (7,8,9);
const size_t EXPECT = sizeof(Num<1>) + sizeof(Num<3>) + sizeof(Num<6>);
const size_t EXPECT = sizeof(Num<1>) + sizeof(Num<3>) + sizeof(Num<6>) + 3*2*sizeof(void*);
CHECK (EXPECT == allocator.numBytes());
CHECK (sum(9) == Dummy::checksum());
@ -500,7 +501,9 @@ namespace test{
CHECK (sum(9) == Dummy::checksum());
// note: elements won't be discarded unless
// the AllocationCluster goes out of scope
SHOW_EXPR(Dummy::checksum())
}
SHOW_EXPR(Dummy::checksum())
CHECK (0 == Dummy::checksum());
}
};

View file

@ -64988,8 +64988,7 @@
die Grundbegriffe sind f&#252;r <b>Concepts</b>&#160;reserviert
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<icon BUILTIN="hourglass"/>
<node CREATED="1716728724156" ID="ID_1720325177" MODIFIED="1716728727615" TEXT="Allocator">
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1716728888214" ID="ID_419230520" MODIFIED="1716728901716" TEXT="Interface mu&#xdf; ausgearbeitet werden">
@ -65037,8 +65036,7 @@
</li>
</ul>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
</node>
<node CREATED="1716729711246" ID="ID_1882332665" MODIFIED="1716729736181">
@ -65049,8 +65047,7 @@
Factory wird das <b>zentrale Schnittstellen-Concept</b>&#160;zur restlichen Applikation
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
</node>
<node CREATED="1716728769205" ID="ID_258354779" MODIFIED="1716728771489" TEXT="Handle">
@ -65181,8 +65178,8 @@
<node COLOR="#338800" CREATED="1716743917838" ID="ID_1038539692" MODIFIED="1716743966300" TEXT="Entwurf: StdFactory (Adapter)">
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1716743934765" ID="ID_472100312" MODIFIED="1716743962761" TEXT="Policy OwningHeapAllocated re-implementieren auf Basis von StdFactory">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1716743934765" ID="ID_472100312" MODIFIED="1716767998222" TEXT="Policy OwningHeapAllocated re-implementieren auf Basis von StdFactory">
<icon BUILTIN="button_ok"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1716683843917" ID="ID_157117808" MODIFIED="1716684087738" TEXT="Standard-Allocator f&#xfc;r AllocationCluster bereitstellen">