Invocation: rearrange SeveralBuilder policy
redefine the policy for `lib::SeveralBuilder` to be a template-template parameter. In fact it should have been this way from start, yet defining this kind of very elaborate code bottom-up lets you sometime miss the wood for the trees So to restate: `lib::SeveralBuilder` takes a ''policy template,'' which then in turn will be instantiated with the same types `I` (interface) and `E` (element type) used on `SeveralBuilder` itself. Obviously, there can be further types involved and thus additional type parameters may be necessary, notably the ''Allocator'' — yet these are better injected when ''defining'' the policy template itself. The default binding for this policy template is defined as `allo::HeapOwn`, which causes the builder to allocate the storage extents through the standard heap allocator, and for the created `lib::Several` to take full ownership of embedded objects, invoking their destructors when falling out of scope.
This commit is contained in:
parent
2fd3629d80
commit
1705c40dc2
4 changed files with 52 additions and 48 deletions
|
|
@ -317,13 +317,11 @@ namespace lib {
|
|||
|
||||
//-----Policies-to-use-AllocationCluster------------------------
|
||||
|
||||
namespace {
|
||||
namespace allo { // Setup for custom allocator policies
|
||||
|
||||
// Forward declaration: configuration policy for lib::SeveralBuilder
|
||||
template<class I, class E, template<typename> class ALO>
|
||||
struct AllocationPolicy;
|
||||
}
|
||||
|
||||
namespace allo { // Setup for custom allocator policies
|
||||
|
||||
template<template<typename> class ALO, typename...ARGS>
|
||||
struct SetupSeveral;
|
||||
|
|
|
|||
|
|
@ -124,8 +124,7 @@ namespace lib {
|
|||
using std::move;
|
||||
using std::byte;
|
||||
|
||||
namespace {// Allocation management policies
|
||||
|
||||
namespace {
|
||||
/** number of storage slots to open initially;
|
||||
* starting with an over-allocation similar to `std::vector`
|
||||
*/
|
||||
|
|
@ -173,7 +172,10 @@ namespace lib {
|
|||
{
|
||||
return positiveDiff (alignment, alignof(void*));
|
||||
}
|
||||
|
||||
}//(End)helpers
|
||||
|
||||
|
||||
namespace allo {// Allocation management policies
|
||||
|
||||
/**
|
||||
* Generic factory to manage objects within an ArrayBucket<I> storage,
|
||||
|
|
@ -355,7 +357,7 @@ namespace lib {
|
|||
template<class I, class E>
|
||||
using HeapOwn = AllocationPolicy<I, E, std::allocator>;
|
||||
|
||||
}//(End)implementation details
|
||||
}//(End) namespace several
|
||||
|
||||
|
||||
|
||||
|
|
@ -381,28 +383,29 @@ namespace lib {
|
|||
* patterns, consistency checks may throw at runtime,
|
||||
* when attempting to add an unsuitable element.
|
||||
*/
|
||||
template<class I ///< Interface or base type visible on resulting Several<I>
|
||||
,class E =I ///< a subclass element element type (relevant when not trivially movable and destructible)
|
||||
,class POL =HeapOwn<I,E> ///< Allocator policy
|
||||
template<class I ///< Interface or base type visible on resulting Several<I>
|
||||
,class E =I ///< a subclass element element type (relevant when not trivially movable and destructible)
|
||||
,template<class,class> class POL =allo::HeapOwn ///< Allocator policy template (parametrised `POL<I,E>`)
|
||||
>
|
||||
class SeveralBuilder
|
||||
: private Several<I>
|
||||
, util::MoveOnly
|
||||
, POL
|
||||
, POL<I,E>
|
||||
{
|
||||
using Coll = Several<I>;
|
||||
using Policy = POL<I,E>;
|
||||
|
||||
using Bucket = ArrayBucket<I>;
|
||||
using Bucket = several::ArrayBucket<I>;
|
||||
using Deleter = typename Bucket::Deleter;
|
||||
|
||||
public:
|
||||
SeveralBuilder() = default;
|
||||
|
||||
/** start Several build using a custom allocator */
|
||||
template<typename...ARGS, typename = meta::enable_if<std::is_constructible<POL,ARGS...>>>
|
||||
template<typename...ARGS, typename = meta::enable_if<std::is_constructible<Policy,ARGS...>>>
|
||||
SeveralBuilder (ARGS&& ...alloInit)
|
||||
: Several<I>{}
|
||||
, POL{forward<ARGS> (alloInit)...}
|
||||
, Policy{forward<ARGS> (alloInit)...}
|
||||
{ }
|
||||
|
||||
|
||||
|
|
@ -549,7 +552,7 @@ namespace lib {
|
|||
adjustStorage (newCnt, max (elmSiz, Coll::spread()));
|
||||
ENSURE (Coll::data_);
|
||||
ensureDeleter<TY>();
|
||||
POL::template createAt<TY> (Coll::data_, newPos, forward<ARGS> (args)...);
|
||||
Policy::template createAt<TY> (Coll::data_, newPos, forward<ARGS> (args)...);
|
||||
Coll::data_->cnt = newPos+1;
|
||||
}
|
||||
|
||||
|
|
@ -583,7 +586,7 @@ namespace lib {
|
|||
{
|
||||
if (not (Coll::empty()
|
||||
or Coll::hasReserve (requiredSiz, newElms)
|
||||
or POL::canExpand (Coll::data_, requiredSiz*(Coll::size() + newElms))
|
||||
or Policy::canExpand (Coll::data_, requiredSiz*(Coll::size() + newElms))
|
||||
or canDynGrow()))
|
||||
throw err::Invalid{_Fmt{"Several-container is unable to accommodate further element of type %s; "
|
||||
"storage reserve (%d bytes ≙ %d elms) exhausted and unable to move "
|
||||
|
|
@ -607,7 +610,7 @@ namespace lib {
|
|||
size_t overhead = sizeof(Bucket) + alignRes(alignof(E));
|
||||
size_t safetyLim = LUMIERA_MAX_ORDINAL_NUMBER * Coll::spread();
|
||||
size_t expandAlloc = min (positiveDiff (min (safetyLim
|
||||
,POL::ALLOC_LIMIT)
|
||||
,Policy::ALLOC_LIMIT)
|
||||
,overhead)
|
||||
,max (2*buffSiz, cnt*spread));
|
||||
// round down to an even number of elements
|
||||
|
|
@ -618,7 +621,7 @@ namespace lib {
|
|||
"exceeds safety limit of %d bytes"} % safetyLim
|
||||
,LERR_(SAFETY_LIMIT)};
|
||||
// allocate new storage block...
|
||||
Coll::data_ = POL::realloc (Coll::data_, newCnt,spread);
|
||||
Coll::data_ = Policy::realloc (Coll::data_, newCnt,spread);
|
||||
}
|
||||
ENSURE (Coll::data_);
|
||||
if (canWildMove() and spread != Coll::spread())
|
||||
|
|
@ -629,11 +632,11 @@ namespace lib {
|
|||
fitStorage()
|
||||
{
|
||||
REQUIRE (not Coll::empty());
|
||||
if (not (POL::canExpand (Coll::data_, Coll::size())
|
||||
if (not (Policy::canExpand (Coll::data_, Coll::size())
|
||||
or canDynGrow()))
|
||||
throw err::Invalid{"Unable to shrink storage for Several-collection, "
|
||||
"since at least one element can not be moved."};
|
||||
Coll::data_ = POL::realloc (Coll::data_, Coll::size(), Coll::spread());
|
||||
Coll::data_ = Policy::realloc (Coll::data_, Coll::size(), Coll::spread());
|
||||
}
|
||||
|
||||
/** move existing data to accommodate spread */
|
||||
|
|
@ -709,7 +712,7 @@ namespace lib {
|
|||
Deleter
|
||||
selectDestructor()
|
||||
{
|
||||
typename POL::Fac& factory(*this);
|
||||
typename Policy::Fac& factory(*this);
|
||||
|
||||
if (is_Subclass<TY,I>() and has_virtual_destructor_v<I>)
|
||||
{
|
||||
|
|
@ -831,7 +834,7 @@ namespace lib {
|
|||
* @see lib::AllocationCluster (which provides a custom adaptation)
|
||||
* @see SeveralBuilder_test::check_CustomAllocator()
|
||||
*/
|
||||
template<class I, class E, class POL>
|
||||
template<class I, class E, template<class,class> class POL>
|
||||
template<template<typename> class ALO, typename...ARGS>
|
||||
inline auto
|
||||
SeveralBuilder<I,E,POL>::withAllocator (ARGS&& ...args)
|
||||
|
|
@ -841,8 +844,7 @@ namespace lib {
|
|||
"prior to adding any elements to the container"};
|
||||
|
||||
using Setup = allo::SetupSeveral<ALO,ARGS...>;
|
||||
using PolicyForAllo = typename Setup::template Policy<I,E>;
|
||||
using BuilderWithAllo = SeveralBuilder<I,E,PolicyForAllo>;
|
||||
using BuilderWithAllo = SeveralBuilder<I,E, Setup::template Policy>;
|
||||
|
||||
return BuilderWithAllo(forward<ARGS> (args)...);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ namespace engine {
|
|||
using PolicyForAllo = typename Setup::template Policy<I,E>;
|
||||
|
||||
template<class I, class E=I>
|
||||
using BuilderType = lib::SeveralBuilder<I,E, PolicyForAllo<I,E>>;
|
||||
using BuilderType = lib::SeveralBuilder<I,E, PolicyForAllo>;
|
||||
};
|
||||
|
||||
struct UseHeapAlloc
|
||||
|
|
|
|||
|
|
@ -2805,9 +2805,7 @@
|
|||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1534636352398" ID="ID_435790811" MODIFIED="1538263469671" TEXT="ähnliche Lage wie bei Destroy">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
GTK bietet nur Anzeigen von top-down:
|
||||
|
|
@ -3123,9 +3121,7 @@
|
|||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#435e98" CREATED="1538281532767" ID="ID_1335570495" MODIFIED="1538365732115" TEXT="Fehler: muß eigens separate GenNode bauen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...weil der Payload-Typ für diesen Aufruf bool ist,
|
||||
|
|
@ -3142,9 +3138,7 @@
|
|||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1538281635897" FOLDED="true" ID="ID_562945035" MODIFIED="1561827464647" TEXT="lexical_cast geht nicht">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
k
|
||||
|
|
@ -5000,9 +4994,7 @@
|
|||
</node>
|
||||
<node CREATED="1482466197707" ID="ID_832611965" MODIFIED="1518487921059">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Architektur-Entscheidung
|
||||
|
|
@ -7319,9 +7311,7 @@
|
|||
</node>
|
||||
<node CREATED="1506180752103" ID="ID_1985524064" MODIFIED="1576282358128" TEXT="starting point">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
navigate to the real UI component
|
||||
|
|
@ -10760,9 +10750,7 @@
|
|||
</node>
|
||||
<node COLOR="#338800" CREATED="1512621101645" ID="ID_1982135306" MODIFIED="1512789977343" TEXT="Polymorphie: verschiedene Pipelines">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
verschiedendste Pipeline-Konstruktionen
|
||||
|
|
@ -87719,8 +87707,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
Alle Typen sind bekannt und bereits angeschrieben; die neulich gefundene Lösung mit dem decltype(<builder>)-Trick hat mich zwar zum Ziel gebracht, ist aber unnötig indirekt — man könnte durchaus die Typen ineinander einsetzen und dann in eine einzige Typedef reduzieren
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
<node CREATED="1721174638056" ID="ID_1423112088" MODIFIED="1721174644592" TEXT="nein: doch nicht ganz..."/>
|
||||
<node CREATED="1721174645372" ID="ID_940405790" MODIFIED="1721174658046" TEXT="es geht schon um die Anordnung der Typ-Parameter"/>
|
||||
|
|
@ -87733,8 +87720,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
Namens-Idee: <b>AlloPolicySelector</b>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="idea"/>
|
||||
<node CREATED="1721171183918" ID="ID_1312928828" MODIFIED="1721174829989" TEXT="aber... das ist doch genau allo::SetupSeveral<ALO,ARGS...>">
|
||||
<arrowlink COLOR="#fefcc9" DESTINATION="ID_1620829594" ENDARROW="Default" ENDINCLINATION="-60;-64;" ID="Arrow_ID_864095772" STARTARROW="None" STARTINCLINATION="-82;4;"/>
|
||||
|
|
@ -87758,6 +87744,24 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node CREATED="1721174156169" ID="ID_137493922" MODIFIED="1721174261682" TEXT="erbt von einfachem Typ-Parameter — obwohl ein Template-Template wünschenswert wäre">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1721179318436" ID="ID_697938671" MODIFIED="1721179370879" TEXT="Nachbessern: die Policy für lib::SeveralBuilder als template-template definieren">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1721179377547" ID="ID_911419354" MODIFIED="1721179383494" TEXT="das ist nur Fleißarbeit"/>
|
||||
<node CREATED="1721179384227" ID="ID_1249905366" MODIFIED="1721179507877" TEXT="und in jedem Fall viel klarer so">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1721179392209" ID="ID_1920236724" MODIFIED="1721179501907" TEXT="Sollte dann auch die AllocationPolicy in einen benannten Namespace legen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
es bieteten sich an: <font face="Monospaced" color="#5c1818">lib::several </font>und<font face="Monospaced" color="#5c1818"> lib::allo</font> ⟵ letzteres ist logischer!
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1721174754965" ID="ID_1620829594" MODIFIED="1721175429658" TEXT="Nebenschauplatz: den decltype()-Trick eliminieren">
|
||||
|
|
|
|||
Loading…
Reference in a new issue