From f597e7c8b45379946d176acc617362fcb0e4f5c5 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sat, 6 Nov 2010 22:32:08 +0100 Subject: [PATCH] optional object link implemented and working --- src/lib/optional-ref.hpp | 121 ++++++++++++++++++++++++-------- tests/40components.tests | 5 ++ tests/lib/optional-ref-test.cpp | 25 +++---- tests/tool/vgsuppression.c | 5 ++ 4 files changed, 111 insertions(+), 45 deletions(-) diff --git a/src/lib/optional-ref.hpp b/src/lib/optional-ref.hpp index ff8b368c9..f819ebe62 100644 --- a/src/lib/optional-ref.hpp +++ b/src/lib/optional-ref.hpp @@ -26,11 +26,6 @@ #include "lib/error.hpp" #include "lib/bool-checkable.hpp" -#include "lib/util.hpp" - -//#include -//#include -//#include namespace lib { @@ -38,26 +33,6 @@ namespace lib { using lumiera::error::LUMIERA_ERROR_BOTTOM_VALUE; - /** - * Reference wrapper implemented as constant function, - * returning the (fixed) reference on invocation - */ - template - class ReturnRef - { - T& ref_; - - public: - ReturnRef(T& target) : ref_(target) { } - T& operator() () const { return ref_;} - }; - - template - ReturnRef - refFunction (T& target) - { - return ReturnRef (target); - } @@ -68,20 +43,110 @@ namespace lib { * is managed automatically by ctor and dtor, can be detected * through \c bool check and -- contrary to a \c NULL pointer * -- produces a real exception instead of crashing. + * * @note \em not taking ownership of the pointee + * + * @see OptionalRef_test + * @see lib::AutoRegistered usage example + * @see SessionInterfaceModules::~SessionInterfaceModules() + * */ template class OptionalRef + : public lib::BoolCheckable > { T* ref_; + public: - OptionalRef() : ref_(0) { } - OptionalRef(T& target) : ref_(&target) { } - ~OptionalRef() { ref_ = 0; } + OptionalRef() + : ref_(0) + { } + + ~OptionalRef() + { + clear(); + } + + // using default copy operations... + + explicit + OptionalRef(T& target) ///< ...\em not allowing implicit conversion from T& + : ref_(&target) + { } + + operator T& () const ///< ...allowing implicit conversion to T& + { + if (!isValid()) + throw lumiera::error::Logic ("access to this object is (not/yet) enabled" + , LUMIERA_ERROR_BOTTOM_VALUE); + return *ref_; + } + + + /* === mutations ===*/ + + void + link_to (T& target) + { + ref_ = ⌖ + } + + void + clear() + { + ref_ = 0; + } + + + /* === comparison and diagnostics === */ + + bool + isValid() const + { + return bool(ref_); + } + + bool + points_to (T const& target) const + { + return isValid() + && ref_ == ⌖ + } + + friend bool + operator== (OptionalRef const& r1, OptionalRef const& r2) + { + return r1.ref_ == r2.ref_; + } + friend bool + operator!= (OptionalRef const& r1, OptionalRef const& r2) + { + return r1.ref_ != r2.ref_; + } + + // mixed comparisons + friend bool + operator== (OptionalRef const& ref, T const& otherTarget) ///< @note might throw + { + T const& thisTarget (ref); // might throw + return thisTarget == otherTarget; + } + + friend bool operator== (T const& otherTarget, OptionalRef const& ref) { return ref == otherTarget; } + friend bool operator!= (T const& otherTarget, OptionalRef const& ref) { return !(ref == otherTarget); } + friend bool operator!= (OptionalRef const& ref, T const& otherTarget) { return !(ref == otherTarget); } }; + template + OptionalRef + optionalRefTo (T& target) + { + return OptionalRef (target); + } + + } // namespace lib #endif diff --git a/tests/40components.tests b/tests/40components.tests index 241606571..ae1d5da0a 100644 --- a/tests/40components.tests +++ b/tests/40components.tests @@ -393,6 +393,11 @@ out: ItemWrapper: sizeof\( .+ItemWrapper.+ ) = END +TEST "switchable reference" OptionalRef_test < -//#include -//#include -//#include -//#include - namespace lib { @@ -46,15 +39,14 @@ namespace test{ - - - - - - /******************************************************************************* - * @test verify a reference-like wrapper class, used to provide a switchable link - * to an already existing object. + * @test verify a reference-like wrapper class, + * used to provide a switchable link to an already existing object. + * - bottom ref can be detected by bool check + * - access to bottom ref raises exception + * - refs can be compared + * - refs can be changed and copied + * - access to refs is secure even after destructor invocation * * @see lib::OptionalRef * @see lib::AutoRegistered usage example @@ -137,7 +129,7 @@ namespace test{ // access is secured even after destruction CHECK (r3); - r1.~OptionalRef(); + r3.~SRef(); // don't try this at home! CHECK (!r3); VERIFY_ERROR (BOTTOM_VALUE, r3 == s1 ); CHECK (r3 != r2); @@ -154,4 +146,3 @@ namespace test{ }} // namespace lib::test - diff --git a/tests/tool/vgsuppression.c b/tests/tool/vgsuppression.c index 6557bdeb1..ffc88298f 100644 --- a/tests/tool/vgsuppression.c +++ b/tests/tool/vgsuppression.c @@ -26,11 +26,15 @@ #include "lib/tmpbuf.h" #include +typedef const char* lumiera_err; struct lumiera_errorcontext_struct; struct lumiera_errorcontext_struct* lumiera_error_get (void); +lumiera_err +lumiera_error_set (lumiera_err, const char*); + int main () @@ -44,6 +48,7 @@ main () /* lumiera_error_get() mallocs a LumieraErrorcontext for each thread */ lumiera_error_get(); + lumiera_error_set("dummy","dummy"); return 0; }