Invocation: complete helper for chained inline tuples
- complete documentation - add extensive test coverage for use of the accessors - demonstrate a more contrieved example, including the dangers
This commit is contained in:
parent
e6403cbc7e
commit
fea2bfde7a
5 changed files with 252 additions and 67 deletions
|
|
@ -45,13 +45,13 @@
|
|||
** auto h1 = Front::build (1,2.3);
|
||||
** using Cons1 = Front::Chain<bool,string>;
|
||||
** auto b2 = Cons1::build (true, "Ψ");
|
||||
** b2.linkInto(c1);
|
||||
** b2.linkInto(h1);
|
||||
** auto& [d1,d2,d3,d4] = Cons1::recast(h1);
|
||||
** CHECK (d1 == 1);
|
||||
** CHECK (d2 == 2.3);
|
||||
** CHECK (d3 == true);
|
||||
** CHECK (d4 == "Ψ");
|
||||
** Cons1::Accessor<string> get4;
|
||||
** Cons1::AccessorFor<string> get4;
|
||||
** CHECK (get4(h1) == "Ψ");
|
||||
** \endcode
|
||||
**
|
||||
|
|
@ -69,17 +69,12 @@
|
|||
|
||||
|
||||
#include "lib/error.hpp"
|
||||
//#include "lib/symbol.hpp"
|
||||
#include "lib/nocopy.hpp"
|
||||
//#include "lib/linked-elements.hpp"
|
||||
#include "lib/meta/typelist.hpp"
|
||||
#include "lib/meta/typelist-manip.hpp"
|
||||
//#include "lib/meta/typelist-util.hpp"
|
||||
#include "lib/meta/typelist-util.hpp"
|
||||
#include "lib/meta/typeseq-util.hpp"
|
||||
#include "lib/test/test-helper.hpp"
|
||||
|
||||
//#include <algorithm>
|
||||
//#include <vector>
|
||||
#include <utility>
|
||||
#include <tuple>
|
||||
|
||||
|
|
@ -115,6 +110,9 @@ namespace lib {
|
|||
|
||||
template<typename SPEC>
|
||||
void linkInto (HeteroData<SPEC>&);
|
||||
|
||||
template<size_t slot> auto& get() noexcept { return std::get<slot>(*this); }
|
||||
template<typename X> auto& get() noexcept { return std::get<X>(*this); }
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -149,11 +147,26 @@ namespace lib {
|
|||
return * reinterpret_cast<_Tail*> (Frame::next);
|
||||
}
|
||||
|
||||
template<typename...SPEC>
|
||||
static _Self&
|
||||
recast (HeteroData<SPEC...>& frontChain)
|
||||
{
|
||||
return reinterpret_cast<_Self&> (frontChain);
|
||||
}
|
||||
template<typename...SPEC>
|
||||
static _Self const&
|
||||
recast (HeteroData<SPEC...> const& frontChain)
|
||||
{
|
||||
return reinterpret_cast<_Self const&> (frontChain);
|
||||
}
|
||||
|
||||
|
||||
template<typename...XX>
|
||||
friend class HeteroData; ///< allow chained types to use recursive type definitions
|
||||
|
||||
using Frame::Frame; ///< data elements shall be populated through the builder front-ends
|
||||
|
||||
|
||||
public:
|
||||
HeteroData() = default;
|
||||
|
||||
|
|
@ -163,9 +176,11 @@ namespace lib {
|
|||
return localSiz + _Tail::size();
|
||||
}
|
||||
|
||||
/** access type to reside in the given slot of the _complete chain_ */
|
||||
template<size_t slot>
|
||||
using Elm_t = typename PickType<slot>::type;
|
||||
|
||||
|
||||
/** access data elements within _complete chain_ by index pos */
|
||||
template<size_t slot>
|
||||
Elm_t<slot>&
|
||||
|
|
@ -185,48 +200,68 @@ namespace lib {
|
|||
return const_cast<HeteroData*>(this)->get<slot>();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Accessor-functor to get at the data residing within some tuple element
|
||||
* Using the enclosing typed scope to ensure safe storage access
|
||||
* @tparam slot numer of the data element, counting from zero over the full chain
|
||||
* @note this functor holds no data, but shall be applied to some existing HeteroData.
|
||||
*/
|
||||
template<size_t slot>
|
||||
struct Accessor
|
||||
{
|
||||
using Type = Elm_t<slot>;
|
||||
|
||||
template<class SPEC>
|
||||
Type&
|
||||
static Type&
|
||||
get (HeteroData<SPEC>& frontEnd)
|
||||
{
|
||||
auto& fullChain = reinterpret_cast<_Self&> (frontEnd);
|
||||
auto& fullChain = _Self::recast (frontEnd);
|
||||
return fullChain.template get<slot>();
|
||||
}
|
||||
|
||||
template<typename HH>
|
||||
Type& operator() (HH& frontEnd) const { return Accessor::get(frontEnd); }
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor-functor to build an extra data segment, which can then be linked to the chain.
|
||||
* @tparam VALS data types to use in the extra storage tuple
|
||||
* @note Using this functor is the only safe path to create and add new data blocks.
|
||||
* Each such data block can be linked in once, and only if the base chain matches
|
||||
* the structure embedded into the type of the enclosing scope.
|
||||
* - storage frames can be default constructed, but not copied / moved thereafter
|
||||
* - the #build() function can be used to create the block and init the data
|
||||
* - after creating a frame, it must be explicitly linked in by invoking NewFrame::linkInto()
|
||||
* - the #recast() function will re-interpret _any_ `HeteroData&` into the storage structure
|
||||
* which can be expected after building the extension frame (use with care!)
|
||||
* - the nested template ChainExtent is a follow-up constructor-functor to add a further block
|
||||
* - the nested template Accessor shall be used for any type-save access to data values
|
||||
* - if all types are distinct, the Accessor can also be selected by-type
|
||||
*/
|
||||
template<typename...VALS>
|
||||
struct Chain
|
||||
{
|
||||
using NewFrame = StorageFrame<seg+1, VALS...>;
|
||||
using ChainType = HeteroData<typename meta::Append<meta::Node<Frame,TAIL>,NewFrame>::List>;
|
||||
|
||||
using Segments = meta::Node<Frame,TAIL>; // ◁———this type describes current chain structure
|
||||
using NewFrame = StorageFrame<meta::count<Segments>::value, VALS...>;
|
||||
using ChainType = HeteroData<typename meta::Append<Segments,NewFrame>::List>;
|
||||
// ...and this would be the extended chain structure
|
||||
template<typename...INIT>
|
||||
static NewFrame
|
||||
build (INIT&& ...initArgs)
|
||||
{
|
||||
return {initArgs ...};
|
||||
return {initArgs ...}; // Note: NewFrame is non-copyable
|
||||
}
|
||||
|
||||
template<typename...SPEC>
|
||||
static ChainType&
|
||||
recast (HeteroData<SPEC...>& frontChain)
|
||||
template<class HET>
|
||||
static auto&
|
||||
recast (HET& frontChain)
|
||||
{
|
||||
return reinterpret_cast<ChainType&> (frontChain);
|
||||
}
|
||||
template<typename...SPEC>
|
||||
static ChainType&
|
||||
recast (HeteroData<SPEC...> const& frontChain)
|
||||
{
|
||||
return reinterpret_cast<ChainType const&> (frontChain);
|
||||
return ChainType::recast (frontChain);
|
||||
}
|
||||
|
||||
template<typename...XVALS>
|
||||
using ChainExtension = typename ChainType::template Chain<XVALS...>;
|
||||
using ChainExtent = typename ChainType::template Chain<XVALS...>;
|
||||
|
||||
template<size_t slot>
|
||||
using Accessor = typename ChainType::template Accessor<_Self::size()+slot>;
|
||||
|
|
@ -306,7 +341,7 @@ namespace lib {
|
|||
, segments);
|
||||
return last->next;
|
||||
}
|
||||
}
|
||||
}//(End)helper
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1367 : Rebuild the Node Invocation
|
||||
#include "lib/nocopy.hpp"
|
||||
#include "lib/time/timevalue.hpp"
|
||||
#include "lib/hetero-data.hpp"
|
||||
|
||||
|
||||
namespace steam {
|
||||
|
|
|
|||
|
|
@ -434,7 +434,7 @@ return: 0
|
|||
END
|
||||
|
||||
|
||||
PLANNED "Heterogeneous data in local storage" HeteroData_test <<END
|
||||
TEST "Heterogeneous data in local storage" HeteroData_test <<END
|
||||
return: 0
|
||||
END
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,8 @@
|
|||
#include "lib/test/run.hpp"
|
||||
#include "lib/hetero-data.hpp"
|
||||
#include "lib/meta/trait.hpp"
|
||||
#include "lib/test/diagnostic-output.hpp"/////////////////TODO
|
||||
#include "lib/test/test-helper.hpp"
|
||||
#include "lib/uninitialised-storage.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
#include <string>
|
||||
|
|
@ -31,15 +32,20 @@ namespace test{
|
|||
using std::string;
|
||||
using meta::is_Subclass;
|
||||
using util::isSameObject;
|
||||
using util::isSameAdr;
|
||||
using util::getAdr;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*************************************************************//**
|
||||
/******************************************************************//**
|
||||
* @test maintain a sequence of data tuples in local storage,
|
||||
* providing pre-configured type-safe data access.
|
||||
*
|
||||
* - the initial block is just a tuple of data in local storage
|
||||
* - but further extension segments can be created _elsewhere_
|
||||
* and attached to an existing chain
|
||||
* - a compile-time »overlay« of constructor- and accessor-functors
|
||||
* is provided as _guard rails_ to prevent out-of bounds access.
|
||||
* @see lib::HeteroData
|
||||
* @see NodeBase_test::verify_TurnoutSystem()
|
||||
*/
|
||||
|
|
@ -49,9 +55,23 @@ namespace test{
|
|||
virtual void
|
||||
run (Arg)
|
||||
{
|
||||
simpleUsage();
|
||||
verify_FrontBlock();
|
||||
verify_ChainBlock();
|
||||
// verify_Accessors();
|
||||
verify_Accessors();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
simpleUsage()
|
||||
{
|
||||
using F = lib::HeteroData<uint,double>; // define type of the front-end segment
|
||||
auto h1 = F::build (1,2.3); // build the front-end, including first data tuple
|
||||
using C = F::Chain<bool,string>; // define a constructor type for a follow-up segment
|
||||
auto b2 = C::build (true, "Ψ"); // build this follow-up segment free-standing
|
||||
b2.linkInto(h1); // link it as second segment into the chain
|
||||
C::AccessorFor<string> get4; // get an accessor functor (picked by value type)
|
||||
CHECK (get4(h1) == "Ψ"); // use accessor on front-type (involves force-cast)
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -152,6 +172,140 @@ namespace test{
|
|||
// auto& [z0,z1,z2,z3] = chain2; // Error: 4 names provided for structured binding, while HeteroData... decomposes into 3 elements
|
||||
// auto& [z0,z1,z2] = b1; // Error: HeteroData<Node<StorageFrame<0, uint>, NullType> >' decomposes into 1 element
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** @test demonstrate elaborate storage layout with several chain frames
|
||||
* - follow-up frames shall be built using constructor types
|
||||
* - these can be defined prior to any data allocation
|
||||
* - individual data elements can be accessed type-safe through accessor functors
|
||||
* @warning as demonstrated, this is a dangerous bare-bone memory layout without runtime checks!
|
||||
*/
|
||||
void
|
||||
verify_Accessors()
|
||||
{
|
||||
using Front = lib::HeteroData<uint,double>;
|
||||
using Cons2 = Front::Chain<bool,string>;
|
||||
using Data2 = Cons2::NewFrame;
|
||||
using List2 = Cons2::ChainType;
|
||||
using Acc4 = Cons2::AccessorFor<string>;
|
||||
using Acc3 = Cons2::AccessorFor<bool>;
|
||||
using Acc2 = Front::Accessor<1>;
|
||||
using Acc1 = Front::Accessor<0>;
|
||||
using Cons3 = Cons2::ChainExtent<CStr,string>;
|
||||
using Data3 = Cons3::NewFrame;
|
||||
using List3 = Cons3::ChainType;
|
||||
using Acc5 = Cons3::AccessorFor<CStr>;
|
||||
using Acc6 = Cons3::AccessorFor<string>;
|
||||
CHECK (2 == Front::size());
|
||||
CHECK (4 == List2::size());
|
||||
CHECK (6 == List3::size());
|
||||
//
|
||||
// Note: up to now, not a single actual data element has been created
|
||||
// Moreover, individual blocks can be created in any order...
|
||||
Data2 d2;
|
||||
d2.get<1>() = "Ψ";
|
||||
Front front;
|
||||
CHECK (front.get<1>() == 0.0);
|
||||
front.get<1>() = 2.3;
|
||||
|
||||
// Note the pitfall: Chain has not been connected yet,
|
||||
// but the Accessors would assume otherwise
|
||||
CHECK (Acc2::get(front) == 2.3);
|
||||
// Acc3::get(front); // would cause NPE (or assertion failure on debug build)
|
||||
|
||||
Acc4 get4; // could even instantiate the accessors...
|
||||
CHECK (sizeof(get4) == 1); // (empty marker object with static methods)
|
||||
// get4(front); // likewise NPE or assertion fail
|
||||
|
||||
// Now link the second data element in properly
|
||||
d2.linkInto(front);
|
||||
CHECK (Acc1::get(front) == 0);
|
||||
CHECK (Acc2::get(front) == 2.3);
|
||||
CHECK (Acc3::get(front) == false);
|
||||
CHECK (get4(front) == "Ψ");
|
||||
|
||||
// further allocations can even be »elsewhere«
|
||||
const void* loc;
|
||||
{
|
||||
Acc6 get6;
|
||||
auto magic = Cons3::build("magic","cloud");
|
||||
loc = getAdr(magic);
|
||||
CHECK (magic.get<0>() == "magic"_expect);
|
||||
CHECK (magic.get<1>() == "cloud"_expect);
|
||||
// link into the cloud...
|
||||
magic.linkInto(front);
|
||||
CHECK (get6(front) == "cloud");
|
||||
}// aaand...
|
||||
// it's gone
|
||||
|
||||
// Evil, evil...
|
||||
lib::UninitialisedStorage<Data3, 1> evilSpace;
|
||||
Data3& d3 = evilSpace[0]; // note: working with left-over data from expired stack frame
|
||||
CHECK (isSameAdr (d3, loc));
|
||||
CHECK (d3.get<0>() == "magic"_expect); // const char* points into static data, so the chars are still there
|
||||
new(&d3.get<1>()) string{"mushrooms"}; // the "cloud"-string was destroyed by magic's destructor
|
||||
|
||||
auto& [v1,v2,v3,v4,v5,v6] = Cons3::recast(front); // using connectivity from the linked list connecting the segments
|
||||
CHECK (v1 == "0"_expect);
|
||||
CHECK (v2 == "2.3"_expect);
|
||||
CHECK (v3 == "false"_expect);
|
||||
CHECK (v4 == "Ψ"_expect);
|
||||
CHECK (v5 == "magic"_expect);
|
||||
CHECK (v6 == "mushrooms"_expect);
|
||||
|
||||
v1 = 42;
|
||||
v2 = 5.5;
|
||||
v3 = true;
|
||||
CHECK (front.get<0>() == 42);
|
||||
CHECK (front.get<1>() == 5.5);
|
||||
CHECK (d2.get<0>() == true);
|
||||
CHECK (d2.get<1>() == "Ψ");
|
||||
|
||||
CHECK (isSameAdr (Acc1::get(front), v1));
|
||||
CHECK (isSameAdr (Acc2::get(front), v2));
|
||||
CHECK (isSameAdr (Acc3::get(front), v3));
|
||||
CHECK (isSameAdr (Acc4::get(front), v4));
|
||||
CHECK (isSameAdr (Acc5::get(front), v5));
|
||||
CHECK (isSameAdr (Acc6::get(front), v6));
|
||||
|
||||
CHECK (not isSameAdr (front, v1));
|
||||
CHECK (not isSameAdr (d2, v3));
|
||||
CHECK (not isSameAdr (d3, v5));
|
||||
// we can directly re-cast into another typed front-end
|
||||
List3& fullChain = Cons3::recast(front);
|
||||
CHECK (isSameAdr (fullChain.get<2>(), std::get<0>(d2)));
|
||||
CHECK (isSameAdr (fullChain.get<3>(), std::get<1>(d2)));
|
||||
CHECK (isSameAdr (fullChain.get<4>(), std::get<0>(d3)));
|
||||
CHECK (isSameAdr (fullChain.get<5>(), std::get<1>(d3)));
|
||||
CHECK (isSameAdr (fullChain.get<0>(), v1));
|
||||
CHECK (isSameAdr (fullChain.get<1>(), v2));
|
||||
CHECK (isSameAdr (fullChain.get<2>(), v3));
|
||||
CHECK (isSameAdr (fullChain.get<3>(), v4));
|
||||
CHECK (isSameAdr (fullChain.get<4>(), v5));
|
||||
CHECK (isSameAdr (fullChain.get<5>(), v6));
|
||||
// we can even use partially specified chains
|
||||
List2& partChain = Cons2::recast(fullChain);
|
||||
CHECK (isSameAdr (partChain.get<0>(), v1));
|
||||
CHECK (isSameAdr (partChain.get<1>(), v2));
|
||||
CHECK (isSameAdr (partChain.get<2>(), v3));
|
||||
CHECK (isSameAdr (partChain.get<3>(), v4));
|
||||
|
||||
// Note: basically we are still using stale memory,
|
||||
// previously allocated to the "magic" block,
|
||||
// and now covered by the UninitialisedStorage
|
||||
CHECK (loc == & d3);
|
||||
CHECK (loc < & v5);
|
||||
CHECK (loc < & v6);
|
||||
|
||||
// structural binding on partial chains is limited
|
||||
CHECK (partChain.size() == 4);
|
||||
auto& [w1,w2,w3,w4] = partChain;
|
||||
CHECK (isSameObject (v1, w1));
|
||||
CHECK (isSameObject (v2, w2));
|
||||
CHECK (isSameObject (v3, w3));
|
||||
CHECK (isSameObject (v4, w4));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -87263,8 +87263,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1733611147207" ID="ID_867806700" MODIFIED="1733611155184" TEXT="Entwurf: Belegung der Slots">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1733611147207" ID="ID_867806700" MODIFIED="1734042089166" TEXT="Entwurf: Belegung der Slots">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node CREATED="1733611235157" ID="ID_1373022274" MODIFIED="1733611269549" TEXT="Abstraktes Ablauf-Schema">
|
||||
<icon BUILTIN="info"/>
|
||||
<node CREATED="1733611321861" ID="ID_1648703683" MODIFIED="1733615415248">
|
||||
|
|
@ -87586,7 +87586,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1733590902929" ID="ID_1045639317" MODIFIED="1733868511337" TEXT="Implementierung overflow-Buckets">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node CREATED="1733765037437" ID="ID_1724101101" MODIFIED="1733765062311" TEXT="unterstützte Interaktionen">
|
||||
<node BACKGROUND_COLOR="#c8c0b6" CREATED="1733765037437" ID="ID_1724101101" MODIFIED="1734041962487" TEXT="unterstützte Interaktionen">
|
||||
<node CREATED="1733765068881" ID="ID_523511672" MODIFIED="1733765084522" TEXT="ein default TurnoutSystem mit Grund-Ausstattung"/>
|
||||
<node CREATED="1733765092674" ID="ID_1865816766" MODIFIED="1733765118024">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
|
|
@ -87612,9 +87612,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1733766910569" ID="ID_462136727" MODIFIED="1734020495134" TEXT="⟹ gebraucht wird">
|
||||
<node BACKGROUND_COLOR="#c8c0b6" CREATED="1733766910569" ID="ID_462136727" MODIFIED="1734041957415" TEXT="⟹ gebraucht wird">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node COLOR="#435e98" CREATED="1733766926415" ID="ID_1686613162" MODIFIED="1734020490977" TEXT="Library für heterogene verknüpfte Storage-Blöcke">
|
||||
<node COLOR="#435e98" CREATED="1733766926415" FOLDED="true" ID="ID_1686613162" MODIFIED="1734041954497" TEXT="Library für heterogene verknüpfte Storage-Blöcke">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node COLOR="#338800" CREATED="1733767199547" ID="ID_22701741" MODIFIED="1733868478977" TEXT="Template HeteroData">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
|
|
@ -87623,12 +87623,12 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1733766989087" ID="ID_1930665408" MODIFIED="1734020488102" TEXT="typsicheres compiletime-Overlay für diese">
|
||||
<node COLOR="#435e98" CREATED="1733766989087" FOLDED="true" ID="ID_1930665408" MODIFIED="1734020488102" TEXT="typsicheres compiletime-Overlay für diese">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1733767103376" ID="ID_36453586" MODIFIED="1733928886422" TEXT="verkettete factory-Funktionen für einzelne Storage-Blöcke"/>
|
||||
<node CREATED="1733767025290" ID="ID_741129447" MODIFIED="1733928908892" TEXT="daraus sind Accessoren für typsicheren Zugriff erzeugbar"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1733767147610" ID="ID_966052237" MODIFIED="1733868469882" TEXT="Zugriff auf einzelne Datenwerte per Accessor">
|
||||
<node COLOR="#435e98" CREATED="1733767147610" FOLDED="true" ID="ID_966052237" MODIFIED="1734041952890" TEXT="Zugriff auf einzelne Datenwerte per Accessor">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1733794253049" ID="ID_524032108" MODIFIED="1733794287860" TEXT="Grundlage: das C++ - Tuple-Protocol implementieren">
|
||||
<icon BUILTIN="idea"/>
|
||||
|
|
@ -87655,9 +87655,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1733799750738" ID="ID_532258033" MODIFIED="1733799768652" TEXT="Implementierung ausarbeiten">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1733804423613" ID="ID_1306152229" MODIFIED="1733882827467" TEXT="Zugriff">
|
||||
<node COLOR="#338800" CREATED="1733799750738" ID="ID_532258033" MODIFIED="1734041922506" TEXT="Implementierung ausarbeiten">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1733804423613" FOLDED="true" ID="ID_1306152229" MODIFIED="1733882827467" TEXT="Zugriff">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1733804463800" ID="ID_1686530886" MODIFIED="1733804491599" TEXT="definiere den Datentyp rekursiv">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
|
|
@ -87758,7 +87758,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1733804575033" ID="ID_374529337" MODIFIED="1734020509491" TEXT="Konstruktur">
|
||||
<node COLOR="#338800" CREATED="1733804575033" FOLDED="true" ID="ID_374529337" MODIFIED="1734020509491" TEXT="Konstruktur">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1733804582990" FOLDED="true" ID="ID_234262358" MODIFIED="1734020457462" TEXT="puh ... komplex">
|
||||
<icon BUILTIN="smily_bad"/>
|
||||
|
|
@ -88175,7 +88175,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1733946409913" ID="ID_766490392" MODIFIED="1734020338263" TEXT="C++ »Tuple-Protocol«">
|
||||
<node COLOR="#338800" CREATED="1733946409913" FOLDED="true" ID="ID_766490392" MODIFIED="1734041937846" TEXT="C++ »Tuple-Protocol«">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1733946436854" ID="ID_1279626510" LINK="https://en.cppreference.com/w/cpp/utility/tuple/tuple-like" MODIFIED="1733946454891" TEXT="exposition-only concept »tuple-like«"/>
|
||||
<node CREATED="1733946456354" ID="ID_1814813251" MODIFIED="1733946486589">
|
||||
|
|
@ -88232,8 +88232,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
heißt auch, man kann hier nicht mit SFINAE arbeiten — und exakt das hat sich am Ende auch als das Problem herausgestellt, die Compilation scheitert bevor unser Code überhaupt eingreifen kann
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#f6e2a1" COLOR="#990000" CREATED="1733960761558" ID="ID_1977939692" MODIFIED="1734020032462" TEXT="trotzdem verstehe ich das Problem nicht.....">
|
||||
<icon BUILTIN="forward"/>
|
||||
|
|
@ -88321,8 +88320,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
 ⟹ Fehler im Test-Setup reproduzierbar
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="idea"/>
|
||||
<node CREATED="1733977452943" ID="ID_1506713776" MODIFIED="1733977494203" TEXT="die Assertion-Failure kommt aus tuple_element_t<I,tuple>">
|
||||
<icon BUILTIN="info"/>
|
||||
|
|
@ -88411,8 +88409,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
damit funktionieren die <b>structured bindings</b>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#304e65" CREATED="1734017114737" ID="ID_1154017972" MODIFIED="1734017708318" TEXT="diese gehen nämlich noch über das »tuple-protocol« hinaus">
|
||||
|
|
@ -88429,16 +88426,16 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1733883489383" ID="ID_155186903" MODIFIED="1733883516460" TEXT="HeteroData_test">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1733883489383" FOLDED="true" ID="ID_155186903" MODIFIED="1734041986220" TEXT="HeteroData_test">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1733883525530" ID="ID_1918349528" MODIFIED="1734025619302" TEXT="verify_FrontBlock">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#435e98" CREATED="1733883562026" ID="ID_941439456" MODIFIED="1733883584764" TEXT="Datenblock erstellen"/>
|
||||
<node COLOR="#435e98" CREATED="1733883567253" ID="ID_252468938" MODIFIED="1733883584764" TEXT="Datenzugriff zeigen"/>
|
||||
<node COLOR="#435e98" CREATED="1733883572964" ID="ID_1308768158" MODIFIED="1734025607198" TEXT="structural binding / Tuple-Protokoll"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1733883536343" ID="ID_877333475" MODIFIED="1733883538992" TEXT="verify_ChainBlock">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1733883536343" ID="ID_877333475" MODIFIED="1734041976272" TEXT="verify_ChainBlock">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#435e98" CREATED="1733883589092" ID="ID_1386279261" MODIFIED="1733883643827" TEXT="erst die Typen konstruieren"/>
|
||||
<node COLOR="#435e98" CREATED="1733883604891" ID="ID_1254661884" MODIFIED="1733883643827" TEXT="Front-Block erstellen und populieren"/>
|
||||
<node COLOR="#435e98" CREATED="1733883616620" ID="ID_1790631124" MODIFIED="1733883643827" TEXT="Chain-Block erstellen und populieren"/>
|
||||
|
|
@ -88446,19 +88443,18 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<linktarget COLOR="#65a6c0" DESTINATION="ID_1607678238" ENDARROW="Default" ENDINCLINATION="189;-12;" ID="Arrow_ID_842453741" SOURCE="ID_1554305818" STARTARROW="None" STARTINCLINATION="-3;109;"/>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1733883629524" ID="ID_88656707" MODIFIED="1733883643826" TEXT="gemeinsamen Datenzugriff direkt zeigen"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1733883922133" ID="ID_745130175" MODIFIED="1733883969468" TEXT="Zugriff per Typ demonstrieren">
|
||||
<linktarget COLOR="#678f9e" DESTINATION="ID_745130175" ENDARROW="Default" ENDINCLINATION="1747;-43;" ID="Arrow_ID_1832059516" SOURCE="ID_1704921041" STARTARROW="None" STARTINCLINATION="55;794;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1733883572964" ID="ID_1694822636" MODIFIED="1734025615096" TEXT="structural binding / Tuple-Protokoll"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1733883656600" ID="ID_972149921" MODIFIED="1733883808249" TEXT="verify_Accessors">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1733883663184" ID="ID_1127481242" MODIFIED="1733883674938" TEXT="hier nun mit mehreren Datenblöcken arbeiten"/>
|
||||
<node CREATED="1733883682093" ID="ID_531287492" MODIFIED="1733883721468" TEXT="Zugriffe via Accessor ohne sichtbaren Cast"/>
|
||||
<node CREATED="1733883747133" ID="ID_276517152" MODIFIED="1733883759060" TEXT="structural Binding mit allen Einschränkungen demonstrieren"/>
|
||||
<node CREATED="1733883781976" ID="ID_1919391319" MODIFIED="1733883795270" TEXT="Speicher-Adressen verifizieren"/>
|
||||
<node CREATED="1733883796910" ID="ID_1268320323" MODIFIED="1733883805336" TEXT="Grenzen / Gefahren / Manipulation zeigen"/>
|
||||
<node COLOR="#338800" CREATED="1733883656600" ID="ID_972149921" MODIFIED="1734041984704" TEXT="verify_Accessors">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#435e98" CREATED="1733883663184" ID="ID_1127481242" MODIFIED="1734040977954" TEXT="hier nun mit mehreren Datenblöcken arbeiten"/>
|
||||
<node COLOR="#435e98" CREATED="1733883682093" ID="ID_531287492" MODIFIED="1734040977954" TEXT="Zugriffe via Accessor ohne sichtbaren Cast"/>
|
||||
<node COLOR="#435e98" CREATED="1733883922133" ID="ID_745130175" MODIFIED="1734029997277" TEXT="Zugriff per Typ demonstrieren">
|
||||
<linktarget COLOR="#678f9e" DESTINATION="ID_745130175" ENDARROW="Default" ENDINCLINATION="1747;-43;" ID="Arrow_ID_1832059516" SOURCE="ID_1704921041" STARTARROW="None" STARTINCLINATION="55;794;"/>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1733883747133" ID="ID_276517152" MODIFIED="1734040982353" TEXT="structural Binding mit allen Einschränkungen demonstrieren"/>
|
||||
<node COLOR="#435e98" CREATED="1733883781976" ID="ID_1919391319" MODIFIED="1734040982354" TEXT="Speicher-Adressen verifizieren"/>
|
||||
<node COLOR="#435e98" CREATED="1733883796910" ID="ID_1268320323" MODIFIED="1734040982353" TEXT="Grenzen / Gefahren / Manipulation zeigen"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1733767161520" ID="ID_1853669534" MODIFIED="1733767188150" TEXT="Standard-Definition für TurnoutSystem auf dieser Basis">
|
||||
|
|
@ -142890,8 +142886,7 @@ std::cout << tmpl.render({"what", "World"}) << s
|
|||
es genügt daß die Member unter dem Namen direkt zugreifbar sind; sie müssen auch in der gleichen Struct liegen (die aber durchaus eine Basisklasse sein kann). Bit-Felder werden unterstützt, Union-Member jedoch nicht
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1733950233731" ID="ID_609631801" LINK="https://devblogs.microsoft.com/oldnewthing/20201015-00/?p=104369" MODIFIED="1733950498051" TEXT="How to add structured binding support to your own types">
|
||||
|
|
|
|||
Loading…
Reference in a new issue