Library: how to use a standard allocator for LinkedElements
By default, LinkedElements uses a policy OwningHeapAllocated; while retaining this interface, this policy should be recast to rely on a standard compliant allocator, with a default fallback to `std::allocator<T>` This way, a single policy would serve all the cases where objects are actually owned and managed by `LinkedElements`, and most special policies would be redundant. This turns out to be quite tedious and technical however, since the newer standard mandates to use std::allocator_traits as front-end, and moreover the standard allocators are always tied to one specific target type, while `LinkedElements` is deliberately used to maintain a polymorphic sequence.
This commit is contained in:
parent
3edf727c23
commit
5259000bc4
2 changed files with 173 additions and 6 deletions
|
|
@ -66,6 +66,7 @@
|
|||
#include "lib/util.hpp"
|
||||
|
||||
#include <utility>
|
||||
#include <memory>
|
||||
|
||||
|
||||
namespace lib {
|
||||
|
|
@ -109,6 +110,84 @@ namespace lib {
|
|||
}
|
||||
};
|
||||
|
||||
template<class ALO>
|
||||
struct OwningAlloc
|
||||
: util::MoveOnly
|
||||
{
|
||||
using Allo = ALO;
|
||||
using AlloT = std::allocator_traits<Allo>;
|
||||
using BaseType = typename Allo::value_type;
|
||||
|
||||
Allo allocator_;
|
||||
|
||||
OwningAlloc (Allo allo = Allo{})
|
||||
: allocator_{allo}
|
||||
{ }
|
||||
|
||||
template<typename X>
|
||||
auto
|
||||
adaptAllocator (Allo const& baseAllocator)
|
||||
{
|
||||
using XAllo = typename AlloT::template rebind_alloc<X>;
|
||||
if constexpr (std::is_constructible_v<XAllo, Allo>)
|
||||
return XAllo(allocator_);
|
||||
else
|
||||
return XAllo();
|
||||
}
|
||||
|
||||
template<class ALOT, typename...ARGS>
|
||||
auto&
|
||||
construct (typename ALOT::alocator_type& allo, ARGS&& ...args)
|
||||
{
|
||||
auto loc = ALOT::allocate (allocator_, 1);
|
||||
ALOT::construct (allocator_, loc, std::forward<ARGS>(args)...);
|
||||
return *loc;
|
||||
}
|
||||
|
||||
template<class ALOT, typename...ARGS>
|
||||
void
|
||||
destroy (typename ALOT::alocator_type& allo, typename ALOT::pointer elm)
|
||||
{
|
||||
ALOT::destroy (allo, elm);
|
||||
ALOT::deallocate (allo, elm, 1);
|
||||
}
|
||||
|
||||
|
||||
/** create new element using the embedded allocator */
|
||||
template<class TY, typename...ARGS>
|
||||
TY&
|
||||
create (ARGS&& ...args)
|
||||
{
|
||||
if constexpr (std::is_same_v<TY, BaseType>)
|
||||
{
|
||||
return construct<AlloT> (allocator_, std::forward<ARGS>(args)...);
|
||||
}
|
||||
else
|
||||
{
|
||||
using XAlloT = typename AlloT::template rebind_traits<TY>;
|
||||
auto xAllo = adaptAllocator<TY> (allocator_);
|
||||
return construct<XAlloT> (xAllo, std::forward<ARGS>(args)...);
|
||||
}
|
||||
}
|
||||
|
||||
template<class TY>
|
||||
void
|
||||
destroy (TY* elm)
|
||||
{
|
||||
if constexpr (std::is_same_v<TY, BaseType>)
|
||||
{
|
||||
destroy<AlloT> (allocator_, elm);
|
||||
}
|
||||
else
|
||||
{
|
||||
using XAlloT = typename AlloT::template rebind_traits<TY>;
|
||||
auto xAllo = adaptAllocator<TY> (allocator_);
|
||||
destroy<XAlloT> (xAllo, elm);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -64932,10 +64932,89 @@
|
|||
<node COLOR="#338800" CREATED="1686696718121" ID="ID_1035772269" MODIFIED="1686696767814" TEXT="vorläufig implementiert durch std::list mit Inline-Buffer">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1686696768847" ID="ID_48162464" MODIFIED="1686696788657" TEXT="das gleiche Aufruf-Pattern in AllocationCluster integrieren">
|
||||
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1686696768847" ID="ID_48162464" MODIFIED="1716683834965" TEXT="das gleiche Aufruf-Pattern in AllocationCluster integrieren">
|
||||
<arrowlink COLOR="#515b9a" DESTINATION="ID_910814489" ENDARROW="Default" ENDINCLINATION="167;-10;" ID="Arrow_ID_96021000" STARTARROW="None" STARTINCLINATION="168;8;"/>
|
||||
<icon BUILTIN="hourglass"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1716677970109" ID="ID_282740712" MODIFIED="1716677984988" TEXT="Konflikt ‖ Design-Ziele nicht klar">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1716678004602" ID="ID_7759126" MODIFIED="1716678008509" TEXT="gewünscht">
|
||||
<node CREATED="1716678013105" ID="ID_1544782146" MODIFIED="1716678171679" TEXT="ein reiner Funktor für Dependency-Injection">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
man möchte ein reines Funktor-Objekt, das <i>irgendwie hintenrum verdrahtet ist.</i> Auf diesem ruft man nur noch den Funktionsoperator auf mit den konkreten Argumenten, denn der Zieltyp ist bereits festgelegt
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1716678038748" ID="ID_763364439" MODIFIED="1716678513794" TEXT="Front-End — zum Erzeugen beliebiger Typen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...auch hier soll die Verdrahtung <i>verborgen bleiben; </i>jedoch ist man nicht auf einen Objekttyp festgelegt, und außerdem soll es die Möglichkeit geben, esplizit eine <font face="Monospaced">destroy()</font>-Funktion aufzurufen, oder alternativ schon aus der Erzeugung ein <i>managing-handle </i>zu bekommen
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1716678081327" ID="ID_1023398550" MODIFIED="1716678667304" TEXT="Policy — Steuern von Teilaspekten">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Speziell bei Containern treten verschiedene Nutzungsmuster und Variationen auf...
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
man möchte das Erzeugen neuer Objekte komplett unterbinden
|
||||
</li>
|
||||
<li>
|
||||
man möchte zum Erzeugen einen eingebetteten Custom-Allocator verwenden
|
||||
</li>
|
||||
<li>
|
||||
man möchte Destuktoren aufrufen oder nicht aufrufen
|
||||
</li>
|
||||
<li>
|
||||
man möchte beim Verwerfen eines Objekts die Allokation freigeben oder auch nicht und ggfs. auch bloß mitzählen
|
||||
</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1716678671271" ID="ID_1764893919" MODIFIED="1716678787519" TEXT="Standard Low-level-Allokator">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Das ist in etwa die Funktionalität, die man von der Standard-Library bekommt, und die damit auch von STL-Containern genutzt werden kann; eigentlich braucht man hier nur die Bereitstellung (und Freigabe) von uninitialisiertem Speicher; das eigentliche Konstruieren und Zerstören erledigen die <font face="Monospaced">std::allocator_traits</font>
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1716683768504" ID="ID_1462693245" MODIFIED="1716683781871" TEXT="Draft / Prototyping">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1716683783293" ID="ID_910814489" MODIFIED="1716683827701" TEXT="Standard-Allocator in LinkedElements integrieren">
|
||||
<linktarget COLOR="#515b9a" DESTINATION="ID_910814489" ENDARROW="Default" ENDINCLINATION="167;-10;" ID="Arrow_ID_96021000" SOURCE="ID_48162464" STARTARROW="None" STARTINCLINATION="168;8;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1716683843917" ID="ID_157117808" MODIFIED="1716684087738" TEXT="Standard-Allocator für AllocationCluster bereitstellen">
|
||||
<linktarget COLOR="#664940" DESTINATION="ID_157117808" ENDARROW="Default" ENDINCLINATION="1249;67;" ID="Arrow_ID_572544135" SOURCE="ID_1456163487" STARTARROW="None" STARTINCLINATION="131;-1027;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1716677442605" ID="ID_1120140540" MODIFIED="1716677451141" TEXT="speziell...">
|
||||
<node CREATED="1716677468353" ID="ID_1849931457" MODIFIED="1716677717812" TEXT="AllocationCluster (für Node-Network)">
|
||||
<arrowlink COLOR="#5e576b" DESTINATION="ID_688601712" ENDARROW="Default" ENDINCLINATION="-933;-99;" ID="Arrow_ID_1200230919" STARTARROW="None" STARTINCLINATION="-758;59;"/>
|
||||
</node>
|
||||
<node CREATED="1716677865819" ID="ID_884450390" MODIFIED="1716677938838" TEXT="BlockFlow (für Scheduler-Activities)">
|
||||
<arrowlink COLOR="#504f86" DESTINATION="ID_1478014419" ENDARROW="Default" ENDINCLINATION="-665;-48;" ID="Arrow_ID_1014939669" STARTARROW="None" STARTINCLINATION="-1064;85;"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1696538097698" ID="ID_762902476" MODIFIED="1696538102051" TEXT="Concurrency">
|
||||
|
|
@ -81623,7 +81702,16 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node CREATED="1715782747520" ID="ID_1770179360" MODIFIED="1715782759542" TEXT="node-basic-test: OK"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1715782790810" ID="ID_1391251855" MODIFIED="1715782799529" TEXT="linked-elements-test: ">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1715815439855" ID="ID_1456163487" MODIFIED="1715815486736" TEXT="sollte LinkedElements umstellen auf Standard-konformen Allocator"/>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1715815439855" ID="ID_1456163487" MODIFIED="1716684137464" TEXT="sollte LinkedElements umstellen auf Standard-konformen Allocator">
|
||||
<arrowlink COLOR="#664940" DESTINATION="ID_157117808" ENDARROW="Default" ENDINCLINATION="1249;67;" ID="Arrow_ID_572544135" STARTARROW="None" STARTINCLINATION="131;-1027;"/>
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node CREATED="1716684095508" ID="ID_1857326363" MODIFIED="1716684131661" TEXT="der muß dann die default-Policy ersetzen">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1716684105741" ID="ID_1677827906" MODIFIED="1716684129032" TEXT="also: Ownership + gegebenen Standard-Allocator als Schnittstelle">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1715815513228" ID="ID_1909349257" MODIFIED="1715815549523" TEXT="die NoOwnership-Policy wird dann zu einem speziellen Allocator"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1715782815501" ID="ID_845459708" MODIFIED="1715782818814" TEXT="Nodefactory">
|
||||
|
|
@ -81700,9 +81788,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
<node COLOR="#338800" CREATED="1716563047722" ID="ID_848423419" MODIFIED="1716566615378" TEXT="Storage-Diagnose">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
muß hier leider eine schecklicke low-level-Trickserei machen; das ist die Konsequenz der Entscheidung, mit dem absolut minimalen Storage-Overhead zu arbeiten, und außerdem muß ich auch noch das Non-Copyable <i>aushebeln...</i>
|
||||
|
|
@ -82144,9 +82230,10 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node CREATED="1680563454868" ID="ID_1187556686" MODIFIED="1680563459014" TEXT="Backbone"/>
|
||||
<node CREATED="1680563460649" ID="ID_127710483" MODIFIED="1715624384997" TEXT="MemManagement">
|
||||
<arrowlink COLOR="#454059" DESTINATION="ID_1595450559" ENDARROW="Default" ENDINCLINATION="-1036;-77;" ID="Arrow_ID_1704085390" STARTARROW="None" STARTINCLINATION="-161;430;"/>
|
||||
<node CREATED="1715623566743" ID="ID_688601712" MODIFIED="1715624494222" TEXT="AllocationCluster">
|
||||
<node CREATED="1715623566743" ID="ID_688601712" MODIFIED="1716677717812" TEXT="AllocationCluster">
|
||||
<linktarget COLOR="#816f7b" DESTINATION="ID_688601712" ENDARROW="Default" ENDINCLINATION="95;-321;" ID="Arrow_ID_1440452458" SOURCE="ID_1219678116" STARTARROW="None" STARTINCLINATION="-521;38;"/>
|
||||
<linktarget COLOR="#816f7b" DESTINATION="ID_688601712" ENDARROW="Default" ENDINCLINATION="95;-321;" ID="Arrow_ID_859179840" SOURCE="ID_303611553" STARTARROW="None" STARTINCLINATION="-264;24;"/>
|
||||
<linktarget COLOR="#5e576b" DESTINATION="ID_688601712" ENDARROW="Default" ENDINCLINATION="-933;-99;" ID="Arrow_ID_1200230919" SOURCE="ID_1849931457" STARTARROW="None" STARTINCLINATION="-758;59;"/>
|
||||
<node CREATED="1715786334834" ID="ID_885525745" MODIFIED="1715786341860" TEXT="Design / Systematik">
|
||||
<node CREATED="1715786372102" ID="ID_1591071302" MODIFIED="1715786382355" TEXT="Aufwand für Memory-Management wird gebündelt"/>
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1715786522984" ID="ID_1870113951" MODIFIED="1715786580201" TEXT="Konflikt: Performance ⟷ Sicherheit">
|
||||
|
|
@ -121704,6 +121791,7 @@ std::cout << tmpl.render({"what", "World"}) << s
|
|||
<node CREATED="1688438172401" ID="ID_1302126473" MODIFIED="1688438176429" TEXT="Memory-Manager">
|
||||
<node COLOR="#338800" CREATED="1693840789997" ID="ID_1478014419" MODIFIED="1693840887589" TEXT="BlockFlow (custom allocation scheme)">
|
||||
<arrowlink COLOR="#578096" DESTINATION="ID_1810148055" ENDARROW="Default" ENDINCLINATION="-1144;102;" ID="Arrow_ID_1579502372" STARTARROW="None" STARTINCLINATION="549;39;"/>
|
||||
<linktarget COLOR="#504f86" DESTINATION="ID_1478014419" ENDARROW="Default" ENDINCLINATION="-665;-48;" ID="Arrow_ID_1014939669" SOURCE="ID_884450390" STARTARROW="None" STARTINCLINATION="-1064;85;"/>
|
||||
<icon BUILTIN="forward"/>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue