//////////////////////////////////////////////////////////////////////////////// // 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$ #include #include #include #include #include #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