From 24762eda89c14f2c3c9c91b66bb77eaac284c065 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sat, 29 Aug 2015 17:09:03 +0200 Subject: [PATCH] Design: extend the Variant::Visitor (1) replicate the existing setup for this design study --- research/try.cpp | 84 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 70 insertions(+), 14 deletions(-) diff --git a/research/try.cpp b/research/try.cpp index 86645c1d0..56beeb48b 100644 --- a/research/try.cpp +++ b/research/try.cpp @@ -28,43 +28,99 @@ // 9/14 - variadic templates and perfect forwarding // 11/14 - pointer to member functions and name mangling // 8/15 - Segfault when loading into GDB (on Debian/Jessie 64bit +// 8/15 - generalising the Variant::Visitor /** @file try.cpp - ** Investigation: Segfault when loading into GDB (on Debian/Jessie 64bit). + ** Design: how to generalise the Variant::Visitor to arbitrary return values. ** - ** Problem could be narrowed down to a std::function bound to lambda, - ** where some argument type is picked up as template parameter + ** Our Variant template allows either for access by known type, or through accepting + ** a classic GoF visitor. Problem is that in many extended use cases we rather want + ** to apply \em functions, e.g. for a monadic flatMap on a data structure built from + ** Variant records. (see our \link diff::GenNode external object representation \endlink). + ** Since our implementation technique relies on a template generated interface anyway, + ** a mere extension to arbitrary return values seems feasible. ** */ -#include +typedef unsigned int uint; + +#include "lib/meta/typelist.hpp" +#include "lib/meta/generator.hpp" +#include "lib/format-util.hpp" + +//#include #include +#include #include using std::string; using std::cout; using std::endl; + + + template + struct ValueAcceptInterface + { + virtual void handle(VAL&) { /* NOP */ }; + }; + + template + using VisitorInterface + = lib::meta::InstantiateForEach; -template -inline string -activate (ELM& something) +template +struct Var { - std::function lambda = [] (ELM const& val) - { - return string(val); - }; - return lambda(something); - } + A a; + B b; + + using TYPES = lib::meta::Types; + using Visitor = VisitorInterface; + + void + accept (Visitor& visitor) + { + ValueAcceptInterface& visA = visitor; + ValueAcceptInterface& visB = visitor; + visA.handle (a); + visB.handle (b); + } + + operator string() const + { + return "Var(" + + util::str(a) + + "|" + + util::str(b) + + ")"; + } + }; + + +class Visi + : public Var::Visitor + { + + virtual void handle(int& i) { ++i; } + virtual void handle(string& s) { s += ".."; } + }; int main (int, char**) { - cout << activate("Data") << endl; + using V = Var; + + V var{12, "hui"}; + cout << string(var)<