diff --git a/src/lib/functor-util.hpp b/src/lib/functor-util.hpp index 473a17dc7..7efee7060 100644 --- a/src/lib/functor-util.hpp +++ b/src/lib/functor-util.hpp @@ -152,7 +152,7 @@ namespace util { ////////////TODO: refactor it. But probably not directly into n * "different" erroneously, due to garbage in * the internal functor data's storage */ template - bool + inline bool rawComparison (function const& f1, function const& f2) { @@ -165,13 +165,24 @@ namespace util { ////////////TODO: refactor it. But probably not directly into n /** catch-all for the comparison: functors with * different base type are always "different" */ template - bool + inline bool rawComparison (function const&, function const&) { return false; } + /** variant with unchecked access */ + inline bool + rawComparison (void* f1, void* f2) + { + typedef HijackedFunction * HijP; + + return (!f1 && !f2) + || *reinterpret_cast (f1) + == *reinterpret_cast (f2); + } + } // namespace util diff --git a/src/lib/meta/function-erasure.hpp b/src/lib/meta/function-erasure.hpp index 167d6c0bc..292260e7c 100644 --- a/src/lib/meta/function-erasure.hpp +++ b/src/lib/meta/function-erasure.hpp @@ -60,7 +60,6 @@ #include "lib/functor-util.hpp" #include -#include namespace lumiera { @@ -69,33 +68,6 @@ namespace typelist{ using std::tr1::function; using util::unConst; - namespace { // comparison access helper functions - - typedef void* RawFunc; ///////////////////TODO - - template - RawFunc - accessRaw (FH funHolder) - { - ////////////////TODO - }; - - template - struct IsEqualTo - { - RawFunc ofunc_; - - IsEqualTo (FH o) - : ofunc_(o) - { } - - bool - operator() (RawFunc func) - { - return util::rawComparison(func, ofunc_); - } - }; - } /****************************************************** @@ -115,8 +87,7 @@ namespace typelist{ */ template struct FunErasure - : boost::equality_comparable< FunErasure - , FH > + : FH { template FunErasure (FUN const& functor) @@ -124,9 +95,9 @@ namespace typelist{ { } friend bool - operator== (FunErasure const& fe1, FunErasure const& fe2) + operator!= (FunErasure const& fer1, FunErasure const& fer2) { - return fe1.query (IsEqualTo (fe2)); + return !(fer1==fer2); // use equality defined by FH } }; @@ -168,6 +139,14 @@ namespace typelist{ { return get >(); } + + + friend bool + operator== (StoreFunction const& o1, + StoreFunction const& o2) + { + return util::rawComparison (o1.asBase(),o2.asBase()); + } }; @@ -199,6 +178,14 @@ namespace typelist{ REQUIRE (fun); return *fun; } + + + friend bool + operator== (StoreFunPtr const& o1, + StoreFunPtr const& o2) + { + return o1.asBase() == o2.asBase(); + } }; @@ -231,19 +218,19 @@ namespace typelist{ return *reinterpret_cast (funP_); } - template - bool - query (FUN predicate) - { - return predicate (funP_); - } - bool isValid() const { return funP_; } + + friend bool + operator== (StoreUncheckedFunPtr const& o1, + StoreUncheckedFunPtr const& o2) + { + return unConst(o1).funP_ == unConst(o2).funP_; + } }; diff --git a/src/lib/opaque-holder.hpp b/src/lib/opaque-holder.hpp index 5ebee8aa3..7f5d63858 100644 --- a/src/lib/opaque-holder.hpp +++ b/src/lib/opaque-holder.hpp @@ -359,6 +359,15 @@ namespace lib { ref.buff().clone (storage_); } + BaseP + asBase () const ///< @internal backdoor e.g. for comparisons + { + BaseP asBase = buff().getBase(); + ASSERT (asBase); + return asBase; + } + + public: @@ -462,9 +471,7 @@ namespace lib { // second try: maybe we can perform a dynamic downcast // or direct conversion to the actual target type. - BaseP asBase = buff().getBase(); - ASSERT (asBase); - SUB* content = AccessPolicy::template access (asBase); + SUB* content = AccessPolicy::template access (asBase()); if (content) return *content; @@ -475,20 +482,6 @@ namespace lib { } - /** invoke a query function on the embedded object, - * accessing it as through the common base type. - * @note this accessor doesn't require any knowledge - * about the concrete type of the target object - */ - template - RET - apply (FUN query) - { - BaseP asBase = buff().getBase(); - ASSERT (asBase); - return query (asBase); - } - bool empty() const diff --git a/src/lib/util.hpp b/src/lib/util.hpp index bcceb2480..02a52941b 100644 --- a/src/lib/util.hpp +++ b/src/lib/util.hpp @@ -227,6 +227,13 @@ namespace util { return const_cast (o); } + template + OBJ& + unConst (OBJ const& ro) + { + return const_cast (ro); + } + /** compare plain object identity, * bypassing any custom comparison operators. diff --git a/src/proc/control/command-mutation.hpp b/src/proc/control/command-mutation.hpp index 4621c03aa..8152f093c 100644 --- a/src/proc/control/command-mutation.hpp +++ b/src/proc/control/command-mutation.hpp @@ -51,7 +51,6 @@ #include "proc/control/command-closure.hpp" #include "proc/control/memento-tie.hpp" -#include #include #include @@ -73,7 +72,6 @@ namespace control { * concealed (erased) on the interface. */ class Mutation - : public boost::equality_comparable { const CmdFunctor func_; @@ -102,6 +100,12 @@ namespace control { { return (m1.func_ == m2.func_); } + + friend bool + operator!= (Mutation const& m1, Mutation const& m2) + { + return !(m1==m2); + } }; diff --git a/tests/components/proc/control/command-equality-test.cpp b/tests/components/proc/control/command-equality-test.cpp index 1c8bdd44d..8e1050072 100644 --- a/tests/components/proc/control/command-equality-test.cpp +++ b/tests/components/proc/control/command-equality-test.cpp @@ -78,23 +78,13 @@ namespace test { typedef string Sig_capt(char); typedef void Sig_undo(char,string); + typedef function Fun_o; + typedef function Fun_c; + typedef function Fun_u; + typedef Tuple > ArgTuple; typedef Closure ArgHolder; typedef MementoTie MemHolder; - - - struct Testframe ///< test data set - { - Sig_oper & o_Fun; - Sig_capt & c_Fun; - Sig_undo & u_Fun; - }; - - - Testframe data1 = {oper_1, capt_1, undo_1}; - Testframe data2 = {oper_2, capt_2, undo_2}; - - Testframe nullD; } @@ -140,9 +130,16 @@ namespace test { void verifyMutationEquality() { - Mutation mut1 (data1.o_Fun); - Mutation muti (data1.o_Fun); - Mutation mut2 (data2.o_Fun); + Fun_o oFun_1 (oper_1); + Fun_o oFun_2 (oper_2); + Fun_o oFun_empty; + + Fun_u uFun_1 (undo_1); + Fun_u uFun_empty; + + Mutation mut1 (oFun_1); + Mutation muti (oFun_1); + Mutation mut2 (oFun_2); ASSERT (mut1 == mut1); ASSERT (mut1 == muti); ASSERT (muti == mut1); @@ -151,15 +148,15 @@ namespace test { ASSERT (muti != mut2); ASSERT (mut2 != muti); - Mutation umu (nullD.o_Fun); + Mutation umu (oFun_empty); // empty operation function ASSERT (mut1 != umu); - Mutation omu (nullD.u_Fun); - ASSERT (omu != umu); - ASSERT (omu != muti); + Mutation mut_u0 (uFun_empty); // empty undo function + ASSERT (mut_u0 != umu); + ASSERT (mut_u0 != muti); - omu = Mutation(data1.u_Fun); - ASSERT (omu != muti); + Mutation mut_u1 (uFun_1); + ASSERT (mut_u0 != mut_u1); // function signatures differing } @@ -185,19 +182,19 @@ namespace test { ASSERT (abuff1 != abuff2); abuff2.bindArguments(newArgs); ASSERT (abuff1 == abuff2); - UndoMutation umu1 (abuff1.tie (data1.u_Fun, data1.c_Fun)); - ASSERT (abuff1 == abuff2); // not detected, as the new memento holder isn't valid yet + UndoMutation umu1 (abuff1.tie (undo_1, capt_1)); + ASSERT (abuff1 == abuff2); // not detected, as the new memento holder isn't valid yet - UndoMutation umu2 (abuff1.tie (data1.u_Fun, data2.c_Fun)); // note: using different capture function! + UndoMutation umu2 (abuff1.tie (undo_1, capt_2)); // note: using different capture function! ASSERT (abuff1 == abuff2); umu1.captureState(a1); umu2.captureState(a1); ASSERT (abuff1 != abuff2); // and now the different state (due to the differing capture function) is detected - umu2 = UndoMutation(abuff1.tie (data1.u_Fun, data1.c_Fun)); // re-bind, now using the "right" capture function + UndoMutation umu3 (abuff1.tie (undo_1, capt_1)); // now using the "right" capture function ASSERT (abuff1 != abuff2); - umu2.captureState(a1); + umu3.captureState(a1); ASSERT (abuff1 == abuff2); // same functions, same memento state } @@ -205,10 +202,18 @@ namespace test { void verifyMementoEquality() { - MemHolder m11 (data1.u_Fun, data1.c_Fun); - MemHolder m12 (data1.u_Fun, data2.c_Fun); - MemHolder m21 (data2.u_Fun, nullD.c_Fun); // note: unbound capture function - MemHolder m22 (data2.u_Fun, data2.c_Fun); + Fun_u uFun_1 (undo_1); + Fun_u uFun_2 (undo_2); + Fun_c cFun_1 (capt_1); + Fun_c cFun_2 (capt_2); + Fun_c cFun_empty; + + Fun_c empty_c; + + MemHolder m11 (uFun_1, cFun_1); + MemHolder m12 (uFun_1, cFun_2); + MemHolder m21 (uFun_2, cFun_empty); // note: unbound capture function + MemHolder m22 (uFun_2, cFun_2); ASSERT ( (m11 == m11)); ASSERT (!(m11 != m11)); @@ -255,14 +260,14 @@ namespace test { verifyCommandEquality() { CommandDef (COMMAND1) - .operation (data1.o_Fun) - .captureUndo (data1.c_Fun) - .undoOperation (data1.u_Fun) + .operation (oper_1) + .captureUndo (capt_1) + .undoOperation (undo_1) ; CommandDef (COMMAND2) - .operation (data2.o_Fun) - .captureUndo (data2.c_Fun) - .undoOperation (data2.u_Fun) + .operation (oper_2) + .captureUndo (capt_2) + .undoOperation (undo_2) ; Command c1 = Command::get(COMMAND1); diff --git a/tests/lib/meta/function-erasure-test.cpp b/tests/lib/meta/function-erasure-test.cpp index 6db81fc3b..27bddaee8 100644 --- a/tests/lib/meta/function-erasure-test.cpp +++ b/tests/lib/meta/function-erasure-test.cpp @@ -95,7 +95,7 @@ namespace test { check_Comparisons (Efun(pAplFunc), Efun(getterFunc)); check_Comparisons (Efun(membFunc), Efun(getterFunc)); - check_Comparisons (Efp(testFunc), Efun(returnIt)); + check_Comparisons (Efp(testFunc), Efp(returnIt)); check_Comparisons (Evoid(testFunc), Evoid(returnIt)); detect_unboundFunctor(Efun(testFunc), Efun(getterFunc), Efun(membFunc)); @@ -224,6 +224,9 @@ namespace test { void check_Comparisons (HOL h1, HOL h2) { + ASSERT (h1 == h1); ASSERT (!(h1 != h1)); + ASSERT (h2 == h2); ASSERT (!(h2 != h2)); + ASSERT (h1 != h2); ASSERT (h2 != h1);