add operator== to Functor, initiated by Eric Beyeler
git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@662 7ec92016-0320-0410-acc4-a06ded1c099a
This commit is contained in:
parent
c272535c72
commit
50d35c6196
2 changed files with 244 additions and 12 deletions
|
@ -34,6 +34,12 @@
|
|||
//#define LOKI_FUNCTOR_IS_NOT_A_SMALLOBJECT
|
||||
#endif
|
||||
|
||||
#ifndef LOKI_FUNCTORS_ARE_COMPARABLE
|
||||
//#define LOKI_FUNCTORS_ARE_COMPARABLE
|
||||
#endif
|
||||
|
||||
//#define LOKI_FUNCTOR_DEBUG
|
||||
|
||||
/// \namespace Loki
|
||||
/// All classes of Loki are in the Loki namespace
|
||||
namespace Loki
|
||||
|
@ -58,7 +64,8 @@ namespace Loki
|
|||
#endif
|
||||
|
||||
typedef R ResultType;
|
||||
|
||||
typedef FunctorImplBase<R, ThreadingModel> FunctorImplBaseType;
|
||||
|
||||
typedef EmptyType Parm1;
|
||||
typedef EmptyType Parm2;
|
||||
typedef EmptyType Parm3;
|
||||
|
@ -85,10 +92,25 @@ namespace Loki
|
|||
static U* Clone(U* pObj)
|
||||
{
|
||||
if (!pObj) return 0;
|
||||
#ifdef LOKI_FUNCTOR_DEBUG
|
||||
U* pClone = dynamic_cast<U*>(pObj->DoClone());
|
||||
#else
|
||||
U* pClone = static_cast<U*>(pObj->DoClone());
|
||||
#endif
|
||||
assert(typeid(*pClone) == typeid(*pObj));
|
||||
return pClone;
|
||||
}
|
||||
|
||||
|
||||
#ifdef LOKI_FUNCTORS_ARE_COMPARABLE
|
||||
|
||||
virtual bool operator==(const FunctorImplBase&) const = 0;
|
||||
|
||||
// there is no static information if Functor holds a member function
|
||||
// or a free function; this is the main difference to tr1::function
|
||||
virtual bool isMemberFuncPtr() const = 0;
|
||||
#endif
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -936,6 +958,28 @@ namespace Loki
|
|||
|
||||
LOKI_DEFINE_CLONE_FUNCTORIMPL(FunctorHandler)
|
||||
|
||||
|
||||
#ifdef LOKI_FUNCTORS_ARE_COMPARABLE
|
||||
|
||||
bool isMemberFuncPtr() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator==(const typename Base::FunctorImplBaseType& rhs) const
|
||||
{
|
||||
if( rhs.isMemberFuncPtr() )
|
||||
return false; // cannot be equal
|
||||
#ifdef LOKI_FUNCTOR_DEBUG
|
||||
const FunctorHandler& fh = dynamic_cast<const FunctorHandler&>(rhs);
|
||||
#else
|
||||
const FunctorHandler& fh = static_cast<const FunctorHandler&>(rhs);
|
||||
#endif
|
||||
// if this line gives a compiler error, you are using a function object.
|
||||
// you need to implement bool MyFnObj::operator == (const MyFnObj&) const;
|
||||
return f_==fh.f_;
|
||||
}
|
||||
#endif
|
||||
// operator() implementations for up to 15 arguments
|
||||
|
||||
ResultType operator()()
|
||||
|
@ -1044,7 +1088,31 @@ namespace Loki
|
|||
{}
|
||||
|
||||
LOKI_DEFINE_CLONE_FUNCTORIMPL(MemFunHandler)
|
||||
|
||||
|
||||
|
||||
#ifdef LOKI_FUNCTORS_ARE_COMPARABLE
|
||||
|
||||
bool isMemberFuncPtr() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator==(const typename Base::FunctorImplBaseType& rhs) const
|
||||
{
|
||||
if(!rhs.isMemberFuncPtr())
|
||||
return false;
|
||||
|
||||
#ifdef LOKI_FUNCTOR_DEBUG
|
||||
const MemFunHandler& mfh = dynamic_cast<const MemFunHandler&>(rhs);
|
||||
#else
|
||||
const MemFunHandler& mfh = static_cast<const MemFunHandler&>(rhs);
|
||||
#endif
|
||||
// if this line gives a compiler error, you are using a function object.
|
||||
// you need to implement bool MyFnObj::operator == (const MyFnObj&) const;
|
||||
return pObj_==mfh.pObj_ && pMemFn_==mfh.pMemFn_;
|
||||
}
|
||||
#endif
|
||||
|
||||
ResultType operator()()
|
||||
{ return ((*pObj_).*pMemFn_)(); }
|
||||
|
||||
|
@ -1162,6 +1230,13 @@ namespace Loki
|
|||
/// It often helps against crashes when using static Functors and multi threading.
|
||||
/// Defining also removes problems when unloading Dlls which hosts
|
||||
/// static Functor objects.
|
||||
///
|
||||
/// \par Macro: LOKI_FUNCTORS_ARE_COMPARABLE
|
||||
/// To enable the operator== define the macro
|
||||
/// \code LOKI_FUNCTORS_ARE_COMPARABLE \endcode
|
||||
/// The macro is disabled by default, because it breaks compiling functor
|
||||
/// objects which have no operator== implemented, keep in mind when you enable
|
||||
/// operator==.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename R = void, class TList = NullType,
|
||||
template<class, class> class ThreadingModel = LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL>
|
||||
|
@ -1239,6 +1314,34 @@ namespace Loki
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef LOKI_FUNCTORS_ARE_COMPARABLE
|
||||
|
||||
bool isMemberFuncPtr() const
|
||||
{
|
||||
if(spImpl_.get()!=0)
|
||||
return spImpl_.get()->isMemberFuncPtr();
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator==(const Functor& rhs) const
|
||||
{
|
||||
if(spImpl_.get()==0 && rhs.spImpl_.get()==0)
|
||||
return true;
|
||||
if(spImpl_.get()!=0 && rhs.spImpl_.get()!=0)
|
||||
return *spImpl_.get() == *rhs.spImpl_.get();
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator!=(const Functor& rhs) const
|
||||
{
|
||||
return !(*this==rhs);
|
||||
}
|
||||
#endif
|
||||
|
||||
// operator() implementations for up to 15 arguments
|
||||
|
||||
ResultType operator()() const
|
||||
{
|
||||
LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
|
||||
|
@ -1357,6 +1460,13 @@ namespace Loki
|
|||
std::auto_ptr<Impl> spImpl_;
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// BindersFirst and Chainer
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace Private
|
||||
{
|
||||
template <class Fctor> struct BinderFirstTraits;
|
||||
|
@ -1443,7 +1553,30 @@ namespace Loki
|
|||
{}
|
||||
|
||||
LOKI_DEFINE_CLONE_FUNCTORIMPL(BinderFirst)
|
||||
|
||||
#ifdef LOKI_FUNCTORS_ARE_COMPARABLE
|
||||
|
||||
bool isMemberFuncPtr() const
|
||||
{
|
||||
return f_.isMemberFuncPtr();
|
||||
}
|
||||
|
||||
bool operator==(const typename Base::FunctorImplBaseType& rhs) const
|
||||
{
|
||||
isMemberFuncPtr();
|
||||
// if this line gives a compiler error, you are using a function object.
|
||||
// you need to implement bool MyFnObj::operator == (const MyFnObj&) const;
|
||||
#ifdef LOKI_FUNCTOR_DEBUG
|
||||
return f_ == ((dynamic_cast<const BinderFirst&> (rhs)).f_) &&
|
||||
b_ == ((dynamic_cast<const BinderFirst&> (rhs)).b_);
|
||||
|
||||
#else
|
||||
return f_ == ((static_cast<const BinderFirst&> (rhs)).f_) &&
|
||||
b_ == ((static_cast<const BinderFirst&> (rhs)).b_);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
// operator() implementations for up to 15 arguments
|
||||
|
||||
ResultType operator()()
|
||||
|
@ -1563,6 +1696,29 @@ namespace Loki
|
|||
|
||||
LOKI_DEFINE_CLONE_FUNCTORIMPL(Chainer)
|
||||
|
||||
#ifdef LOKI_FUNCTORS_ARE_COMPARABLE
|
||||
|
||||
bool isMemberFuncPtr() const
|
||||
{
|
||||
assert(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator==(const typename Base::Impl::FunctorImplBaseType& rhs) const
|
||||
{
|
||||
// if this line gives a compiler error, you are using a function object.
|
||||
// you need to implement bool MyFnObj::operator == (const MyFnObj&) const;
|
||||
#ifdef LOKI_FUNCTOR_DEBUG
|
||||
return f1_ == ((dynamic_cast<const Chainer&> (rhs)).f2_) &&
|
||||
f2_ == ((dynamic_cast<const Chainer&> (rhs)).f1_);
|
||||
|
||||
#else
|
||||
return f1_ == ((static_cast<const Chainer&> (rhs)).f2_) &&
|
||||
f2_ == ((static_cast<const Chainer&> (rhs)).f1_);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
// operator() implementations for up to 15 arguments
|
||||
|
||||
ResultType operator()()
|
||||
|
@ -1689,6 +1845,9 @@ namespace Loki
|
|||
#endif // FUNCTOR_INC_
|
||||
|
||||
// $Log$
|
||||
// Revision 1.21 2006/06/01 12:33:05 syntheticpp
|
||||
// add operator== to Functor, initiated by Eric Beyeler
|
||||
//
|
||||
// Revision 1.20 2006/05/20 10:23:07 syntheticpp
|
||||
// add warnings in the documentation about the special lifetime when using SmallObjects
|
||||
//
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue