Library: enable empty-base optimisation for allocator
...this is an important detail: quite commonly, a custom allocator is actually implemented as monostate, to avoid bloating every client container with a backlink pointer; by inheriting the `StdFactory` adapter from the allocator, the empty-base optimisation can be exploited. In the standard case thus LinkedElements is the same size as a single pointer, which is already exploited at several places in the code base. Notably `AllocationCluster` uses a »virtual overlay« to dress-up the position pointer as `LinkedElements`, allowing to delegate most of the administration and memory management to existing and verified code. With this adjustments, `LinkedElements` pass the tests again and the rework of `AllocationCluster` is considered complete.
This commit is contained in:
parent
cf80a292c1
commit
178107e8b9
6 changed files with 202 additions and 131 deletions
|
|
@ -109,11 +109,14 @@ namespace lib {
|
|||
};
|
||||
using Extents = lib::LinkedElements<Extent>;
|
||||
|
||||
static_assert (sizeof(Destructors) == sizeof(void*));
|
||||
static_assert (sizeof(Extents) == sizeof(void*));
|
||||
|
||||
union ManagementView
|
||||
{
|
||||
Storage storage;
|
||||
Extents extents;
|
||||
};
|
||||
}; //Note: storage.pos and extents.head_ reside at the same location
|
||||
|
||||
ManagementView view_;
|
||||
|
||||
|
|
|
|||
|
|
@ -65,20 +65,6 @@ namespace lib {
|
|||
class AllocationCluster
|
||||
: util::MoveOnly
|
||||
{
|
||||
|
||||
template<typename X>
|
||||
struct Allocator
|
||||
{
|
||||
using value_type = X;
|
||||
|
||||
[[nodiscard]] X* allocate (size_t n) { return mother_->allot<X>(n); }
|
||||
void deallocate (X*, size_t) noexcept { /* rejoice */ }
|
||||
|
||||
Allocator(AllocationCluster* m) : mother_{m} { }
|
||||
private:
|
||||
AllocationCluster* mother_;
|
||||
};
|
||||
|
||||
class StorageManager;
|
||||
|
||||
/** maintaining the Allocation */
|
||||
|
|
@ -106,12 +92,9 @@ namespace lib {
|
|||
AllocationCluster ();
|
||||
~AllocationCluster () noexcept;
|
||||
|
||||
template<typename X>
|
||||
Allocator<X>
|
||||
getAllocator()
|
||||
{
|
||||
return Allocator<X>{this};
|
||||
}
|
||||
/* === diagnostics === */
|
||||
size_t numExtents() const;
|
||||
size_t numBytes() const;
|
||||
|
||||
|
||||
template<class TY, typename...ARGS>
|
||||
|
|
@ -121,10 +104,24 @@ namespace lib {
|
|||
TY& createDisposable (ARGS&& ...);
|
||||
|
||||
|
||||
/* === diagnostics === */
|
||||
template<typename X>
|
||||
struct Allocator
|
||||
{
|
||||
using value_type = X;
|
||||
|
||||
[[nodiscard]] X* allocate (size_t n) { return mother_->allot<X>(n); }
|
||||
void deallocate (X*, size_t) noexcept { /* rejoice */ }
|
||||
|
||||
Allocator(AllocationCluster* m) : mother_{m} { }
|
||||
// standard copy acceptable
|
||||
template<typename T>
|
||||
Allocator(Allocator<T> const& o) : mother_{o.mother_} { }
|
||||
|
||||
AllocationCluster* mother_;
|
||||
};
|
||||
|
||||
size_t numExtents() const;
|
||||
size_t numBytes() const;
|
||||
template<typename X>
|
||||
Allocator<X> getAllocator() { return this; }
|
||||
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -85,27 +85,31 @@ namespace lib {
|
|||
* from the given base allocator
|
||||
* - alternatively, an attempt will be made to default-construct
|
||||
* the rebound allocator for the other type requested.
|
||||
* @warn Both avenues for adaptation may fail, which could lead to
|
||||
* compilation or runtime failures.
|
||||
* @warning Both avenues for adaptation may fail,
|
||||
* which could lead to compilation or runtime failure.
|
||||
* @remark deliberately this class inherits from the allocator,
|
||||
* allowing to exploit empty-base-optimisation, since
|
||||
* usage of monostate allocators is quite common.
|
||||
*/
|
||||
template<class ALO>
|
||||
class StdFactory
|
||||
: private ALO
|
||||
{
|
||||
using Allo = ALO;
|
||||
using AlloT = std::allocator_traits<Allo>;
|
||||
using BaseType = typename Allo::value_type;
|
||||
|
||||
Allo allocator_;
|
||||
Allo& baseAllocator() { return *this; }
|
||||
|
||||
template<typename X>
|
||||
auto
|
||||
adaptAllocator (Allo const& baseAllocator)
|
||||
adaptAllocator()
|
||||
{
|
||||
using XAllo = typename AlloT::template rebind_alloc<X>;
|
||||
if constexpr (std::is_constructible_v<XAllo, Allo>)
|
||||
return XAllo(allocator_);
|
||||
return XAllo{baseAllocator()};
|
||||
else
|
||||
return XAllo();
|
||||
return XAllo{};
|
||||
}
|
||||
|
||||
template<class ALOT, typename...ARGS>
|
||||
|
|
@ -139,18 +143,18 @@ namespace lib {
|
|||
* all those front-end instances exchangeable.
|
||||
*/
|
||||
StdFactory (Allo allo = Allo{})
|
||||
: allocator_{std::move (allo)}
|
||||
: Allo{std::move (allo)}
|
||||
{ }
|
||||
|
||||
template<class XALO>
|
||||
bool constexpr operator== (StdFactory<XALO> const& o) const
|
||||
{
|
||||
return allocator_ == o.allocator_;
|
||||
return baseAllocator() == o.baseAllocator();
|
||||
}
|
||||
template<class XALO>
|
||||
bool constexpr operator!= (StdFactory<XALO> const& o) const
|
||||
{
|
||||
return not (allocator_ == o.allocator_);
|
||||
return not (*this == o);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -161,12 +165,12 @@ namespace lib {
|
|||
{
|
||||
if constexpr (std::is_same_v<TY, BaseType>)
|
||||
{
|
||||
return construct<AlloT> (allocator_, std::forward<ARGS>(args)...);
|
||||
return construct<AlloT> (baseAllocator(), std::forward<ARGS>(args)...);
|
||||
}
|
||||
else
|
||||
{
|
||||
using XAlloT = typename AlloT::template rebind_traits<TY>;
|
||||
auto xAllo = adaptAllocator<TY> (allocator_);
|
||||
auto xAllo = adaptAllocator<TY>();
|
||||
return construct<XAlloT> (xAllo, std::forward<ARGS>(args)...);
|
||||
}
|
||||
}
|
||||
|
|
@ -178,12 +182,12 @@ namespace lib {
|
|||
{
|
||||
if constexpr (std::is_same_v<TY, BaseType>)
|
||||
{
|
||||
destroy<AlloT> (allocator_, elm);
|
||||
destroy<AlloT> (baseAllocator(), elm);
|
||||
}
|
||||
else
|
||||
{
|
||||
using XAlloT = typename AlloT::template rebind_traits<TY>;
|
||||
auto xAllo = adaptAllocator<TY> (allocator_);
|
||||
auto xAllo = adaptAllocator<TY>();
|
||||
destroy<XAlloT> (xAllo, elm);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,9 @@
|
|||
** - convenient access through Lumiera Forward Iterators
|
||||
** - the need to integrate tightly with a custom allocator
|
||||
**
|
||||
** @note effectively, LinkedElements is „just a dressed-up pointer“;
|
||||
** under the assumption that the allocator is a _monostate_, and
|
||||
** exploiting _empty-base-optimisation,_ footprint is minimal.
|
||||
** @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 not be member in
|
||||
|
|
@ -96,13 +99,14 @@ namespace lib {
|
|||
using CustomAllocator = ALO;
|
||||
};
|
||||
|
||||
|
||||
/** default policy: use standard heap allocation for new elements */
|
||||
template<class N>
|
||||
using OwningHeapAllocated = OwningAllocated<std::allocator<N>>;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Policy for LinkedElements: never create or destroy
|
||||
* any elements, only allow to add already existing nodes.
|
||||
|
|
@ -133,58 +137,7 @@ namespace lib {
|
|||
} // ... you'll have to do that yourself (that's the whole point of using this strategy)
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef LIB_ALLOCATION_CLUSTER_H
|
||||
|
||||
/**
|
||||
* Policy for LinkedElements: especially using a
|
||||
* lib::AllocationCluster instance for creating
|
||||
* new node elements. It is mandatory to pass
|
||||
* this cluster instance to the ctor of any
|
||||
* LinkedElements list using this policy
|
||||
* @note AllocationCluster always de-allocates
|
||||
* any created elements in one sway.
|
||||
*/
|
||||
struct UseAllocationCluster
|
||||
{
|
||||
typedef AllocationCluster& CustomAllocator;
|
||||
|
||||
CustomAllocator cluster_;
|
||||
|
||||
|
||||
explicit
|
||||
UseAllocationCluster (CustomAllocator clu)
|
||||
: cluster_(clu)
|
||||
{ }
|
||||
|
||||
|
||||
/** while this policy indeed implies creating and owing
|
||||
* new objects, the AllocationCluster doesn't support
|
||||
* discarding individual instances. All created objects
|
||||
* within the cluster will be bulk de-allocated
|
||||
* when the cluster as such goes out of scope.
|
||||
*/
|
||||
void
|
||||
dispose (void*)
|
||||
{
|
||||
/* does nothing */
|
||||
}
|
||||
|
||||
|
||||
template<class TY, typename...ARGS>
|
||||
TY*
|
||||
create (ARGS&& ...args)
|
||||
{
|
||||
return & cluster_.create<TY> (std::forward<ARGS> (args)...);
|
||||
}
|
||||
};
|
||||
|
||||
#endif //(End)if lib/allocation-cluster.hpp was included
|
||||
|
||||
}//(END)namespace linked_elements
|
||||
}//(END)namespace linked_elements (predefined policies)
|
||||
|
||||
|
||||
|
||||
|
|
@ -195,7 +148,7 @@ namespace lib {
|
|||
|
||||
|
||||
|
||||
/**
|
||||
/****************************************************************************//**
|
||||
* Intrusive single linked list, possibly taking ownership of node elements.
|
||||
* Additional elements can be pushed (prepended) to the list; element access
|
||||
* is per index number (slow) or through an Lumiera Forward Iterator traversing
|
||||
|
|
@ -205,9 +158,10 @@ namespace lib {
|
|||
* The allocation and ownership related behaviour is controlled by a policy class
|
||||
* provided as template parameter. When this policy supports creation of new
|
||||
* elements, these might be created and prepended in one step.
|
||||
* @note with the default policy, `sizeof(LinkedElements) == sizeof(N*)`
|
||||
*/
|
||||
template
|
||||
< class N ///< node class or Base/Interface class for nodes
|
||||
< class N ///< node class or Base/Interface class for nodes
|
||||
, class ALO = linked_elements::OwningHeapAllocated<N>
|
||||
>
|
||||
class LinkedElements
|
||||
|
|
@ -218,7 +172,7 @@ namespace lib {
|
|||
|
||||
public:
|
||||
|
||||
~LinkedElements()
|
||||
~LinkedElements() noexcept
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
|
@ -244,7 +198,8 @@ namespace lib {
|
|||
, head_{nullptr}
|
||||
{ }
|
||||
|
||||
/** creating a LinkedElements list in RAII-style:
|
||||
/**
|
||||
* creating a LinkedElements list in RAII-style:
|
||||
* @param elements iterator to provide all the elements
|
||||
* to be pushed into this newly created collection
|
||||
* @note any exception while populating the container
|
||||
|
|
@ -269,7 +224,7 @@ namespace lib {
|
|||
|
||||
/** @note EX_FREE */
|
||||
void
|
||||
clear()
|
||||
clear() noexcept
|
||||
{
|
||||
while (head_)
|
||||
{
|
||||
|
|
@ -304,7 +259,7 @@ namespace lib {
|
|||
*/
|
||||
template<typename TY>
|
||||
TY&
|
||||
push (TY& elm)
|
||||
push (TY& elm) noexcept
|
||||
{
|
||||
elm.next = head_;
|
||||
head_ = &elm;
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@
|
|||
|
||||
#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"
|
||||
|
|
@ -158,7 +157,7 @@ namespace test{
|
|||
return n*(n+1) / 2;
|
||||
}
|
||||
|
||||
}//(End) subversive test data
|
||||
}//(End) test data and helpers
|
||||
|
||||
|
||||
|
||||
|
|
@ -170,9 +169,6 @@ namespace test{
|
|||
/// managing existing node elements without taking ownership
|
||||
using ListNotOwner = LinkedElements<Nummy, linked_elements::NoOwnership>;
|
||||
|
||||
/// creating nodes in-place, using a custom allocator for creation and disposal
|
||||
using ListCustomAllocated = LinkedElements<Nummy, linked_elements::UseAllocationCluster>;
|
||||
|
||||
|
||||
|
||||
/****************************************************************//**
|
||||
|
|
@ -474,21 +470,56 @@ namespace test{
|
|||
}
|
||||
|
||||
|
||||
|
||||
/** Policy to use an Allocation cluster,
|
||||
* but also to invoke all object destructors */
|
||||
struct UseAllocationCluster
|
||||
{
|
||||
typedef AllocationCluster& CustomAllocator;
|
||||
|
||||
CustomAllocator cluster_;
|
||||
|
||||
UseAllocationCluster (CustomAllocator clu)
|
||||
: cluster_(clu)
|
||||
{ }
|
||||
|
||||
template<class TY, typename...ARGS>
|
||||
TY*
|
||||
create (ARGS&& ...args)
|
||||
{
|
||||
return & cluster_.create<TY> (std::forward<ARGS> (args)...);
|
||||
}
|
||||
|
||||
void dispose (void*) { /* does nothing */ }
|
||||
};
|
||||
|
||||
/** @test use custom allocator to create list elements
|
||||
* - a dedicated policy allows to refer to an existing AllocationCluster
|
||||
* and to arrange for all object destructors to be called when this
|
||||
* cluster goes out of scope
|
||||
* - a C++ standard allocator can also be used; as an example, again an
|
||||
* AllocationCluster is used, but this time with the default adapter,
|
||||
* which places objects tight and skips invocation of destructors;
|
||||
* however, since the LinkedElements destructor is called, it
|
||||
* walks all elements and delegates through std::allocator_traits,
|
||||
* which will invoke the (virtual) base class destructors.
|
||||
*/
|
||||
void
|
||||
verify_customAllocator()
|
||||
{
|
||||
CHECK (0 == Dummy::checksum());
|
||||
{
|
||||
AllocationCluster allocator;
|
||||
AllocationCluster cluster;
|
||||
|
||||
ListCustomAllocated elements(allocator);
|
||||
LinkedElements<Nummy, UseAllocationCluster> elements(cluster);
|
||||
|
||||
elements.emplace<Num<1>> (2);
|
||||
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>) + 3*2*sizeof(void*);
|
||||
CHECK (EXPECT == allocator.numBytes());
|
||||
const size_t EXPECT = sizeof(Num<1>) + sizeof(Num<3>) + sizeof(Num<6>)
|
||||
+ 3*2*sizeof(void*); // ◁┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄overhead for storing 3 dtor-invokers
|
||||
CHECK (EXPECT == cluster.numBytes());
|
||||
CHECK (sum(9) == Dummy::checksum());
|
||||
|
||||
CHECK (3 == elements.size());
|
||||
|
|
@ -497,13 +528,34 @@ namespace test{
|
|||
CHECK (6+7+8+9 == elements[0].getVal());
|
||||
|
||||
elements.clear();
|
||||
CHECK (EXPECT == allocator.numBytes());
|
||||
CHECK (EXPECT == cluster.numBytes());
|
||||
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());
|
||||
{
|
||||
// now use AllocationCluster through the default allocator adapter...
|
||||
AllocationCluster cluster;
|
||||
using Allo = AllocationCluster::Allocator<Nummy>;
|
||||
using Elms = LinkedElements<Nummy, linked_elements::OwningAllocated<Allo>>;
|
||||
|
||||
Elms elements{cluster.getAllocator<Nummy>()};
|
||||
|
||||
elements.emplace<Num<1>> (2);
|
||||
elements.emplace<Num<3>> (4,5);
|
||||
|
||||
const size_t EXPECT = sizeof(Num<1>) + sizeof(Num<3>);
|
||||
CHECK (EXPECT == cluster.numBytes());
|
||||
CHECK (sum(5) == Dummy::checksum());
|
||||
|
||||
CHECK (2 == elements.size());
|
||||
CHECK (1+2 == elements[1].getVal());
|
||||
CHECK (3+4+5 == elements[0].getVal());
|
||||
// note: this time the destructors will be invoked
|
||||
// from LinkedElements::clear(), but not from
|
||||
// the destructor of AllocationCluster
|
||||
}
|
||||
CHECK (0 == Dummy::checksum());
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -65106,9 +65106,9 @@
|
|||
<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="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 COLOR="#5b280f" CREATED="1686696768847" ID="ID_48162464" MODIFIED="1716828253252" TEXT="das gleiche Aufruf-Pattern in AllocationCluster integrieren">
|
||||
<arrowlink COLOR="#517f9a" DESTINATION="ID_910814489" ENDARROW="Default" ENDINCLINATION="167;-10;" ID="Arrow_ID_96021000" STARTARROW="None" STARTINCLINATION="168;8;"/>
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1716677970109" ID="ID_282740712" MODIFIED="1716677984988" TEXT="Konflikt ‖ Design-Ziele nicht klar">
|
||||
|
|
@ -65172,19 +65172,56 @@
|
|||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1716683768504" ID="ID_1462693245" MODIFIED="1716683781871" TEXT="Draft / Prototyping">
|
||||
<linktarget COLOR="#943871" DESTINATION="ID_1462693245" ENDARROW="Default" ENDINCLINATION="-1171;2688;" ID="Arrow_ID_230796845" SOURCE="ID_158782942" STARTARROW="None" STARTINCLINATION="-815;-23;"/>
|
||||
<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 COLOR="#338800" CREATED="1716683783293" ID="ID_910814489" MODIFIED="1716828248548" TEXT="Standard-Allocator in LinkedElements integrieren">
|
||||
<linktarget COLOR="#517f9a" DESTINATION="ID_910814489" ENDARROW="Default" ENDINCLINATION="167;-10;" ID="Arrow_ID_96021000" SOURCE="ID_48162464" STARTARROW="None" STARTINCLINATION="168;8;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1716743917838" ID="ID_1038539692" MODIFIED="1716743966300" TEXT="Entwurf: StdFactory (Adapter)">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1716769836348" ID="ID_323593289" MODIFIED="1716769873715" TEXT="private Adapter-Funktionen und den Allokator in ein privates Feld"/>
|
||||
<node COLOR="#435e98" CREATED="1716769874254" ID="ID_1245762585" MODIFIED="1716822400050" TEXT="ließe sich der Allokator als Basisklasse anordnen?">
|
||||
<linktarget COLOR="#e7053e" DESTINATION="ID_1245762585" ENDARROW="Default" ENDINCLINATION="16;46;" ID="Arrow_ID_316103810" SOURCE="ID_221563395" STARTARROW="None" STARTINCLINATION="-49;-3;"/>
|
||||
<icon BUILTIN="help"/>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#a6278d" CREATED="1716769956164" ID="ID_1434540712" MODIFIED="1716769975843" TEXT="puh... das wird hässlich">
|
||||
<icon BUILTIN="smiley-angry"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1716769978195" ID="ID_660104995" MODIFIED="1716822397747" TEXT="EBO ist aber ein wichtiger Belang hier">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1716822372753" ID="ID_1585783821" MODIFIED="1716822393513" TEXT="mit einer casting-Hilfsfunktion bekommt man es einigermaßen lesbar">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1716822385027" ID="ID_1753587284" MODIFIED="1716822390899" TEXT="erklärender Kommentar dazu">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1716743934765" ID="ID_472100312" MODIFIED="1716767998222" TEXT="Policy OwningHeapAllocated re-implementieren auf Basis von StdFactory">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1716769724137" ID="ID_221563395" MODIFIED="1716822406633" TEXT="Problem: empty-base-optimisation greift nicht mehr">
|
||||
<arrowlink COLOR="#e7053e" DESTINATION="ID_1245762585" ENDARROW="Default" ENDINCLINATION="16;46;" ID="Arrow_ID_316103810" STARTARROW="None" STARTINCLINATION="-49;-3;"/>
|
||||
<icon BUILTIN="broken-line"/>
|
||||
<node CREATED="1716769752783" ID="ID_143245631" MODIFIED="1716769760514" TEXT="der Adapter hat ein Feld allocator_"/>
|
||||
<node CREATED="1716769776693" ID="ID_1419342319" MODIFIED="1716822425789">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
⟹ LinkedElements ist nicht mehr kongruent
|
||||
</p>
|
||||
<p>
|
||||
      mit einem einfachen Pointer
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</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 CREATED="1716822440964" ID="ID_214165023" MODIFIED="1716822473804" TEXT="StdFactory auf EBO umgestellt ⟹ funktioniert mit std::allocator"/>
|
||||
</node>
|
||||
<node CREATED="1716822489293" ID="ID_181197177" MODIFIED="1716822501360" TEXT="die spezielle Policy für AllocationCluster wird damit hinfällig"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1716683843917" ID="ID_157117808" MODIFIED="1716828259250" TEXT="Standard-Allocator für AllocationCluster bereitstellen">
|
||||
<linktarget COLOR="#404f66" DESTINATION="ID_157117808" ENDARROW="Default" ENDINCLINATION="1249;67;" ID="Arrow_ID_572544135" SOURCE="ID_1456163487" STARTARROW="None" STARTINCLINATION="131;-1027;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -81862,10 +81899,13 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
<node COLOR="#338800" CREATED="1715725787852" ID="ID_1127426666" MODIFIED="1715729452446" TEXT="neues einfacheres Interface einbauen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1715726296833" ID="ID_320488527" MODIFIED="1715726378902" TEXT="Problem: einzel-Allocator pro Typ">
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1715726296833" ID="ID_320488527" MODIFIED="1716828384070" TEXT="Problem: einzel-Allocator pro Typ">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1715726380325" ID="ID_810607124" MODIFIED="1715726397415" TEXT="führt zu hierarchischer Struktur"/>
|
||||
<node CREATED="1715726517963" ID="ID_1603078940" MODIFIED="1715726538868" TEXT="als nested class mit Zugang zu privaten Methoden"/>
|
||||
<node CREATED="1716828352153" ID="ID_1078249129" MODIFIED="1716828378896" TEXT="quer-Konstruierbarkeit als spezielle Erweierung für unsere StdFactory">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1715727163500" ID="ID_164792121" MODIFIED="1715727175958" TEXT="API">
|
||||
<node CREATED="1715727225764" ID="ID_123722889" MODIFIED="1715727230671" TEXT="getAllocator<TY>"/>
|
||||
|
|
@ -81877,22 +81917,22 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1715782501810" ID="ID_455348105" MODIFIED="1715782506785" TEXT="Verwendungen anpassen">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1715782508685" ID="ID_524633561" MODIFIED="1715782536584" TEXT="AllocationCluster selber muß weiterhin default-constructible sein">
|
||||
<node COLOR="#435e98" CREATED="1715782508685" ID="ID_524633561" MODIFIED="1716828337676" TEXT="AllocationCluster selber muß weiterhin default-constructible sein">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1715782580806" ID="ID_1223928211" MODIFIED="1715782592605" TEXT="tatsächliche Objekt-Erzeugungen nachvollziehen...">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<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 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 COLOR="#338800" CREATED="1715782790810" ID="ID_1391251855" MODIFIED="1716828317465" TEXT="linked-elements-test">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1715815439855" ID="ID_1456163487" MODIFIED="1716828291983" TEXT="LinkedElements umstellen auf Standard-konformen Allocator">
|
||||
<arrowlink COLOR="#404f66" DESTINATION="ID_157117808" ENDARROW="Default" ENDINCLINATION="1249;67;" ID="Arrow_ID_572544135" STARTARROW="None" STARTINCLINATION="131;-1027;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<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 COLOR="#338800" CREATED="1716684105741" ID="ID_1677827906" MODIFIED="1716828275075" TEXT="also: Ownership + gegebenen Standard-Allocator als Schnittstelle">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1715815513228" ID="ID_1909349257" MODIFIED="1715815549523" TEXT="die NoOwnership-Policy wird dann zu einem speziellen Allocator"/>
|
||||
|
|
@ -81944,8 +81984,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node CREATED="1715819206460" ID="ID_897739837" MODIFIED="1715819231318" TEXT="muß jedweils im aktuellen Block den Rest-Speicher feststellen können"/>
|
||||
<node CREATED="1715819263910" ID="ID_1512700101" MODIFIED="1715819291686" TEXT="soll idealerweise auch noch die Destructor-Closures mit unterbringen"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1715819352242" ID="ID_1754180627" MODIFIED="1715820238650" TEXT="Implementierung">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1715819352242" FOLDED="true" ID="ID_1754180627" MODIFIED="1716828681835" TEXT="Implementierung">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1715820246484" ID="ID_232038748" MODIFIED="1715820255249" TEXT="Idee / Skizze">
|
||||
<icon BUILTIN="idea"/>
|
||||
<node CREATED="1715819500198" ID="ID_210469417" MODIFIED="1715819513137" TEXT="ein Paar (next*, remaining_size)">
|
||||
|
|
@ -82121,7 +82161,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1716130730820" ID="ID_539013579" MODIFIED="1716130744964" TEXT="ich mache hier gefährliche Sachen">
|
||||
<icon BUILTIN="clanbomber"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1716130764415" ID="ID_966285930" MODIFIED="1716657861262" TEXT="explizit zu verifizieren">
|
||||
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1716130764415" ID="ID_966285930" MODIFIED="1716828421762" TEXT="explizit zu verifizieren">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node COLOR="#338800" CREATED="1716130773434" ID="ID_643589646" MODIFIED="1716657856744" TEXT="Destruktoren werden aufgerufen ⟹ Prüfsumme">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
|
|
@ -82133,6 +82173,26 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1716828422424" ID="ID_255250462" MODIFIED="1716828445335" TEXT="den gesamten Konstruktions / Destruktions-Ablauf im Debugger nachvollzogen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1716828448665" ID="ID_696174319" MODIFIED="1716828458676" TEXT="static-assertions für den Layout-Constraint">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1716828459932" HGAP="23" ID="ID_265585252" LINK="#ID_221563395" MODIFIED="1716828628769" TEXT="aus gutem Grund...." VSHIFT="2">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
beim Umbau der Policy für LinkedElements habe ich zunächst einen Adapter geschrieben, der den std::allocator schön sauber als Member hält — nur wird dadurch dann sizeof(LinkedElements) ≡ 2 »slots«. Und damit kippt der ganze Layout-Trick weg und der Destruktor läuft Amok.
|
||||
</p>
|
||||
<p>
|
||||
   <i>Lessions Learned</i>
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<font NAME="SansSerif" SIZE="11"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1716130832134" ID="ID_1783945506" MODIFIED="1716133346231" TEXT="hierfür einen friend-Test schaffen">
|
||||
<linktarget COLOR="#4173be" DESTINATION="ID_1783945506" ENDARROW="Default" ENDINCLINATION="204;17;" ID="Arrow_ID_1547348126" SOURCE="ID_253325898" STARTARROW="None" STARTINCLINATION="292;-22;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
|
|
@ -82141,7 +82201,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1715790315814" ID="ID_878890004" MODIFIED="1716659839834" TEXT="Lösung für die Destruktoren schaffen">
|
||||
<linktarget COLOR="#af578d" DESTINATION="ID_878890004" ENDARROW="Default" ENDINCLINATION="-446;33;" ID="Arrow_ID_464677545" SOURCE="ID_412040509" STARTARROW="None" STARTINCLINATION="-568;-24;"/>
|
||||
<linktarget COLOR="#57a3af" DESTINATION="ID_878890004" ENDARROW="Default" ENDINCLINATION="-446;33;" ID="Arrow_ID_464677545" SOURCE="ID_412040509" STARTARROW="None" STARTINCLINATION="-568;-24;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1715790397014" ID="ID_14966020" LINK="#ID_869337683" MODIFIED="1715790537195" TEXT="Ergebnis einer Konfliktlösung">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
|
|
@ -82547,7 +82607,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node CREATED="1715790137116" ID="ID_609184098" MODIFIED="1715790158047" TEXT="es wird explizit eine Registrierung für clean-up vorgesehen"/>
|
||||
<node CREATED="1715790158683" ID="ID_863625795" MODIFIED="1715790174701" TEXT="diese bleibt aber getrennt vom eigentlichen Allokations-Management"/>
|
||||
<node CREATED="1715790293402" ID="ID_412040509" MODIFIED="1715790393998" TEXT="sie wird per convenience-Shortcut an den Allocation-Cluster gebunden">
|
||||
<arrowlink COLOR="#af578d" DESTINATION="ID_878890004" ENDARROW="Default" ENDINCLINATION="-446;33;" ID="Arrow_ID_464677545" STARTARROW="None" STARTINCLINATION="-568;-24;"/>
|
||||
<arrowlink COLOR="#57a3af" DESTINATION="ID_878890004" ENDARROW="Default" ENDINCLINATION="-446;33;" ID="Arrow_ID_464677545" STARTARROW="None" STARTINCLINATION="-568;-24;"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue