Library: investigate malfunction in metaprogramming
the template lib::PolymorphicValue seemingly picked the wrong implementation strategy for "virtual copy support": In fact it is possible to use the optimal strategy here, since our interface inherits from CloneSupport, yet the metaprogramming logic picked the mix-in-adapter (which requires one additional "slot" of storage plus a dynamic_cast at runtime). The reason for this malfunction was the fact that we used META_DETECT_FUNCTION to detect the presence of a clone-support-function. This is not correct, since it can only detect a function in the *same* class, not an inherited function. Thus, switching to META_DETECT_FUNCTION_NAME solves this problem Well, this solution has some downsides, but since I intend to rewrite the whole virtual copy support (#1197) anyway, I'll deem this acceptable for now TODO / WIP: still some diagnostics code to clean up, plus a better solution for the EmptyBase
This commit is contained in:
parent
23c9da7c62
commit
8f43c2591e
5 changed files with 172 additions and 10 deletions
|
|
@ -244,6 +244,12 @@ applyTuple (FUN& fun)
|
|||
}
|
||||
};
|
||||
|
||||
using lib::meta::Yes_t;
|
||||
using lib::meta::No_t;
|
||||
|
||||
META_DETECT_FUNCTION(void, cloneInto, (void*) const);
|
||||
META_DETECT_FUNCTION_NAME(cloneInto);
|
||||
|
||||
|
||||
int
|
||||
main (int, char**)
|
||||
|
|
@ -275,6 +281,19 @@ main (int, char**)
|
|||
// recy.grrrn (std::get<0>(trp), Trackr(5));
|
||||
holyh.applyTo (recy);
|
||||
|
||||
cout << "---Types---"<<endl;
|
||||
using BussI = lib::VerbInvoker<Receiver, void>;
|
||||
using CloneI = lib::polyvalue::CloneValueSupport<lib::polyvalue::EmptyBase>;
|
||||
SHOW_TYPE(BussI);
|
||||
SHOW_EXPR (lib::polyvalue::exposes_CloneFunction<BussI>::value)
|
||||
SHOW_EXPR (HasFunSig_cloneInto<BussI>::value)
|
||||
SHOW_EXPR (HasFunSig_cloneInto<CloneI>::value)
|
||||
SHOW_EXPR (HasFunName_cloneInto<BussI>::value)
|
||||
SHOW_EXPR (HasFunName_cloneInto<CloneI>::value)
|
||||
using BussP = decltype(&BussI::cloneInto);
|
||||
SHOW_TYPE(BussP)
|
||||
|
||||
|
||||
cout << "\n.gulp.\n";
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@
|
|||
** Moreover, the PolymorphicValue container provides static builder functions,
|
||||
** allowing to place a concrete instance of a subclass into the content buffer.
|
||||
** After construction, the actual type of this instance will be forgotten
|
||||
** (``type erasure''), but because of the embedded vtable, on access the
|
||||
** (``type erasure''), but because of the embedded vtable, on access, the
|
||||
** proper implementation functions will be invoked.
|
||||
**
|
||||
** Expanding on that pattern, the copying and cloning operations of the whole
|
||||
|
|
@ -230,11 +230,11 @@ namespace lib {
|
|||
class exposes_CloneFunction
|
||||
{
|
||||
|
||||
META_DETECT_FUNCTION(void, cloneInto, (void*) const);
|
||||
META_DETECT_FUNCTION_NAME(cloneInto);
|
||||
|
||||
public:
|
||||
enum{ value = HasFunSig_cloneInto<T>::value
|
||||
};
|
||||
enum{ value = HasFunName_cloneInto<T>::value
|
||||
}; // warning: match on the function name only
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -373,7 +373,7 @@ namespace lib {
|
|||
>
|
||||
class PolymorphicValue
|
||||
{
|
||||
|
||||
public:
|
||||
typedef polyvalue::Trait<CPY> _Traits;
|
||||
typedef typename _Traits::CopyAPI _CopyHandlingAdapter;
|
||||
typedef typename _Traits::Assignment _AssignmentPolicy; /////////////////TICKET #1197 : confusingly indirect decision logic
|
||||
|
|
|
|||
|
|
@ -72,9 +72,11 @@ namespace lib {
|
|||
}
|
||||
}
|
||||
|
||||
using EmptyBasE = struct { };
|
||||
|
||||
template<class REC, class RET>
|
||||
struct VerbInvoker
|
||||
: polyvalue::CloneValueSupport<polyvalue::EmptyBase> // mark and mix-in virtual copy construction support
|
||||
: polyvalue::CloneValueSupport<EmptyBasE> // mark and mix-in virtual copy construction support
|
||||
{
|
||||
virtual ~VerbInvoker() { }
|
||||
|
||||
|
|
|
|||
|
|
@ -130,6 +130,10 @@ namespace test{
|
|||
|
||||
|
||||
|
||||
#define SHOW_TYPE(_TY_) \
|
||||
cout << "typeof( " << STRINGIFY(_TY_) << " )= " << lib::meta::typeStr<_TY_>() <<endl;
|
||||
#define SHOW_EXPR(_XX_) \
|
||||
cout << "Probe " << STRINGIFY(_XX_) << " ? = " << _XX_ <<endl;
|
||||
|
||||
|
||||
|
||||
|
|
@ -151,6 +155,22 @@ namespace test{
|
|||
TokenSeq tokens = build_and_copy_tokens();
|
||||
render_verbose (tokens);
|
||||
// profile.append_woof(1, 2);
|
||||
|
||||
using IrrelvantType = struct{};
|
||||
const size_t VERB_TOK_SIZE = sizeof(lib::VerbToken<IrrelvantType, void(void)>);
|
||||
using HoldL = Holder<Receiver, string(string)>;
|
||||
const size_t VERB_TOK_SIZ2 = sizeof(HoldL::Verb);
|
||||
const size_t HOLDER_SIZE = sizeof(HoldL);
|
||||
const size_t ARG_TUP_SIZE = sizeof(std::tuple<string>);
|
||||
|
||||
SHOW_EXPR (VERB_TOK_SIZE);
|
||||
SHOW_EXPR (VERB_TOK_SIZ2);
|
||||
SHOW_EXPR (HOLDER_SIZE);
|
||||
SHOW_EXPR (ARG_TUP_SIZE);
|
||||
SHOW_EXPR (sizeof(string));
|
||||
using AdapT = Token::Adapter<HoldL>;
|
||||
SHOW_TYPE (AdapT);
|
||||
SHOW_EXPR (sizeof(AdapT));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -19971,8 +19971,8 @@
|
|||
</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 COLOR="#338800" CREATED="1555807646555" ID="ID_84342308" MODIFIED="1557446814390" TEXT="CloneValueSupport nicht (korrekt) erkannt">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1555807666086" ID="ID_1670738915" MODIFIED="1555807723294" TEXT="offensichtlich wird die falsche Trait-Variante gewählt">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
|
@ -19986,15 +19986,136 @@
|
|||
</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">
|
||||
<node CREATED="1557446452899" ID="ID_454930922" MODIFIED="1557446811594" TEXT="META_DETECT_FUNCTION erkennt keine geerbten Methoden">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...denn diese Duck-Detector-Metafunktion bildet den <b>Typ</b> eines Member-Pointers,
|
||||
</p>
|
||||
<p>
|
||||
und dieser Typ enthält explizit den statischen Namen der Klasse, welche die gewünschte Methode trägt.
|
||||
</p>
|
||||
<p>
|
||||
Und wenn man eine Methode bloß erbt, dann existiert diese Methode, statisch, nur auf der Basisklasse.
|
||||
</p>
|
||||
<p>
|
||||
Also ist das sogar das korrekte Verhalten.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1557446482447" ID="ID_835188518" MODIFIED="1557446493804" TEXT="Lösung: Duck-Detector für Methoden-Name">
|
||||
<node CREATED="1557446494679" ID="ID_1259664145" MODIFIED="1557446574477" TEXT="verzichtet auf Signatur-Check">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
d.h. wenn zufällig das Interface auch eine Methode CloneInto() enthält, aber mit einer unpassenden Signatur
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
<node CREATED="1557446561925" ID="ID_1267977919" MODIFIED="1557446571295" TEXT="ist ohnehin keine wirkliche Sicherheit"/>
|
||||
<node CREATED="1557446503084" ID="ID_1518606339" MODIFIED="1557446523133" TEXT="würde ohnehin später beim Compilieren scheitern"/>
|
||||
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1557446627092" ID="ID_805659416" MODIFIED="1557446697850" TEXT="mit #1197 hinfällig">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
weil ich dann explizit ein bestimmtes Basis-Interface verlangen werde,
|
||||
</p>
|
||||
<p>
|
||||
nämlich VirtualCopySupport<IFA>
|
||||
</p>
|
||||
<p>
|
||||
|
||||
</p>
|
||||
<p>
|
||||
das ist auch gut so, zu viel Flexibilität schadet (besonders, wenn man sie dann gar nicht unterstützt)
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<font ITALIC="true" NAME="SansSerif" SIZE="14"/>
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1557446881265" ID="ID_743886485" MODIFIED="1557446897772" TEXT="Folgeproblem: ambiguous base class">
|
||||
<icon BUILTIN="clanbomber"/>
|
||||
<node CREATED="1557446902070" ID="ID_1511315997" MODIFIED="1557447072957" TEXT="kommt davon, wenn man mehrfach polyvalue::EmptyBase verwendet">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
weil nämlich der Trait, für den optimalen Fall, ebenfalls die EmptyBase verwendet, um den Mix-In zu deaktivieren.
|
||||
</p>
|
||||
<p>
|
||||
Leider haben wir dann zweimal die gleiche Basisklasse in beiden Zweigen der multiple inheritance...
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1557446924907" ID="ID_1029661613" MODIFIED="1557446979586" TEXT="...was hier absolut naheliegend ist">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
nämlich immer dann, wenn man tatsächlich den CopySupport oder CloneSupport als Basis des Interfaces verwendet...
|
||||
</p>
|
||||
<p>
|
||||
(was ich bisher in der Praxis so noch nie gemacht habe)
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1557447075623" ID="ID_1422873677" MODIFIED="1557447148035" TEXT="dummerweise kann dann der GCC die EmptyBase nicht wegoptimieren">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...was sich dann in einer Static-Assertion-Failure äußert.
|
||||
</p>
|
||||
<p>
|
||||
hab das ganz explizit ausgeknobelt, es fehlt hier genau dieser eine zusätzliche "Slot"
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<icon BUILTIN="broken-line"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1557447159900" ID="ID_691196423" MODIFIED="1557447167364" TEXT="Lösung: anderen Namen verwenden">
|
||||
<icon BUILTIN="flag-pink"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1555807305357" ID="ID_1511870599" MODIFIED="1555807322414" TEXT="Plan: PolymorphicValue überarbeiten">
|
||||
</node>
|
||||
<node CREATED="1555807305357" ID="ID_1511870599" MODIFIED="1557446848388" TEXT="Plan: PolymorphicValue überarbeiten">
|
||||
<arrowlink COLOR="#1a64bc" DESTINATION="ID_596556632" ENDARROW="Default" ENDINCLINATION="-129;0;" ID="Arrow_ID_884404467" STARTARROW="None" STARTINCLINATION="-284;0;"/>
|
||||
<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 BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1557446611550" ID="ID_596556632" MODIFIED="1557446843936" TEXT="Ticket #1197 : rationalise copy support in PolymorphicValue">
|
||||
<linktarget COLOR="#1a64bc" DESTINATION="ID_596556632" ENDARROW="Default" ENDINCLINATION="-129;0;" ID="Arrow_ID_884404467" SOURCE="ID_1511870599" STARTARROW="None" STARTINCLINATION="-284;0;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</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"/>
|
||||
|
|
|
|||
Loading…
Reference in a new issue