Library: investigate copy behaviour in forwarding calls
This commit is contained in:
parent
5191073558
commit
e28635a11a
4 changed files with 333 additions and 10 deletions
|
|
@ -50,7 +50,7 @@
|
|||
** from a factory or configuration function <i>by value</i> would open a lot of
|
||||
** straight forward design possibilities and concise formulations.
|
||||
**
|
||||
** \par how to build a copyable value without knowing it's layout in detail
|
||||
** # how to build a copyable value without knowing it's layout in detail
|
||||
**
|
||||
** So the goal is to build a copyable and assignable type with value semantics,
|
||||
** without disclosing the actual implementation and object layout at the usage site.
|
||||
|
|
@ -107,6 +107,16 @@
|
|||
** the "implementation type" specified by the client. Thus, within the
|
||||
** context of the copy operation, we know all the concrete types.
|
||||
**
|
||||
** @todo the actual implementation for copy support basically achieves this goal,
|
||||
** but it is somewhat confusing and muddled, and not entirely correct in some
|
||||
** corner cases (esp. when the target type does _not collaborate_ but also
|
||||
** does _only support copy construction_, but no assignment.
|
||||
** In fact, part of the solution implemented here is known as "virtual copy
|
||||
** support"; meanwhile we use a generic version of that pattern in our
|
||||
** [Variant container](\ref variant.hpp). Thus, at some point, we should
|
||||
** rework this aspect of the solution to make it more orthogonal, clearer
|
||||
** to understand and more correct. /////////////////////////////////////////////TICKET #1197
|
||||
**
|
||||
**
|
||||
** # using polymorphic value objects
|
||||
**
|
||||
|
|
@ -209,7 +219,7 @@ namespace lib {
|
|||
virtual ~CloneValueSupport() { };
|
||||
virtual void cloneInto (void* targetBuffer) const =0;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////TICKET #1197 : this should be a full "virtual copy support" to cover all possible cases
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -285,11 +295,12 @@ namespace lib {
|
|||
* In this case, the CopySupport interface is mixed in at the
|
||||
* level of the concrete implementation class and later on
|
||||
* accessed through a \c dynamic_cast
|
||||
* @todo this whole decision logic works but is confusingly written ///////////////////////TICKET #1197 : improve design of copy support
|
||||
*/
|
||||
template <class TY, class YES = void>
|
||||
struct Trait
|
||||
{
|
||||
typedef CopySupport<TY,EmptyBase> CopyAPI;
|
||||
typedef CopySupport<TY,EmptyBase> CopyAPI; ///////////////////////////TICKET #1197 : this is naive, we do not know if the target really has full copy support...
|
||||
enum{ ADMIN_OVERHEAD = 2 * sizeof(void*) };
|
||||
|
||||
static CopyAPI&
|
||||
|
|
@ -365,7 +376,7 @@ namespace lib {
|
|||
|
||||
typedef polyvalue::Trait<CPY> _Traits;
|
||||
typedef typename _Traits::CopyAPI _CopyHandlingAdapter;
|
||||
typedef typename _Traits::Assignment _AssignmentPolicy;
|
||||
typedef typename _Traits::Assignment _AssignmentPolicy; /////////////////TICKET #1197 : confusingly indirect decision logic
|
||||
enum{
|
||||
siz = storage + _Traits::ADMIN_OVERHEAD
|
||||
};
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ namespace lib {
|
|||
|
||||
template<class REC, class RET>
|
||||
struct VerbInvoker
|
||||
: polyvalue::CloneValueSupport<polyvalue::EmptyBase> // mark and mix-in virtual copy construction support
|
||||
{
|
||||
virtual ~VerbInvoker() { }
|
||||
|
||||
|
|
@ -85,8 +86,7 @@ namespace lib {
|
|||
|
||||
template<class REC, class RET, typename... ARGS>
|
||||
struct Holder<REC, RET(ARGS...)>
|
||||
: polyvalue::CopySupport< // mix-in virtual copy/move support
|
||||
VerbInvoker<REC,RET>> // ...the common interface to use
|
||||
: VerbInvoker<REC,RET>
|
||||
{
|
||||
using Verb = VerbToken<REC,RET(ARGS...)>;
|
||||
using Args = std::tuple<ARGS...>;
|
||||
|
|
|
|||
|
|
@ -43,6 +43,39 @@ using std::vector;
|
|||
|
||||
namespace lib {
|
||||
namespace test{
|
||||
///////////////////////////TODO : Debugging
|
||||
struct Trackr
|
||||
{
|
||||
size_t num;
|
||||
|
||||
Trackr (size_t val)
|
||||
: num(val)
|
||||
{
|
||||
cout <<"Trackr("<<val<<")"<<endl;
|
||||
}
|
||||
~Trackr()
|
||||
{
|
||||
cout <<"~Trackr()"<<endl;
|
||||
}
|
||||
Trackr (Trackr const& lval)
|
||||
: num(lval.num)
|
||||
{
|
||||
cout <<"Trackr()<<-LVal"<<endl;
|
||||
}
|
||||
Trackr (Trackr && rval)
|
||||
: num(rval.num)
|
||||
{
|
||||
cout <<"Trackr()<<-RVal"<<endl;
|
||||
}
|
||||
Trackr&
|
||||
operator= (Trackr const& orig)
|
||||
{
|
||||
cout <<"Tracker = orig"<<endl;
|
||||
num = orig.num;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
///////////////////////////TODO : Debugging
|
||||
|
||||
|
||||
class Receiver
|
||||
|
|
@ -52,7 +85,7 @@ namespace test{
|
|||
|
||||
virtual string woof (bool huge, uint cnt) =0;
|
||||
virtual string honk (string) =0;
|
||||
virtual string moo (size_t num) =0;
|
||||
virtual string moo (Trackr num) =0;
|
||||
virtual string meh () =0;
|
||||
};
|
||||
|
||||
|
|
@ -83,9 +116,9 @@ namespace test{
|
|||
return theHonk+"-"+theHonk+"!";
|
||||
}
|
||||
string
|
||||
moo (size_t num) override
|
||||
moo (Trackr num) override
|
||||
{
|
||||
return join (vector<string>{num, "Moo"}, "__");
|
||||
return join (vector<string>{num.num, "Moo"}, "__");
|
||||
}
|
||||
string
|
||||
meh() override
|
||||
|
|
@ -145,7 +178,7 @@ namespace test{
|
|||
Token littleWoof(&Receiver::woof, "woof", false, 3u);
|
||||
Token quack(&Receiver::honk, "honk", string{"quaack"});
|
||||
Token honk(&Receiver::honk, "honk", string{"Hoonk"});
|
||||
Token moo(&Receiver::moo, "moo", size_t(3));
|
||||
Token moo(&Receiver::moo, "moo", Trackr(3));
|
||||
Token meh(&Receiver::meh, "meh");
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -19681,6 +19681,285 @@
|
|||
<node CREATED="1555247744121" ID="ID_1280520595" MODIFIED="1555247751428" TEXT="ausgehend von Kopie des VerbToken"/>
|
||||
<node CREATED="1555247757037" ID="ID_1249615365" MODIFIED="1555247774360" TEXT="(optional) vielleicht letztlich in eine Lösung verschmelzen?"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1555806526685" ID="ID_192016641" MODIFIED="1555806690486" TEXT="Lösungsansatz: PolymorphicValue">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node CREATED="1555806541914" ID="ID_1260020116" MODIFIED="1555806660375" TEXT="der bietet genau den flexiblen inline-Buffer, den ich hier brauche">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
nämlich mit minimalem Admin-Overhead,
|
||||
</p>
|
||||
<p>
|
||||
indem er sich auf die VTable des einzubettenden Typs abstützt.
|
||||
</p>
|
||||
<p>
|
||||
|
||||
</p>
|
||||
<p>
|
||||
Die andere Alternative, der OpaqueHolder, verwendet selber nochmal einen zustäzlichen virtuellen Holder,
|
||||
</p>
|
||||
<p>
|
||||
und Variant paßt auch nicht, da ich ja mit Template-generierten Subklassen arbeite,
|
||||
</p>
|
||||
<p>
|
||||
und daher nicht a priori die Liste aller einzubettenden Varianten kenne
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1555806670026" ID="ID_604641822" MODIFIED="1555806695925" TEXT="Probleme bei der Umsetzung">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1555807073875" ID="ID_1971528084" MODIFIED="1555807225299" TEXT="std::apply verwenden">
|
||||
<icon BUILTIN="stop-sign"/>
|
||||
<node CREATED="1555807086938" ID="ID_354296634" MODIFIED="1555807098052" TEXT="gitbts noch nicht auf Debian-Stretch"/>
|
||||
<node CREATED="1555807099280" ID="ID_1984270952" MODIFIED="1555807109994" TEXT="nachprogrammieren / extrahieren...?"/>
|
||||
<node CREATED="1555807110911" ID="ID_1729201379" MODIFIED="1555807230565" TEXT="Ist auch nicht ohne Weiteres anwendbar auf den vorliegenden Fall">
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
<node CREATED="1555807137136" ID="ID_1357571620" MODIFIED="1555807171527" TEXT="wir haben ein zusätzliches erstes Argument">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
nämlich hier der Visitor, der den Aufruf letztlich emfpängt
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1555807172534" ID="ID_473316032" MODIFIED="1555807180977" TEXT="das müßte man dann in das Tupel reinfrickeln"/>
|
||||
<node CREATED="1555807181534" ID="ID_484250647" MODIFIED="1555807202821" TEXT="und dann auch noch den double-Dispatcher (hier das VerbToken) in einen Funktor wickeln"/>
|
||||
<node CREATED="1555807203432" ID="ID_1628579018" MODIFIED="1555807210371" TEXT="dann besser direkt ausprogrammieren">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1555806696990" ID="ID_1464210384" MODIFIED="1555806729401" TEXT="kann nicht Tuple-Element per std::forward weitergeben">
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
<node CREATED="1555806733962" ID="ID_1424612840" MODIFIED="1555806749379" TEXT="Compiler möchte eine RValue-Referenz"/>
|
||||
<node CREATED="1555806760125" ID="ID_1741677842" MODIFIED="1555806781118" TEXT="workaround: das Tuple selber per std::forward an std::get übergeben">
|
||||
<node CREATED="1555806782283" ID="ID_1783286457" MODIFIED="1555806788797" TEXT="das machen andere anscheinend auch so"/>
|
||||
<node CREATED="1555806792065" ID="ID_1773083646" MODIFIED="1555806806755" TEXT="Beispiel: die Textbook-Implementierung von std::apply"/>
|
||||
<node CREATED="1555806824441" ID="ID_948993908" MODIFIED="1555806837435" TEXT="Resultat: aus dem std::get fällt eine rvalue-Referenz raus"/>
|
||||
<node CREATED="1555806920309" ID="ID_1549876372" MODIFIED="1555807062290" TEXT="das könnte sogar das Standard-Baumuster für "perfect forwarding" sein">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...denn es handelt sich hierbei um einen Konstruktionstrick.
|
||||
</p>
|
||||
<p>
|
||||
Scott Meyers spricht deshalb auch immer von "unverersal references" und unterscheidet
|
||||
</p>
|
||||
<p>
|
||||
diese von einer expliziten RValue-Referenz.
|
||||
</p>
|
||||
<p>
|
||||
|
||||
</p>
|
||||
<p>
|
||||
Demnach wäre das Standard-Baumuster, daß alle Glieder <b>in</b>  der perfect-forwarding-Kette
|
||||
</p>
|
||||
<p>
|
||||
per universal-Reference miteinander verbunden sind. Und im Konkreten fall muß man
|
||||
</p>
|
||||
<p>
|
||||
das so hintricksen, indem man die std::get-Funktion passend bestückt...
|
||||
</p>
|
||||
<p>
|
||||
|
||||
</p>
|
||||
<p>
|
||||
Au weia
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1555806839235" ID="ID_1636335140" MODIFIED="1555806914250" TEXT="ist der workaround gefährlich?">
|
||||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1555806851177" ID="ID_1212118219" MODIFIED="1555806866323" TEXT="d.h. kommt am Ende nicht doch ein RValue an?"/>
|
||||
<node CREATED="1555806866887" ID="ID_815971236" MODIFIED="1555806883289" TEXT="auch dann nicht: wenn die Funktion einen RValue verlangt??"/>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1555806884936" ID="ID_1433427722" MODIFIED="1555806896802" TEXT="per Experiment verifizieren">
|
||||
<icon BUILTIN="flag-pink"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1555807238238" ID="ID_383098394" MODIFIED="1555807261859" TEXT="Copy-Support von PolymorphicValue ist "komisch"">
|
||||
<node CREATED="1555807266221" ID="ID_262959695" MODIFIED="1555807278396" TEXT="nach heutigem Stand: unbeholfen implementiert"/>
|
||||
<node CREATED="1555807285055" ID="ID_1456730365" MODIFIED="1555807297103" TEXT="braucht expliziten Support vom Payload typ"/>
|
||||
<node CREATED="1555807297726" ID="ID_1905059435" MODIFIED="1555807304816" TEXT="das wäre heute gar nicht mehr notwendig"/>
|
||||
<node CREATED="1555807489204" ID="ID_1385287282" MODIFIED="1555807633730" TEXT="Ausführung ist lückenhaft, und teilweise nicht korrekt">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Beispiel: Wenn der Typ selber keinen Support anbietet,
|
||||
</p>
|
||||
<p>
|
||||
dann nehmen wir immer das volle CopySupport-API, und differenzieren nicht
|
||||
</p>
|
||||
<p>
|
||||
mehr nach Typen mit reinem clone-support. Was dann tatsächlich dazu führt,
|
||||
</p>
|
||||
<p>
|
||||
daß der Compiler verucht, den Zuweisungsoperator zu verwernden!
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1555807646555" ID="ID_84342308" MODIFIED="1555807746266" TEXT="CloneValueSupport nicht (korrekt) erkannt">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1555807666086" ID="ID_1670738915" MODIFIED="1555807723294" TEXT="offensichtlich wird die falsche Trait-Variante gewählt">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
nämlich diejenige für Typen ohne Support auf dem API.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1555807724232" ID="ID_1817680115" MODIFIED="1555807744748" TEXT="und das, obwohl ich CloneValueSupport als Basis verwendet habe"/>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1555807747713" ID="ID_341140224" MODIFIED="1555807752169" TEXT="aufzuklären">
|
||||
<icon BUILTIN="flag-pink"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1555807305357" ID="ID_1511870599" MODIFIED="1555807322414" TEXT="Plan: PolymorphicValue überarbeiten">
|
||||
<node CREATED="1555807415718" ID="ID_639233049" MODIFIED="1555807439478" TEXT="mit "VirtualCopySupport" von meiner Variant-Implementierung zusammenführen"/>
|
||||
<node CREATED="1555807443642" ID="ID_90620144" MODIFIED="1555807458413" TEXT="sollte selbständig erkennen, ob der Zieltyp kopierbar ist"/>
|
||||
<node CREATED="1555807464657" ID="ID_1089528099" MODIFIED="1555807476065" TEXT="diese meta-Intelligenz sollte komplett in dem Adapter stecken"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1555807762543" ID="ID_1645640007" MODIFIED="1555807777516" TEXT="Problem: Puffergröße">
|
||||
<node CREATED="1555807778751" ID="ID_1563586526" MODIFIED="1555807801996" TEXT="PolymorphicValue verlangt, daß man die Puffergröße als Template-Argument definiert"/>
|
||||
<node CREATED="1555807802562" ID="ID_1845631121" MODIFIED="1555807822507" TEXT="hier hängt diese aber von der Storage für die Funktionsargumente ab."/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1555807833997" ID="ID_1153160392" MODIFIED="1555807958411" TEXT="Idealfall: das müßte automatisch funktionieren">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1555807861314" ID="ID_352919826" MODIFIED="1555807866077" TEXT="geht das überhaupt?"/>
|
||||
<node CREATED="1555807866689" ID="ID_1851833268" MODIFIED="1555807946327" TEXT="würde vermutlich auf ein Builder-Konstrukt hinauslaufen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...etwas analog zu meinem TreeMutator.
|
||||
</p>
|
||||
<p>
|
||||
D.h. man muß alle verwendeten Signaturen auf dem Receiver
|
||||
</p>
|
||||
<p>
|
||||
erst mal in einem Builder-Konstrukt gewissermaßen "registrieren", um dann den passenden
|
||||
</p>
|
||||
<p>
|
||||
VerbPack-Typ konstruiert zu bekommen.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1555807962932" ID="ID_378229584" MODIFIED="1555808017855" TEXT="bisher hat meine Lösung aber grade den einen Vorteil, komplet "ad hoc" zu sein">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
d.h. man erzeugt in einem einzigen Aufruf den VerbPack für eine Zielfunktion
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1555807845319" ID="ID_1999765895" MODIFIED="1555807959734" TEXT="Halbe Lösung: wenigstens eine Hilfsfunktion bereitstellen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1555808026434" ID="ID_1634107778" MODIFIED="1555808049833" TEXT="automatische Konversionen für konkrete Argumente">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1555808055328" ID="ID_1683773555" MODIFIED="1555808098743" TEXT="der VerbPack - Konstruktor sollte sich genau so verhalten wie die Zielfunktion">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node CREATED="1555808100082" ID="ID_1008688397" MODIFIED="1555808121930" TEXT="Beispiel: Zielfunktion nimmt einen std::string, gegeben ist ein C-String-Literal"/>
|
||||
<node CREATED="1555808124882" ID="ID_364451047" MODIFIED="1555808137896" TEXT="aktuell wird exakt der korrekte Typ erwartet"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1555808138474" ID="ID_847234596" MODIFIED="1555808161273" TEXT="Grund: Funktionsweise der Teplate-Argument-Inferenz">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1555808184873" ID="ID_804931772" MODIFIED="1555808194813" TEXT="sinnvoller Workaround">
|
||||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1555808201687" ID="ID_191950649" MODIFIED="1555808251007" TEXT=""Zwiebelschalen-Konstrukt"??">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
zwei verschachtelte, delegierende Konstruktoren,
|
||||
</p>
|
||||
<p>
|
||||
von denen der zweite, innere die eigentliche Typinferenz macht
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1555808280478" ID="ID_59896827" MODIFIED="1555808285065" TEXT="Testabdeckung">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1555808288856" ID="ID_1931717111" MODIFIED="1555808422559" TEXT="Frage: ist das Design gut?">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1555808300703" ID="ID_621465643" MODIFIED="1555808419535" TEXT="kann/sollte die Lösong mehr integriert sein?">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
sollten z.B. die Konstruktor-Funktionen nicht unmittelbar mit definiert werden?
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1555808311417" ID="ID_1932269477" MODIFIED="1555808361842" TEXT="oder ist es grade ein Vorteil, wenn sie ein roher Baustein ist">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...weil man stets noch einen Layer darübersetzt?
|
||||
</p>
|
||||
<p>
|
||||
Wie auch im konkreten Fall das TrackProfile, was dann ein vector<VerbPack> werden würde?
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue