From ab90d9c71d1d85417b3c2dec6939de019fc8c0f4 Mon Sep 17 00:00:00 2001
From: Ichthyostega
Date: Sun, 23 Jun 2019 19:43:47 +0200
Subject: [PATCH] Functions-Commands: discard the ability to compare functors
for equivalence (closes #294)
evil hack R.I.P
---
doc/technical/code/darkCorners.txt | 40 ----
src/common/guifacade.cpp | 1 -
src/lib/functor-util.hpp | 190 ----------------
src/lib/meta/function-erasure.hpp | 25 ---
src/lib/meta/maybe-compare.hpp | 18 +-
src/steam/control/command-closure.hpp | 1 -
src/steam/control/command-impl.hpp | 22 --
src/steam/control/command-mutation.hpp | 15 --
src/steam/control/command-op-closure.hpp | 21 --
src/steam/control/command-simple-closure.hpp | 24 --
src/steam/control/command-storage-holder.hpp | 25 ---
src/steam/control/command.cpp | 7 -
src/steam/control/command.hpp | 1 -
src/steam/control/memento-tie.hpp | 15 --
src/steam/engine/type-handler.hpp | 1 -
.../steam/control/command-argument-test.cpp | 45 ----
.../control/command-clone-builder-test.cpp | 5 -
.../steam/control/command-equality-test.cpp | 167 +-------------
.../steam/control/command-registry-test.cpp | 3 -
tests/core/steam/control/memento-tie-test.cpp | 45 ----
tests/library/functor-util-test.cpp | 212 ------------------
tests/library/meta/function-erasure-test.cpp | 47 ----
wiki/thinkPad.ichthyo.mm | 86 ++++---
23 files changed, 46 insertions(+), 970 deletions(-)
delete mode 100644 src/lib/functor-util.hpp
delete mode 100644 tests/library/functor-util-test.cpp
diff --git a/doc/technical/code/darkCorners.txt b/doc/technical/code/darkCorners.txt
index 771ec6175..8e40f0831 100644
--- a/doc/technical/code/darkCorners.txt
+++ b/doc/technical/code/darkCorners.txt
@@ -7,46 +7,6 @@ nonportable hacks, terrorism and other misdemeanour_
Library
-------
-Equality of Functors
-~~~~~~~~~~~~~~~~~~~~
-One of the more important recent additions to the C++ language are function objects.
-In addition to the features actually provided by the boost implementation, the tr1 report
-also requires function instances to implement an equality operator. Unfortunately the
-implementation approach choosen by boost makes a 100% correct implementation of
-comparision very dificult, if not impossible. Thus, the boost developers refused
-to implement this feature.
-
-The bad news is that really using the power of opaque function objects quickly drove
-us (Lumiera) into a situation where such an equalty test and a hash calculation on
-function objects would be necessary. The whole point of using function objects is
-the ability to ``erase'' specific details, which has the downside that the resulting
-generic objects are opaque and often dificult to manage, when it comes to storing
-and retrieving objects building on such functors.
-
-Thus I built an hack, based on the implementation details of boost::function.
-In +functor-util.hpp+ we define a +class HijackedFunction+, which has the same
-data layout as the original boost::function. After forcibly casting such an function
-(reference or pointer) into a +HijackedFunction+, we're able to inspect and evaluate
-the implementation pointers for equality comparison and hash value calculation.
-This approach works and actually detects copied functions to be _equal_, but is
-unable to pinpoint _equivalence_, e.g. functors bound to the same function with
-the same arguments through separate but otherwise identical invocations of +bind+.
-Besides, should boost or the standard library implementors eventually change the
-implementation, this workaround will break.
-
-post C++11
-^^^^^^^^^^
-As of this writing (1/2016), this still remains an unsolved issue. +
-The new standard _does indeed require a comparison_, but only a comparison against
-`nullptr`, which is equivalent to the `bool` conversion. It seems we need more.
-
-WARNING: what we have here is a really evil hack, and even the notion of ``equality''
- is not correct. We admit that real equality can not be achieved with something
- like `std::function`, but in spite of that, we do have our own needs.
-
-[red]#TODO# investigate what we _really_ need and come up with a better concept...
-
-
Binding Placeholders
~~~~~~~~~~~~~~~~~~~~
The standard allows function objects to be partially closed; this is achieved by
diff --git a/src/common/guifacade.cpp b/src/common/guifacade.cpp
index 1b11bac13..0efed9e21 100644
--- a/src/common/guifacade.cpp
+++ b/src/common/guifacade.cpp
@@ -36,7 +36,6 @@
#include "lib/sync.hpp"
#include "lib/error.hpp"
#include "lib/depend.hpp"
-#include "lib/functor-util.hpp"
#include "common/instancehandle.hpp"
#include "common/option.hpp"
diff --git a/src/lib/functor-util.hpp b/src/lib/functor-util.hpp
deleted file mode 100644
index 92ed46633..000000000
--- a/src/lib/functor-util.hpp
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- FUNCTOR-UTIL.hpp - collection of helpers for dealing with functors and signals
-
- Copyright (C) Lumiera.org
- 2008, Hermann Vosseler
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of
- the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-
-/** @file functor-util.hpp
- ** Collection of small helpers and utilities related to function objects.
- **
- ** @todo combine with meta/function-closure.hpp and reorganise
- ** @todo 2017 find out to what extent we still need that (looks obsolete)
- **
- ** @see GuiSubsysDescriptor#start (guifacade.cpp)
- ** @see MementoTie
- ** @see functor-util-test.cpp
- **
- */
-
-
-
-#ifndef FUNCTOR_UTIL_H
-#define FUNCTOR_UTIL_H
-
-#include "lib/hash-value.h"
-
-#include
-#include
-
-
-
-namespace util { ////////////TODO: refactor namespace. But probably not directly into namespace lib. Needs some more consideration though
-
- using std::function;
- using std::bind;
- using std::placeholders::_1;
-
- namespace { // hiding some nasty details...
-
- using lib::HashVal;
- using boost::hash_combine;
-
- /**
- * This Class is used to bypass the access protection
- * and break into the tr1::function implementation.
- * Thus we can implement a raw comparison function,
- * as a replacement for the missing functor comparison
- * facility. (TR1 requires an operator==, but boost
- * seemingly doesn't provide it, because it can't
- * be done correctly/properly in all cases. See
- * the section "FAQ" in the documentation of
- * the boost/function library)
- *
- * The layout of this class is chosen to mimic that
- * of the boost function implementation, without all
- * the generic type decoration. For the comparison
- * we use a conservative approach, by requiring
- * the concrete invoker, the storage manager and
- * the actual function and argument data pointers
- * to be the same.
- * @todo 2017 is this still necessary today?
- */
- class HijackedFunction
- : std::_Function_base
- {
- typedef void (*DummyInvoker) (void);
- DummyInvoker invoker_;
-
- public:
-
- friend bool
- operator== (HijackedFunction const& f1,
- HijackedFunction const& f2)
- {
- return (f1.invoker_ == f2.invoker_)
- && (f1._M_manager == f2._M_manager)
- && (f1._M_functor._M_unused._M_const_object ==
- f2._M_functor._M_unused._M_const_object );
- } // note: we don't cover any member pointer offset
-
- friend HashVal
- hash_value (HijackedFunction const& fun)
- {
- HashVal hash(0);
- hash_combine (hash, fun.invoker_);
- hash_combine (hash, fun._M_manager);
- hash_combine (hash, fun._M_functor._M_unused._M_const_object);
- return hash; // note: member pointer offset part uncovered
- }
- };
-
- }
-
-
- /** temporary workaround: tr1/functional should define
- * public comparison operators for functor objects, but
- * in the implementation provided by boost 1.34 it doesn't.
- * To get at least \em some comparison capability, we do a
- * brute force comparison of the functor's internal data.
- * @note use with caution. This implementation relies on
- * internal details of boost/function; but it is
- * rather conservative and might deem functors
- * "different" erroneously, due to garbage in
- * the internal functor data's storage */
- template
- inline bool
- rawComparison (function const& f1,
- function const& f2)
- {
- typedef HijackedFunction const& Hij;
-
- return reinterpret_cast (f1)
- == reinterpret_cast (f2);
- }
-
- /** catch-all for the comparison: functors with
- * different base type are always "different" */
- template
- 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);
- }
-
-
- /** workaround to calculate a hash value for a given function object.
- * @note use with caution. This implementation relies on internal details
- * of boost/function; it can be expected to be rather conservative,
- * i.e. yielding different hash values for objects, which actually
- * are semantically equivalent.
- * @warning especially function objects bound to member functions aren't
- * fully supported. It \em may happen that we miss differences on the
- * offset part and only hash the "this" pointer on some platform.
- */
- template
- inline HashVal
- rawHashValue (function const& fun)
- {
- typedef HijackedFunction const& Hij;
-
- return hash_value (reinterpret_cast (fun));
- }
-
-} // namespace util
-
-namespace std {
-
- /** inject into std::tr1 to be picked up by ADL:
- * @return hash value of given functor
- * @note use with caution. Hash is calculated
- * relying on undocumented boost internals.
- */
-// template
-// inline lib::HashVal
-// hash_value (function const& fun)
-// {
-// return util::rawHashValue (fun);
-// }
-
-}
-
-#endif /*FUNCTOR_UTIL_H*/
diff --git a/src/lib/meta/function-erasure.hpp b/src/lib/meta/function-erasure.hpp
index 47764a6ea..6f41e78aa 100644
--- a/src/lib/meta/function-erasure.hpp
+++ b/src/lib/meta/function-erasure.hpp
@@ -58,7 +58,6 @@
#include "lib/util.hpp"
#include "lib/error.hpp"
#include "lib/opaque-holder.hpp"
-#include "lib/functor-util.hpp"
#include
@@ -140,14 +139,6 @@ namespace meta{
{
return get>();
}
-
-
- friend bool
- operator== (StoreFunction const& o1,
- StoreFunction const& o2)
- {
- return util::rawComparison (o1.asBase(),o2.asBase());
- }
};
@@ -179,16 +170,6 @@ namespace meta{
REQUIRE (fun);
return *fun;
}
-
-
- friend bool
- operator== (StoreFunPtr const& o1,
- StoreFunPtr const& o2)
- {
- void * *fun1 = reinterpret_cast (o1.asBase());
- void * *fun2 = reinterpret_cast (o2.asBase());
- return *fun1 == *fun2;
- }
};
@@ -224,12 +205,6 @@ namespace meta{
explicit operator bool() const { return 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/meta/maybe-compare.hpp b/src/lib/meta/maybe-compare.hpp
index 3564495ba..0cb56e408 100644
--- a/src/lib/meta/maybe-compare.hpp
+++ b/src/lib/meta/maybe-compare.hpp
@@ -30,15 +30,11 @@
#define LIB_META_MAYBE_COMPARE_H
-#include "lib/functor-util.hpp"
-
-#include
namespace lib {
namespace meta{
- using std::function;
/**
* Trait template for invoking equality comparison.
@@ -54,19 +50,7 @@ namespace meta{
}
};
- /** while the boost function implementation doesn't provide comparison,
- * we'll use our private hack, which at least detects equivalence
- * in \em some cases... */
- template
- struct Comparator>
- {
- static bool
- equals (function const& f1, function const& f2)
- {
- return util::rawComparison(f1,f2);
- }
-
- };
+ /* == add specialisations here == */
template
diff --git a/src/steam/control/command-closure.hpp b/src/steam/control/command-closure.hpp
index 1951f1827..8d92a8617 100644
--- a/src/steam/control/command-closure.hpp
+++ b/src/steam/control/command-closure.hpp
@@ -112,7 +112,6 @@ namespace control {
virtual operator string() const =0;
virtual bool isValid () const =0; ///< does this closure hold a valid argument tuple?
virtual bool isCaptured () const =0; ///< does this closure hold captured UNDO state?
- virtual bool equals (CmdClosure const&) const =0; ///< is equivalent to the given other closure?
virtual void bindArguments (Arguments&) =0; ///< store a set of parameter values within this closure
virtual void bindArguments (lib::diff::Rec const&) =0; ///< store a set of parameter values, passed as GenNode sequence
virtual void unbindArguments() =0; ///< discard any parameters and return to _unbound state_
diff --git a/src/steam/control/command-impl.hpp b/src/steam/control/command-impl.hpp
index d1e06c8c0..437c7a8c4 100644
--- a/src/steam/control/command-impl.hpp
+++ b/src/steam/control/command-impl.hpp
@@ -29,8 +29,6 @@
** identity and usually located within the (pooled) storage managed by the
** CommandRegistry. Client code gets access to a specific CommandImpl through
** a Command instance, which is a small (refcounting smart-ptr) handle.
- **
- ** //TODO
**
** @see Command
** @see SteamDispatcher
@@ -246,26 +244,6 @@ namespace control {
% canUndo()
% (pClo_? string(*pClo_) : util::FAILURE_INDICATOR);
}
-
-
-
- friend bool
- operator== (CommandImpl const& ci1, CommandImpl const& ci2)
- {
- return (ci1.do_ == ci2.do_)
-// and (ci1.undo_ == ci2.undo_) // causes failure regularly, due to the missing equality on boost::function. See Ticket #294
- and (ci1.defaultPatt_ == ci2.defaultPatt_)
- and (ci1.canExec() == ci2.canExec())
- and (ci1.canUndo() == ci2.canUndo())
- and (ci1.pClo_->equals(*ci2.pClo_))
- ;
- }
-
- friend bool
- operator!= (CommandImpl const& ci1, CommandImpl const& ci2)
- {
- return not (ci1==ci2);
- }
};
diff --git a/src/steam/control/command-mutation.hpp b/src/steam/control/command-mutation.hpp
index 282443169..1184e9503 100644
--- a/src/steam/control/command-mutation.hpp
+++ b/src/steam/control/command-mutation.hpp
@@ -83,21 +83,6 @@ namespace control {
LERR_(UNBOUND_ARGUMENTS));
clo.invoke (func_);
}
-
-
-
- /// Supporting equality comparisons...
- friend bool
- operator== (Mutation const& m1, Mutation const& m2)
- {
- return (m1.func_ == m2.func_);
- }
-
- friend bool
- operator!= (Mutation const& m1, Mutation const& m2)
- {
- return not (m1==m2);
- }
};
diff --git a/src/steam/control/command-op-closure.hpp b/src/steam/control/command-op-closure.hpp
index f97282a74..e04040482 100644
--- a/src/steam/control/command-op-closure.hpp
+++ b/src/steam/control/command-op-closure.hpp
@@ -64,7 +64,6 @@ namespace control {
using lib::meta::NullType;
using lib::meta::buildTuple;
- using lib::meta::equals_safeInvoke;
using lib::TypedAllocationManager;
using std::function;
using std::ostream;
@@ -96,20 +95,11 @@ namespace control {
/////////////////////////////////////////////////////////////TICKET #798 : we need to pick up arguments from a lib::diff::Record.
-
ostream&
dump (ostream& output) const
{
return BASE::dump (output << element() << ',');
}
-
- friend bool
- compare (ParamAccessor const& p1, ParamAccessor const& p2)
- {
- return equals_safeInvoke (p1.element(), p2.element())
- && compare ( static_cast(p1)
- , static_cast(p2) );
- }
};
template
@@ -135,12 +125,6 @@ namespace control {
{
return output;
}
-
- friend bool
- compare (ParamAccessor const&, ParamAccessor const&)
- {
- return true;
- }
};
@@ -218,11 +202,6 @@ namespace control {
else
return dumped+")";
}
-
-
- /// Supporting equality comparisons...
- friend bool operator== (OpClosure const& c1, OpClosure const& c2) { return compare (c1.params_, c2.params_); }
- friend bool operator!= (OpClosure const& c1, OpClosure const& c2) { return not (c1 == c2); }
};
diff --git a/src/steam/control/command-simple-closure.hpp b/src/steam/control/command-simple-closure.hpp
index 0a64ec06f..dc10d49f5 100644
--- a/src/steam/control/command-simple-closure.hpp
+++ b/src/steam/control/command-simple-closure.hpp
@@ -204,30 +204,6 @@ namespace control {
{
arguments_.template create();
}
-
-
- bool
- equals (CmdClosure const& other) const override
- {
- const SimpleClosure* toCompare = dynamic_cast (&other);
- return (toCompare)
- and (*this == *toCompare);
- }
-
- /// Supporting equality comparisons...
- friend bool
- operator== (SimpleClosure const& a1, SimpleClosure const& a2)
- {
- return (a1.arguments_->isValid() == a2.arguments_->isValid())
- and (*a1.arguments_ == *a2.arguments_)
- ;
- }
-
- friend bool
- operator!= (SimpleClosure const& a1, SimpleClosure const& a2)
- {
- return not (a1 == a2);
- }
};
diff --git a/src/steam/control/command-storage-holder.hpp b/src/steam/control/command-storage-holder.hpp
index e818f1c16..236c228a8 100644
--- a/src/steam/control/command-storage-holder.hpp
+++ b/src/steam/control/command-storage-holder.hpp
@@ -255,31 +255,6 @@ namespace control {
{
return memento_->getState();
}
-
- bool
- equals (CmdClosure const& other) const
- {
- const StorageHolder* toCompare = dynamic_cast (&other);
- return (toCompare)
- and (*this == *toCompare);
- }
-
- /// Supporting equality comparisons...
- friend bool
- operator== (StorageHolder const& a1, StorageHolder const& a2)
- {
- return (a1.arguments_->isValid() == a2.arguments_->isValid())
- && (*a1.arguments_ == *a2.arguments_)
- && (a1.memento_->isValid() == a2.memento_->isValid())
- && (*a1.memento_ == *a2.memento_)
- ;
- }
-
- friend bool
- operator!= (StorageHolder const& a1, StorageHolder const& a2)
- {
- return not (a1 == a2);
- }
};
diff --git a/src/steam/control/command.cpp b/src/steam/control/command.cpp
index 2844408f4..9f09f10f5 100644
--- a/src/steam/control/command.cpp
+++ b/src/steam/control/command.cpp
@@ -369,13 +369,6 @@ namespace control {
}
- bool
- Command::equivalentImpl (Command const& c1, Command const& c2)
- {
- return c1.impl() == c2.impl();
- }
-
-
Symbol
Command::getID() const noexcept
{
diff --git a/src/steam/control/command.hpp b/src/steam/control/command.hpp
index 7b1191976..33f3dd5f2 100644
--- a/src/steam/control/command.hpp
+++ b/src/steam/control/command.hpp
@@ -223,7 +223,6 @@ namespace control {
private:
void setArguments (Arguments&);
void setArguments (lib::diff::Rec const&);
- static bool equivalentImpl (Command const&, Command const&);
};
diff --git a/src/steam/control/memento-tie.hpp b/src/steam/control/memento-tie.hpp
index 71535cf45..50f70f97a 100644
--- a/src/steam/control/memento-tie.hpp
+++ b/src/steam/control/memento-tie.hpp
@@ -44,7 +44,6 @@
#include "lib/meta/function-closure.hpp"
#include "steam/control/command-signature.hpp"
#include "lib/replaceable-item.hpp"
-#include "lib/functor-util.hpp"
#include "lib/format-obj.hpp"
#include "lib/util.hpp"
@@ -202,20 +201,6 @@ namespace control {
/** for diagnostics: include format-util.hpp */
operator std::string() const;
-
- /// Supporting equality comparisons...
- friend bool
- operator== (MementoTie const& m1, MementoTie const& m2)
- {
- return ((!m1.undo_ && !m2.undo_ && !m1.capture_ && !m2.capture_) // either no valid functions
- || ( util::rawComparison(m1.undo_, m2.undo_ ) // or identical functions
- && util::rawComparison(m1.capture_,m2.capture_ )
- )
- )
- && (m1.isCaptured_ == m2.isCaptured_) // either both not captured or identical state
- && (!m1.isCaptured_
- || equals_safeInvoke (m1.memento_, m2.memento_));
- }
};
diff --git a/src/steam/engine/type-handler.hpp b/src/steam/engine/type-handler.hpp
index cf49bcd9e..0eae6666f 100644
--- a/src/steam/engine/type-handler.hpp
+++ b/src/steam/engine/type-handler.hpp
@@ -44,7 +44,6 @@
#include "lib/error.hpp"
#include "lib/hash-value.h"
-#include "lib/functor-util.hpp"
#include
#include
diff --git a/tests/core/steam/control/command-argument-test.cpp b/tests/core/steam/control/command-argument-test.cpp
index ba3b39c80..1b6a4155b 100644
--- a/tests/core/steam/control/command-argument-test.cpp
+++ b/tests/core/steam/control/command-argument-test.cpp
@@ -213,7 +213,6 @@ namespace test {
Tracker::instanceCnt = 0;
createTuples (testTuples);
- checkArgumentComparison ();
serialiseArgTuples (testTuples);
testTuples.clear();
@@ -291,50 +290,6 @@ namespace test {
- /** @test verify the comparison operators */
- void
- checkArgumentComparison ()
- {
- StorageHolder one, two;
- CHECK (one == two); // empty, identically typed argument holders -->equal
-
- one.tie(dummyU,dummyC)
- .tieCaptureFunc()(1,9);
- CHECK (one != two); // now one contains captured UNDO state
-
- two.tie(dummyU,dummyC)
- .tieCaptureFunc()(1,9);
- two.memento() = one.memento(); // put the same UNDO state in both
- CHECK (one == two); // ...makes them equal again
-
- one.storeTuple (make_tuple (1,2));
- CHECK (one != two); // verify argument tuple comparison
- CHECK (two != one);
- CHECK (!isnil (one));
- CHECK ( isnil (two));
-
- two.storeTuple (make_tuple (3,4));
- CHECK (!isnil (two));
- CHECK (one != two);
- CHECK (two != one);
-
- one.storeTuple (make_tuple (1,4));
- CHECK (!isnil (one));
- CHECK (one != two);
- CHECK (two != one);
-
- one.storeTuple (make_tuple (3,4));
- CHECK (!isnil (one));
- CHECK (one == two);
- CHECK (two == one);
- two.memento() = 12345;
- CHECK (!isnil (two));
- CHECK (one != two);
- CHECK (two != one);
- }
-
-
-
/** @test simulate a complete command lifecycle with regards to the
* storage handling of the command parameters and state memento.
*/
diff --git a/tests/core/steam/control/command-clone-builder-test.cpp b/tests/core/steam/control/command-clone-builder-test.cpp
index bccb0df22..27d399b17 100644
--- a/tests/core/steam/control/command-clone-builder-test.cpp
+++ b/tests/core/steam/control/command-clone-builder-test.cpp
@@ -137,7 +137,6 @@ namespace test {
CHECK (orig && copy);
CHECK (orig->canExec());
CHECK (copy->canExec());
- CHECK (orig == copy);
// prepare for command invocation on implementation level....
@@ -151,13 +150,11 @@ namespace test {
long state_after_exec1 = command1::check_;
CHECK (command1::check_ > 0);
CHECK (orig->canUndo());
- CHECK (orig != copy);
CHECK (!copy->canUndo());
testExec.exec (*copy, "Execute clone"); // EXEC 2
CHECK (command1::check_ != state_after_exec1);
CHECK (copy->canUndo());
- CHECK (copy != orig);
// invoke UNDO on the clone
testExec.undo (*copy, "Undo clone"); // UNDO 2
@@ -166,8 +163,6 @@ namespace test {
// invoke UNDO on original
testExec.undo (*orig, "Undo original"); // UNDO 1
CHECK (command1::check_ ==0);
-
- CHECK (copy != orig);
}
};
diff --git a/tests/core/steam/control/command-equality-test.cpp b/tests/core/steam/control/command-equality-test.cpp
index 963bee5d5..513a21abf 100644
--- a/tests/core/steam/control/command-equality-test.cpp
+++ b/tests/core/steam/control/command-equality-test.cpp
@@ -98,30 +98,15 @@ namespace test {
/*************************************************************************************//**
* @test cover command equality detection.
- * Two commands are deemed equivalent, if they
- * - build on the same Mutation functors
- * - are either both incomplete or
- * - are bound to equivalent arguments
- * - hold equivalent undo state (memento)
- * To conduct this test, we set up two sets of functions, and then build both complete
- * command objects and command implementation facilities based on them.
- *
- * @note The hidden problem with those comparisons is the equivalence of function objects.
- * While required by TR1, unfortunately lib boost refuses to implement functor equality.
- * Which forces us to resort to a low level hack, based on internals of the boost function
- * implementation. This workaround reliably pinpoints differing functions, but sometimes
- * fails to detect equivalent functions under specific circumstances (e.g. when there is
- * binding involved, and / or the binders have been cloned). Bottom line: \c == is
- * reliable, \c != might be wrong.
+ * Two commands are deemed equivalent, if they are based on the same CommandImpl record.
+ * This means, we only rely on the _identity_ of those commands, but do not check the
+ * _equivalence_ of their backing implementations. The latter can not be possibly
+ * implemented in a totally airtight fashion, and for this reason, the C++ standard
+ * decided not to support comparison between std::function objects.
*
* @see control::Command
- * @see control::CmdClosure
- * @see control::Mutation
- * @see control::UndoMutation
- * @see control::MementoTie
* @see control::CommandImpl
* @see command-basic-test.hpp
- * @see functor-util.hpp functor equality workaround
*/
class CommandEquality_test : public Test
{
@@ -133,148 +118,6 @@ namespace test {
CHECK (&capt_1 != &capt_2);
CHECK (&undo_1 != &undo_2);
- verifyMutationEquality();
- verifyMementoEquality();
- verifyClosureEquality();
- verifyCommandEquality();
- }
-
-
-
- void
- verifyMutationEquality()
- {
- 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);
- CHECK (mut1 == mut1);
- CHECK (mut1 == muti);
- CHECK (muti == mut1);
- CHECK (mut1 != mut2);
- CHECK (mut2 != mut1);
- CHECK (muti != mut2);
- CHECK (mut2 != muti);
-
- Mutation umu (oFun_empty); // empty operation function
- CHECK (mut1 != umu);
-
- Mutation mut_u0 (uFun_empty); // empty undo function
- CHECK (mut_u0 != umu);
- CHECK (mut_u0 != muti);
-
- Mutation mut_u1 (uFun_1);
- CHECK (mut_u0 != mut_u1); // function signatures differing
- }
-
-
- void
- verifyClosureEquality()
- {
- ArgHolder a1 (make_tuple ('a'));
- ArgHolder a2 (make_tuple ('a'));
- ArgHolder a3 (make_tuple ('z'));
- CHECK (a1 == a1);
- CHECK (a1 == a2);
- CHECK (a2 == a1);
- CHECK (a1 != a3);
- CHECK (a3 != a1);
- CHECK (a2 != a3);
- CHECK (a3 != a2);
-
- typedef StorageHolder Storage;
- Storage abuff1;
- Storage abuff2;
- CHECK (abuff1 == abuff2);
-
- TypedArguments newArgs (make_tuple ('z'));
- abuff1.bindArguments(newArgs);
- CHECK (abuff1 != abuff2);
- abuff2.bindArguments(newArgs);
- CHECK (abuff1 == abuff2);
- UndoMutation umu1 (abuff1.tie (undo_1, capt_1));
- CHECK (abuff1 != abuff2); // abuff2 isn't tied yet, i.e. has no undo/capture function
- UndoMutation umu2 (abuff2.tie (undo_1, capt_1));
- CHECK (abuff1 == abuff2); // same capture function, no memento state!
-
- Closure args {make_tuple ('u')};
- umu1.captureState(args);
- CHECK (abuff1 != abuff2);
- umu2.captureState(args);
- CHECK (abuff1 == abuff2); // same functions, same memento state
-
- check_ += "fake"; // manipulate the "state" to be captured
- umu2.captureState(args); // capture again...
- CHECK (abuff1 != abuff2); // captured memento differs!
-
- UndoMutation umu3 (abuff2.tie (undo_1, capt_2));
- umu3.captureState(args);
- CHECK (abuff1 != abuff2); // differing functions detected
- }
-
-
- void
- verifyMementoEquality()
- {
- 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);
-
- CHECK (m11 == m11);
- CHECK (m12 == m12);
- CHECK (m21 == m21);
- CHECK (m22 == m22);
- CHECK (!(m11 != m11));
-
- CHECK (m11 != m12);
- CHECK (m11 != m21);
- CHECK (m11 != m22);
- CHECK (m12 != m11);
- CHECK (m12 != m21);
- CHECK (m12 != m22);
- CHECK (m21 != m11);
- CHECK (m21 != m12);
- CHECK (m21 != m22);
- CHECK (m22 != m11);
- CHECK (m22 != m12);
- CHECK (m22 != m21);
-
- MemHolder m22x (m22); // clone copy
- CHECK (!m22x);
- CHECK (m22 == m22x); // same functions, no state --> equal
-
- m22x.tieCaptureFunc() ('x'); // produce a memento state
- CHECK (!isnil (m22x.getState()));
-
- CHECK (m22 != m22x);
- m22.tieCaptureFunc() ('x'); // get same value into the memento within m22
- CHECK (m22 == m22x);
-
- // document shortcomings on UndoMutation comparisons
- UndoMutation umu11 (m11);
- UndoMutation umu12 (m11); // note: due to cloning the embedded functor,
- CHECK (umu11 != umu12); // our hacked-in comparison operator fails
- }
-
-
- void
- verifyCommandEquality()
- {
CommandDef (COMMAND1)
.operation (oper_1)
.captureUndo (capt_1)
diff --git a/tests/core/steam/control/command-registry-test.cpp b/tests/core/steam/control/command-registry-test.cpp
index 0e9e118fa..364b46b16 100644
--- a/tests/core/steam/control/command-registry-test.cpp
+++ b/tests/core/steam/control/command-registry-test.cpp
@@ -217,7 +217,6 @@ namespace test {
CHECK (2+cnt_inst == registry.instance_count());
CHECK (!isSameObject (*pImpl, *clone));
- CHECK (*pImpl == *clone);
CHECK (!pImpl->canExec());
typedef Types ArgType;
@@ -226,12 +225,10 @@ namespace test {
CHECK (pImpl->canExec());
CHECK (!clone->canExec()); // this proves the clone has indeed a separate identity
- CHECK (*pImpl != *clone);
// discard the first clone and overwrite with a new one
clone = registry.createCloneImpl(*pImpl);
CHECK (2+cnt_inst == registry.instance_count());
- CHECK (*pImpl == *clone);
CHECK (clone->canExec());
clone.reset();
diff --git a/tests/core/steam/control/memento-tie-test.cpp b/tests/core/steam/control/memento-tie-test.cpp
index 7b5e73495..0bc5d96cb 100644
--- a/tests/core/steam/control/memento-tie-test.cpp
+++ b/tests/core/steam/control/memento-tie-test.cpp
@@ -87,7 +87,6 @@ namespace test {
run (Arg)
{
checkStateCapturingMechanism();
- verifyComparisons();
}
@@ -134,50 +133,6 @@ namespace test {
bound_undo_func(3*rr);
CHECK (testVal == -20 + 3*rr - (5+rr));
}
-
-
- void
- verifyComparisons()
- {
- function u1_fun; // deliberately unbound
- function u2_fun = undo;
- function< int(short)> c1_fun;
- function< int(short)> c2_fun = capture;
-
- MemHolder m11 (u1_fun, c1_fun);
- MemHolder m12 (u1_fun, c2_fun);
- MemHolder m21 (u2_fun, c1_fun);
- MemHolder m22 (u2_fun, c2_fun);
-
- CHECK (!m11 && !m12 && !m21 && !m22);
- CHECK ( (m11 == m11));
- CHECK (!(m11 != m11));
-
- CHECK (m11 != m12);
- CHECK (m11 != m21);
- CHECK (m11 != m22);
- CHECK (m12 != m11);
- CHECK (m12 != m21);
- CHECK (m12 != m22);
- CHECK (m21 != m11);
- CHECK (m21 != m12);
- CHECK (m21 != m22);
- CHECK (m22 != m11);
- CHECK (m22 != m12);
- CHECK (m22 != m21);
-
- MemHolder m22x (m22); // clone copy
- CHECK (!m22x);
- CHECK (m22 == m22x); // same functions, no state --> equal
-
- testVal = 0;
- m22x.tieCaptureFunc() (1 + (rand() % 9)); // produce a random memento value != 0
- CHECK (0 < m22x.getState());
-
- CHECK (m22 != m22x);
- m22.tieCaptureFunc() (m22x.getState()); // get the same value into the memento within m22
- CHECK (m22 == m22x);
- }
};
diff --git a/tests/library/functor-util-test.cpp b/tests/library/functor-util-test.cpp
deleted file mode 100644
index ad1e11c7b..000000000
--- a/tests/library/functor-util-test.cpp
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- FunctorUtil(Test) - verifying function object and signal utilities
-
- Copyright (C) Lumiera.org
- 2009, Hermann Vosseler
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of
- the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-* *****************************************************/
-
-/** @file functor-util-test.cpp
- ** unit test \ref FunctorUtil_test
- */
-
-
-
-#include "lib/test/run.hpp"
-#include "lib/functor-util.hpp"
-
-#include
-#include
-#include
-
-using lib::HashVal;
-using std::cout;
-using std::function;
-using boost::hash; // note: only boost::hash allows for easy defining of custom hash functions
-
-
-namespace util {
-namespace test {
-
-
- namespace {
-
- void fun1 (int i) { cout << "fun1 (" << i << ")\n"; }
- void fun2 (int i) { cout << "fun2 (" << i << ")\n"; }
-
- struct Dummy
- {
- void gummi (int i) { cout << "gummi (" << i << ")\n"; }
- };
- }
-
-
-
-
-
- /*****************************************************************//**
- * @test verify some aspects of the functor-util's behaviour.
- * At times, this is just a scrapbook for new ideas....
- */
- class FunctorUtil_test : public Test
- {
- virtual void
- run (Arg)
- {
-// verifyBruteForceComparison();
-// verifyHashThroughBackdoor();
- }
-
- typedef function Fvi;
- typedef function Fiv;
-
- typedef function Fvv;
-
-
- /** @test workaround for the missing functor comparison operator */
-// void
-// verifyBruteForceComparison()
-// {
-// Fvi f0;
-// Fvi f1 (fun1);
-// Fvi f2 (fun2);
-//
-// CHECK (!rawComparison(f0, f1));
-// CHECK (!rawComparison(f1, f2));
-// CHECK (!rawComparison(f0, f2));
-//
-// Fvi f22 (f2);
-// CHECK ( rawComparison(f2, f22));
-//
-// f1 = f2;
-// CHECK ( rawComparison(f1, f2));
-//
-// CHECK (!rawComparison(f0, Fvi())); // note: can't detect they are equivalent
-// CHECK (!rawComparison(f0, Fiv()));
-//
-// f1 = bind (fun2, _1);
-// CHECK (!rawComparison(f1, f2));
-//
-// Dummy dum1, dum2;
-// Fvi fm1 = bind (&Dummy::gummi, dum1, _1);
-// Fvi fm2 = bind (&Dummy::gummi, dum2, _1);
-// Fvv fm3 = bind (&Dummy::gummi, dum1, 23);
-// Fvv fm4 = bind (&Dummy::gummi, dum1, 24);
-// Fvv fm5 = bind (&Dummy::gummi, dum2, 24);
-// Fvv fm6 = bind (&Dummy::gummi, dum2, 24);
-//
-// CHECK (!rawComparison(f1, fm1));
-//
-// CHECK (!rawComparison(fm1, fm2));
-// CHECK (!rawComparison(fm1, fm3));
-// CHECK (!rawComparison(fm1, fm4));
-// CHECK (!rawComparison(fm1, fm5));
-// CHECK (!rawComparison(fm1, fm6));
-// CHECK (!rawComparison(fm2, fm3));
-// CHECK (!rawComparison(fm2, fm4));
-// CHECK (!rawComparison(fm2, fm5));
-// CHECK (!rawComparison(fm2, fm6));
-// CHECK (!rawComparison(fm3, fm4));
-// CHECK (!rawComparison(fm3, fm5));
-// CHECK (!rawComparison(fm3, fm6));
-// CHECK (!rawComparison(fm4, fm5)); // note: same argument but different functor instance
-// CHECK (!rawComparison(fm4, fm6));
-// CHECK (!rawComparison(fm5, fm6)); // again: can't detect they are equivalent
-// }
-
-
- /** @test workaround for missing standard hash
- * calculation for functor objects.
- * Workaround relying on boost
- * implementation internals */
-// void
-// verifyHashThroughBackdoor()
-// {
-// Fvi f0;
-// Fvi f1 (fun1);
-// Fvi f2 (fun2);
-// Fvi f22 (f2);
-//
-// hash calculateHash;
-// CHECK (calculateHash (f0));
-// CHECK (calculateHash (f1));
-// CHECK (calculateHash (f2));
-// CHECK (calculateHash (f22));
-//
-// HashVal h0 = calculateHash (f0);
-// HashVal h1 = calculateHash (f1);
-// HashVal h2 = calculateHash (f2);
-// HashVal h22 = calculateHash (f22);
-//
-// CHECK (h0 != h1);
-// CHECK (h0 != h2);
-// CHECK (h1 != h2);
-//
-// CHECK (h2 == h22);
-//
-// f1 = f2;
-// h1 = calculateHash (f1);
-// CHECK (h1 == h2);
-// CHECK (h1 != h0);
-//
-// CHECK (h0 != calculateHash (Fvi())); // note: equivalence not detected
-//
-// // checking functors based on member function(s)
-// Dummy dum1, dum2;
-// Fvi fm1 = bind (&Dummy::gummi, dum1, _1);
-// Fvi fm2 = bind (&Dummy::gummi, dum2, _1);
-// Fvv fm3 = bind (&Dummy::gummi, dum1, 23);
-// Fvv fm4 = bind (&Dummy::gummi, dum1, 24);
-// Fvv fm5 = bind (&Dummy::gummi, dum2, 24);
-// Fvv fm6 = bind (&Dummy::gummi, dum2, 24);
-//
-// HashVal hm1 = calculateHash (fm1);
-// HashVal hm2 = calculateHash (fm2);
-//
-// hash calculateHashVV;
-// HashVal hm3 = calculateHashVV (fm3);
-// HashVal hm4 = calculateHashVV (fm4);
-// HashVal hm5 = calculateHashVV (fm5);
-// HashVal hm6 = calculateHashVV (fm6);
-//
-// CHECK (h1 != hm1);
-//
-// CHECK (hm1 != hm2);
-// CHECK (hm1 != hm3);
-// CHECK (hm1 != hm4);
-// CHECK (hm1 != hm5);
-// CHECK (hm1 != hm6);
-// CHECK (hm2 != hm3);
-// CHECK (hm2 != hm4);
-// CHECK (hm2 != hm5);
-// CHECK (hm2 != hm6);
-// CHECK (hm3 != hm4);
-// CHECK (hm3 != hm5);
-// CHECK (hm3 != hm6);
-// CHECK (hm4 != hm5);
-// CHECK (hm4 != hm6);
-// CHECK (hm5 != hm6); // again: unable to detect the equivalence
-// }
- };
-
-
- /** Register this test class... */
- LAUNCHER (FunctorUtil_test, "unit common");
-
-
-
-}} // namespace util::test
diff --git a/tests/library/meta/function-erasure-test.cpp b/tests/library/meta/function-erasure-test.cpp
index 9cda013e6..60dfeb7f5 100644
--- a/tests/library/meta/function-erasure-test.cpp
+++ b/tests/library/meta/function-erasure-test.cpp
@@ -88,27 +88,6 @@ namespace test {
check_FunctPtrHolder(Efp(testFunc),Efp(&testFunc), Efp(returnIt));
check_VoidPtrHolder(Evoid(testFunc),Evoid(&testFunc),Evoid(returnIt));
- check_Comparisons (Efun(testFunc), Efun(bindFunc));
- check_Comparisons (Efun(testFunc), Efun(pAplFunc));
- check_Comparisons (Efun(testFunc), Efun(membFunc));
- check_Comparisons (Efun(testFunc), Efun(getterFunc));
- check_Comparisons (Efun(bindFunc), Efun(pAplFunc));
- check_Comparisons (Efun(bindFunc), Efun(membFunc));
- check_Comparisons (Efun(bindFunc), Efun(getterFunc));
- check_Comparisons (Efun(pAplFunc), Efun(membFunc));
- check_Comparisons (Efun(pAplFunc), Efun(getterFunc));
- check_Comparisons (Efun(membFunc), Efun(getterFunc));
-
- check_Comparisons (Efp(testFunc), Efp(returnIt));
- check_Comparisons (Evoid(testFunc), Evoid(returnIt));
-
- CHECK ( detect_Clone (Efun(testFunc)));
- CHECK (!detect_Clone (Efun(bindFunc))); //note equality not detected when cloning a bind term
- CHECK (!detect_Clone (Efun(pAplFunc))); //similarly
- CHECK (!detect_Clone (Efun(membFunc))); //analogous for bound member function
- CHECK ( detect_Clone (Efp(testFunc) ));
- CHECK ( detect_Clone (Evoid(testFunc)));
-
detect_unboundFunctor(Efun(testFunc), Efun(getterFunc), Efun(membFunc));
detect_unboundFunctor(Efp(testFunc),Efp(&testFunc), Efp(returnIt));
detect_unboundFunctor(Evoid(testFunc),Evoid(&testFunc),Evoid(returnIt));
@@ -194,11 +173,6 @@ namespace test {
CHECK (_sum_ == 10+'a'+20+'b'+30+'c');
CHECK (_sum_ == (f3.getFun()) () );
-
-#if false ////////////////////////////////////////////////////////TODO: restore throwing ASSERT
- VERIFY_ERROR (ASSERTION, f1.getFun() );
-#endif////////////////////////////////////////////////////////////
-
}
@@ -231,27 +205,6 @@ namespace test {
} // likely to result in heap corruption or SEGV
- template
- void
- check_Comparisons (HOL h1, HOL h2)
- {
- CHECK (h1 == h1); CHECK (!(h1 != h1));
- CHECK (h2 == h2); CHECK (!(h2 != h2));
-
- CHECK (h1 != h2);
- CHECK (h2 != h1);
- }
-
-
- template
- bool
- detect_Clone (HOL const& h1)
- {
- HOL clone (h1);
- return (clone == h1);
- }
-
-
template
void
detect_unboundFunctor (HOL h1, HOL h2, HOL h3)
diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm
index cdba0726f..7cbd61f5e 100644
--- a/wiki/thinkPad.ichthyo.mm
+++ b/wiki/thinkPad.ichthyo.mm
@@ -44930,7 +44930,8 @@
-
+
+
@@ -45162,8 +45163,8 @@
-
-
+
+
@@ -45255,11 +45256,11 @@
-
-
-
-
-
+
+
+
+
+
@@ -45731,7 +45732,8 @@
-
+
+
@@ -45763,7 +45765,7 @@
-
+
@@ -45779,7 +45781,7 @@
-
+
@@ -45793,8 +45795,6 @@
-
-
@@ -45939,11 +45939,10 @@
-
-
-
-
-
+
+
+
+
@@ -45956,10 +45955,9 @@
er wollte "versuchen, Lumiera zu bauen"
-
-
-
-
+
+
+
@@ -45988,8 +45986,7 @@
wann sind Funktoren äquivalent ??
-
-
+
@@ -46008,8 +46005,7 @@
sei die Dose offen...
-
-
+