diff --git a/src/lib/several-builder.hpp b/src/lib/several-builder.hpp index fc546636f..726292e88 100644 --- a/src/lib/several-builder.hpp +++ b/src/lib/several-builder.hpp @@ -146,7 +146,7 @@ namespace lib { }; - template class ALO> + template class ALO> struct AllocationPolicy : ElementFactory { @@ -205,53 +205,54 @@ namespace lib { } return newBucket; } + +// // ensure sufficient storage or verify the ability to re-allocate +// if (not (Coll::hasReserve(sizeof(TY)) +// or POL::canExpand(sizeof(TY)) +// or handling_.template canDynGrow())) +// throw err::Invalid{_Fmt{"Unable to accommodate further element of type %s "} +// % util::typeStr()}; } }; - template - using HeapOwn = AllocationPolicy; + template + using HeapOwn = AllocationPolicy; using std::is_trivially_move_constructible_v; using std::is_trivially_destructible_v; using std::has_virtual_destructor_v; + using std::is_trivially_copyable_v; using std::is_same_v; using lib::meta::is_Subclass; template struct HandlingStrategy { - bool disposable :1 ; - bool wild_move :1 ; + bool disposable ; + bool lock_move ; HandlingStrategy (bool unmanaged) : disposable{unmanaged or (is_trivially_destructible_v and is_trivially_destructible_v)} - , wild_move{false} + , lock_move{false} { } /** mark that we're about to accept an otherwise unknown type, - * which can be trivially moved (by `memmove`). This irrevocably - * enables low-level`memove` usage for this container instance */ + * which can not be trivially moved. This irrevocably disables + * relocations by low-level `memove` for this container instance */ template - bool - markWildMovePossibility() + void + probeMoveCapability() { - if (wild_move and not isWildMoveCapable()) - return false; // must reject, since it can not wild-moved - if (isWildMoveCapable() - and is_trivially_move_constructible_v - and is_trivially_move_constructible_v) - wild_move = true; - return true; // accept anyway (not sure yet if it must be moved) + if (not (is_same_v or is_trivially_copyable_v)) + lock_move = true; } - template bool - isWildMoveCapable() + canWildMove() { - return not (is_same_v or is_same_v) - and is_trivially_move_constructible_v; + return is_trivially_copyable_v and not lock_move; } @@ -265,13 +266,6 @@ namespace lib { or (is_same_v and is_Subclass()); } - template - bool - canDynGrow() - { - return is_same_v or wild_move; - } - auto getDeleter() { @@ -289,9 +283,9 @@ namespace lib { * Wrap a vector holding objects of a subtype and * provide array-like access using the interface type. */ - template - ,class E =I ///< a subclass element element type (relevant when not trivially movable and destructible) - ,class POL =HeapOwn ///< Allocator policy + template + ,class E =I ///< a subclass element element type (relevant when not trivially movable and destructible) + ,class POL =HeapOwn ///< Allocator policy > class SeveralBuilder : Several @@ -402,25 +396,15 @@ namespace lib { throw err::Invalid{_Fmt{"Unable to handle destructor for element type %s"} % util::typeStr()}; - // mark acceptance of trivially movable arbitrary data types - if (not handling_.template markWildMovePossibility()) - throw err::Invalid{_Fmt{"Unable to trivially move element type %s, " - "while other elements in this container are trivially movable."} - % util::typeStr()}; + // mark when target type is not trivially movable + handling_.template probeMoveCapability(); // ensure sufficient element capacity or the ability to adapt element spread - if (Coll::spread() < sizeof(TY) and not (Coll::empty() or handling_.wild_move)) + if (Coll::spread() < sizeof(TY) and not (Coll::empty() or handling_.canWildMove())) throw err::Invalid{_Fmt{"Unable to place element of type %s (size=%d)" "into container for element size %d."} % util::typeStr() % sizeof(TY) % Coll::spread()}; - // ensure sufficient storage or verify the ability to re-allocate - if (not (Coll::hasReserve(sizeof(TY)) - or POL::canExpand(sizeof(TY)) - or handling_.template canDynGrow())) - throw err::Invalid{_Fmt{"Unable to accommodate further element of type %s "} - % util::typeStr()}; - size_t elmSiz = sizeof(TY); size_t newCnt = Coll::size()+1; adjustStorage (newCnt, max (elmSiz, Coll::spread())); diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index f475a5b26..5eb18afb7 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -82598,6 +82598,61 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + + + + + + + + + + + + +

+ Das ist eine Festlegung aus pragmatischen Gründen; weder der Container noch der Builder erfasst den Typ einzelner Elemente, daher gibt es auch keine Möglichkeit, überschüssigen Spread festzustellen. Zwar könnte der Client-Code diese Information besitzen, aber dann könnte er auch gleich richtig dimensionieren. Generell wird der Änderung des Spread keine besondere Bedeutung zugemessen — wenn es geht, wird's gemacht. +

+ + +
+ +
+ + + + + + + + + + + + + + +

+ der Puffer sollte mit einem Initial-Wert beginnen, und dann in Verdoppelungs-Schriten wachsen; Verdoppelung setzt natürlich Kenntnis der aktuellen Puffergröße voraus; dabei gäbe es aber auch noch einen Maximalwert zu beachten, der vom Allokator abhängen kann. +

+ + +
+
+
+ + + + + + + +