From 7686122354a5dc9d08d7d8194ffa124df85fa764 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 19 Apr 2015 02:02:54 +0200 Subject: [PATCH] implementation complete -- kindof works there is a problem with the virtual assignment, seems the default policy was picked. Beyond that, the rest of the unit test passes --- src/lib/test/suite.cpp | 2 +- src/lib/variant.hpp | 83 +++++++++++++++++++++++++++------- tests/library/variant-test.cpp | 11 +++-- 3 files changed, 74 insertions(+), 22 deletions(-) diff --git a/src/lib/test/suite.cpp b/src/lib/test/suite.cpp index fd22de79a..0faf7ccf9 100644 --- a/src/lib/test/suite.cpp +++ b/src/lib/test/suite.cpp @@ -183,7 +183,7 @@ namespace test { catch (lumiera::Error& failure) { lumiera_err errorID = lumiera_error(); // reset error flag - cerr << "*** Test Failure " << showType(theTest) << endl; + cerr << "*** Test Failure " << demangleCxx(showType(theTest)) << endl; cerr << "*** : " << failure.what() << endl; ERROR (test, "Error state %s", errorID); WARN (progress, "Caught exception %s", failure.what()); diff --git a/src/lib/variant.hpp b/src/lib/variant.hpp index 0ecf89a80..1581e0b43 100644 --- a/src/lib/variant.hpp +++ b/src/lib/variant.hpp @@ -58,6 +58,7 @@ #include "lib/meta/typelist.hpp" #include "lib/meta/typelist-util.hpp" +#include "lib/meta/generator.hpp" //#include "lib/util.hpp" #include @@ -79,6 +80,7 @@ namespace lib { template class Variant; + namespace { // implementation helpers @@ -284,7 +286,7 @@ namespace lib { struct use_if_supports_copy_and_assignment : enable_if< is_move_constructible::value && is_copy_constructible::value - && !can_use_assignment::value + && can_use_assignment::value ,X > { }; @@ -322,6 +324,18 @@ namespace lib { }; + + template + struct ValueAcceptInterface + { + virtual void handle(VAL&) { /* NOP */ }; + }; + + template + using VisitorInterface + = meta::InstantiateForEach; + + }//(End) implementation helpers @@ -340,8 +354,18 @@ namespace lib { template class Variant { + public: enum { SIZ = meta::maxSize::value }; + class Visitor + : public VisitorInterface + { + public: + virtual ~Visitor() { } ///< this is an interface + }; + + + private: /** Inner capsule managing the contained object (interface) */ struct Buffer : VirtualCopySupportInterface @@ -353,6 +377,8 @@ namespace lib { virtual ~Buffer() {} ///< this is an ABC with VTable + virtual void dispatch (Visitor&) =0; + virtual operator string() const =0; }; @@ -434,6 +460,16 @@ namespace lib { else return *buff; } + + void + dispatch (Visitor& visitor) + { + ValueAcceptInterface& typeDispatcher = visitor; + typeDispatcher.handle (this->access()); + } + + /** diagnostic helper */ + operator string() const; }; enum{ BUFFSIZE = sizeof(Buffer) }; @@ -538,14 +574,9 @@ namespace lib { } -#ifdef LIB_TEST_TEST_HELPER_H - /* == diagnostic helper == */ + /** diagnostic helper */ + operator string() const; - operator string() const - { - UNIMPLEMENTED("diagnostic string conversion"); - } -#endif /* === Access === */ @@ -560,20 +591,40 @@ namespace lib { } - class Visitor - { - public: - virtual ~Visitor() { } ///< this is an interface - }; - void accept (Visitor& visitor) { - UNIMPLEMENTED("visitor style value access"); + buffer().dispatch (visitor); } }; -} // namespace lib +} // namespace lib + + + + /* == diagnostic helper == */ + +#ifdef LIB_FORMAT_UTIL_H +namespace lib { + + template + Variant::operator string() const + { + return string(buffer()); + } + + template + template + Variant::Buff::operator string() const + { + return "Variant|" + + util::str (this->access(), + (util::tyStr()+"|").c_str() + ); + } +} // namespace lib + +#endif #endif /*LIB_VARIANT_H*/ diff --git a/tests/library/variant-test.cpp b/tests/library/variant-test.cpp index 9ff282ae7..4b63e349a 100644 --- a/tests/library/variant-test.cpp +++ b/tests/library/variant-test.cpp @@ -25,6 +25,7 @@ #include "lib/test/run.hpp" #include "lib/test/test-helper.hpp" #include "lib/time/timevalue.hpp" +#include "lib/format-util.hpp" #include "lib/variant.hpp" #include "lib/util.hpp" @@ -106,10 +107,10 @@ namespace test{ CHECK (contains (string(v0), "Variant")); CHECK (contains (string(v0), "bool")); - CHECK (contains (string(v0), "false")); + CHECK (contains (string(v0), "0")); CHECK (contains (string(v1), "Variant")); - CHECK (contains (string(v1), "int64_t")); + CHECK (contains (string(v1), "int64_t") || contains (string(v1), "long") ); CHECK (contains (string(v1), "11")); CHECK (contains (string(v2), "Variant")); @@ -118,7 +119,7 @@ namespace test{ CHECK (contains (string(v3), "Variant")); CHECK (contains (string(v3), "lib::time::Time")); - CHECK (contains (string(v3), "0:00:00:00")); + CHECK (contains (string(v3), "0:00:00.000")); } @@ -167,8 +168,8 @@ namespace test{ int i_ = 12; TimeVar t_; - void handle (bool b) { b_ = b; } - void handle (Time t) { t_ = t; } + void handle (bool& b) { b_ = b; } + void handle (Time& t) { t_ = t; } void handle (int64_t& i6) {