From 9a2a524f1e311853d08050be2dcdddc09ac7759a Mon Sep 17 00:00:00 2001 From: Daniel Wilhelm Date: Fri, 18 Apr 2014 17:01:29 +0200 Subject: 3.0 --- shared/loki/Functor.h | 1789 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1789 insertions(+) create mode 100644 shared/loki/Functor.h (limited to 'shared/loki/Functor.h') diff --git a/shared/loki/Functor.h b/shared/loki/Functor.h new file mode 100644 index 00000000..bcba855d --- /dev/null +++ b/shared/loki/Functor.h @@ -0,0 +1,1789 @@ +//////////////////////////////////////////////////////////////////////////////// +// The Loki Library +// Copyright (c) 2001 by Andrei Alexandrescu +// This code accompanies the book: +// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design +// Patterns Applied". Copyright (c) 2001. Addison-Wesley. +// 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 or Addison-Wesley Longman make no representations about the +// suitability of this software for any purpose. It is provided "as is" +// without express or implied warranty. +//////////////////////////////////////////////////////////////////////////////// +#ifndef LOKI_FUNCTOR_INC_ +#define LOKI_FUNCTOR_INC_ + +// $Id: Functor.h 750 2006-10-17 19:50:02Z syntheticpp $ + + +#include "Typelist.h" +#include "Sequence.h" +#include "EmptyType.h" +#include "SmallObj.h" +#include "TypeTraits.h" +#include +#include + +/// \defgroup FunctorGroup Function objects + +#ifndef LOKI_FUNCTOR_IS_NOT_A_SMALLOBJECT +//#define LOKI_FUNCTOR_IS_NOT_A_SMALLOBJECT +#endif + +#ifndef LOKI_FUNCTORS_ARE_COMPARABLE +//#define LOKI_FUNCTORS_ARE_COMPARABLE +#endif + + +/// \namespace Loki +/// All classes of Loki are in the Loki namespace +namespace Loki +{ +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl (internal) +//////////////////////////////////////////////////////////////////////////////// + + namespace Private + { + template class ThreadingModel> + struct FunctorImplBase +#ifdef LOKI_FUNCTOR_IS_NOT_A_SMALLOBJECT + { +#else + : public SmallValueObject + { + inline FunctorImplBase() : + SmallValueObject() {} + inline FunctorImplBase(const FunctorImplBase&) : + SmallValueObject() {} +#endif + + typedef R ResultType; + typedef FunctorImplBase FunctorImplBaseType; + + typedef EmptyType Parm1; + typedef EmptyType Parm2; + typedef EmptyType Parm3; + typedef EmptyType Parm4; + typedef EmptyType Parm5; + typedef EmptyType Parm6; + typedef EmptyType Parm7; + typedef EmptyType Parm8; + typedef EmptyType Parm9; + typedef EmptyType Parm10; + typedef EmptyType Parm11; + typedef EmptyType Parm12; + typedef EmptyType Parm13; + typedef EmptyType Parm14; + typedef EmptyType Parm15; + + + virtual ~FunctorImplBase() + {} + + virtual FunctorImplBase* DoClone() const = 0; + + template + static U* Clone(U* pObj) + { + if (!pObj) return 0; + U* pClone = static_cast(pObj->DoClone()); + assert(typeid(*pClone) == typeid(*pObj)); + return pClone; + } + + +#ifdef LOKI_FUNCTORS_ARE_COMPARABLE + + virtual bool operator==(const FunctorImplBase&) const = 0; + +#endif + + }; + } + +//////////////////////////////////////////////////////////////////////////////// +// macro LOKI_DEFINE_CLONE_FUNCTORIMPL +// Implements the DoClone function for a functor implementation +//////////////////////////////////////////////////////////////////////////////// + +#define LOKI_DEFINE_CLONE_FUNCTORIMPL(Cls) \ + virtual Cls* DoClone() const { return new Cls(*this); } + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// The base class for a hierarchy of functors. The FunctorImpl class is not used +// directly; rather, the Functor class manages and forwards to a pointer to +// FunctorImpl +// You may want to derive your own functors from FunctorImpl. +// Specializations of FunctorImpl for up to 15 parameters follow +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel = LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL> + class FunctorImpl; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 0 (zero) parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl + : public Private::FunctorImplBase + { + public: + typedef R ResultType; + virtual R operator()() = 0; + }; + + //////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 1 parameter +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl, ThreadingModel> + : public Private::FunctorImplBase + { + public: + typedef R ResultType; + typedef typename TypeTraits::ParameterType Parm1; + virtual R operator()(Parm1) = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 2 parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl, ThreadingModel> + : public Private::FunctorImplBase + { + public: + typedef R ResultType; + typedef typename TypeTraits::ParameterType Parm1; + typedef typename TypeTraits::ParameterType Parm2; + virtual R operator()(Parm1, Parm2) = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 3 parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl, ThreadingModel> + : public Private::FunctorImplBase + { + public: + typedef R ResultType; + typedef typename TypeTraits::ParameterType Parm1; + typedef typename TypeTraits::ParameterType Parm2; + typedef typename TypeTraits::ParameterType Parm3; + virtual R operator()(Parm1, Parm2, Parm3) = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 4 parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl, ThreadingModel> + : public Private::FunctorImplBase + { + public: + typedef R ResultType; + typedef typename TypeTraits::ParameterType Parm1; + typedef typename TypeTraits::ParameterType Parm2; + typedef typename TypeTraits::ParameterType Parm3; + typedef typename TypeTraits::ParameterType Parm4; + virtual R operator()(Parm1, Parm2, Parm3, Parm4) = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 5 parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl, ThreadingModel> + : public Private::FunctorImplBase + { + public: + typedef R ResultType; + typedef typename TypeTraits::ParameterType Parm1; + typedef typename TypeTraits::ParameterType Parm2; + typedef typename TypeTraits::ParameterType Parm3; + typedef typename TypeTraits::ParameterType Parm4; + typedef typename TypeTraits::ParameterType Parm5; + virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5) = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 6 parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl, ThreadingModel> + : public Private::FunctorImplBase + { + public: + typedef R ResultType; + typedef typename TypeTraits::ParameterType Parm1; + typedef typename TypeTraits::ParameterType Parm2; + typedef typename TypeTraits::ParameterType Parm3; + typedef typename TypeTraits::ParameterType Parm4; + typedef typename TypeTraits::ParameterType Parm5; + typedef typename TypeTraits::ParameterType Parm6; + virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6) = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 7 parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl, ThreadingModel> + : public Private::FunctorImplBase + { + public: + typedef R ResultType; + typedef typename TypeTraits::ParameterType Parm1; + typedef typename TypeTraits::ParameterType Parm2; + typedef typename TypeTraits::ParameterType Parm3; + typedef typename TypeTraits::ParameterType Parm4; + typedef typename TypeTraits::ParameterType Parm5; + typedef typename TypeTraits::ParameterType Parm6; + typedef typename TypeTraits::ParameterType Parm7; + virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, + Parm7) = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 8 parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl, + ThreadingModel> + : public Private::FunctorImplBase + { + public: + typedef R ResultType; + typedef typename TypeTraits::ParameterType Parm1; + typedef typename TypeTraits::ParameterType Parm2; + typedef typename TypeTraits::ParameterType Parm3; + typedef typename TypeTraits::ParameterType Parm4; + typedef typename TypeTraits::ParameterType Parm5; + typedef typename TypeTraits::ParameterType Parm6; + typedef typename TypeTraits::ParameterType Parm7; + typedef typename TypeTraits::ParameterType Parm8; + virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, + Parm7, Parm8) = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 9 parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl, + ThreadingModel> + : public Private::FunctorImplBase + { + public: + typedef R ResultType; + typedef typename TypeTraits::ParameterType Parm1; + typedef typename TypeTraits::ParameterType Parm2; + typedef typename TypeTraits::ParameterType Parm3; + typedef typename TypeTraits::ParameterType Parm4; + typedef typename TypeTraits::ParameterType Parm5; + typedef typename TypeTraits::ParameterType Parm6; + typedef typename TypeTraits::ParameterType Parm7; + typedef typename TypeTraits::ParameterType Parm8; + typedef typename TypeTraits::ParameterType Parm9; + virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, + Parm7, Parm8, Parm9) = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 10 parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl, + ThreadingModel> + : public Private::FunctorImplBase + { + public: + typedef R ResultType; + typedef typename TypeTraits::ParameterType Parm1; + typedef typename TypeTraits::ParameterType Parm2; + typedef typename TypeTraits::ParameterType Parm3; + typedef typename TypeTraits::ParameterType Parm4; + typedef typename TypeTraits::ParameterType Parm5; + typedef typename TypeTraits::ParameterType Parm6; + typedef typename TypeTraits::ParameterType Parm7; + typedef typename TypeTraits::ParameterType Parm8; + typedef typename TypeTraits::ParameterType Parm9; + typedef typename TypeTraits::ParameterType Parm10; + virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, + Parm7, Parm8, Parm9, Parm10) = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 11 parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl, + ThreadingModel> + : public Private::FunctorImplBase + { + public: + typedef R ResultType; + typedef typename TypeTraits::ParameterType Parm1; + typedef typename TypeTraits::ParameterType Parm2; + typedef typename TypeTraits::ParameterType Parm3; + typedef typename TypeTraits::ParameterType Parm4; + typedef typename TypeTraits::ParameterType Parm5; + typedef typename TypeTraits::ParameterType Parm6; + typedef typename TypeTraits::ParameterType Parm7; + typedef typename TypeTraits::ParameterType Parm8; + typedef typename TypeTraits::ParameterType Parm9; + typedef typename TypeTraits::ParameterType Parm10; + typedef typename TypeTraits::ParameterType Parm11; + virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, + Parm7, Parm8, Parm9, Parm10, Parm11) = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 12 parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl, + ThreadingModel> + : public Private::FunctorImplBase + { + public: + typedef R ResultType; + typedef typename TypeTraits::ParameterType Parm1; + typedef typename TypeTraits::ParameterType Parm2; + typedef typename TypeTraits::ParameterType Parm3; + typedef typename TypeTraits::ParameterType Parm4; + typedef typename TypeTraits::ParameterType Parm5; + typedef typename TypeTraits::ParameterType Parm6; + typedef typename TypeTraits::ParameterType Parm7; + typedef typename TypeTraits::ParameterType Parm8; + typedef typename TypeTraits::ParameterType Parm9; + typedef typename TypeTraits::ParameterType Parm10; + typedef typename TypeTraits::ParameterType Parm11; + typedef typename TypeTraits::ParameterType Parm12; + virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, + Parm7, Parm8, Parm9, Parm10, Parm11, Parm12) = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 13 parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl, + ThreadingModel> + : public Private::FunctorImplBase + { + public: + typedef R ResultType; + typedef typename TypeTraits::ParameterType Parm1; + typedef typename TypeTraits::ParameterType Parm2; + typedef typename TypeTraits::ParameterType Parm3; + typedef typename TypeTraits::ParameterType Parm4; + typedef typename TypeTraits::ParameterType Parm5; + typedef typename TypeTraits::ParameterType Parm6; + typedef typename TypeTraits::ParameterType Parm7; + typedef typename TypeTraits::ParameterType Parm8; + typedef typename TypeTraits::ParameterType Parm9; + typedef typename TypeTraits::ParameterType Parm10; + typedef typename TypeTraits::ParameterType Parm11; + typedef typename TypeTraits::ParameterType Parm12; + typedef typename TypeTraits::ParameterType Parm13; + virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, + Parm7, Parm8, Parm9, Parm10, Parm11, Parm12, Parm13) = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 14 parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl, + ThreadingModel> + : public Private::FunctorImplBase + { + public: + typedef R ResultType; + typedef typename TypeTraits::ParameterType Parm1; + typedef typename TypeTraits::ParameterType Parm2; + typedef typename TypeTraits::ParameterType Parm3; + typedef typename TypeTraits::ParameterType Parm4; + typedef typename TypeTraits::ParameterType Parm5; + typedef typename TypeTraits::ParameterType Parm6; + typedef typename TypeTraits::ParameterType Parm7; + typedef typename TypeTraits::ParameterType Parm8; + typedef typename TypeTraits::ParameterType Parm9; + typedef typename TypeTraits::ParameterType Parm10; + typedef typename TypeTraits::ParameterType Parm11; + typedef typename TypeTraits::ParameterType Parm12; + typedef typename TypeTraits::ParameterType Parm13; + typedef typename TypeTraits::ParameterType Parm14; + virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, + Parm7, Parm8, Parm9, Parm10, Parm11, Parm12, Parm13, Parm14) = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 15 parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl, + ThreadingModel> + : public Private::FunctorImplBase + { + public: + typedef R ResultType; + typedef typename TypeTraits::ParameterType Parm1; + typedef typename TypeTraits::ParameterType Parm2; + typedef typename TypeTraits::ParameterType Parm3; + typedef typename TypeTraits::ParameterType Parm4; + typedef typename TypeTraits::ParameterType Parm5; + typedef typename TypeTraits::ParameterType Parm6; + typedef typename TypeTraits::ParameterType Parm7; + typedef typename TypeTraits::ParameterType Parm8; + typedef typename TypeTraits::ParameterType Parm9; + typedef typename TypeTraits::ParameterType Parm10; + typedef typename TypeTraits::ParameterType Parm11; + typedef typename TypeTraits::ParameterType Parm12; + typedef typename TypeTraits::ParameterType Parm13; + typedef typename TypeTraits::ParameterType Parm14; + typedef typename TypeTraits::ParameterType Parm15; + virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, + Parm7, Parm8, Parm9, Parm10, Parm11, Parm12, Parm13, Parm14, + Parm15) = 0; + }; + +#ifndef LOKI_DISABLE_TYPELIST_MACROS + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 1 parameter +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl + : public Private::FunctorImplBase + { + public: + typedef R ResultType; + typedef typename TypeTraits::ParameterType Parm1; + virtual R operator()(Parm1) = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 2 parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl + : public Private::FunctorImplBase + { + public: + typedef R ResultType; + typedef typename TypeTraits::ParameterType Parm1; + typedef typename TypeTraits::ParameterType Parm2; + virtual R operator()(Parm1, Parm2) = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 3 parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl + : public Private::FunctorImplBase + { + public: + typedef R ResultType; + typedef typename TypeTraits::ParameterType Parm1; + typedef typename TypeTraits::ParameterType Parm2; + typedef typename TypeTraits::ParameterType Parm3; + virtual R operator()(Parm1, Parm2, Parm3) = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 4 parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl + : public Private::FunctorImplBase + { + public: + typedef R ResultType; + typedef typename TypeTraits::ParameterType Parm1; + typedef typename TypeTraits::ParameterType Parm2; + typedef typename TypeTraits::ParameterType Parm3; + typedef typename TypeTraits::ParameterType Parm4; + virtual R operator()(Parm1, Parm2, Parm3, Parm4) = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 5 parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl + : public Private::FunctorImplBase + { + public: + typedef R ResultType; + typedef typename TypeTraits::ParameterType Parm1; + typedef typename TypeTraits::ParameterType Parm2; + typedef typename TypeTraits::ParameterType Parm3; + typedef typename TypeTraits::ParameterType Parm4; + typedef typename TypeTraits::ParameterType Parm5; + virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5) = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 6 parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl + : public Private::FunctorImplBase + { + public: + typedef R ResultType; + typedef typename TypeTraits::ParameterType Parm1; + typedef typename TypeTraits::ParameterType Parm2; + typedef typename TypeTraits::ParameterType Parm3; + typedef typename TypeTraits::ParameterType Parm4; + typedef typename TypeTraits::ParameterType Parm5; + typedef typename TypeTraits::ParameterType Parm6; + virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6) = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 7 parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl + : public Private::FunctorImplBase + { + public: + typedef R ResultType; + typedef typename TypeTraits::ParameterType Parm1; + typedef typename TypeTraits::ParameterType Parm2; + typedef typename TypeTraits::ParameterType Parm3; + typedef typename TypeTraits::ParameterType Parm4; + typedef typename TypeTraits::ParameterType Parm5; + typedef typename TypeTraits::ParameterType Parm6; + typedef typename TypeTraits::ParameterType Parm7; + virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, + Parm7) = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 8 parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl + : public Private::FunctorImplBase + { + public: + typedef R ResultType; + typedef typename TypeTraits::ParameterType Parm1; + typedef typename TypeTraits::ParameterType Parm2; + typedef typename TypeTraits::ParameterType Parm3; + typedef typename TypeTraits::ParameterType Parm4; + typedef typename TypeTraits::ParameterType Parm5; + typedef typename TypeTraits::ParameterType Parm6; + typedef typename TypeTraits::ParameterType Parm7; + typedef typename TypeTraits::ParameterType Parm8; + virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, + Parm7, Parm8) = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 9 parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl + : public Private::FunctorImplBase + { + public: + typedef R ResultType; + typedef typename TypeTraits::ParameterType Parm1; + typedef typename TypeTraits::ParameterType Parm2; + typedef typename TypeTraits::ParameterType Parm3; + typedef typename TypeTraits::ParameterType Parm4; + typedef typename TypeTraits::ParameterType Parm5; + typedef typename TypeTraits::ParameterType Parm6; + typedef typename TypeTraits::ParameterType Parm7; + typedef typename TypeTraits::ParameterType Parm8; + typedef typename TypeTraits::ParameterType Parm9; + virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, + Parm7, Parm8, Parm9) = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 10 parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl + : public Private::FunctorImplBase + { + public: + typedef R ResultType; + typedef typename TypeTraits::ParameterType Parm1; + typedef typename TypeTraits::ParameterType Parm2; + typedef typename TypeTraits::ParameterType Parm3; + typedef typename TypeTraits::ParameterType Parm4; + typedef typename TypeTraits::ParameterType Parm5; + typedef typename TypeTraits::ParameterType Parm6; + typedef typename TypeTraits::ParameterType Parm7; + typedef typename TypeTraits::ParameterType Parm8; + typedef typename TypeTraits::ParameterType Parm9; + typedef typename TypeTraits::ParameterType Parm10; + virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, + Parm7, Parm8, Parm9, Parm10) = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 11 parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl + : public Private::FunctorImplBase + { + public: + typedef R ResultType; + typedef typename TypeTraits::ParameterType Parm1; + typedef typename TypeTraits::ParameterType Parm2; + typedef typename TypeTraits::ParameterType Parm3; + typedef typename TypeTraits::ParameterType Parm4; + typedef typename TypeTraits::ParameterType Parm5; + typedef typename TypeTraits::ParameterType Parm6; + typedef typename TypeTraits::ParameterType Parm7; + typedef typename TypeTraits::ParameterType Parm8; + typedef typename TypeTraits::ParameterType Parm9; + typedef typename TypeTraits::ParameterType Parm10; + typedef typename TypeTraits::ParameterType Parm11; + virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, + Parm7, Parm8, Parm9, Parm10, Parm11) = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 12 parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl + : public Private::FunctorImplBase + { + public: + typedef R ResultType; + typedef typename TypeTraits::ParameterType Parm1; + typedef typename TypeTraits::ParameterType Parm2; + typedef typename TypeTraits::ParameterType Parm3; + typedef typename TypeTraits::ParameterType Parm4; + typedef typename TypeTraits::ParameterType Parm5; + typedef typename TypeTraits::ParameterType Parm6; + typedef typename TypeTraits::ParameterType Parm7; + typedef typename TypeTraits::ParameterType Parm8; + typedef typename TypeTraits::ParameterType Parm9; + typedef typename TypeTraits::ParameterType Parm10; + typedef typename TypeTraits::ParameterType Parm11; + typedef typename TypeTraits::ParameterType Parm12; + virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, + Parm7, Parm8, Parm9, Parm10, Parm11, Parm12) = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 13 parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl + : public Private::FunctorImplBase + { + public: + typedef R ResultType; + typedef typename TypeTraits::ParameterType Parm1; + typedef typename TypeTraits::ParameterType Parm2; + typedef typename TypeTraits::ParameterType Parm3; + typedef typename TypeTraits::ParameterType Parm4; + typedef typename TypeTraits::ParameterType Parm5; + typedef typename TypeTraits::ParameterType Parm6; + typedef typename TypeTraits::ParameterType Parm7; + typedef typename TypeTraits::ParameterType Parm8; + typedef typename TypeTraits::ParameterType Parm9; + typedef typename TypeTraits::ParameterType Parm10; + typedef typename TypeTraits::ParameterType Parm11; + typedef typename TypeTraits::ParameterType Parm12; + typedef typename TypeTraits::ParameterType Parm13; + virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, + Parm7, Parm8, Parm9, Parm10, Parm11, Parm12, Parm13) = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 14 parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl + : public Private::FunctorImplBase + { + public: + typedef R ResultType; + typedef typename TypeTraits::ParameterType Parm1; + typedef typename TypeTraits::ParameterType Parm2; + typedef typename TypeTraits::ParameterType Parm3; + typedef typename TypeTraits::ParameterType Parm4; + typedef typename TypeTraits::ParameterType Parm5; + typedef typename TypeTraits::ParameterType Parm6; + typedef typename TypeTraits::ParameterType Parm7; + typedef typename TypeTraits::ParameterType Parm8; + typedef typename TypeTraits::ParameterType Parm9; + typedef typename TypeTraits::ParameterType Parm10; + typedef typename TypeTraits::ParameterType Parm11; + typedef typename TypeTraits::ParameterType Parm12; + typedef typename TypeTraits::ParameterType Parm13; + typedef typename TypeTraits::ParameterType Parm14; + virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, + Parm7, Parm8, Parm9, Parm10, Parm11, Parm12, Parm13, Parm14) = 0; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorImpl +// Specialization for 15 parameters +//////////////////////////////////////////////////////////////////////////////// + + template class ThreadingModel> + class FunctorImpl + : public Private::FunctorImplBase + { + public: + typedef R ResultType; + typedef typename TypeTraits::ParameterType Parm1; + typedef typename TypeTraits::ParameterType Parm2; + typedef typename TypeTraits::ParameterType Parm3; + typedef typename TypeTraits::ParameterType Parm4; + typedef typename TypeTraits::ParameterType Parm5; + typedef typename TypeTraits::ParameterType Parm6; + typedef typename TypeTraits::ParameterType Parm7; + typedef typename TypeTraits::ParameterType Parm8; + typedef typename TypeTraits::ParameterType Parm9; + typedef typename TypeTraits::ParameterType Parm10; + typedef typename TypeTraits::ParameterType Parm11; + typedef typename TypeTraits::ParameterType Parm12; + typedef typename TypeTraits::ParameterType Parm13; + typedef typename TypeTraits::ParameterType Parm14; + typedef typename TypeTraits::ParameterType Parm15; + virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, + Parm7, Parm8, Parm9, Parm10, Parm11, Parm12, Parm13, Parm14, + Parm15) = 0; + }; + +#endif //LOKI_DISABLE_TYPELIST_MACROS + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorHandler +// Wraps functors and pointers to functions +//////////////////////////////////////////////////////////////////////////////// + + template + class FunctorHandler + : public ParentFunctor::Impl + { + typedef typename ParentFunctor::Impl Base; + + public: + typedef typename Base::ResultType ResultType; + typedef typename Base::Parm1 Parm1; + typedef typename Base::Parm2 Parm2; + typedef typename Base::Parm3 Parm3; + typedef typename Base::Parm4 Parm4; + typedef typename Base::Parm5 Parm5; + typedef typename Base::Parm6 Parm6; + typedef typename Base::Parm7 Parm7; + typedef typename Base::Parm8 Parm8; + typedef typename Base::Parm9 Parm9; + typedef typename Base::Parm10 Parm10; + typedef typename Base::Parm11 Parm11; + typedef typename Base::Parm12 Parm12; + typedef typename Base::Parm13 Parm13; + typedef typename Base::Parm14 Parm14; + typedef typename Base::Parm15 Parm15; + + FunctorHandler(const Fun& fun) : f_(fun) {} + + LOKI_DEFINE_CLONE_FUNCTORIMPL(FunctorHandler) + + +#ifdef LOKI_FUNCTORS_ARE_COMPARABLE + + + bool operator==(const typename Base::FunctorImplBaseType& rhs) const + { + // there is no static information if Functor holds a member function + // or a free function; this is the main difference to tr1::function + if(typeid(*this) != typeid(rhs)) + return false; // cannot be equal + + const FunctorHandler& fh = static_cast(rhs); + // 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()() + { return f_(); } + + ResultType operator()(Parm1 p1) + { return f_(p1); } + + ResultType operator()(Parm1 p1, Parm2 p2) + { return f_(p1, p2); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3) + { return f_(p1, p2, p3); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4) + { return f_(p1, p2, p3, p4); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5) + { return f_(p1, p2, p3, p4, p5); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6) + { return f_(p1, p2, p3, p4, p5, p6); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7) + { return f_(p1, p2, p3, p4, p5, p6, p7); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8) + { return f_(p1, p2, p3, p4, p5, p6, p7, p8); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9) + { return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10) + { return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11) + { return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11, + Parm12 p12) + { return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11, + Parm12 p12, Parm13 p13) + { return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11, + Parm12 p12, Parm13 p13, Parm14 p14) + { + return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, + p14); + } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11, + Parm12 p12, Parm13 p13, Parm14 p14, Parm15 p15) + { + return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, + p14, p15); + } + + private: + Fun f_; + }; + +//////////////////////////////////////////////////////////////////////////////// +// class template FunctorHandler +// Wraps pointers to member functions +//////////////////////////////////////////////////////////////////////////////// + + template + class MemFunHandler : public ParentFunctor::Impl + { + typedef typename ParentFunctor::Impl Base; + + public: + typedef typename Base::ResultType ResultType; + typedef typename Base::Parm1 Parm1; + typedef typename Base::Parm2 Parm2; + typedef typename Base::Parm3 Parm3; + typedef typename Base::Parm4 Parm4; + typedef typename Base::Parm5 Parm5; + typedef typename Base::Parm6 Parm6; + typedef typename Base::Parm7 Parm7; + typedef typename Base::Parm8 Parm8; + typedef typename Base::Parm9 Parm9; + typedef typename Base::Parm10 Parm10; + typedef typename Base::Parm11 Parm11; + typedef typename Base::Parm12 Parm12; + typedef typename Base::Parm13 Parm13; + typedef typename Base::Parm14 Parm14; + typedef typename Base::Parm15 Parm15; + + MemFunHandler(const PointerToObj& pObj, PointerToMemFn pMemFn) + : pObj_(pObj), pMemFn_(pMemFn) + {} + + LOKI_DEFINE_CLONE_FUNCTORIMPL(MemFunHandler) + + +#ifdef LOKI_FUNCTORS_ARE_COMPARABLE + + bool operator==(const typename Base::FunctorImplBaseType& rhs) const + { + if(typeid(*this) != typeid(rhs)) + return false; // cannot be equal + + const MemFunHandler& mfh = static_cast(rhs); + // 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_)(); } + + ResultType operator()(Parm1 p1) + { return ((*pObj_).*pMemFn_)(p1); } + + ResultType operator()(Parm1 p1, Parm2 p2) + { return ((*pObj_).*pMemFn_)(p1, p2); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3) + { return ((*pObj_).*pMemFn_)(p1, p2, p3); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4) + { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5) + { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6) + { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7) + { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8) + { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9) + { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10) + { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11) + { + return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, + p11); + } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11, + Parm12 p12) + { + return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, + p11, p12); + } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11, + Parm12 p12, Parm13 p13) + { + return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, + p11, p12, p13); + } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11, + Parm12 p12, Parm13 p13, Parm14 p14) + { + return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, + p11, p12, p13, p14); + } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11, + Parm12 p12, Parm13 p13, Parm14 p14, Parm15 p15) + { + return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, + p11, p12, p13, p14, p15); + } + + private: + PointerToObj pObj_; + 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 Functor +/// +/// \ingroup FunctorGroup +/// A generalized functor implementation with value semantics +/// +/// \par Macro: LOKI_FUNCTOR_IS_NOT_A_SMALLOBJECT +/// Define +/// \code LOKI_FUNCTOR_IS_NOT_A_SMALLOBJECT \endcode +/// to avoid static instantiation/delete +/// order problems. +/// 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 class ThreadingModel = LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL> + class Functor + { + public: + // Handy type definitions for the body type + typedef FunctorImpl Impl; + typedef R ResultType; + typedef TList ParmList; + typedef typename Impl::Parm1 Parm1; + typedef typename Impl::Parm2 Parm2; + typedef typename Impl::Parm3 Parm3; + typedef typename Impl::Parm4 Parm4; + typedef typename Impl::Parm5 Parm5; + typedef typename Impl::Parm6 Parm6; + typedef typename Impl::Parm7 Parm7; + typedef typename Impl::Parm8 Parm8; + typedef typename Impl::Parm9 Parm9; + typedef typename Impl::Parm10 Parm10; + typedef typename Impl::Parm11 Parm11; + typedef typename Impl::Parm12 Parm12; + typedef typename Impl::Parm13 Parm13; + typedef typename Impl::Parm14 Parm14; + typedef typename Impl::Parm15 Parm15; + + // Member functions + + Functor() : spImpl_(0) + {} + + Functor(const Functor& rhs) : spImpl_(Impl::Clone(rhs.spImpl_.get())) + {} + + Functor(std::auto_ptr spImpl) : spImpl_(spImpl) + {} + + template + Functor(Fun fun) + : spImpl_(new FunctorHandler(fun)) + {} + + template + Functor(const PtrObj& p, MemFn memFn) + : spImpl_(new MemFunHandler(p, memFn)) + {} + + typedef Impl * (std::auto_ptr::*unspecified_bool_type)() const; + + operator unspecified_bool_type() const + { + return spImpl_.get() ? &std::auto_ptr::get : 0; + } + + Functor& operator=(const Functor& rhs) + { + Functor copy(rhs); + // swap auto_ptrs by hand + Impl* p = spImpl_.release(); + spImpl_.reset(copy.spImpl_.release()); + copy.spImpl_.reset(p); + return *this; + } + +#ifdef LOKI_ENABLE_FUNCTION + + bool empty() const + { + return spImpl_.get() == 0; + } + + void clear() + { + spImpl_.reset(0); + } +#endif + +#ifdef LOKI_FUNCTORS_ARE_COMPARABLE + + 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 + return (*spImpl_)(); + } + + ResultType operator()(Parm1 p1) const + { + LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL + return (*spImpl_)(p1); + } + + ResultType operator()(Parm1 p1, Parm2 p2) const + { + LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL + return (*spImpl_)(p1, p2); + } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3) const + { + LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL + return (*spImpl_)(p1, p2, p3); + } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4) const + { + 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 + { + 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, + Parm6 p6) const + { + 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, + Parm6 p6, Parm7 p7) const + { + 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, + Parm6 p6, Parm7 p7, Parm8 p8) const + { + 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, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9) const + { + 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, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10) const + { + 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, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11) const + { + 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, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11, + Parm12 p12) const + { + LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL + return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, + p12); + } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11, + Parm12 p12, Parm13 p13) const + { + LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL + return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, + p12, p13); + } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11, + 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, + p12, p13, p14); + } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11, + 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, + p12, p13, p14, p15); + } + + private: + std::auto_ptr spImpl_; + }; + + +//////////////////////////////////////////////////////////////////////////////// +// +// BindersFirst and Chainer +// +//////////////////////////////////////////////////////////////////////////////// + + namespace Private + { + template struct BinderFirstTraits; + + template class ThreadingModel> + struct BinderFirstTraits< Functor > + { + typedef Functor OriginalFunctor; + + typedef typename TL::Erase::Result> + ::Result + ParmList; + + typedef typename TL::TypeAt::Result OriginalParm1; + + typedef Functor BoundFunctorType; + + typedef typename BoundFunctorType::Impl Impl; + + }; + + + template + struct BinderFirstBoundTypeStorage; + + template + struct BinderFirstBoundTypeStorage + { + typedef typename TypeTraits::ParameterType RefOrValue; + }; + + template class ThreadingModel> + struct BinderFirstBoundTypeStorage< Functor > + { + typedef Functor OriginalFunctor; + typedef const typename TypeTraits::ReferredType RefOrValue; + }; + + + } // namespace Private + +//////////////////////////////////////////////////////////////////////////////// +/// \class BinderFirst +/// +/// \ingroup FunctorGroup +/// Binds the first parameter of a Functor object to a specific value +//////////////////////////////////////////////////////////////////////////////// + + template + class BinderFirst + : public Private::BinderFirstTraits::Impl + { + typedef typename Private::BinderFirstTraits::Impl Base; + typedef typename OriginalFunctor::ResultType ResultType; + + typedef typename OriginalFunctor::Parm1 BoundType; + + typedef typename Private::BinderFirstBoundTypeStorage< + typename Private::BinderFirstTraits + ::OriginalParm1> + ::RefOrValue + BoundTypeStorage; + + typedef typename OriginalFunctor::Parm2 Parm1; + typedef typename OriginalFunctor::Parm3 Parm2; + typedef typename OriginalFunctor::Parm4 Parm3; + typedef typename OriginalFunctor::Parm5 Parm4; + typedef typename OriginalFunctor::Parm6 Parm5; + typedef typename OriginalFunctor::Parm7 Parm6; + typedef typename OriginalFunctor::Parm8 Parm7; + typedef typename OriginalFunctor::Parm9 Parm8; + typedef typename OriginalFunctor::Parm10 Parm9; + typedef typename OriginalFunctor::Parm11 Parm10; + typedef typename OriginalFunctor::Parm12 Parm11; + typedef typename OriginalFunctor::Parm13 Parm12; + typedef typename OriginalFunctor::Parm14 Parm13; + typedef typename OriginalFunctor::Parm15 Parm14; + typedef EmptyType Parm15; + + public: + + BinderFirst(const OriginalFunctor& fun, BoundType bound) + : f_(fun), b_(bound) + {} + + LOKI_DEFINE_CLONE_FUNCTORIMPL(BinderFirst) + +#ifdef LOKI_FUNCTORS_ARE_COMPARABLE + + bool operator==(const typename Base::FunctorImplBaseType& rhs) const + { + if(typeid(*this) != typeid(rhs)) + return false; // cannot be equal + // 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_ == ((static_cast (rhs)).f_) && + b_ == ((static_cast (rhs)).b_); + } +#endif + + // operator() implementations for up to 15 arguments + + ResultType operator()() + { return f_(b_); } + + ResultType operator()(Parm1 p1) + { return f_(b_, p1); } + + ResultType operator()(Parm1 p1, Parm2 p2) + { return f_(b_, p1, p2); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3) + { return f_(b_, p1, p2, p3); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4) + { return f_(b_, p1, p2, p3, p4); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5) + { return f_(b_, p1, p2, p3, p4, p5); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6) + { return f_(b_, p1, p2, p3, p4, p5, p6); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7) + { return f_(b_, p1, p2, p3, p4, p5, p6, p7); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8) + { return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9) + { return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8, p9); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10) + { return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11) + { return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11, + Parm12 p12) + { return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11, + Parm12 p12, Parm13 p13) + { return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11, + Parm12 p12, Parm13 p13, Parm14 p14) + { + return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, + p14); + } + + private: + OriginalFunctor f_; + BoundTypeStorage b_; + }; + +//////////////////////////////////////////////////////////////////////////////// +/// Binds the first parameter of a Functor object to a specific value +/// \ingroup FunctorGroup +//////////////////////////////////////////////////////////////////////////////// + + template + typename Private::BinderFirstTraits::BoundFunctorType + BindFirst( + const Fctor& fun, + typename Fctor::Parm1 bound) + { + typedef typename Private::BinderFirstTraits::BoundFunctorType + Outgoing; + + return Outgoing(std::auto_ptr( + new BinderFirst(fun, bound))); + } + +//////////////////////////////////////////////////////////////////////////////// +/// \class Chainer +/// +/// \ingroup FunctorGroup +/// Chains two functor calls one after another +//////////////////////////////////////////////////////////////////////////////// + + template + class Chainer : public Fun2::Impl + { + typedef Fun2 Base; + + public: + typedef typename Base::ResultType ResultType; + typedef typename Base::Parm1 Parm1; + typedef typename Base::Parm2 Parm2; + typedef typename Base::Parm3 Parm3; + typedef typename Base::Parm4 Parm4; + typedef typename Base::Parm5 Parm5; + typedef typename Base::Parm6 Parm6; + typedef typename Base::Parm7 Parm7; + typedef typename Base::Parm8 Parm8; + typedef typename Base::Parm9 Parm9; + typedef typename Base::Parm10 Parm10; + typedef typename Base::Parm11 Parm11; + typedef typename Base::Parm12 Parm12; + typedef typename Base::Parm13 Parm13; + typedef typename Base::Parm14 Parm14; + typedef typename Base::Parm15 Parm15; + + Chainer(const Fun1& fun1, const Fun2& fun2) : f1_(fun1), f2_(fun2) {} + + LOKI_DEFINE_CLONE_FUNCTORIMPL(Chainer) + +#ifdef LOKI_FUNCTORS_ARE_COMPARABLE + + bool operator==(const typename Base::Impl::FunctorImplBaseType& rhs) const + { + if(typeid(*this) != typeid(rhs)) + return false; // cannot be equal + // if this line gives a compiler error, you are using a function object. + // you need to implement bool MyFnObj::operator == (const MyFnObj&) const; + return f1_ == ((static_cast (rhs)).f2_) && + f2_ == ((static_cast (rhs)).f1_); + } +#endif + + // operator() implementations for up to 15 arguments + + ResultType operator()() + { return f1_(), f2_(); } + + ResultType operator()(Parm1 p1) + { return f1_(p1), f2_(p1); } + + ResultType operator()(Parm1 p1, Parm2 p2) + { return f1_(p1, p2), f2_(p1, p2); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3) + { return f1_(p1, p2, p3), f2_(p1, p2, p3); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4) + { return f1_(p1, p2, p3, p4), f2_(p1, p2, p3, p4); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5) + { return f1_(p1, p2, p3, p4, p5), f2_(p1, p2, p3, p4, p5); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6) + { return f1_(p1, p2, p3, p4, p5, p6), f2_(p1, p2, p3, p4, p5, p6); } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7) + { + return f1_(p1, p2, p3, p4, p5, p6, p7), + f2_(p1, p2, p3, p4, p5, p6, p7); + } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8) + { + return f1_(p1, p2, p3, p4, p5, p6, p7, p8), + f2_(p1, p2, p3, p4, p5, p6, p7, p8); + } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9) + { + return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9), + f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9); + } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10) + { + return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), + f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); + } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11) + { + return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), + f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); + } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11, + Parm12 p12) + { + return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12), + f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); + } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11, + Parm12 p12, Parm13 p13) + { + return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), + f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); + } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11, + Parm12 p12, Parm13 p13, Parm14 p14) + { + return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, + p14), + f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, + p14); + } + + ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, + Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11, + Parm12 p12, Parm13 p13, Parm14 p14, Parm15 p15) + { + return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, + p14, p15), + f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, + p14, p15); + } + + private: + Fun1 f1_; + Fun2 f2_; + }; + +//////////////////////////////////////////////////////////////////////////////// +/// Chains two functor calls one after another +/// \ingroup FunctorGroup +//////////////////////////////////////////////////////////////////////////////// + + + template + Fun2 Chain( + const Fun1& fun1, + const Fun2& fun2) + { + return Fun2(std::auto_ptr( + new Chainer(fun1, fun2))); + } + +} // namespace Loki + + +#endif // end file guardian + -- cgit