www.pudn.com > Loki.rar > Functor.h
//////////////////////////////////////////////////////////////////////////////// // 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-Welsey Longman make no representations about the // suitability of this software for any purpose. It is provided "as is" // without express or implied warranty. //////////////////////////////////////////////////////////////////////////////// // Last update: May 19, 2002 #ifndef FUNCTOR_INC_ #define FUNCTOR_INC_ #include "Typelist.h" #include "EmptyType.h" #include "SmallObj.h" #include "TypeTraits.h" #include#include namespace Loki { //////////////////////////////////////////////////////////////////////////////// // class template FunctorImpl (internal) //////////////////////////////////////////////////////////////////////////////// namespace Private { template class ThreadingModel> struct FunctorImplBase : public SmallObject { typedef R ResultType; 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* 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; } }; //////////////////////////////////////////////////////////////////////////////// // macro DEFINE_CLONE_FUNCTORIMPL // Implements the DoClone function for a functor implementation //////////////////////////////////////////////////////////////////////////////// #define DEFINE_CLONE_FUNCTORIMPL(Cls) \ virtual Cls* DoClone() const { return new Cls(*this); } //////////////////////////////////////////////////////////////////////////////// // class template FunctorImplHelper // Base template //////////////////////////////////////////////////////////////////////////////// template struct FunctorImplHelper; //////////////////////////////////////////////////////////////////////////////// // class template FunctorImplHelper // Specialization for 0 (zero) parameters //////////////////////////////////////////////////////////////////////////////// template <> struct FunctorImplHelper<0> { template class ThreadingModel> class In : public Private::FunctorImplBase { public: typedef R ResultType; virtual R operator()() = 0; }; }; //////////////////////////////////////////////////////////////////////////////// // class template FunctorImplHelper // Specialization for 1 parameter //////////////////////////////////////////////////////////////////////////////// template <> struct FunctorImplHelper<1> { template class ThreadingModel> class In : public Private::FunctorImplBase { typedef typename TL::TypeAt ::Result P1; public: typedef R ResultType; typedef typename TypeTraits ::ParameterType Parm1; virtual R operator()(Parm1) = 0; }; }; //////////////////////////////////////////////////////////////////////////////// // class template FunctorImplHelper // Specialization for 2 parameters //////////////////////////////////////////////////////////////////////////////// template <> struct FunctorImplHelper<2> { template class ThreadingModel> class In : public Private::FunctorImplBase { typedef typename TL::TypeAt ::Result P1; typedef typename TL::TypeAt ::Result P2; public: typedef R ResultType; typedef typename TypeTraits ::ParameterType Parm1; typedef typename TypeTraits ::ParameterType Parm2; virtual R operator()(Parm1, Parm2) = 0; }; }; //////////////////////////////////////////////////////////////////////////////// // class template FunctorImplHelper // Specialization for 3 parameters //////////////////////////////////////////////////////////////////////////////// template <> struct FunctorImplHelper<3> { template class ThreadingModel> class In : public Private::FunctorImplBase { typedef typename TL::TypeAt ::Result P1; typedef typename TL::TypeAt ::Result P2; typedef typename TL::TypeAt ::Result P3; 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 FunctorImplHelper // Specialization for 4 parameters //////////////////////////////////////////////////////////////////////////////// template <> struct FunctorImplHelper<4> { template class ThreadingModel> class In : public Private::FunctorImplBase { typedef typename TL::TypeAt ::Result P1; typedef typename TL::TypeAt ::Result P2; typedef typename TL::TypeAt ::Result P3; typedef typename TL::TypeAt ::Result P4; 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 FunctorImplHelper // Specialization for 5 parameters //////////////////////////////////////////////////////////////////////////////// template <> struct FunctorImplHelper<5> { template class ThreadingModel> class In : public Private::FunctorImplBase { typedef typename TL::TypeAt ::Result P1; typedef typename TL::TypeAt ::Result P2; typedef typename TL::TypeAt ::Result P3; typedef typename TL::TypeAt ::Result P4; typedef typename TL::TypeAt ::Result P5; 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 FunctorImplHelper // Specialization for 6 parameters //////////////////////////////////////////////////////////////////////////////// template <> struct FunctorImplHelper<6> { template class ThreadingModel> class In : public Private::FunctorImplBase { typedef typename TL::TypeAt ::Result P1; typedef typename TL::TypeAt ::Result P2; typedef typename TL::TypeAt ::Result P3; typedef typename TL::TypeAt ::Result P4; typedef typename TL::TypeAt ::Result P5; typedef typename TL::TypeAt ::Result P6; 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 FunctorImplHelper // Specialization for 7 parameters //////////////////////////////////////////////////////////////////////////////// template <> struct FunctorImplHelper<7> { template class ThreadingModel> class In : public Private::FunctorImplBase { typedef typename TL::TypeAt ::Result P1; typedef typename TL::TypeAt ::Result P2; typedef typename TL::TypeAt ::Result P3; typedef typename TL::TypeAt ::Result P4; typedef typename TL::TypeAt ::Result P5; typedef typename TL::TypeAt ::Result P6; typedef typename TL::TypeAt ::Result P7; 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 FunctorImplHelper // Specialization for 8 parameters //////////////////////////////////////////////////////////////////////////////// template <> struct FunctorImplHelper<8> { template class ThreadingModel> class In : public Private::FunctorImplBase { typedef typename TL::TypeAt ::Result P1; typedef typename TL::TypeAt ::Result P2; typedef typename TL::TypeAt ::Result P3; typedef typename TL::TypeAt ::Result P4; typedef typename TL::TypeAt ::Result P5; typedef typename TL::TypeAt ::Result P6; typedef typename TL::TypeAt ::Result P7; typedef typename TL::TypeAt ::Result P8; 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 FunctorImplHelper // Specialization for 9 parameters //////////////////////////////////////////////////////////////////////////////// template <> struct FunctorImplHelper<9> { template class ThreadingModel> class In : public Private::FunctorImplBase { typedef typename TL::TypeAt ::Result P1; typedef typename TL::TypeAt ::Result P2; typedef typename TL::TypeAt ::Result P3; typedef typename TL::TypeAt ::Result P4; typedef typename TL::TypeAt ::Result P5; typedef typename TL::TypeAt ::Result P6; typedef typename TL::TypeAt ::Result P7; typedef typename TL::TypeAt ::Result P8; typedef typename TL::TypeAt ::Result P9; 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 FunctorImplHelper // Specialization for 10 parameters //////////////////////////////////////////////////////////////////////////////// template <> struct FunctorImplHelper<10> { template class ThreadingModel> class In : public Private::FunctorImplBase { typedef typename TL::TypeAt ::Result P1; typedef typename TL::TypeAt ::Result P2; typedef typename TL::TypeAt ::Result P3; typedef typename TL::TypeAt ::Result P4; typedef typename TL::TypeAt ::Result P5; typedef typename TL::TypeAt ::Result P6; typedef typename TL::TypeAt ::Result P7; typedef typename TL::TypeAt ::Result P8; typedef typename TL::TypeAt ::Result P9; typedef typename TL::TypeAt ::Result P10; 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 FunctorImplHelper // Specialization for 11 parameters //////////////////////////////////////////////////////////////////////////////// template <> struct FunctorImplHelper<11> { template class ThreadingModel> class In : public Private::FunctorImplBase { typedef typename TL::TypeAt ::Result P1; typedef typename TL::TypeAt ::Result P2; typedef typename TL::TypeAt ::Result P3; typedef typename TL::TypeAt ::Result P4; typedef typename TL::TypeAt ::Result P5; typedef typename TL::TypeAt ::Result P6; typedef typename TL::TypeAt ::Result P7; typedef typename TL::TypeAt ::Result P8; typedef typename TL::TypeAt ::Result P9; typedef typename TL::TypeAt ::Result P10; typedef typename TL::TypeAt ::Result P11; 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 FunctorImplHelper // Specialization for 12 parameters //////////////////////////////////////////////////////////////////////////////// template <> struct FunctorImplHelper<12> { template class ThreadingModel> class In : public Private::FunctorImplBase { typedef typename TL::TypeAt ::Result P1; typedef typename TL::TypeAt ::Result P2; typedef typename TL::TypeAt ::Result P3; typedef typename TL::TypeAt ::Result P4; typedef typename TL::TypeAt ::Result P5; typedef typename TL::TypeAt ::Result P6; typedef typename TL::TypeAt ::Result P7; typedef typename TL::TypeAt ::Result P8; typedef typename TL::TypeAt ::Result P9; typedef typename TL::TypeAt ::Result P10; typedef typename TL::TypeAt ::Result P11; typedef typename TL::TypeAt ::Result P12; 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 FunctorImplHelper // Specialization for 13 parameters //////////////////////////////////////////////////////////////////////////////// template <> struct FunctorImplHelper<13> { template class ThreadingModel> class In : public Private::FunctorImplBase { typedef typename TL::TypeAt ::Result P1; typedef typename TL::TypeAt ::Result P2; typedef typename TL::TypeAt ::Result P3; typedef typename TL::TypeAt ::Result P4; typedef typename TL::TypeAt ::Result P5; typedef typename TL::TypeAt ::Result P6; typedef typename TL::TypeAt ::Result P7; typedef typename TL::TypeAt ::Result P8; typedef typename TL::TypeAt ::Result P9; typedef typename TL::TypeAt ::Result P10; typedef typename TL::TypeAt ::Result P11; typedef typename TL::TypeAt ::Result P12; typedef typename TL::TypeAt ::Result P13; 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 FunctorImplHelper // Specialization for 14 parameters //////////////////////////////////////////////////////////////////////////////// template <> struct FunctorImplHelper<14> { template class ThreadingModel> class In : public Private::FunctorImplBase { typedef typename TL::TypeAt ::Result P1; typedef typename TL::TypeAt ::Result P2; typedef typename TL::TypeAt ::Result P3; typedef typename TL::TypeAt ::Result P4; typedef typename TL::TypeAt ::Result P5; typedef typename TL::TypeAt ::Result P6; typedef typename TL::TypeAt ::Result P7; typedef typename TL::TypeAt ::Result P8; typedef typename TL::TypeAt ::Result P9; typedef typename TL::TypeAt ::Result P10; typedef typename TL::TypeAt ::Result P11; typedef typename TL::TypeAt ::Result P12; typedef typename TL::TypeAt ::Result P13; typedef typename TL::TypeAt ::Result P14; 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 FunctorImplHelper // Specialization for 15 parameters //////////////////////////////////////////////////////////////////////////////// template <> struct FunctorImplHelper<15> { template class ThreadingModel> class In : public Private::FunctorImplBase { typedef typename TL::TypeAt ::Result P1; typedef typename TL::TypeAt ::Result P2; typedef typename TL::TypeAt ::Result P3; typedef typename TL::TypeAt ::Result P4; typedef typename TL::TypeAt ::Result P5; typedef typename TL::TypeAt