WIP draft how the equality comparison on a function erasure could work

This commit is contained in:
Fischlurch 2009-10-04 16:43:49 +02:00
parent 6a737a5838
commit 5068016805
5 changed files with 105 additions and 12 deletions

View file

@ -57,8 +57,10 @@
#include "lib/error.hpp"
#include "lib/bool-checkable.hpp"
#include "lib/opaque-holder.hpp"
#include "lib/functor-util.hpp"
#include <tr1/functional>
#include <boost/operators.hpp>
namespace lumiera {
@ -67,6 +69,33 @@ namespace typelist{
using std::tr1::function;
using util::unConst;
namespace { // comparison access helper functions
typedef void* RawFunc; ///////////////////TODO
template<class FH>
RawFunc
accessRaw (FH funHolder)
{
////////////////TODO
};
template<class FH>
struct IsEqualTo
{
RawFunc ofunc_;
IsEqualTo (FH o)
: ofunc_(o)
{ }
bool
operator() (RawFunc func)
{
return util::rawComparison(func, ofunc_);
}
};
}
/******************************************************
@ -86,12 +115,19 @@ namespace typelist{
*/
template<class FH>
struct FunErasure
: FH
: boost::equality_comparable< FunErasure
, FH >
{
template<typename FUN>
FunErasure (FUN const& functor)
: FH(functor)
{ }
friend bool
operator== (FunErasure const& fe1, FunErasure const& fe2)
{
return fe1.query (IsEqualTo (fe2));
}
};
@ -195,6 +231,13 @@ namespace typelist{
return *reinterpret_cast<SIG*> (funP_);
}
template<class FUN>
bool
query (FUN predicate)
{
return predicate (funP_);
}
bool
isValid() const

View file

@ -475,6 +475,21 @@ 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<typename RET, typename FUN>
RET
apply (FUN query)
{
BaseP asBase = buff().getBase();
ASSERT (asBase);
return query (asBase);
}
bool
empty() const
{

View file

@ -51,6 +51,7 @@
#include "proc/control/command-closure.hpp"
#include "proc/control/memento-tie.hpp"
#include <boost/operators.hpp>
#include <iostream>
#include <string>
@ -72,6 +73,7 @@ namespace control {
* concealed (erased) on the interface.
*/
class Mutation
: public boost::equality_comparable<Mutation>
{
const CmdFunctor func_;
@ -92,6 +94,14 @@ namespace control {
clo.invoke (func_);
}
/// Supporting equality comparisons...
friend bool
operator== (Mutation const& m1, Mutation const& m2)
{
return (m1.func_ == m2.func_);
}
};

View file

@ -85,16 +85,14 @@ namespace test {
struct Testframe ///< test data set
{
char param;
function<Sig_oper> o_Fun;
function<Sig_capt> c_Fun;
function<Sig_undo> u_Fun;
Sig_oper & o_Fun;
Sig_capt & c_Fun;
Sig_undo & u_Fun;
};
Testframe data1 = {'a', &oper_1, &capt_1, &undo_1};
Testframe data2 = {'z', &oper_2, &capt_2, &undo_2};
Testframe data1 = {oper_1, capt_1, undo_1};
Testframe data2 = {oper_2, capt_2, undo_2};
Testframe nullD;
}
@ -168,13 +166,13 @@ namespace test {
void
verifyClosureEquality()
{
ArgHolder a1 (tuple::make (data1.param));
ArgHolder a2 (tuple::make (data2.param));
ArgHolder a1 (tuple::make ('a'));
ArgHolder a2 (tuple::make ('z'));
ASSERT (a1 == a1);
ASSERT (a1 != a2);
ASSERT (a2 != a1);
TypedArguments<ArgTuple> newArgs (tuple::make (data2.param));
TypedArguments<ArgTuple> newArgs (tuple::make ('z'));
a1.bindArguments(newArgs);
ASSERT (a1 == a2);
ASSERT (a2 == a1);

View file

@ -84,6 +84,20 @@ 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), Efun(returnIt));
check_Comparisons (Evoid(testFunc), Evoid(returnIt));
detect_unboundFunctor(Efun(testFunc), Efun(getterFunc), Efun(membFunc));
detect_unboundFunctor(Efp(testFunc),Efp(&testFunc), Efp(returnIt));
detect_unboundFunctor(Evoid(testFunc),Evoid(&testFunc),Evoid(returnIt));
@ -208,7 +222,20 @@ namespace test {
template<class HOL>
void
detect_unboundFunctor(HOL h1, HOL h2, HOL h3)
check_Comparisons (HOL h1, HOL h2)
{
ASSERT (h1 != h2);
ASSERT (h2 != h1);
HOL clone (h1);
ASSERT (clone == h1);
ASSERT (clone != h2);
}
template<class HOL>
void
detect_unboundFunctor (HOL h1, HOL h2, HOL h3)
{
// fabricate an unbound functor...