add boost/TR1 like usage of Functor, with a test program from boost 1.33
git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@320 7ec92016-0320-0410-acc4-a06ded1c099a
This commit is contained in:
parent
b73fe0bbcf
commit
da979a7e0e
4 changed files with 1295 additions and 14 deletions
337
include/loki/Function.h
Executable file
337
include/loki/Function.h
Executable file
|
@ -0,0 +1,337 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// The Loki Library
|
||||||
|
// Copyright (c) 2005 Peter Kümmel
|
||||||
|
// Permission to use, copy, modify, distribute and sell this software for any
|
||||||
|
// purpose is hereby granted without fee, provided that the above copyright
|
||||||
|
// notice appear in all copies and that both that copyright notice and this
|
||||||
|
// permission notice appear in supporting documentation.
|
||||||
|
// The author makes no representations about the
|
||||||
|
// suitability of this software for any purpose. It is provided "as is"
|
||||||
|
// without express or implied warranty.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#define LOKI_ENABLE_FUNCTION
|
||||||
|
|
||||||
|
#include <loki/Functor.h>
|
||||||
|
#include <loki/Sequence.h>
|
||||||
|
|
||||||
|
namespace Loki
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class R>
|
||||||
|
struct Function;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Function allows a boost/TR1 like usage of Functor.
|
||||||
|
//
|
||||||
|
// e.g. Functor<int,LOKI_TYPELIST_2(int,int)> becomes Function<int(int,int)>
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class R>
|
||||||
|
struct Function<R()> : public Functor<R>
|
||||||
|
{
|
||||||
|
typedef Functor<R> FBase;
|
||||||
|
|
||||||
|
Function() : FBase() {}
|
||||||
|
|
||||||
|
Function(const Function& func) : FBase()
|
||||||
|
{
|
||||||
|
if( !func.empty())
|
||||||
|
FBase::operator=(func);
|
||||||
|
}
|
||||||
|
|
||||||
|
// emptiness
|
||||||
|
template<class R2>
|
||||||
|
Function(Function<R2()> func) : FBase()
|
||||||
|
{
|
||||||
|
if(!func.empty())
|
||||||
|
FBase::operator=(func);
|
||||||
|
}
|
||||||
|
|
||||||
|
// clear by '= 0'
|
||||||
|
Function(const int i) : FBase()
|
||||||
|
{
|
||||||
|
if(i==0)
|
||||||
|
FBase::clear();
|
||||||
|
else
|
||||||
|
throw std::runtime_error("Loki::Function(const int i): i!=0");
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Func>
|
||||||
|
Function(Func func) : FBase(func) {}
|
||||||
|
|
||||||
|
template<class Host, class Func>
|
||||||
|
Function(const Host& host, const Func& func) : FBase(host,func) {}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// macros for the repetitions
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#define LOKI_FUNCTION_BODY \
|
||||||
|
\
|
||||||
|
Function() : FBase() {} \
|
||||||
|
\
|
||||||
|
Function(const Function& func) : FBase() \
|
||||||
|
{ \
|
||||||
|
if( !func.empty()) \
|
||||||
|
FBase::operator=(func); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
Function(const int i) : FBase() \
|
||||||
|
{ \
|
||||||
|
if(i==0) \
|
||||||
|
FBase::clear(); \
|
||||||
|
else \
|
||||||
|
throw std::runtime_error( \
|
||||||
|
"Loki::Function(const int i): i!=0"); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
template<class Func> \
|
||||||
|
Function(Func func) : FBase(func) {} \
|
||||||
|
\
|
||||||
|
template<class Host, class Func> \
|
||||||
|
Function(const Host& host, const Func& func): FBase(host,func) {}
|
||||||
|
|
||||||
|
|
||||||
|
#define LOKI_FUNCTION_R2_CTOR_BODY \
|
||||||
|
\
|
||||||
|
: FBase() \
|
||||||
|
{ \
|
||||||
|
if(!func.empty()) \
|
||||||
|
FBase::operator=(func); \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// repetitions
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class R,class P01>
|
||||||
|
struct Function<R(P01)>
|
||||||
|
: public Loki::Functor<R,typename Seq<P01>::Type>
|
||||||
|
{
|
||||||
|
typedef Functor<R,typename Seq<P01>::Type> FBase;
|
||||||
|
|
||||||
|
template<class R2,class Q01>
|
||||||
|
Function(Function<R2(Q01)> func)
|
||||||
|
LOKI_FUNCTION_R2_CTOR_BODY
|
||||||
|
|
||||||
|
LOKI_FUNCTION_BODY
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class R,class P01,class P02>
|
||||||
|
struct Function<R(P01,P02)>
|
||||||
|
: public Functor<R,typename Seq<P01,P02>::Type>
|
||||||
|
{
|
||||||
|
typedef Functor<R,typename Seq<P01,P02>::Type> FBase;
|
||||||
|
|
||||||
|
template<class R2,class Q01, class Q02>
|
||||||
|
Function(Function<R2(Q01,Q02)> func)
|
||||||
|
LOKI_FUNCTION_R2_CTOR_BODY
|
||||||
|
|
||||||
|
LOKI_FUNCTION_BODY
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class R,class P01,class P02, class P03>
|
||||||
|
struct Function<R(P01,P02,P03)>
|
||||||
|
: public Functor<R,typename Seq<P01,P02,P03>::Type>
|
||||||
|
{
|
||||||
|
typedef Functor<R,typename Seq<P01,P02,P03>::Type> FBase;
|
||||||
|
|
||||||
|
template<class R2,class Q01, class Q02,class Q03>
|
||||||
|
Function(Function<R2(Q01,Q02,Q03)> func)
|
||||||
|
LOKI_FUNCTION_R2_CTOR_BODY
|
||||||
|
|
||||||
|
LOKI_FUNCTION_BODY
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class R,class P01,class P02, class P03,class P04>
|
||||||
|
struct Function<R(P01,P02,P03,P04)>
|
||||||
|
: public Functor<R,typename Seq<P01,P02,P03,P04>::Type>
|
||||||
|
{
|
||||||
|
typedef Functor<R,typename Seq<P01,P02,P03,P04>::Type> FBase;
|
||||||
|
|
||||||
|
template<class R2,class Q01,class Q02, class Q03,class Q04>
|
||||||
|
Function(Function<R2(Q01,Q02,Q03,Q04)> func)
|
||||||
|
LOKI_FUNCTION_R2_CTOR_BODY
|
||||||
|
|
||||||
|
LOKI_FUNCTION_BODY
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class R,class P01,class P02, class P03,class P04,class P05>
|
||||||
|
struct Function<R(P01,P02,P03,P04,P05)>
|
||||||
|
: public Functor<R,typename Seq<P01,P02,P03,P04,P05>::Type>
|
||||||
|
{
|
||||||
|
typedef Functor<R,typename Seq<P01,P02,P03,P04,P05>::Type> FBase;
|
||||||
|
|
||||||
|
template<class R2,class Q01,class Q02, class Q03,class Q04,class Q05>
|
||||||
|
Function(Function<R2(Q01,Q02,Q03,Q04,Q05)> func)
|
||||||
|
LOKI_FUNCTION_R2_CTOR_BODY
|
||||||
|
|
||||||
|
LOKI_FUNCTION_BODY
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class R, class P01,class P02, class P03,class P04,class P05,
|
||||||
|
class P06>
|
||||||
|
struct Function<R(P01,P02,P03,P04,P05,P06)>
|
||||||
|
: public Functor<R,typename Seq<P01,P02,P03,P04,P05,P06>::Type>
|
||||||
|
{
|
||||||
|
typedef Functor<R,typename Seq<P01,P02,P03,P04,P05,P06>::Type> FBase;
|
||||||
|
|
||||||
|
template<class R2, class Q01,class Q02, class Q03,class Q04,class Q05,
|
||||||
|
class Q06>
|
||||||
|
Function(Function<R2(Q01,Q02,Q03,Q04,Q05,Q06)> func)
|
||||||
|
LOKI_FUNCTION_R2_CTOR_BODY
|
||||||
|
|
||||||
|
LOKI_FUNCTION_BODY
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class R, class P01,class P02, class P03,class P04,class P05,
|
||||||
|
class P06,class P07>
|
||||||
|
struct Function<R(P01,P02,P03,P04,P05,P06,P07)>
|
||||||
|
: public Functor<R,typename Seq<P01,P02,P03,P04,P05,P06,P07>::Type>
|
||||||
|
{
|
||||||
|
typedef Functor<R,typename Seq<P01,P02,P03,P04,P05,P06,P07>::Type> FBase;
|
||||||
|
|
||||||
|
template<class R2, class Q01,class Q02, class Q03,class Q04,class Q05,
|
||||||
|
class Q06,class Q07>
|
||||||
|
Function(Function<R2(Q01,Q02,Q03,Q04,Q05,Q06,Q07)> func)
|
||||||
|
LOKI_FUNCTION_R2_CTOR_BODY
|
||||||
|
|
||||||
|
LOKI_FUNCTION_BODY
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class R, class P01,class P02, class P03,class P04,class P05,
|
||||||
|
class P06,class P07, class P08>
|
||||||
|
struct Function<R(P01,P02,P03,P04,P05,P06,P07,P08)>
|
||||||
|
: public Functor<R,typename Seq<P01,P02,P03,P04,P05,P06,P07,P08>::Type>
|
||||||
|
{
|
||||||
|
typedef Functor<R,typename Seq<P01,P02,P03,P04,P05,P06,P07,P08>::Type> FBase;
|
||||||
|
|
||||||
|
template<class R2, class Q01,class Q02, class Q03,class Q04,class Q05,
|
||||||
|
class Q06,class Q07, class Q08>
|
||||||
|
Function(Function<R2(Q01,Q02,Q03,Q04,Q05,Q06,Q07,Q08)> func)
|
||||||
|
LOKI_FUNCTION_R2_CTOR_BODY
|
||||||
|
|
||||||
|
LOKI_FUNCTION_BODY
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class R, class P01,class P02, class P03,class P04,class P05,
|
||||||
|
class P06,class P07, class P08,class P09>
|
||||||
|
struct Function<R(P01,P02,P03,P04,P05,P06,P07,P08,P09)>
|
||||||
|
: public Functor<R,typename Seq<P01,P02,P03,P04,P05,P06,P07,P08,P09>::Type>
|
||||||
|
{
|
||||||
|
typedef Functor<R,typename Seq<P01,P02,P03,P04,P05,P06,P07,P08,P09 >::Type> FBase;
|
||||||
|
|
||||||
|
template<class R2, class Q01,class Q02, class Q03,class Q04,class Q05,
|
||||||
|
class Q06,class Q07, class Q08,class Q09>
|
||||||
|
Function(Function<R2(Q01,Q02,Q03,Q04,Q05,Q06,Q07,Q08,Q09)> func)
|
||||||
|
LOKI_FUNCTION_R2_CTOR_BODY
|
||||||
|
|
||||||
|
LOKI_FUNCTION_BODY
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class R, class P01,class P02, class P03,class P04,class P05,
|
||||||
|
class P06,class P07, class P08,class P09,class P10>
|
||||||
|
struct Function<R(P01,P02,P03,P04,P05,P06,P07,P08,P09,P10)>
|
||||||
|
: public Functor<R,typename Seq<P01,P02,P03,P04,P05,P06,P07,P08,P09,P10>::Type>
|
||||||
|
{
|
||||||
|
typedef Functor<R,typename Seq<P01,P02,P03,P04,P05,P06,P07,P08,P09,P10>::Type> FBase;
|
||||||
|
|
||||||
|
template<class R2, class Q01,class Q02, class Q03,class Q04,class Q05,
|
||||||
|
class Q06,class Q07, class Q08,class Q09,class Q10>
|
||||||
|
Function(Function<R2(Q01,Q02,Q03,Q04,Q05,Q06,Q07,Q08,Q09,Q10)> func)
|
||||||
|
LOKI_FUNCTION_R2_CTOR_BODY
|
||||||
|
|
||||||
|
LOKI_FUNCTION_BODY
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class R, class P01,class P02, class P03,class P04,class P05,
|
||||||
|
class P06,class P07, class P08,class P09,class P10,
|
||||||
|
class P11>
|
||||||
|
struct Function<R(P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11)>
|
||||||
|
: public Functor<R,typename Seq<P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11>::Type>
|
||||||
|
{
|
||||||
|
typedef Functor<R,typename Seq<P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11>::Type>FBase;
|
||||||
|
|
||||||
|
template<class R2, class Q01,class Q02, class Q03,class Q04,class Q05,
|
||||||
|
class Q06,class Q07, class Q08,class Q09,class Q10,
|
||||||
|
class Q11>
|
||||||
|
Function(Function<R2(Q01,Q02,Q03,Q04,Q05,Q06,Q07,Q08,Q09,Q10,Q11)> func)
|
||||||
|
LOKI_FUNCTION_R2_CTOR_BODY
|
||||||
|
|
||||||
|
LOKI_FUNCTION_BODY
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class R, class P01,class P02, class P03,class P04,class P05,
|
||||||
|
class P06,class P07, class P08,class P09,class P10,
|
||||||
|
class P11,class P12>
|
||||||
|
struct Function<R(P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11,P12)>
|
||||||
|
: public Functor<R,typename Seq<P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11,P12>::Type>
|
||||||
|
{
|
||||||
|
typedef Functor<R,typename Seq<P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11,P12>::Type> FBase;
|
||||||
|
|
||||||
|
template<class R2, class Q01,class Q02, class Q03,class Q04,class Q05,
|
||||||
|
class Q06,class Q07, class Q08,class Q09,class Q10,
|
||||||
|
class Q11,class Q12>
|
||||||
|
Function(Function<R2(Q01,Q02,Q03,Q04,Q05,Q06,Q07,Q08,Q09,Q10,Q11)> func)
|
||||||
|
LOKI_FUNCTION_R2_CTOR_BODY
|
||||||
|
|
||||||
|
LOKI_FUNCTION_BODY
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class R, class P01,class P02, class P03,class P04,class P05,
|
||||||
|
class P06,class P07, class P08,class P09,class P10,
|
||||||
|
class P11,class P12, class P13>
|
||||||
|
struct Function<R(P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11,P12,P13)>
|
||||||
|
: public Functor<R,typename Seq<P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11,P12,P13>::Type>
|
||||||
|
{
|
||||||
|
typedef Functor<R,typename Seq<P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11,P12,P13>::Type> FBase;
|
||||||
|
|
||||||
|
template<class R2, class Q01,class Q02, class Q03,class Q04,class Q05,
|
||||||
|
class Q06,class Q07, class Q08,class Q09,class Q10,
|
||||||
|
class Q11,class Q12, class Q13>
|
||||||
|
Function(Function<R2(Q01,Q02,Q03,Q04,Q05,Q06,Q07,Q08,Q09,Q10,Q11,Q12,Q13)> func)
|
||||||
|
LOKI_FUNCTION_R2_CTOR_BODY
|
||||||
|
|
||||||
|
LOKI_FUNCTION_BODY
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class R, class P01,class P02, class P03,class P04,class P05,
|
||||||
|
class P06,class P07, class P08,class P09,class P10,
|
||||||
|
class P11,class P12, class P13,class P14>
|
||||||
|
struct Function<R(P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11,P12,P13,P14)>
|
||||||
|
: public Functor<R,typename Seq<P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11,P12,P13,P14>::Type>
|
||||||
|
{
|
||||||
|
typedef Functor<R,typename Seq<P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11,P12,P13,P14>::Type> FBase;
|
||||||
|
template<class R2, class Q01,class Q02, class Q03,class Q04,class Q05,
|
||||||
|
class Q06,class Q07, class Q08,class Q09,class Q10,
|
||||||
|
class Q11,class Q12, class Q13,class Q14>
|
||||||
|
Function(Function<R2(Q01,Q02,Q03,Q04,Q05,Q06,Q07,Q08,Q09,Q10,Q11,Q12,Q13,Q14)> func)
|
||||||
|
LOKI_FUNCTION_R2_CTOR_BODY
|
||||||
|
|
||||||
|
LOKI_FUNCTION_BODY
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class R, class P01,class P02, class P03,class P04,class P05,
|
||||||
|
class P06,class P07, class P08,class P09,class P10,
|
||||||
|
class P11,class P12, class P13,class P14,class P15>
|
||||||
|
struct Function<R(P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11,P12,P13,P14,P15)>
|
||||||
|
: public Functor<R,typename Seq<P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11,P12,P13,P14,P15>::Type>
|
||||||
|
{
|
||||||
|
typedef Functor<R,typename Seq<P01,P02,P03,P04,P05,P06,P07,P08,P09,P10,P11,P12,P13,P14,P15>::Type> FBase;
|
||||||
|
|
||||||
|
template<class R2, class Q01,class Q02, class Q03,class Q04,class Q05,
|
||||||
|
class Q06,class Q07, class Q08,class Q09,class Q10,
|
||||||
|
class Q11,class Q12, class Q13,class Q14,class Q15>
|
||||||
|
Function(Function<R2(Q01,Q02,Q03,Q04,Q05,Q06,Q07,Q08,Q09,Q10,Q11,Q12,Q13,Q14,Q15)> func)
|
||||||
|
LOKI_FUNCTION_R2_CTOR_BODY
|
||||||
|
|
||||||
|
LOKI_FUNCTION_BODY
|
||||||
|
};
|
||||||
|
|
||||||
|
}// namespace Loki
|
||||||
|
|
|
@ -714,11 +714,31 @@ namespace Loki
|
||||||
PointerToMemFn pMemFn_;
|
PointerToMemFn pMemFn_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// TR1 exception
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifdef LOKI_ENABLE_FUNCTION
|
||||||
|
|
||||||
|
class bad_function_call : public std::runtime_error
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bad_function_call() : std::runtime_error("bad_function_call in Loki::Functor")
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
#define LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL if(empty()) throw bad_function_call();
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// class template Functor
|
// class template Functor
|
||||||
// A generalized functor implementation with value semantics
|
// A generalized functor implementation with value semantics
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template <typename R, class TList = NullType,
|
template <typename R, class TList = NullType,
|
||||||
template<class> class ThreadingModel = LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL>
|
template<class> class ThreadingModel = LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL>
|
||||||
class Functor
|
class Functor
|
||||||
|
@ -782,52 +802,102 @@ namespace Loki
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef LOKI_ENABLE_FUNCTION
|
||||||
|
|
||||||
|
bool empty() const
|
||||||
|
{
|
||||||
|
return spImpl_.get() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
spImpl_.reset(0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
ResultType operator()() const
|
ResultType operator()() const
|
||||||
{ return (*spImpl_)(); }
|
{
|
||||||
|
LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
|
||||||
|
return (*spImpl_)();
|
||||||
|
}
|
||||||
|
|
||||||
ResultType operator()(Parm1 p1) const
|
ResultType operator()(Parm1 p1) const
|
||||||
{ return (*spImpl_)(p1); }
|
{
|
||||||
|
LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
|
||||||
|
return (*spImpl_)(p1);
|
||||||
|
}
|
||||||
|
|
||||||
ResultType operator()(Parm1 p1, Parm2 p2) const
|
ResultType operator()(Parm1 p1, Parm2 p2) const
|
||||||
{ return (*spImpl_)(p1, p2); }
|
{
|
||||||
|
LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
|
||||||
|
return (*spImpl_)(p1, p2);
|
||||||
|
}
|
||||||
|
|
||||||
ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3) const
|
ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3) const
|
||||||
{ return (*spImpl_)(p1, p2, p3); }
|
{
|
||||||
|
LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
|
||||||
|
return (*spImpl_)(p1, p2, p3);
|
||||||
|
}
|
||||||
|
|
||||||
ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4) const
|
ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4) const
|
||||||
{ return (*spImpl_)(p1, p2, p3, p4); }
|
{
|
||||||
|
LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
|
||||||
|
return (*spImpl_)(p1, p2, p3, p4);
|
||||||
|
}
|
||||||
|
|
||||||
ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5) const
|
ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5) const
|
||||||
{ return (*spImpl_)(p1, p2, p3, p4, p5); }
|
{
|
||||||
|
LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
|
||||||
|
return (*spImpl_)(p1, p2, p3, p4, p5);
|
||||||
|
}
|
||||||
|
|
||||||
ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
|
ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
|
||||||
Parm6 p6) const
|
Parm6 p6) const
|
||||||
{ return (*spImpl_)(p1, p2, p3, p4, p5, p6); }
|
{
|
||||||
|
LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
|
||||||
|
return (*spImpl_)(p1, p2, p3, p4, p5, p6);
|
||||||
|
}
|
||||||
|
|
||||||
ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
|
ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
|
||||||
Parm6 p6, Parm7 p7) const
|
Parm6 p6, Parm7 p7) const
|
||||||
{ return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7); }
|
{
|
||||||
|
LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
|
||||||
|
return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7);
|
||||||
|
}
|
||||||
|
|
||||||
ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
|
ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
|
||||||
Parm6 p6, Parm7 p7, Parm8 p8) const
|
Parm6 p6, Parm7 p7, Parm8 p8) const
|
||||||
{ return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8); }
|
{
|
||||||
|
LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
|
||||||
|
return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8);
|
||||||
|
}
|
||||||
|
|
||||||
ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
|
ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
|
||||||
Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9) const
|
Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9) const
|
||||||
{ return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9); }
|
{
|
||||||
|
LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
|
||||||
|
return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9);
|
||||||
|
}
|
||||||
|
|
||||||
ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
|
ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
|
||||||
Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10) const
|
Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10) const
|
||||||
{ return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); }
|
{
|
||||||
|
LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
|
||||||
|
return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
|
||||||
|
}
|
||||||
|
|
||||||
ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
|
ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
|
||||||
Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11) const
|
Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11) const
|
||||||
{ return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); }
|
{
|
||||||
|
LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
|
||||||
|
return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11);
|
||||||
|
}
|
||||||
|
|
||||||
ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
|
ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
|
||||||
Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
|
Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
|
||||||
Parm12 p12) const
|
Parm12 p12) const
|
||||||
{
|
{
|
||||||
|
LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
|
||||||
return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11,
|
return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11,
|
||||||
p12);
|
p12);
|
||||||
}
|
}
|
||||||
|
@ -836,6 +906,7 @@ namespace Loki
|
||||||
Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
|
Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
|
||||||
Parm12 p12, Parm13 p13) const
|
Parm12 p12, Parm13 p13) const
|
||||||
{
|
{
|
||||||
|
LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
|
||||||
return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11,
|
return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11,
|
||||||
p12, p13);
|
p12, p13);
|
||||||
}
|
}
|
||||||
|
@ -844,6 +915,7 @@ namespace Loki
|
||||||
Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
|
Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
|
||||||
Parm12 p12, Parm13 p13, Parm14 p14) const
|
Parm12 p12, Parm13 p13, Parm14 p14) const
|
||||||
{
|
{
|
||||||
|
LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
|
||||||
return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11,
|
return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11,
|
||||||
p12, p13, p14);
|
p12, p13, p14);
|
||||||
}
|
}
|
||||||
|
@ -852,6 +924,7 @@ namespace Loki
|
||||||
Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
|
Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
|
||||||
Parm12 p12, Parm13 p13, Parm14 p14, Parm15 p15) const
|
Parm12 p12, Parm13 p13, Parm14 p14, Parm15 p15) const
|
||||||
{
|
{
|
||||||
|
LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
|
||||||
return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11,
|
return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11,
|
||||||
p12, p13, p14, p15);
|
p12, p13, p14, p15);
|
||||||
}
|
}
|
||||||
|
|
792
test/Function/FunctionTest.cpp
Executable file
792
test/Function/FunctionTest.cpp
Executable file
|
@ -0,0 +1,792 @@
|
||||||
|
// Boost.Function library
|
||||||
|
|
||||||
|
// Copyright Douglas Gregor 2001-2003. Use, modification and
|
||||||
|
// distribution is subject to the Boost Software License, Version
|
||||||
|
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
// For more information, see http://www.boost.org
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <cassert>
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
#include <boost/test/minimal.hpp>
|
||||||
|
|
||||||
|
#define TEST_LOKI_FUNCTION
|
||||||
|
|
||||||
|
#ifndef TEST_LOKI_FUNCTION
|
||||||
|
|
||||||
|
#include <boost/function.hpp>
|
||||||
|
using namespace boost;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
|
||||||
|
#include <boost/ref.hpp>
|
||||||
|
#include <loki/Function.h>
|
||||||
|
using namespace Loki;
|
||||||
|
#define BOOST_FUNCTION_TARGET_FIX(x) x
|
||||||
|
#define function Function
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
int global_int;
|
||||||
|
|
||||||
|
struct write_five_obj{void operator()() const {global_int = 5;}};
|
||||||
|
|
||||||
|
#ifndef TEST_LOKI_FUNCTION
|
||||||
|
struct write_three_obj{int operator()() const {global_int = 3; return 7;}};
|
||||||
|
#else
|
||||||
|
struct write_three_obj{void operator()() const {global_int = 3;}};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void write_five() {global_int = 5;}
|
||||||
|
static void write_three() {global_int = 3;}
|
||||||
|
struct generate_five_obj {int operator()() const {return 5;}};
|
||||||
|
struct generate_three_obj {int operator()() const {return 3;}};
|
||||||
|
static int generate_five() {return 5;}
|
||||||
|
static int generate_three() {return 3;}
|
||||||
|
static string identity_str(const string& s){return s;}
|
||||||
|
static string string_cat(const string& s1, const string& s2){return s1+s2;}
|
||||||
|
static int sum_ints(int x, int y){return x+y;}
|
||||||
|
|
||||||
|
struct write_const_1_nonconst_2
|
||||||
|
{
|
||||||
|
void operator()(){global_int = 2;}
|
||||||
|
void operator()() const {global_int = 1;}
|
||||||
|
};
|
||||||
|
struct add_to_obj
|
||||||
|
{
|
||||||
|
add_to_obj(int v) : value(v) {}
|
||||||
|
int operator()(int x) const {return value + x;}
|
||||||
|
int value;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void test_zero_args()
|
||||||
|
{
|
||||||
|
typedef function<void ()> func_void_type;
|
||||||
|
|
||||||
|
write_five_obj five;
|
||||||
|
write_three_obj three;
|
||||||
|
|
||||||
|
// Default construction
|
||||||
|
func_void_type v1;
|
||||||
|
BOOST_CHECK(v1.empty());
|
||||||
|
|
||||||
|
// Assignment to an empty function
|
||||||
|
v1 = five;
|
||||||
|
BOOST_CHECK(v1 != 0);
|
||||||
|
|
||||||
|
// Invocation of a function
|
||||||
|
global_int = 0;
|
||||||
|
v1();
|
||||||
|
BOOST_CHECK(global_int == 5);
|
||||||
|
|
||||||
|
// clear() method
|
||||||
|
v1.clear();
|
||||||
|
BOOST_CHECK(v1 == 0);
|
||||||
|
|
||||||
|
// Assignment to an empty function
|
||||||
|
v1 = three;
|
||||||
|
BOOST_CHECK(!v1.empty());
|
||||||
|
|
||||||
|
// Invocation and self-assignment
|
||||||
|
global_int = 0;
|
||||||
|
v1 = v1;
|
||||||
|
v1();
|
||||||
|
BOOST_CHECK(global_int == 3);
|
||||||
|
|
||||||
|
// Assignment to a non-empty function
|
||||||
|
v1 = five;
|
||||||
|
|
||||||
|
// Invocation and self-assignment
|
||||||
|
global_int = 0;
|
||||||
|
v1 = (v1);
|
||||||
|
v1();
|
||||||
|
BOOST_CHECK(global_int == 5);
|
||||||
|
|
||||||
|
// clear
|
||||||
|
v1 = 0;
|
||||||
|
BOOST_CHECK(0 == v1);
|
||||||
|
|
||||||
|
// Assignment to an empty function from a free function
|
||||||
|
v1 = BOOST_FUNCTION_TARGET_FIX(&) write_five;
|
||||||
|
BOOST_CHECK(0 != v1);
|
||||||
|
|
||||||
|
// Invocation
|
||||||
|
global_int = 0;
|
||||||
|
v1();
|
||||||
|
BOOST_CHECK(global_int == 5);
|
||||||
|
|
||||||
|
// Assignment to a non-empty function from a free function
|
||||||
|
v1 = BOOST_FUNCTION_TARGET_FIX(&) write_three;
|
||||||
|
BOOST_CHECK(!v1.empty());
|
||||||
|
|
||||||
|
// Invocation
|
||||||
|
global_int = 0;
|
||||||
|
v1();
|
||||||
|
BOOST_CHECK(global_int == 3);
|
||||||
|
|
||||||
|
// Assignment
|
||||||
|
v1 = five;
|
||||||
|
BOOST_CHECK(!v1.empty());
|
||||||
|
|
||||||
|
// Invocation
|
||||||
|
global_int = 0;
|
||||||
|
v1();
|
||||||
|
BOOST_CHECK(global_int == 5);
|
||||||
|
|
||||||
|
// Assignment to a non-empty function from a free function
|
||||||
|
v1 = &write_three;
|
||||||
|
BOOST_CHECK(!v1.empty());
|
||||||
|
|
||||||
|
// Invocation
|
||||||
|
global_int = 0;
|
||||||
|
v1();
|
||||||
|
BOOST_CHECK(global_int == 3);
|
||||||
|
|
||||||
|
// Construction from another function (that is empty)
|
||||||
|
v1.clear();
|
||||||
|
func_void_type v2(v1);
|
||||||
|
BOOST_CHECK(!v2? true : false);
|
||||||
|
|
||||||
|
// Assignment to an empty function
|
||||||
|
v2 = three;
|
||||||
|
BOOST_CHECK(!v2.empty());
|
||||||
|
|
||||||
|
// Invocation
|
||||||
|
global_int = 0;
|
||||||
|
v2();
|
||||||
|
BOOST_CHECK(global_int == 3);
|
||||||
|
|
||||||
|
// Assignment to a non-empty function
|
||||||
|
v2 = (five);
|
||||||
|
|
||||||
|
// Invocation
|
||||||
|
global_int = 0;
|
||||||
|
v2();
|
||||||
|
BOOST_CHECK(global_int == 5);
|
||||||
|
|
||||||
|
v2.clear();
|
||||||
|
BOOST_CHECK(v2.empty());
|
||||||
|
|
||||||
|
// Assignment to an empty function from a free function
|
||||||
|
v2 = (BOOST_FUNCTION_TARGET_FIX(&) write_five);
|
||||||
|
BOOST_CHECK(v2? true : false);
|
||||||
|
|
||||||
|
// Invocation
|
||||||
|
global_int = 0;
|
||||||
|
v2();
|
||||||
|
BOOST_CHECK(global_int == 5);
|
||||||
|
|
||||||
|
// Assignment to a non-empty function from a free function
|
||||||
|
v2 = BOOST_FUNCTION_TARGET_FIX(&) write_three;
|
||||||
|
BOOST_CHECK(!v2.empty());
|
||||||
|
|
||||||
|
// Invocation
|
||||||
|
global_int = 0;
|
||||||
|
v2();
|
||||||
|
BOOST_CHECK(global_int == 3);
|
||||||
|
|
||||||
|
// Swapping
|
||||||
|
v1 = five;
|
||||||
|
swap(v1, v2);
|
||||||
|
v2();
|
||||||
|
BOOST_CHECK(global_int == 5);
|
||||||
|
v1();
|
||||||
|
BOOST_CHECK(global_int == 3);
|
||||||
|
swap(v1, v2);
|
||||||
|
v1.clear();
|
||||||
|
|
||||||
|
// Assignment
|
||||||
|
v2 = five;
|
||||||
|
BOOST_CHECK(!v2.empty());
|
||||||
|
|
||||||
|
// Invocation
|
||||||
|
global_int = 0;
|
||||||
|
v2();
|
||||||
|
BOOST_CHECK(global_int == 5);
|
||||||
|
|
||||||
|
// Assignment to a non-empty function from a free function
|
||||||
|
v2 = &write_three;
|
||||||
|
BOOST_CHECK(!v2.empty());
|
||||||
|
|
||||||
|
// Invocation
|
||||||
|
global_int = 0;
|
||||||
|
v2();
|
||||||
|
BOOST_CHECK(global_int == 3);
|
||||||
|
|
||||||
|
// Assignment to a function from an empty function
|
||||||
|
v2 = v1;
|
||||||
|
BOOST_CHECK(v2.empty());
|
||||||
|
|
||||||
|
// Assignment to a function from a function with a functor
|
||||||
|
v1 = three;
|
||||||
|
v2 = v1;
|
||||||
|
BOOST_CHECK(!v1.empty());
|
||||||
|
BOOST_CHECK(!v2.empty());
|
||||||
|
|
||||||
|
// Invocation
|
||||||
|
global_int = 0;
|
||||||
|
v1();
|
||||||
|
BOOST_CHECK(global_int == 3);
|
||||||
|
global_int = 0;
|
||||||
|
v2();
|
||||||
|
BOOST_CHECK(global_int == 3);
|
||||||
|
|
||||||
|
// Assign to a function from a function with a function
|
||||||
|
v2 = BOOST_FUNCTION_TARGET_FIX(&) write_five;
|
||||||
|
v1 = v2;
|
||||||
|
BOOST_CHECK(!v1.empty());
|
||||||
|
BOOST_CHECK(!v2.empty());
|
||||||
|
global_int = 0;
|
||||||
|
v1();
|
||||||
|
BOOST_CHECK(global_int == 5);
|
||||||
|
global_int = 0;
|
||||||
|
v2();
|
||||||
|
BOOST_CHECK(global_int == 5);
|
||||||
|
|
||||||
|
// Construct a function given another function containing a function
|
||||||
|
func_void_type v3(v1);
|
||||||
|
|
||||||
|
// Invocation of a function
|
||||||
|
global_int = 0;
|
||||||
|
v3();
|
||||||
|
BOOST_CHECK(global_int == 5);
|
||||||
|
|
||||||
|
// clear() method
|
||||||
|
v3.clear();
|
||||||
|
BOOST_CHECK(!v3? true : false);
|
||||||
|
|
||||||
|
// Assignment to an empty function
|
||||||
|
v3 = three;
|
||||||
|
BOOST_CHECK(!v3.empty());
|
||||||
|
|
||||||
|
// Invocation
|
||||||
|
global_int = 0;
|
||||||
|
v3();
|
||||||
|
BOOST_CHECK(global_int == 3);
|
||||||
|
|
||||||
|
// Assignment to a non-empty function
|
||||||
|
v3 = five;
|
||||||
|
|
||||||
|
// Invocation
|
||||||
|
global_int = 0;
|
||||||
|
v3();
|
||||||
|
BOOST_CHECK(global_int == 5);
|
||||||
|
|
||||||
|
// clear()
|
||||||
|
v3.clear();
|
||||||
|
BOOST_CHECK(v3.empty());
|
||||||
|
|
||||||
|
// Assignment to an empty function from a free function
|
||||||
|
v3 = &write_five;
|
||||||
|
BOOST_CHECK(!v3.empty());
|
||||||
|
|
||||||
|
// Invocation
|
||||||
|
global_int = 0;
|
||||||
|
v3();
|
||||||
|
BOOST_CHECK(global_int == 5);
|
||||||
|
|
||||||
|
// Assignment to a non-empty function from a free function
|
||||||
|
v3 = &write_three;
|
||||||
|
BOOST_CHECK(!v3.empty());
|
||||||
|
|
||||||
|
// Invocation
|
||||||
|
global_int = 0;
|
||||||
|
v3();
|
||||||
|
BOOST_CHECK(global_int == 3);
|
||||||
|
|
||||||
|
// Assignment
|
||||||
|
v3 = five;
|
||||||
|
BOOST_CHECK(!v3.empty());
|
||||||
|
|
||||||
|
// Invocation
|
||||||
|
global_int = 0;
|
||||||
|
v3();
|
||||||
|
BOOST_CHECK(global_int == 5);
|
||||||
|
|
||||||
|
// Construction of a function from a function containing a functor
|
||||||
|
func_void_type v4(v3);
|
||||||
|
|
||||||
|
// Invocation of a function
|
||||||
|
global_int = 0;
|
||||||
|
v4();
|
||||||
|
BOOST_CHECK(global_int == 5);
|
||||||
|
|
||||||
|
// clear() method
|
||||||
|
v4.clear();
|
||||||
|
BOOST_CHECK(v4.empty());
|
||||||
|
|
||||||
|
// Assignment to an empty function
|
||||||
|
v4 = three;
|
||||||
|
BOOST_CHECK(!v4.empty());
|
||||||
|
|
||||||
|
// Invocation
|
||||||
|
global_int = 0;
|
||||||
|
v4();
|
||||||
|
BOOST_CHECK(global_int == 3);
|
||||||
|
|
||||||
|
// Assignment to a non-empty function
|
||||||
|
v4 = five;
|
||||||
|
|
||||||
|
// Invocation
|
||||||
|
global_int = 0;
|
||||||
|
v4();
|
||||||
|
BOOST_CHECK(global_int == 5);
|
||||||
|
|
||||||
|
// clear()
|
||||||
|
v4.clear();
|
||||||
|
BOOST_CHECK(v4.empty());
|
||||||
|
|
||||||
|
// Assignment to an empty function from a free function
|
||||||
|
v4 = &write_five;
|
||||||
|
BOOST_CHECK(!v4.empty());
|
||||||
|
|
||||||
|
// Invocation
|
||||||
|
global_int = 0;
|
||||||
|
v4();
|
||||||
|
BOOST_CHECK(global_int == 5);
|
||||||
|
|
||||||
|
// Assignment to a non-empty function from a free function
|
||||||
|
v4 = &write_three;
|
||||||
|
BOOST_CHECK(!v4.empty());
|
||||||
|
|
||||||
|
// Invocation
|
||||||
|
global_int = 0;
|
||||||
|
v4();
|
||||||
|
BOOST_CHECK(global_int == 3);
|
||||||
|
|
||||||
|
// Assignment
|
||||||
|
v4 = five;
|
||||||
|
BOOST_CHECK(!v4.empty());
|
||||||
|
|
||||||
|
// Invocation
|
||||||
|
global_int = 0;
|
||||||
|
v4();
|
||||||
|
BOOST_CHECK(global_int == 5);
|
||||||
|
|
||||||
|
// Construction of a function from a functor
|
||||||
|
func_void_type v5(five);
|
||||||
|
|
||||||
|
// Invocation of a function
|
||||||
|
global_int = 0;
|
||||||
|
v5();
|
||||||
|
BOOST_CHECK(global_int == 5);
|
||||||
|
|
||||||
|
// clear() method
|
||||||
|
v5.clear();
|
||||||
|
BOOST_CHECK(v5.empty());
|
||||||
|
|
||||||
|
// Assignment to an empty function
|
||||||
|
v5 = three;
|
||||||
|
BOOST_CHECK(!v5.empty());
|
||||||
|
|
||||||
|
// Invocation
|
||||||
|
global_int = 0;
|
||||||
|
v5();
|
||||||
|
BOOST_CHECK(global_int == 3);
|
||||||
|
|
||||||
|
// Assignment to a non-empty function
|
||||||
|
v5 = five;
|
||||||
|
|
||||||
|
// Invocation
|
||||||
|
global_int = 0;
|
||||||
|
v5();
|
||||||
|
BOOST_CHECK(global_int == 5);
|
||||||
|
|
||||||
|
// clear()
|
||||||
|
v5.clear();
|
||||||
|
BOOST_CHECK(v5.empty());
|
||||||
|
|
||||||
|
// Assignment to an empty function from a free function
|
||||||
|
v5 = &write_five;
|
||||||
|
BOOST_CHECK(!v5.empty());
|
||||||
|
|
||||||
|
// Invocation
|
||||||
|
global_int = 0;
|
||||||
|
v5();
|
||||||
|
BOOST_CHECK(global_int == 5);
|
||||||
|
|
||||||
|
// Assignment to a non-empty function from a free function
|
||||||
|
v5 = &write_three;
|
||||||
|
BOOST_CHECK(!v5.empty());
|
||||||
|
|
||||||
|
// Invocation
|
||||||
|
global_int = 0;
|
||||||
|
v5();
|
||||||
|
BOOST_CHECK(global_int == 3);
|
||||||
|
|
||||||
|
// Assignment
|
||||||
|
v5 = five;
|
||||||
|
BOOST_CHECK(!v5.empty());
|
||||||
|
|
||||||
|
// Invocation
|
||||||
|
global_int = 0;
|
||||||
|
v5();
|
||||||
|
BOOST_CHECK(global_int == 5);
|
||||||
|
|
||||||
|
// Construction of a function from a function
|
||||||
|
func_void_type v6(&write_five);
|
||||||
|
|
||||||
|
// Invocation of a function
|
||||||
|
global_int = 0;
|
||||||
|
v6();
|
||||||
|
BOOST_CHECK(global_int == 5);
|
||||||
|
|
||||||
|
// clear() method
|
||||||
|
v6.clear();
|
||||||
|
BOOST_CHECK(v6.empty());
|
||||||
|
|
||||||
|
// Assignment to an empty function
|
||||||
|
v6 = three;
|
||||||
|
BOOST_CHECK(!v6.empty());
|
||||||
|
|
||||||
|
// Invocation
|
||||||
|
global_int = 0;
|
||||||
|
v6();
|
||||||
|
BOOST_CHECK(global_int == 3);
|
||||||
|
|
||||||
|
// Assignment to a non-empty function
|
||||||
|
v6 = five;
|
||||||
|
|
||||||
|
// Invocation
|
||||||
|
global_int = 0;
|
||||||
|
v6();
|
||||||
|
BOOST_CHECK(global_int == 5);
|
||||||
|
|
||||||
|
// clear()
|
||||||
|
v6.clear();
|
||||||
|
BOOST_CHECK(v6.empty());
|
||||||
|
|
||||||
|
// Assignment to an empty function from a free function
|
||||||
|
v6 = &write_five;
|
||||||
|
BOOST_CHECK(!v6.empty());
|
||||||
|
|
||||||
|
// Invocation
|
||||||
|
global_int = 0;
|
||||||
|
v6();
|
||||||
|
BOOST_CHECK(global_int == 5);
|
||||||
|
|
||||||
|
// Assignment to a non-empty function from a free function
|
||||||
|
v6 = &write_three;
|
||||||
|
BOOST_CHECK(!v6.empty());
|
||||||
|
|
||||||
|
// Invocation
|
||||||
|
global_int = 0;
|
||||||
|
v6();
|
||||||
|
BOOST_CHECK(global_int == 3);
|
||||||
|
|
||||||
|
// Assignment
|
||||||
|
v6 = five;
|
||||||
|
BOOST_CHECK(!v6.empty());
|
||||||
|
|
||||||
|
// Invocation
|
||||||
|
global_int = 0;
|
||||||
|
v6();
|
||||||
|
BOOST_CHECK(global_int == 5);
|
||||||
|
|
||||||
|
// Const vs. non-const
|
||||||
|
write_const_1_nonconst_2 one_or_two;
|
||||||
|
const function<void ()> v7(one_or_two);
|
||||||
|
function<void ()> v8(one_or_two);
|
||||||
|
|
||||||
|
global_int = 0;
|
||||||
|
v7();
|
||||||
|
BOOST_CHECK(global_int == 2);
|
||||||
|
|
||||||
|
global_int = 0;
|
||||||
|
v8();
|
||||||
|
BOOST_CHECK(global_int == 2);
|
||||||
|
|
||||||
|
// Test construction from 0 and comparison to 0
|
||||||
|
func_void_type v9(0);
|
||||||
|
BOOST_CHECK(v9 == 0);
|
||||||
|
BOOST_CHECK(0 == v9);
|
||||||
|
|
||||||
|
// Test return values
|
||||||
|
typedef function<int ()> func_int_type;
|
||||||
|
generate_five_obj gen_five;
|
||||||
|
generate_three_obj gen_three;
|
||||||
|
|
||||||
|
func_int_type i0(gen_five);
|
||||||
|
|
||||||
|
BOOST_CHECK(i0() == 5);
|
||||||
|
i0 = gen_three;
|
||||||
|
BOOST_CHECK(i0() == 3);
|
||||||
|
i0 = &generate_five;
|
||||||
|
BOOST_CHECK(i0() == 5);
|
||||||
|
i0 = &generate_three;
|
||||||
|
BOOST_CHECK(i0() == 3);
|
||||||
|
BOOST_CHECK(i0? true : false);
|
||||||
|
i0.clear();
|
||||||
|
BOOST_CHECK(!i0? true : false);
|
||||||
|
|
||||||
|
// Test return values with compatible types
|
||||||
|
typedef function<long ()> func_long_type;
|
||||||
|
func_long_type i1(gen_five);
|
||||||
|
|
||||||
|
BOOST_CHECK(i1() == 5);
|
||||||
|
i1 = gen_three;
|
||||||
|
BOOST_CHECK(i1() == 3);
|
||||||
|
i1 = &generate_five;
|
||||||
|
BOOST_CHECK(i1() == 5);
|
||||||
|
i1 = &generate_three;
|
||||||
|
BOOST_CHECK(i1() == 3);
|
||||||
|
BOOST_CHECK(i1? true : false);
|
||||||
|
i1.clear();
|
||||||
|
BOOST_CHECK(!i1? true : false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_one_arg()
|
||||||
|
{
|
||||||
|
negate<int> neg;
|
||||||
|
|
||||||
|
function<int (int)> f1(neg);
|
||||||
|
BOOST_CHECK(f1(5) == -5);
|
||||||
|
|
||||||
|
function<string (string)> id(&identity_str);
|
||||||
|
BOOST_CHECK(id("str") == "str");
|
||||||
|
|
||||||
|
function<string (const char*)> id2(&identity_str);
|
||||||
|
BOOST_CHECK(id2("foo") == "foo");
|
||||||
|
|
||||||
|
add_to_obj add_to(5);
|
||||||
|
function<int (int)> f2(add_to);
|
||||||
|
BOOST_CHECK(f2(3) == 8);
|
||||||
|
|
||||||
|
const function<int (int)> cf2(add_to);
|
||||||
|
BOOST_CHECK(cf2(3) == 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_two_args()
|
||||||
|
{
|
||||||
|
function<string (const string&, const string&)> cat(&string_cat);
|
||||||
|
BOOST_CHECK(cat("str", "ing") == "string");
|
||||||
|
|
||||||
|
function<int (short, short)> sum(&sum_ints);
|
||||||
|
BOOST_CHECK(sum(2, 3) == 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_emptiness()
|
||||||
|
{
|
||||||
|
function<float ()> f1;
|
||||||
|
BOOST_CHECK(f1.empty());
|
||||||
|
|
||||||
|
function<float ()> f2;
|
||||||
|
f2 = f1;
|
||||||
|
BOOST_CHECK(f2.empty());
|
||||||
|
|
||||||
|
function<double ()> f3;
|
||||||
|
f3 = f2;
|
||||||
|
BOOST_CHECK(f3.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
struct X
|
||||||
|
{
|
||||||
|
X(int v) : value(v)
|
||||||
|
{}
|
||||||
|
|
||||||
|
int twice() const
|
||||||
|
{
|
||||||
|
return 2*value;
|
||||||
|
}
|
||||||
|
int plus(int v)
|
||||||
|
{
|
||||||
|
return value + v;
|
||||||
|
}
|
||||||
|
|
||||||
|
int value;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void test_member_functions()
|
||||||
|
{
|
||||||
|
#ifndef TEST_LOKI_FUNCTION
|
||||||
|
|
||||||
|
boost::function<int (X*)> f1(&X::twice);
|
||||||
|
|
||||||
|
X one(1);
|
||||||
|
X five(5);
|
||||||
|
|
||||||
|
BOOST_CHECK(f1(&one) == 2);
|
||||||
|
BOOST_CHECK(f1(&five) == 10);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
X one(1);
|
||||||
|
X five(5);
|
||||||
|
|
||||||
|
Loki::Function<int()> f1(&one,&X::twice);
|
||||||
|
BOOST_CHECK(f1() == 2);
|
||||||
|
|
||||||
|
f1 = Loki::Function<int()>(&five,&X::twice);
|
||||||
|
BOOST_CHECK(f1() == 10);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TEST_LOKI_FUNCTION
|
||||||
|
|
||||||
|
boost::function<int (X*)> f1_2;
|
||||||
|
|
||||||
|
f1_2 = &X::twice;
|
||||||
|
|
||||||
|
BOOST_CHECK(f1_2(&one) == 2);
|
||||||
|
BOOST_CHECK(f1_2(&five) == 10);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
Loki::Function<int ()> f1_2(&one,&X::twice);
|
||||||
|
BOOST_CHECK(f1_2() == 2);
|
||||||
|
|
||||||
|
f1_2 = Loki::function<int ()>(&five,&X::twice);
|
||||||
|
BOOST_CHECK(f1_2() == 10);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TEST_LOKI_FUNCTION
|
||||||
|
|
||||||
|
boost::function<int (X&, int)> f2(&X::plus);
|
||||||
|
|
||||||
|
BOOST_CHECK(f2(one, 3) == 4);
|
||||||
|
BOOST_CHECK(f2(five, 4) == 9);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
Loki::Function<int (int)> f2(&one,&X::plus);
|
||||||
|
BOOST_CHECK(f2(3) == 4);
|
||||||
|
|
||||||
|
f2 = Loki::Function<int (int)>(&five,&X::plus);
|
||||||
|
BOOST_CHECK(f2(4) == 9);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
struct add_with_throw_on_copy
|
||||||
|
{
|
||||||
|
int operator()(int x, int y) const
|
||||||
|
{
|
||||||
|
return x+y;
|
||||||
|
}
|
||||||
|
|
||||||
|
add_with_throw_on_copy()
|
||||||
|
{}
|
||||||
|
|
||||||
|
add_with_throw_on_copy(const add_with_throw_on_copy&)
|
||||||
|
{
|
||||||
|
throw runtime_error("But this CAN'T throw");
|
||||||
|
}
|
||||||
|
|
||||||
|
add_with_throw_on_copy& operator=(const add_with_throw_on_copy&)
|
||||||
|
{
|
||||||
|
throw runtime_error("But this CAN'T throw");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void test_ref()
|
||||||
|
{
|
||||||
|
add_with_throw_on_copy atc;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
#ifndef TEST_LOKI_FUNCTION
|
||||||
|
boost::function<int (int, int)> f(ref(atc));
|
||||||
|
BOOST_CHECK(f(1, 3) == 4);
|
||||||
|
#else
|
||||||
|
//TODO: implement Loki::Ref
|
||||||
|
//Loki::Function<int (int, int)> f(Loki::ref(atc));
|
||||||
|
//BOOST_CHECK(f(1, 3) == 4);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
catch(runtime_error e)
|
||||||
|
{
|
||||||
|
BOOST_ERROR("Nonthrowing constructor threw an exception");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_exception()
|
||||||
|
{
|
||||||
|
#ifndef TEST_LOKI_FUNCTION
|
||||||
|
boost::function<int (int, int)> f;
|
||||||
|
#else
|
||||||
|
Loki::Function<int (int, int)> f;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
f(5, 4);
|
||||||
|
BOOST_CHECK(false);
|
||||||
|
}
|
||||||
|
#ifndef TEST_LOKI_FUNCTION
|
||||||
|
catch(boost::bad_function_call)
|
||||||
|
#else
|
||||||
|
catch(Loki::bad_function_call)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
// okay
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TEST_LOKI_FUNCTION
|
||||||
|
typedef boost::function< void * (void * reader) > reader_type;
|
||||||
|
#else
|
||||||
|
typedef Loki::Function< void * (void * reader) > reader_type;
|
||||||
|
#endif
|
||||||
|
typedef std::pair<int, reader_type> mapped_type;
|
||||||
|
|
||||||
|
static void test_implicit()
|
||||||
|
{
|
||||||
|
mapped_type m;
|
||||||
|
m = mapped_type();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef TEST_LOKI_FUNCTION
|
||||||
|
static void test_call_obj(boost::function<int (int, int)> f)
|
||||||
|
#else
|
||||||
|
static void test_call_obj(Loki::function<int (int, int)> f)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
assert(!f.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef TEST_LOKI_FUNCTION
|
||||||
|
static void test_call_cref(const boost::function<int (int, int)>& f)
|
||||||
|
#else
|
||||||
|
static void test_call_cref(const Loki::Function<int (int, int)>& f)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
assert(!f.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_call()
|
||||||
|
{
|
||||||
|
test_call_obj(std::plus<int>());
|
||||||
|
test_call_cref(std::plus<int>());
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_main(int, char* [])
|
||||||
|
{
|
||||||
|
test_zero_args();
|
||||||
|
test_one_arg();
|
||||||
|
test_two_args();
|
||||||
|
test_emptiness();
|
||||||
|
test_member_functions();
|
||||||
|
test_ref();
|
||||||
|
test_exception();
|
||||||
|
test_implicit();
|
||||||
|
test_call();
|
||||||
|
|
||||||
|
system("pause");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
79
test/Function/FunctionTest.dev
Executable file
79
test/Function/FunctionTest.dev
Executable file
|
@ -0,0 +1,79 @@
|
||||||
|
[Project]
|
||||||
|
FileName=FunctionTest.dev
|
||||||
|
Name=FunctionTest
|
||||||
|
UnitCount=3
|
||||||
|
Type=1
|
||||||
|
Ver=1
|
||||||
|
ObjFiles=
|
||||||
|
Includes=..\..\include;..;.
|
||||||
|
Libs=
|
||||||
|
PrivateResource=
|
||||||
|
ResourceIncludes=
|
||||||
|
MakeIncludes=
|
||||||
|
Compiler=
|
||||||
|
CppCompiler=-Wall -pedantic_@@_
|
||||||
|
Linker=
|
||||||
|
IsCpp=1
|
||||||
|
Icon=
|
||||||
|
ExeOutput=
|
||||||
|
ObjectOutput=
|
||||||
|
OverrideOutput=0
|
||||||
|
OverrideOutputName=FunctionTest.exe
|
||||||
|
HostApplication=
|
||||||
|
Folders=
|
||||||
|
CommandLine=
|
||||||
|
UseCustomMakefile=0
|
||||||
|
CustomMakefile=Makefile.loki
|
||||||
|
IncludeVersionInfo=0
|
||||||
|
SupportXPThemes=0
|
||||||
|
CompilerSet=0
|
||||||
|
CompilerSettings=0000000001010000000000
|
||||||
|
|
||||||
|
[VersionInfo]
|
||||||
|
Major=0
|
||||||
|
Minor=1
|
||||||
|
Release=1
|
||||||
|
Build=1
|
||||||
|
LanguageID=1033
|
||||||
|
CharsetID=1252
|
||||||
|
CompanyName=
|
||||||
|
FileVersion=
|
||||||
|
FileDescription=Developed using the Dev-C++ IDE
|
||||||
|
InternalName=
|
||||||
|
LegalCopyright=
|
||||||
|
LegalTrademarks=
|
||||||
|
OriginalFilename=
|
||||||
|
ProductName=
|
||||||
|
ProductVersion=
|
||||||
|
AutoIncBuildNr=0
|
||||||
|
|
||||||
|
[Unit1]
|
||||||
|
FileName=..\..\src\Singleton.cpp
|
||||||
|
CompileCpp=1
|
||||||
|
Folder=FunctionTest
|
||||||
|
Compile=1
|
||||||
|
Link=1
|
||||||
|
Priority=1000
|
||||||
|
OverrideBuildCmd=0
|
||||||
|
BuildCmd=
|
||||||
|
|
||||||
|
[Unit2]
|
||||||
|
FileName=..\..\src\SmallObj.cpp
|
||||||
|
CompileCpp=1
|
||||||
|
Folder=FunctionTest
|
||||||
|
Compile=1
|
||||||
|
Link=1
|
||||||
|
Priority=1000
|
||||||
|
OverrideBuildCmd=0
|
||||||
|
BuildCmd=
|
||||||
|
|
||||||
|
[Unit3]
|
||||||
|
FileName=FunctionTest.cpp
|
||||||
|
CompileCpp=1
|
||||||
|
Folder=FunctionTest
|
||||||
|
Compile=1
|
||||||
|
Link=1
|
||||||
|
Priority=1000
|
||||||
|
OverrideBuildCmd=0
|
||||||
|
BuildCmd=
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue