Functor.h

00001 
00002 // The Loki Library
00003 // Copyright (c) 2001 by Andrei Alexandrescu
00004 // This code accompanies the book:
00005 // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 
00006 //     Patterns Applied". Copyright (c) 2001. Addison-Wesley.
00007 // Permission to use, copy, modify, distribute and sell this software for any 
00008 //     purpose is hereby granted without fee, provided that the above copyright 
00009 //     notice appear in all copies and that both that copyright notice and this 
00010 //     permission notice appear in supporting documentation.
00011 // The author or Addison-Wesley Longman make no representations about the 
00012 //     suitability of this software for any purpose. It is provided "as is" 
00013 //     without express or implied warranty.
00015 #ifndef LOKI_FUNCTOR_INC_
00016 #define LOKI_FUNCTOR_INC_
00017 
00018 // $Id: Functor.h 750 2006-10-17 19:50:02Z syntheticpp $
00019 
00020 
00021 #include "Typelist.h"
00022 #include "Sequence.h"
00023 #include "EmptyType.h"
00024 #include "SmallObj.h"
00025 #include "TypeTraits.h"
00026 #include <typeinfo>
00027 #include <memory>
00028 
00030 
00031 #ifndef LOKI_FUNCTOR_IS_NOT_A_SMALLOBJECT
00032 //#define LOKI_FUNCTOR_IS_NOT_A_SMALLOBJECT
00033 #endif
00034 
00035 #ifndef LOKI_FUNCTORS_ARE_COMPARABLE
00036 //#define LOKI_FUNCTORS_ARE_COMPARABLE
00037 #endif
00038 
00039 
00042 namespace Loki
00043 {
00045 // class template FunctorImpl (internal)
00047 
00048     namespace Private
00049     {
00050         template <typename R, template <class, class> class ThreadingModel>
00051         struct FunctorImplBase 
00052 #ifdef LOKI_FUNCTOR_IS_NOT_A_SMALLOBJECT
00053         {
00054 #else
00055             : public SmallValueObject<ThreadingModel>
00056         {
00057             inline FunctorImplBase() :
00058                 SmallValueObject<ThreadingModel>() {}
00059             inline FunctorImplBase(const FunctorImplBase&) :
00060                 SmallValueObject<ThreadingModel>() {}
00061 #endif
00062 
00063             typedef R ResultType;
00064             typedef FunctorImplBase<R, ThreadingModel> FunctorImplBaseType;
00065 
00066             typedef EmptyType Parm1;
00067             typedef EmptyType Parm2;
00068             typedef EmptyType Parm3;
00069             typedef EmptyType Parm4;
00070             typedef EmptyType Parm5;
00071             typedef EmptyType Parm6;
00072             typedef EmptyType Parm7;
00073             typedef EmptyType Parm8;
00074             typedef EmptyType Parm9;
00075             typedef EmptyType Parm10;
00076             typedef EmptyType Parm11;
00077             typedef EmptyType Parm12;
00078             typedef EmptyType Parm13;
00079             typedef EmptyType Parm14;
00080             typedef EmptyType Parm15;
00081 
00082 
00083             virtual ~FunctorImplBase()
00084             {}
00085 
00086             virtual FunctorImplBase* DoClone() const = 0;
00087 
00088             template <class U>
00089             static U* Clone(U* pObj)
00090             {
00091                 if (!pObj) return 0;
00092                 U* pClone = static_cast<U*>(pObj->DoClone());
00093                 assert(typeid(*pClone) == typeid(*pObj));
00094                 return pClone;
00095             }
00096 
00097 
00098 #ifdef LOKI_FUNCTORS_ARE_COMPARABLE
00099 
00100             virtual bool operator==(const FunctorImplBase&) const = 0;
00101            
00102 #endif            
00103          
00104         };
00105     }
00106     
00108 // macro LOKI_DEFINE_CLONE_FUNCTORIMPL
00109 // Implements the DoClone function for a functor implementation
00111 
00112 #define LOKI_DEFINE_CLONE_FUNCTORIMPL(Cls) \
00113     virtual Cls* DoClone() const { return new Cls(*this); }
00114 
00116 // class template FunctorImpl
00117 // The base class for a hierarchy of functors. The FunctorImpl class is not used
00118 //     directly; rather, the Functor class manages and forwards to a pointer to
00119 //     FunctorImpl
00120 // You may want to derive your own functors from FunctorImpl.
00121 // Specializations of FunctorImpl for up to 15 parameters follow
00123 
00124     template <typename R, class TList, 
00125         template <class, class> class ThreadingModel = LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL>
00126     class FunctorImpl;
00127 
00129 // class template FunctorImpl
00130 // Specialization for 0 (zero) parameters
00132 
00133     template <typename R, template <class, class> class ThreadingModel>
00134     class FunctorImpl<R, NullType, ThreadingModel>
00135         : public Private::FunctorImplBase<R, ThreadingModel>
00136     {
00137     public:
00138         typedef R ResultType;
00139         virtual R operator()() = 0;
00140     };
00141 
00143 // class template FunctorImpl
00144 // Specialization for 1 parameter
00146 
00147     template <typename R, typename P1, template <class, class> class ThreadingModel>
00148         class FunctorImpl<R, Seq<P1>, ThreadingModel>
00149         : public Private::FunctorImplBase<R, ThreadingModel>
00150     {
00151     public:
00152         typedef R ResultType;
00153         typedef typename TypeTraits<P1>::ParameterType Parm1;
00154         virtual R operator()(Parm1) = 0;
00155     };
00156 
00158 // class template FunctorImpl
00159 // Specialization for 2 parameters
00161 
00162     template <typename R, typename P1, typename P2, 
00163         template <class, class> class ThreadingModel>
00164     class FunctorImpl<R, Seq<P1, P2>, ThreadingModel>
00165         : public Private::FunctorImplBase<R, ThreadingModel>
00166     {
00167     public:
00168         typedef R ResultType;
00169         typedef typename TypeTraits<P1>::ParameterType Parm1;
00170         typedef typename TypeTraits<P2>::ParameterType Parm2;
00171         virtual R operator()(Parm1, Parm2) = 0;
00172     };
00173 
00175 // class template FunctorImpl
00176 // Specialization for 3 parameters
00178 
00179     template <typename R, typename P1, typename P2, typename P3,
00180         template <class, class> class ThreadingModel>
00181     class FunctorImpl<R, Seq<P1, P2, P3>, ThreadingModel>
00182         : public Private::FunctorImplBase<R, ThreadingModel>
00183     {
00184     public:
00185         typedef R ResultType;
00186         typedef typename TypeTraits<P1>::ParameterType Parm1;
00187         typedef typename TypeTraits<P2>::ParameterType Parm2;
00188         typedef typename TypeTraits<P3>::ParameterType Parm3;
00189         virtual R operator()(Parm1, Parm2, Parm3) = 0;
00190     };
00191 
00193 // class template FunctorImpl
00194 // Specialization for 4 parameters
00196 
00197     template <typename R, typename P1, typename P2, typename P3, typename P4,
00198         template <class, class> class ThreadingModel>
00199     class FunctorImpl<R, Seq<P1, P2, P3, P4>, ThreadingModel>
00200         : public Private::FunctorImplBase<R, ThreadingModel>
00201     {
00202     public:
00203         typedef R ResultType;
00204         typedef typename TypeTraits<P1>::ParameterType Parm1;
00205         typedef typename TypeTraits<P2>::ParameterType Parm2;
00206         typedef typename TypeTraits<P3>::ParameterType Parm3;
00207         typedef typename TypeTraits<P4>::ParameterType Parm4;
00208         virtual R operator()(Parm1, Parm2, Parm3, Parm4) = 0;
00209     };
00210 
00212 // class template FunctorImpl
00213 // Specialization for 5 parameters
00215 
00216     template <typename R, typename P1, typename P2, typename P3, typename P4,
00217         typename P5,
00218         template <class, class> class ThreadingModel>
00219     class FunctorImpl<R, Seq<P1, P2, P3, P4, P5>, ThreadingModel>
00220         : public Private::FunctorImplBase<R, ThreadingModel>
00221     {
00222     public:
00223         typedef R ResultType;
00224         typedef typename TypeTraits<P1>::ParameterType Parm1;
00225         typedef typename TypeTraits<P2>::ParameterType Parm2;
00226         typedef typename TypeTraits<P3>::ParameterType Parm3;
00227         typedef typename TypeTraits<P4>::ParameterType Parm4;
00228         typedef typename TypeTraits<P5>::ParameterType Parm5;
00229         virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5) = 0;
00230     };
00231 
00233 // class template FunctorImpl
00234 // Specialization for 6 parameters
00236 
00237     template <typename R, typename P1, typename P2, typename P3, typename P4,
00238         typename P5, typename P6,
00239         template <class, class> class ThreadingModel>
00240     class FunctorImpl<R, Seq<P1, P2, P3, P4, P5, P6>, ThreadingModel>
00241         : public Private::FunctorImplBase<R, ThreadingModel>
00242     {
00243     public:
00244         typedef R ResultType;
00245         typedef typename TypeTraits<P1>::ParameterType Parm1;
00246         typedef typename TypeTraits<P2>::ParameterType Parm2;
00247         typedef typename TypeTraits<P3>::ParameterType Parm3;
00248         typedef typename TypeTraits<P4>::ParameterType Parm4;
00249         typedef typename TypeTraits<P5>::ParameterType Parm5;
00250         typedef typename TypeTraits<P6>::ParameterType Parm6;
00251         virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6) = 0;
00252     };
00253 
00255 // class template FunctorImpl
00256 // Specialization for 7 parameters
00258 
00259     template <typename R, typename P1, typename P2, typename P3, typename P4,
00260         typename P5, typename P6, typename P7,
00261         template <class, class> class ThreadingModel>
00262     class FunctorImpl<R, Seq<P1, P2, P3, P4, P5, P6, P7>, ThreadingModel>
00263         : public Private::FunctorImplBase<R, ThreadingModel>
00264     {
00265     public:
00266         typedef R ResultType;
00267         typedef typename TypeTraits<P1>::ParameterType Parm1;
00268         typedef typename TypeTraits<P2>::ParameterType Parm2;
00269         typedef typename TypeTraits<P3>::ParameterType Parm3;
00270         typedef typename TypeTraits<P4>::ParameterType Parm4;
00271         typedef typename TypeTraits<P5>::ParameterType Parm5;
00272         typedef typename TypeTraits<P6>::ParameterType Parm6;
00273         typedef typename TypeTraits<P7>::ParameterType Parm7;
00274         virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, 
00275             Parm7) = 0;
00276     };
00277 
00279 // class template FunctorImpl
00280 // Specialization for 8 parameters
00282 
00283     template <typename R, typename P1, typename P2, typename P3, typename P4,
00284         typename P5, typename P6, typename P7, typename P8,
00285         template <class, class> class ThreadingModel>
00286     class FunctorImpl<R, Seq<P1, P2, P3, P4, P5, P6, P7, P8>,
00287             ThreadingModel>
00288         : public Private::FunctorImplBase<R, ThreadingModel>
00289     {
00290     public:
00291         typedef R ResultType;
00292         typedef typename TypeTraits<P1>::ParameterType Parm1;
00293         typedef typename TypeTraits<P2>::ParameterType Parm2;
00294         typedef typename TypeTraits<P3>::ParameterType Parm3;
00295         typedef typename TypeTraits<P4>::ParameterType Parm4;
00296         typedef typename TypeTraits<P5>::ParameterType Parm5;
00297         typedef typename TypeTraits<P6>::ParameterType Parm6;
00298         typedef typename TypeTraits<P7>::ParameterType Parm7;
00299         typedef typename TypeTraits<P8>::ParameterType Parm8;
00300         virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, 
00301             Parm7, Parm8) = 0;
00302     };
00303 
00305 // class template FunctorImpl
00306 // Specialization for 9 parameters
00308 
00309     template <typename R, typename P1, typename P2, typename P3, typename P4,
00310         typename P5, typename P6, typename P7, typename P8, typename P9,
00311         template <class, class> class ThreadingModel>
00312     class FunctorImpl<R, Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9>,
00313             ThreadingModel>
00314         : public Private::FunctorImplBase<R, ThreadingModel>
00315     {
00316     public:
00317         typedef R ResultType;
00318         typedef typename TypeTraits<P1>::ParameterType Parm1;
00319         typedef typename TypeTraits<P2>::ParameterType Parm2;
00320         typedef typename TypeTraits<P3>::ParameterType Parm3;
00321         typedef typename TypeTraits<P4>::ParameterType Parm4;
00322         typedef typename TypeTraits<P5>::ParameterType Parm5;
00323         typedef typename TypeTraits<P6>::ParameterType Parm6;
00324         typedef typename TypeTraits<P7>::ParameterType Parm7;
00325         typedef typename TypeTraits<P8>::ParameterType Parm8;
00326         typedef typename TypeTraits<P9>::ParameterType Parm9;
00327         virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, 
00328             Parm7, Parm8, Parm9) = 0;
00329     };
00330 
00332 // class template FunctorImpl
00333 // Specialization for 10 parameters
00335 
00336     template <typename R, typename P1, typename P2, typename P3, typename P4,
00337         typename P5, typename P6, typename P7, typename P8, typename P9,
00338         typename P10,
00339         template <class, class> class ThreadingModel>
00340     class FunctorImpl<R, Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10>,
00341             ThreadingModel>
00342         : public Private::FunctorImplBase<R, ThreadingModel>
00343     {
00344     public:
00345         typedef R ResultType;
00346         typedef typename TypeTraits<P1>::ParameterType Parm1;
00347         typedef typename TypeTraits<P2>::ParameterType Parm2;
00348         typedef typename TypeTraits<P3>::ParameterType Parm3;
00349         typedef typename TypeTraits<P4>::ParameterType Parm4;
00350         typedef typename TypeTraits<P5>::ParameterType Parm5;
00351         typedef typename TypeTraits<P6>::ParameterType Parm6;
00352         typedef typename TypeTraits<P7>::ParameterType Parm7;
00353         typedef typename TypeTraits<P8>::ParameterType Parm8;
00354         typedef typename TypeTraits<P9>::ParameterType Parm9;
00355         typedef typename TypeTraits<P10>::ParameterType Parm10;
00356         virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, 
00357             Parm7, Parm8, Parm9, Parm10) = 0;
00358     };
00359 
00361 // class template FunctorImpl
00362 // Specialization for 11 parameters
00364 
00365     template <typename R, typename P1, typename P2, typename P3, typename P4,
00366         typename P5, typename P6, typename P7, typename P8, typename P9,
00367         typename P10, typename P11,
00368         template <class, class> class ThreadingModel>
00369     class FunctorImpl<R,
00370             Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11>,
00371             ThreadingModel>
00372         : public Private::FunctorImplBase<R, ThreadingModel>
00373     {
00374     public:
00375         typedef R ResultType;
00376         typedef typename TypeTraits<P1>::ParameterType Parm1;
00377         typedef typename TypeTraits<P2>::ParameterType Parm2;
00378         typedef typename TypeTraits<P3>::ParameterType Parm3;
00379         typedef typename TypeTraits<P4>::ParameterType Parm4;
00380         typedef typename TypeTraits<P5>::ParameterType Parm5;
00381         typedef typename TypeTraits<P6>::ParameterType Parm6;
00382         typedef typename TypeTraits<P7>::ParameterType Parm7;
00383         typedef typename TypeTraits<P8>::ParameterType Parm8;
00384         typedef typename TypeTraits<P9>::ParameterType Parm9;
00385         typedef typename TypeTraits<P10>::ParameterType Parm10;
00386         typedef typename TypeTraits<P11>::ParameterType Parm11;
00387         virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, 
00388             Parm7, Parm8, Parm9, Parm10, Parm11) = 0;
00389     };
00390 
00392 // class template FunctorImpl
00393 // Specialization for 12 parameters
00395 
00396     template <typename R, typename P1, typename P2, typename P3, typename P4,
00397         typename P5, typename P6, typename P7, typename P8, typename P9,
00398         typename P10, typename P11, typename P12,
00399         template <class, class> class ThreadingModel>
00400     class FunctorImpl<R,
00401             Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12>,
00402             ThreadingModel>
00403         : public Private::FunctorImplBase<R, ThreadingModel>
00404     {
00405     public:
00406         typedef R ResultType;
00407         typedef typename TypeTraits<P1>::ParameterType Parm1;
00408         typedef typename TypeTraits<P2>::ParameterType Parm2;
00409         typedef typename TypeTraits<P3>::ParameterType Parm3;
00410         typedef typename TypeTraits<P4>::ParameterType Parm4;
00411         typedef typename TypeTraits<P5>::ParameterType Parm5;
00412         typedef typename TypeTraits<P6>::ParameterType Parm6;
00413         typedef typename TypeTraits<P7>::ParameterType Parm7;
00414         typedef typename TypeTraits<P8>::ParameterType Parm8;
00415         typedef typename TypeTraits<P9>::ParameterType Parm9;
00416         typedef typename TypeTraits<P10>::ParameterType Parm10;
00417         typedef typename TypeTraits<P11>::ParameterType Parm11;
00418         typedef typename TypeTraits<P12>::ParameterType Parm12;
00419         virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, 
00420             Parm7, Parm8, Parm9, Parm10, Parm11, Parm12) = 0;
00421     };
00422 
00424 // class template FunctorImpl
00425 // Specialization for 13 parameters
00427 
00428     template <typename R, typename P1, typename P2, typename P3, typename P4,
00429         typename P5, typename P6, typename P7, typename P8, typename P9,
00430         typename P10, typename P11, typename P12, typename P13,
00431         template <class, class> class ThreadingModel>
00432     class FunctorImpl<R,
00433             Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13>,
00434             ThreadingModel>
00435         : public Private::FunctorImplBase<R, ThreadingModel>
00436     {
00437     public:
00438         typedef R ResultType;
00439         typedef typename TypeTraits<P1>::ParameterType Parm1;
00440         typedef typename TypeTraits<P2>::ParameterType Parm2;
00441         typedef typename TypeTraits<P3>::ParameterType Parm3;
00442         typedef typename TypeTraits<P4>::ParameterType Parm4;
00443         typedef typename TypeTraits<P5>::ParameterType Parm5;
00444         typedef typename TypeTraits<P6>::ParameterType Parm6;
00445         typedef typename TypeTraits<P7>::ParameterType Parm7;
00446         typedef typename TypeTraits<P8>::ParameterType Parm8;
00447         typedef typename TypeTraits<P9>::ParameterType Parm9;
00448         typedef typename TypeTraits<P10>::ParameterType Parm10;
00449         typedef typename TypeTraits<P11>::ParameterType Parm11;
00450         typedef typename TypeTraits<P12>::ParameterType Parm12;
00451         typedef typename TypeTraits<P13>::ParameterType Parm13;
00452         virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, 
00453             Parm7, Parm8, Parm9, Parm10, Parm11, Parm12, Parm13) = 0;
00454     };
00455 
00457 // class template FunctorImpl
00458 // Specialization for 14 parameters
00460 
00461     template <typename R, typename P1, typename P2, typename P3, typename P4,
00462         typename P5, typename P6, typename P7, typename P8, typename P9,
00463         typename P10, typename P11, typename P12, typename P13, typename P14,
00464         template <class, class> class ThreadingModel>
00465     class FunctorImpl<R,
00466             Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13,
00467                 P14>,
00468             ThreadingModel>
00469         : public Private::FunctorImplBase<R, ThreadingModel>
00470     {
00471     public:
00472         typedef R ResultType;
00473         typedef typename TypeTraits<P1>::ParameterType Parm1;
00474         typedef typename TypeTraits<P2>::ParameterType Parm2;
00475         typedef typename TypeTraits<P3>::ParameterType Parm3;
00476         typedef typename TypeTraits<P4>::ParameterType Parm4;
00477         typedef typename TypeTraits<P5>::ParameterType Parm5;
00478         typedef typename TypeTraits<P6>::ParameterType Parm6;
00479         typedef typename TypeTraits<P7>::ParameterType Parm7;
00480         typedef typename TypeTraits<P8>::ParameterType Parm8;
00481         typedef typename TypeTraits<P9>::ParameterType Parm9;
00482         typedef typename TypeTraits<P10>::ParameterType Parm10;
00483         typedef typename TypeTraits<P11>::ParameterType Parm11;
00484         typedef typename TypeTraits<P12>::ParameterType Parm12;
00485         typedef typename TypeTraits<P13>::ParameterType Parm13;
00486         typedef typename TypeTraits<P14>::ParameterType Parm14;
00487         virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, 
00488             Parm7, Parm8, Parm9, Parm10, Parm11, Parm12, Parm13, Parm14) = 0;
00489     };
00490 
00492 // class template FunctorImpl
00493 // Specialization for 15 parameters
00495 
00496     template <typename R, typename P1, typename P2, typename P3, typename P4,
00497         typename P5, typename P6, typename P7, typename P8, typename P9,
00498         typename P10, typename P11, typename P12, typename P13, typename P14,
00499         typename P15, template <class, class> class ThreadingModel>
00500     class FunctorImpl<R,
00501             Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13,
00502                 P14, P15>,
00503             ThreadingModel>
00504         : public Private::FunctorImplBase<R, ThreadingModel>
00505     {
00506     public:
00507         typedef R ResultType;
00508         typedef typename TypeTraits<P1>::ParameterType Parm1;
00509         typedef typename TypeTraits<P2>::ParameterType Parm2;
00510         typedef typename TypeTraits<P3>::ParameterType Parm3;
00511         typedef typename TypeTraits<P4>::ParameterType Parm4;
00512         typedef typename TypeTraits<P5>::ParameterType Parm5;
00513         typedef typename TypeTraits<P6>::ParameterType Parm6;
00514         typedef typename TypeTraits<P7>::ParameterType Parm7;
00515         typedef typename TypeTraits<P8>::ParameterType Parm8;
00516         typedef typename TypeTraits<P9>::ParameterType Parm9;
00517         typedef typename TypeTraits<P10>::ParameterType Parm10;
00518         typedef typename TypeTraits<P11>::ParameterType Parm11;
00519         typedef typename TypeTraits<P12>::ParameterType Parm12;
00520         typedef typename TypeTraits<P13>::ParameterType Parm13;
00521         typedef typename TypeTraits<P14>::ParameterType Parm14;
00522         typedef typename TypeTraits<P15>::ParameterType Parm15;
00523         virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, 
00524             Parm7, Parm8, Parm9, Parm10, Parm11, Parm12, Parm13, Parm14,
00525             Parm15) = 0;
00526     };
00527 
00528 #ifndef LOKI_DISABLE_TYPELIST_MACROS
00529 
00531 // class template FunctorImpl
00532 // Specialization for 1 parameter
00534 
00535     template <typename R, typename P1, template <class, class> class ThreadingModel>
00536     class FunctorImpl<R, LOKI_TYPELIST_1(P1), ThreadingModel>
00537         : public Private::FunctorImplBase<R, ThreadingModel>
00538     {
00539     public:
00540         typedef R ResultType;
00541         typedef typename TypeTraits<P1>::ParameterType Parm1;
00542         virtual R operator()(Parm1) = 0;
00543     };
00544 
00546 // class template FunctorImpl
00547 // Specialization for 2 parameters
00549 
00550     template <typename R, typename P1, typename P2, 
00551         template <class, class> class ThreadingModel>
00552     class FunctorImpl<R, LOKI_TYPELIST_2(P1, P2), ThreadingModel>
00553         : public Private::FunctorImplBase<R, ThreadingModel>
00554     {
00555     public:
00556         typedef R ResultType;
00557         typedef typename TypeTraits<P1>::ParameterType Parm1;
00558         typedef typename TypeTraits<P2>::ParameterType Parm2;
00559         virtual R operator()(Parm1, Parm2) = 0;
00560     };
00561 
00563 // class template FunctorImpl
00564 // Specialization for 3 parameters
00566 
00567     template <typename R, typename P1, typename P2, typename P3,
00568         template <class, class> class ThreadingModel>
00569     class FunctorImpl<R, LOKI_TYPELIST_3(P1, P2, P3), ThreadingModel>
00570         : public Private::FunctorImplBase<R, ThreadingModel>
00571     {
00572     public:
00573         typedef R ResultType;
00574         typedef typename TypeTraits<P1>::ParameterType Parm1;
00575         typedef typename TypeTraits<P2>::ParameterType Parm2;
00576         typedef typename TypeTraits<P3>::ParameterType Parm3;
00577         virtual R operator()(Parm1, Parm2, Parm3) = 0;
00578     };
00579 
00581 // class template FunctorImpl
00582 // Specialization for 4 parameters
00584 
00585     template <typename R, typename P1, typename P2, typename P3, typename P4,
00586         template <class, class> class ThreadingModel>
00587     class FunctorImpl<R, LOKI_TYPELIST_4(P1, P2, P3, P4), ThreadingModel>
00588         : public Private::FunctorImplBase<R, ThreadingModel>
00589     {
00590     public:
00591         typedef R ResultType;
00592         typedef typename TypeTraits<P1>::ParameterType Parm1;
00593         typedef typename TypeTraits<P2>::ParameterType Parm2;
00594         typedef typename TypeTraits<P3>::ParameterType Parm3;
00595         typedef typename TypeTraits<P4>::ParameterType Parm4;
00596         virtual R operator()(Parm1, Parm2, Parm3, Parm4) = 0;
00597     };
00598 
00600 // class template FunctorImpl
00601 // Specialization for 5 parameters
00603 
00604     template <typename R, typename P1, typename P2, typename P3, typename P4,
00605         typename P5,
00606         template <class, class> class ThreadingModel>
00607     class FunctorImpl<R, LOKI_TYPELIST_5(P1, P2, P3, P4, P5), ThreadingModel>
00608         : public Private::FunctorImplBase<R, ThreadingModel>
00609     {
00610     public:
00611         typedef R ResultType;
00612         typedef typename TypeTraits<P1>::ParameterType Parm1;
00613         typedef typename TypeTraits<P2>::ParameterType Parm2;
00614         typedef typename TypeTraits<P3>::ParameterType Parm3;
00615         typedef typename TypeTraits<P4>::ParameterType Parm4;
00616         typedef typename TypeTraits<P5>::ParameterType Parm5;
00617         virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5) = 0;
00618     };
00619 
00621 // class template FunctorImpl
00622 // Specialization for 6 parameters
00624 
00625     template <typename R, typename P1, typename P2, typename P3, typename P4,
00626         typename P5, typename P6,
00627         template <class, class> class ThreadingModel>
00628     class FunctorImpl<R, LOKI_TYPELIST_6(P1, P2, P3, P4, P5, P6), ThreadingModel>
00629         : public Private::FunctorImplBase<R, ThreadingModel>
00630     {
00631     public:
00632         typedef R ResultType;
00633         typedef typename TypeTraits<P1>::ParameterType Parm1;
00634         typedef typename TypeTraits<P2>::ParameterType Parm2;
00635         typedef typename TypeTraits<P3>::ParameterType Parm3;
00636         typedef typename TypeTraits<P4>::ParameterType Parm4;
00637         typedef typename TypeTraits<P5>::ParameterType Parm5;
00638         typedef typename TypeTraits<P6>::ParameterType Parm6;
00639         virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6) = 0;
00640     };
00641 
00643 // class template FunctorImpl
00644 // Specialization for 7 parameters
00646 
00647     template <typename R, typename P1, typename P2, typename P3, typename P4,
00648         typename P5, typename P6, typename P7,
00649         template <class, class> class ThreadingModel>
00650     class FunctorImpl<R, LOKI_TYPELIST_7(P1, P2, P3, P4, P5, P6, P7), ThreadingModel>
00651         : public Private::FunctorImplBase<R, ThreadingModel>
00652     {
00653     public:
00654         typedef R ResultType;
00655         typedef typename TypeTraits<P1>::ParameterType Parm1;
00656         typedef typename TypeTraits<P2>::ParameterType Parm2;
00657         typedef typename TypeTraits<P3>::ParameterType Parm3;
00658         typedef typename TypeTraits<P4>::ParameterType Parm4;
00659         typedef typename TypeTraits<P5>::ParameterType Parm5;
00660         typedef typename TypeTraits<P6>::ParameterType Parm6;
00661         typedef typename TypeTraits<P7>::ParameterType Parm7;
00662         virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, 
00663             Parm7) = 0;
00664     };
00665 
00667 // class template FunctorImpl
00668 // Specialization for 8 parameters
00670 
00671     template <typename R, typename P1, typename P2, typename P3, typename P4,
00672         typename P5, typename P6, typename P7, typename P8,
00673         template <class, class> class ThreadingModel>
00674     class FunctorImpl<R, LOKI_TYPELIST_8(P1, P2, P3, P4, P5, P6, P7, P8),
00675             ThreadingModel>
00676         : public Private::FunctorImplBase<R, ThreadingModel>
00677     {
00678     public:
00679         typedef R ResultType;
00680         typedef typename TypeTraits<P1>::ParameterType Parm1;
00681         typedef typename TypeTraits<P2>::ParameterType Parm2;
00682         typedef typename TypeTraits<P3>::ParameterType Parm3;
00683         typedef typename TypeTraits<P4>::ParameterType Parm4;
00684         typedef typename TypeTraits<P5>::ParameterType Parm5;
00685         typedef typename TypeTraits<P6>::ParameterType Parm6;
00686         typedef typename TypeTraits<P7>::ParameterType Parm7;
00687         typedef typename TypeTraits<P8>::ParameterType Parm8;
00688         virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, 
00689             Parm7, Parm8) = 0;
00690     };
00691 
00693 // class template FunctorImpl
00694 // Specialization for 9 parameters
00696 
00697     template <typename R, typename P1, typename P2, typename P3, typename P4,
00698         typename P5, typename P6, typename P7, typename P8, typename P9,
00699         template <class, class> class ThreadingModel>
00700     class FunctorImpl<R, LOKI_TYPELIST_9(P1, P2, P3, P4, P5, P6, P7, P8, P9),
00701             ThreadingModel>
00702         : public Private::FunctorImplBase<R, ThreadingModel>
00703     {
00704     public:
00705         typedef R ResultType;
00706         typedef typename TypeTraits<P1>::ParameterType Parm1;
00707         typedef typename TypeTraits<P2>::ParameterType Parm2;
00708         typedef typename TypeTraits<P3>::ParameterType Parm3;
00709         typedef typename TypeTraits<P4>::ParameterType Parm4;
00710         typedef typename TypeTraits<P5>::ParameterType Parm5;
00711         typedef typename TypeTraits<P6>::ParameterType Parm6;
00712         typedef typename TypeTraits<P7>::ParameterType Parm7;
00713         typedef typename TypeTraits<P8>::ParameterType Parm8;
00714         typedef typename TypeTraits<P9>::ParameterType Parm9;
00715         virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, 
00716             Parm7, Parm8, Parm9) = 0;
00717     };
00718 
00720 // class template FunctorImpl
00721 // Specialization for 10 parameters
00723 
00724     template <typename R, typename P1, typename P2, typename P3, typename P4,
00725         typename P5, typename P6, typename P7, typename P8, typename P9,
00726         typename P10,
00727         template <class, class> class ThreadingModel>
00728     class FunctorImpl<R, LOKI_TYPELIST_10(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10),
00729             ThreadingModel>
00730         : public Private::FunctorImplBase<R, ThreadingModel>
00731     {
00732     public:
00733         typedef R ResultType;
00734         typedef typename TypeTraits<P1>::ParameterType Parm1;
00735         typedef typename TypeTraits<P2>::ParameterType Parm2;
00736         typedef typename TypeTraits<P3>::ParameterType Parm3;
00737         typedef typename TypeTraits<P4>::ParameterType Parm4;
00738         typedef typename TypeTraits<P5>::ParameterType Parm5;
00739         typedef typename TypeTraits<P6>::ParameterType Parm6;
00740         typedef typename TypeTraits<P7>::ParameterType Parm7;
00741         typedef typename TypeTraits<P8>::ParameterType Parm8;
00742         typedef typename TypeTraits<P9>::ParameterType Parm9;
00743         typedef typename TypeTraits<P10>::ParameterType Parm10;
00744         virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, 
00745             Parm7, Parm8, Parm9, Parm10) = 0;
00746     };
00747 
00749 // class template FunctorImpl
00750 // Specialization for 11 parameters
00752 
00753     template <typename R, typename P1, typename P2, typename P3, typename P4,
00754         typename P5, typename P6, typename P7, typename P8, typename P9,
00755         typename P10, typename P11,
00756         template <class, class> class ThreadingModel>
00757     class FunctorImpl<R,
00758             LOKI_TYPELIST_11(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11),
00759             ThreadingModel>
00760         : public Private::FunctorImplBase<R, ThreadingModel>
00761     {
00762     public:
00763         typedef R ResultType;
00764         typedef typename TypeTraits<P1>::ParameterType Parm1;
00765         typedef typename TypeTraits<P2>::ParameterType Parm2;
00766         typedef typename TypeTraits<P3>::ParameterType Parm3;
00767         typedef typename TypeTraits<P4>::ParameterType Parm4;
00768         typedef typename TypeTraits<P5>::ParameterType Parm5;
00769         typedef typename TypeTraits<P6>::ParameterType Parm6;
00770         typedef typename TypeTraits<P7>::ParameterType Parm7;
00771         typedef typename TypeTraits<P8>::ParameterType Parm8;
00772         typedef typename TypeTraits<P9>::ParameterType Parm9;
00773         typedef typename TypeTraits<P10>::ParameterType Parm10;
00774         typedef typename TypeTraits<P11>::ParameterType Parm11;
00775         virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, 
00776             Parm7, Parm8, Parm9, Parm10, Parm11) = 0;
00777     };
00778 
00780 // class template FunctorImpl
00781 // Specialization for 12 parameters
00783 
00784     template <typename R, typename P1, typename P2, typename P3, typename P4,
00785         typename P5, typename P6, typename P7, typename P8, typename P9,
00786         typename P10, typename P11, typename P12,
00787         template <class, class> class ThreadingModel>
00788     class FunctorImpl<R,
00789             LOKI_TYPELIST_12(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12),
00790             ThreadingModel>
00791         : public Private::FunctorImplBase<R, ThreadingModel>
00792     {
00793     public:
00794         typedef R ResultType;
00795         typedef typename TypeTraits<P1>::ParameterType Parm1;
00796         typedef typename TypeTraits<P2>::ParameterType Parm2;
00797         typedef typename TypeTraits<P3>::ParameterType Parm3;
00798         typedef typename TypeTraits<P4>::ParameterType Parm4;
00799         typedef typename TypeTraits<P5>::ParameterType Parm5;
00800         typedef typename TypeTraits<P6>::ParameterType Parm6;
00801         typedef typename TypeTraits<P7>::ParameterType Parm7;
00802         typedef typename TypeTraits<P8>::ParameterType Parm8;
00803         typedef typename TypeTraits<P9>::ParameterType Parm9;
00804         typedef typename TypeTraits<P10>::ParameterType Parm10;
00805         typedef typename TypeTraits<P11>::ParameterType Parm11;
00806         typedef typename TypeTraits<P12>::ParameterType Parm12;
00807         virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, 
00808             Parm7, Parm8, Parm9, Parm10, Parm11, Parm12) = 0;
00809     };
00810 
00812 // class template FunctorImpl
00813 // Specialization for 13 parameters
00815 
00816     template <typename R, typename P1, typename P2, typename P3, typename P4,
00817         typename P5, typename P6, typename P7, typename P8, typename P9,
00818         typename P10, typename P11, typename P12, typename P13,
00819         template <class, class> class ThreadingModel>
00820     class FunctorImpl<R,
00821             LOKI_TYPELIST_13(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13),
00822             ThreadingModel>
00823         : public Private::FunctorImplBase<R, ThreadingModel>
00824     {
00825     public:
00826         typedef R ResultType;
00827         typedef typename TypeTraits<P1>::ParameterType Parm1;
00828         typedef typename TypeTraits<P2>::ParameterType Parm2;
00829         typedef typename TypeTraits<P3>::ParameterType Parm3;
00830         typedef typename TypeTraits<P4>::ParameterType Parm4;
00831         typedef typename TypeTraits<P5>::ParameterType Parm5;
00832         typedef typename TypeTraits<P6>::ParameterType Parm6;
00833         typedef typename TypeTraits<P7>::ParameterType Parm7;
00834         typedef typename TypeTraits<P8>::ParameterType Parm8;
00835         typedef typename TypeTraits<P9>::ParameterType Parm9;
00836         typedef typename TypeTraits<P10>::ParameterType Parm10;
00837         typedef typename TypeTraits<P11>::ParameterType Parm11;
00838         typedef typename TypeTraits<P12>::ParameterType Parm12;
00839         typedef typename TypeTraits<P13>::ParameterType Parm13;
00840         virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, 
00841             Parm7, Parm8, Parm9, Parm10, Parm11, Parm12, Parm13) = 0;
00842     };
00843 
00845 // class template FunctorImpl
00846 // Specialization for 14 parameters
00848 
00849     template <typename R, typename P1, typename P2, typename P3, typename P4,
00850         typename P5, typename P6, typename P7, typename P8, typename P9,
00851         typename P10, typename P11, typename P12, typename P13, typename P14,
00852         template <class, class> class ThreadingModel>
00853     class FunctorImpl<R,
00854             LOKI_TYPELIST_14(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13,
00855                 P14),
00856             ThreadingModel>
00857         : public Private::FunctorImplBase<R, ThreadingModel>
00858     {
00859     public:
00860         typedef R ResultType;
00861         typedef typename TypeTraits<P1>::ParameterType Parm1;
00862         typedef typename TypeTraits<P2>::ParameterType Parm2;
00863         typedef typename TypeTraits<P3>::ParameterType Parm3;
00864         typedef typename TypeTraits<P4>::ParameterType Parm4;
00865         typedef typename TypeTraits<P5>::ParameterType Parm5;
00866         typedef typename TypeTraits<P6>::ParameterType Parm6;
00867         typedef typename TypeTraits<P7>::ParameterType Parm7;
00868         typedef typename TypeTraits<P8>::ParameterType Parm8;
00869         typedef typename TypeTraits<P9>::ParameterType Parm9;
00870         typedef typename TypeTraits<P10>::ParameterType Parm10;
00871         typedef typename TypeTraits<P11>::ParameterType Parm11;
00872         typedef typename TypeTraits<P12>::ParameterType Parm12;
00873         typedef typename TypeTraits<P13>::ParameterType Parm13;
00874         typedef typename TypeTraits<P14>::ParameterType Parm14;
00875         virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, 
00876             Parm7, Parm8, Parm9, Parm10, Parm11, Parm12, Parm13, Parm14) = 0;
00877     };
00878 
00880 // class template FunctorImpl
00881 // Specialization for 15 parameters
00883 
00884     template <typename R, typename P1, typename P2, typename P3, typename P4,
00885         typename P5, typename P6, typename P7, typename P8, typename P9,
00886         typename P10, typename P11, typename P12, typename P13, typename P14,
00887         typename P15, template <class, class> class ThreadingModel>
00888     class FunctorImpl<R,
00889             LOKI_TYPELIST_15(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13,
00890                 P14, P15),
00891             ThreadingModel>
00892         : public Private::FunctorImplBase<R, ThreadingModel>
00893     {
00894     public:
00895         typedef R ResultType;
00896         typedef typename TypeTraits<P1>::ParameterType Parm1;
00897         typedef typename TypeTraits<P2>::ParameterType Parm2;
00898         typedef typename TypeTraits<P3>::ParameterType Parm3;
00899         typedef typename TypeTraits<P4>::ParameterType Parm4;
00900         typedef typename TypeTraits<P5>::ParameterType Parm5;
00901         typedef typename TypeTraits<P6>::ParameterType Parm6;
00902         typedef typename TypeTraits<P7>::ParameterType Parm7;
00903         typedef typename TypeTraits<P8>::ParameterType Parm8;
00904         typedef typename TypeTraits<P9>::ParameterType Parm9;
00905         typedef typename TypeTraits<P10>::ParameterType Parm10;
00906         typedef typename TypeTraits<P11>::ParameterType Parm11;
00907         typedef typename TypeTraits<P12>::ParameterType Parm12;
00908         typedef typename TypeTraits<P13>::ParameterType Parm13;
00909         typedef typename TypeTraits<P14>::ParameterType Parm14;
00910         typedef typename TypeTraits<P15>::ParameterType Parm15;
00911         virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, 
00912             Parm7, Parm8, Parm9, Parm10, Parm11, Parm12, Parm13, Parm14,
00913             Parm15) = 0;
00914     };
00915 
00916 #endif //LOKI_DISABLE_TYPELIST_MACROS
00917 
00919 // class template FunctorHandler
00920 // Wraps functors and pointers to functions
00922 
00923     template <class ParentFunctor, typename Fun>
00924     class FunctorHandler
00925         : public ParentFunctor::Impl
00926     {
00927         typedef typename ParentFunctor::Impl Base;
00928 
00929     public:
00930         typedef typename Base::ResultType ResultType;
00931         typedef typename Base::Parm1 Parm1;
00932         typedef typename Base::Parm2 Parm2;
00933         typedef typename Base::Parm3 Parm3;
00934         typedef typename Base::Parm4 Parm4;
00935         typedef typename Base::Parm5 Parm5;
00936         typedef typename Base::Parm6 Parm6;
00937         typedef typename Base::Parm7 Parm7;
00938         typedef typename Base::Parm8 Parm8;
00939         typedef typename Base::Parm9 Parm9;
00940         typedef typename Base::Parm10 Parm10;
00941         typedef typename Base::Parm11 Parm11;
00942         typedef typename Base::Parm12 Parm12;
00943         typedef typename Base::Parm13 Parm13;
00944         typedef typename Base::Parm14 Parm14;
00945         typedef typename Base::Parm15 Parm15;
00946         
00947         FunctorHandler(const Fun& fun) : f_(fun) {}
00948         
00949         LOKI_DEFINE_CLONE_FUNCTORIMPL(FunctorHandler)
00950 
00951 
00952 #ifdef LOKI_FUNCTORS_ARE_COMPARABLE
00953 
00954 
00955         bool operator==(const typename Base::FunctorImplBaseType& rhs) const
00956         {
00957             // there is no static information if Functor holds a member function 
00958             // or a free function; this is the main difference to tr1::function
00959             if(typeid(*this) != typeid(rhs))
00960                 return false; // cannot be equal
00961 
00962             const FunctorHandler& fh = static_cast<const FunctorHandler&>(rhs);
00963             // if this line gives a compiler error, you are using a function object.
00964             // you need to implement bool MyFnObj::operator == (const MyFnObj&) const;
00965             return  f_==fh.f_;
00966         }
00967 #endif
00968         // operator() implementations for up to 15 arguments
00969                 
00970         ResultType operator()()
00971         { return f_(); }
00972 
00973         ResultType operator()(Parm1 p1)
00974         { return f_(p1); }
00975         
00976         ResultType operator()(Parm1 p1, Parm2 p2)
00977         { return f_(p1, p2); }
00978         
00979         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3)
00980         { return f_(p1, p2, p3); }
00981         
00982         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4)
00983         { return f_(p1, p2, p3, p4); }
00984         
00985         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5)
00986         { return f_(p1, p2, p3, p4, p5); }
00987         
00988         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
00989             Parm6 p6)
00990         { return f_(p1, p2, p3, p4, p5, p6); }
00991         
00992         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
00993             Parm6 p6, Parm7 p7)
00994         { return f_(p1, p2, p3, p4, p5, p6, p7); }
00995         
00996         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
00997             Parm6 p6, Parm7 p7, Parm8 p8)
00998         { return f_(p1, p2, p3, p4, p5, p6, p7, p8); }
00999         
01000         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01001             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9)
01002         { return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9); }
01003         
01004         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01005             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10)
01006         { return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); }
01007         
01008         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01009             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11)
01010         { return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); }
01011         
01012         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01013             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
01014             Parm12 p12)
01015         { return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); }
01016         
01017         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01018             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
01019             Parm12 p12, Parm13 p13)
01020         { return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); }
01021         
01022         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01023             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
01024             Parm12 p12, Parm13 p13, Parm14 p14)
01025         {
01026             return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, 
01027                 p14);
01028         }
01029         
01030         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01031             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
01032             Parm12 p12, Parm13 p13, Parm14 p14, Parm15 p15)
01033         {
01034             return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, 
01035                 p14, p15);
01036         }
01037         
01038     private:
01039         Fun f_;
01040     };
01041         
01043 // class template FunctorHandler
01044 // Wraps pointers to member functions
01046 
01047     template <class ParentFunctor, typename PointerToObj,
01048         typename PointerToMemFn>
01049     class MemFunHandler : public ParentFunctor::Impl
01050     {
01051         typedef typename ParentFunctor::Impl Base;
01052 
01053     public:
01054         typedef typename Base::ResultType ResultType;
01055         typedef typename Base::Parm1 Parm1;
01056         typedef typename Base::Parm2 Parm2;
01057         typedef typename Base::Parm3 Parm3;
01058         typedef typename Base::Parm4 Parm4;
01059         typedef typename Base::Parm5 Parm5;
01060         typedef typename Base::Parm6 Parm6;
01061         typedef typename Base::Parm7 Parm7;
01062         typedef typename Base::Parm8 Parm8;
01063         typedef typename Base::Parm9 Parm9;
01064         typedef typename Base::Parm10 Parm10;
01065         typedef typename Base::Parm11 Parm11;
01066         typedef typename Base::Parm12 Parm12;
01067         typedef typename Base::Parm13 Parm13;
01068         typedef typename Base::Parm14 Parm14;
01069         typedef typename Base::Parm15 Parm15;
01070 
01071         MemFunHandler(const PointerToObj& pObj, PointerToMemFn pMemFn) 
01072         : pObj_(pObj), pMemFn_(pMemFn)
01073         {}
01074         
01075         LOKI_DEFINE_CLONE_FUNCTORIMPL(MemFunHandler)
01076 
01077 
01078 #ifdef LOKI_FUNCTORS_ARE_COMPARABLE
01079 
01080         bool operator==(const typename Base::FunctorImplBaseType& rhs) const
01081         {
01082             if(typeid(*this) != typeid(rhs))
01083                 return false; // cannot be equal 
01084 
01085             const MemFunHandler& mfh = static_cast<const MemFunHandler&>(rhs);
01086             // if this line gives a compiler error, you are using a function object.
01087             // you need to implement bool MyFnObj::operator == (const MyFnObj&) const;
01088             return  pObj_==mfh.pObj_ && pMemFn_==mfh.pMemFn_;
01089         }
01090 #endif   
01091 
01092         ResultType operator()()
01093         { return ((*pObj_).*pMemFn_)(); }
01094 
01095         ResultType operator()(Parm1 p1)
01096         { return ((*pObj_).*pMemFn_)(p1); }
01097         
01098         ResultType operator()(Parm1 p1, Parm2 p2)
01099         { return ((*pObj_).*pMemFn_)(p1, p2); }
01100         
01101         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3)
01102         { return ((*pObj_).*pMemFn_)(p1, p2, p3); }
01103         
01104         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4)
01105         { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4); }
01106         
01107         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5)
01108         { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5); }
01109         
01110         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01111             Parm6 p6)
01112         { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6); }
01113         
01114         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01115             Parm6 p6, Parm7 p7)
01116         { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7); }
01117         
01118         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01119             Parm6 p6, Parm7 p7, Parm8 p8)
01120         { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8); }
01121         
01122         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01123             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9)
01124         { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9); }
01125         
01126         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01127             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10)
01128         { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); }
01129         
01130         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01131             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11)
01132         {
01133             return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, 
01134                 p11);
01135         }
01136         
01137         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01138             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
01139             Parm12 p12)
01140         {
01141             return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, 
01142                 p11, p12);
01143         }
01144         
01145         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01146             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
01147             Parm12 p12, Parm13 p13)
01148         {
01149             return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, 
01150                 p11, p12, p13);
01151         }
01152         
01153         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01154             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
01155             Parm12 p12, Parm13 p13, Parm14 p14)
01156         {
01157             return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, 
01158                 p11, p12, p13, p14);
01159         }
01160         
01161         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01162             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
01163             Parm12 p12, Parm13 p13, Parm14 p14, Parm15 p15)
01164         {
01165             return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, 
01166                 p11, p12, p13, p14, p15);
01167         }
01168         
01169     private:
01170         PointerToObj pObj_;
01171         PointerToMemFn pMemFn_;
01172     };
01173         
01175 // TR1 exception
01177 
01178 #ifdef LOKI_ENABLE_FUNCTION
01179 
01180     class bad_function_call : public std::runtime_error
01181     {
01182     public:
01183         bad_function_call() : std::runtime_error("bad_function_call in Loki::Functor")
01184         {}
01185     };
01186 
01187 #define LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL if(empty()) throw bad_function_call();
01188 
01189 #else
01190 
01191 #define LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL 
01192 
01193 #endif
01194 
01217     template <typename R = void, class TList = NullType,
01218         template<class, class> class ThreadingModel = LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL>
01219     class Functor
01220     {
01221     public:
01222         // Handy type definitions for the body type
01223         typedef FunctorImpl<R, TList, ThreadingModel> Impl;
01224         typedef R ResultType;
01225         typedef TList ParmList;
01226         typedef typename Impl::Parm1 Parm1;
01227         typedef typename Impl::Parm2 Parm2;
01228         typedef typename Impl::Parm3 Parm3;
01229         typedef typename Impl::Parm4 Parm4;
01230         typedef typename Impl::Parm5 Parm5;
01231         typedef typename Impl::Parm6 Parm6;
01232         typedef typename Impl::Parm7 Parm7;
01233         typedef typename Impl::Parm8 Parm8;
01234         typedef typename Impl::Parm9 Parm9;
01235         typedef typename Impl::Parm10 Parm10;
01236         typedef typename Impl::Parm11 Parm11;
01237         typedef typename Impl::Parm12 Parm12;
01238         typedef typename Impl::Parm13 Parm13;
01239         typedef typename Impl::Parm14 Parm14;
01240         typedef typename Impl::Parm15 Parm15;
01241 
01242         // Member functions
01243 
01244         Functor() : spImpl_(0)
01245         {}
01246         
01247         Functor(const Functor& rhs) : spImpl_(Impl::Clone(rhs.spImpl_.get()))
01248         {}
01249         
01250         Functor(std::auto_ptr<Impl> spImpl) : spImpl_(spImpl)
01251         {}
01252         
01253         template <typename Fun>
01254         Functor(Fun fun)
01255         : spImpl_(new FunctorHandler<Functor, Fun>(fun))
01256         {}
01257 
01258         template <class PtrObj, typename MemFn>
01259         Functor(const PtrObj& p, MemFn memFn)
01260         : spImpl_(new MemFunHandler<Functor, PtrObj, MemFn>(p, memFn))
01261         {}
01262 
01263         typedef Impl * (std::auto_ptr<Impl>::*unspecified_bool_type)() const;
01264 
01265         operator unspecified_bool_type() const
01266         {
01267             return spImpl_.get() ? &std::auto_ptr<Impl>::get : 0;
01268         }
01269 
01270         Functor& operator=(const Functor& rhs)
01271         {
01272             Functor copy(rhs);
01273             // swap auto_ptrs by hand
01274             Impl* p = spImpl_.release();
01275             spImpl_.reset(copy.spImpl_.release());
01276             copy.spImpl_.reset(p);
01277             return *this;
01278         }
01279 
01280 #ifdef LOKI_ENABLE_FUNCTION
01281 
01282         bool empty() const
01283         {
01284             return spImpl_.get() == 0;
01285         }
01286 
01287         void clear()
01288         {
01289             spImpl_.reset(0);
01290         }
01291 #endif
01292 
01293 #ifdef LOKI_FUNCTORS_ARE_COMPARABLE
01294 
01295         bool operator==(const Functor& rhs) const
01296         {
01297             if(spImpl_.get()==0 && rhs.spImpl_.get()==0)
01298                 return true;
01299             if(spImpl_.get()!=0 && rhs.spImpl_.get()!=0)
01300                 return *spImpl_.get() == *rhs.spImpl_.get();
01301             else
01302                 return false;
01303         }
01304 
01305         bool operator!=(const Functor& rhs) const
01306         {
01307             return !(*this==rhs);
01308         }
01309 #endif
01310 
01311         // operator() implementations for up to 15 arguments
01312 
01313         ResultType operator()() const
01314         {
01315             LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
01316             return (*spImpl_)(); 
01317         }
01318 
01319         ResultType operator()(Parm1 p1) const
01320         { 
01321             LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
01322             return (*spImpl_)(p1); 
01323         }
01324         
01325         ResultType operator()(Parm1 p1, Parm2 p2) const
01326         {    
01327             LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
01328             return (*spImpl_)(p1, p2); 
01329         }
01330         
01331         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3) const
01332         {    
01333             LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
01334             return (*spImpl_)(p1, p2, p3); 
01335         }
01336         
01337         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4) const
01338         { 
01339             LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
01340             return (*spImpl_)(p1, p2, p3, p4); 
01341         }
01342         
01343         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5) const
01344         { 
01345             LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
01346             return (*spImpl_)(p1, p2, p3, p4, p5); 
01347         }
01348         
01349         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01350             Parm6 p6) const
01351         { 
01352             LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
01353             return (*spImpl_)(p1, p2, p3, p4, p5, p6); 
01354         }
01355         
01356         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01357             Parm6 p6, Parm7 p7) const
01358         { 
01359             LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
01360             return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7); 
01361         }
01362         
01363         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01364             Parm6 p6, Parm7 p7, Parm8 p8) const
01365         { 
01366             LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
01367             return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8); 
01368         }
01369         
01370         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01371             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9) const
01372         { 
01373             LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
01374             return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9); 
01375         }
01376         
01377         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01378             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10) const
01379         { 
01380             LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
01381             return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); 
01382         }
01383         
01384         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01385             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11) const
01386         { 
01387             LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
01388             return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); 
01389         }
01390         
01391         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01392             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
01393             Parm12 p12) const
01394         {
01395             LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
01396             return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, 
01397                 p12);
01398         }
01399         
01400         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01401             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
01402             Parm12 p12, Parm13 p13) const
01403         {
01404             LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
01405             return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11,
01406             p12, p13);
01407         }
01408         
01409         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01410             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
01411             Parm12 p12, Parm13 p13, Parm14 p14) const
01412         {
01413             LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
01414             return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, 
01415                 p12, p13, p14);
01416         }
01417         
01418         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01419             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
01420             Parm12 p12, Parm13 p13, Parm14 p14, Parm15 p15) const
01421         {
01422             LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
01423             return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, 
01424                 p12, p13, p14, p15);
01425         }
01426 
01427     private:
01428         std::auto_ptr<Impl> spImpl_;
01429     };
01430     
01431 
01433 //  
01434 //  BindersFirst and Chainer 
01435 //
01437 
01438     namespace Private
01439     {
01440         template <class Fctor> struct BinderFirstTraits;
01441 
01442         template <typename R, class TList, template <class, class> class ThreadingModel>
01443         struct BinderFirstTraits< Functor<R, TList, ThreadingModel> >
01444         {
01445             typedef Functor<R, TList, ThreadingModel> OriginalFunctor;
01446 
01447             typedef typename TL::Erase<TList,typename TL::TypeAt<TList, 0>::Result>
01448                              ::Result
01449                     ParmList;
01450 
01451             typedef typename TL::TypeAt<TList, 0>::Result OriginalParm1;
01452 
01453             typedef Functor<R, ParmList, ThreadingModel> BoundFunctorType;
01454 
01455             typedef typename BoundFunctorType::Impl Impl;
01456 
01457         };  
01458 
01459 
01460         template<class T>
01461         struct BinderFirstBoundTypeStorage;
01462 
01463         template<class T>
01464         struct BinderFirstBoundTypeStorage
01465         {
01466             typedef typename TypeTraits<T>::ParameterType RefOrValue;
01467         };
01468         
01469         template <typename R, class TList, template <class, class> class ThreadingModel>
01470         struct BinderFirstBoundTypeStorage< Functor<R, TList, ThreadingModel> >
01471         {
01472             typedef Functor<R, TList, ThreadingModel> OriginalFunctor;
01473             typedef const typename TypeTraits<OriginalFunctor>::ReferredType RefOrValue;
01474         };  
01475 
01476 
01477     } // namespace Private
01478 
01485 
01486     template <class OriginalFunctor>
01487     class BinderFirst 
01488         : public Private::BinderFirstTraits<OriginalFunctor>::Impl
01489     {
01490         typedef typename Private::BinderFirstTraits<OriginalFunctor>::Impl Base;
01491         typedef typename OriginalFunctor::ResultType ResultType;
01492 
01493         typedef typename OriginalFunctor::Parm1 BoundType;
01494 
01495         typedef typename Private::BinderFirstBoundTypeStorage<
01496                              typename Private::BinderFirstTraits<OriginalFunctor>
01497                              ::OriginalParm1>
01498                          ::RefOrValue
01499                 BoundTypeStorage;
01500                         
01501         typedef typename OriginalFunctor::Parm2 Parm1;
01502         typedef typename OriginalFunctor::Parm3 Parm2;
01503         typedef typename OriginalFunctor::Parm4 Parm3;
01504         typedef typename OriginalFunctor::Parm5 Parm4;
01505         typedef typename OriginalFunctor::Parm6 Parm5;
01506         typedef typename OriginalFunctor::Parm7 Parm6;
01507         typedef typename OriginalFunctor::Parm8 Parm7;
01508         typedef typename OriginalFunctor::Parm9 Parm8;
01509         typedef typename OriginalFunctor::Parm10 Parm9;
01510         typedef typename OriginalFunctor::Parm11 Parm10;
01511         typedef typename OriginalFunctor::Parm12 Parm11;
01512         typedef typename OriginalFunctor::Parm13 Parm12;
01513         typedef typename OriginalFunctor::Parm14 Parm13;
01514         typedef typename OriginalFunctor::Parm15 Parm14;
01515         typedef EmptyType Parm15;
01516 
01517     public:
01518         
01519         BinderFirst(const OriginalFunctor& fun, BoundType bound)
01520         : f_(fun), b_(bound)
01521         {}
01522 
01523         LOKI_DEFINE_CLONE_FUNCTORIMPL(BinderFirst)
01524 
01525 #ifdef LOKI_FUNCTORS_ARE_COMPARABLE
01526         
01527         bool operator==(const typename Base::FunctorImplBaseType& rhs) const
01528         {
01529             if(typeid(*this) != typeid(rhs))
01530                 return false; // cannot be equal 
01531             // if this line gives a compiler error, you are using a function object.
01532             // you need to implement bool MyFnObj::operator == (const MyFnObj&) const;
01533             return    f_ == ((static_cast<const BinderFirst&> (rhs)).f_) &&
01534                       b_ == ((static_cast<const BinderFirst&> (rhs)).b_);
01535         }
01536 #endif
01537 
01538         // operator() implementations for up to 15 arguments
01539                 
01540         ResultType operator()()
01541         { return f_(b_); }
01542 
01543         ResultType operator()(Parm1 p1)
01544         { return f_(b_, p1); }
01545         
01546         ResultType operator()(Parm1 p1, Parm2 p2)
01547         { return f_(b_, p1, p2); }
01548         
01549         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3)
01550         { return f_(b_, p1, p2, p3); }
01551         
01552         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4)
01553         { return f_(b_, p1, p2, p3, p4); }
01554         
01555         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5)
01556         { return f_(b_, p1, p2, p3, p4, p5); }
01557         
01558         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01559             Parm6 p6)
01560         { return f_(b_, p1, p2, p3, p4, p5, p6); }
01561         
01562         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01563             Parm6 p6, Parm7 p7)
01564         { return f_(b_, p1, p2, p3, p4, p5, p6, p7); }
01565         
01566         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01567             Parm6 p6, Parm7 p7, Parm8 p8)
01568         { return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8); }
01569         
01570         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01571             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9)
01572         { return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8, p9); }
01573         
01574         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01575             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10)
01576         { return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); }
01577         
01578         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01579             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11)
01580         { return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); }
01581         
01582         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01583             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
01584             Parm12 p12)
01585         { return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); }
01586         
01587         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01588             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
01589             Parm12 p12, Parm13 p13)
01590         { return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); }
01591         
01592         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01593             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
01594             Parm12 p12, Parm13 p13, Parm14 p14)
01595         {
01596             return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, 
01597                 p14);
01598         }
01599         
01600     private:
01601         OriginalFunctor f_;
01602         BoundTypeStorage b_;
01603     };
01604     
01609 
01610     template <class Fctor>
01611     typename Private::BinderFirstTraits<Fctor>::BoundFunctorType
01612     BindFirst(
01613         const Fctor& fun, 
01614         typename Fctor::Parm1 bound)
01615     {
01616         typedef typename Private::BinderFirstTraits<Fctor>::BoundFunctorType
01617             Outgoing;
01618         
01619         return Outgoing(std::auto_ptr<typename Outgoing::Impl>(
01620             new BinderFirst<Fctor>(fun, bound)));
01621     }
01622 
01629 
01630     template <typename Fun1, typename Fun2>
01631     class Chainer : public Fun2::Impl
01632     {
01633         typedef Fun2 Base;
01634 
01635     public:
01636         typedef typename Base::ResultType ResultType;
01637         typedef typename Base::Parm1 Parm1;
01638         typedef typename Base::Parm2 Parm2;
01639         typedef typename Base::Parm3 Parm3;
01640         typedef typename Base::Parm4 Parm4;
01641         typedef typename Base::Parm5 Parm5;
01642         typedef typename Base::Parm6 Parm6;
01643         typedef typename Base::Parm7 Parm7;
01644         typedef typename Base::Parm8 Parm8;
01645         typedef typename Base::Parm9 Parm9;
01646         typedef typename Base::Parm10 Parm10;
01647         typedef typename Base::Parm11 Parm11;
01648         typedef typename Base::Parm12 Parm12;
01649         typedef typename Base::Parm13 Parm13;
01650         typedef typename Base::Parm14 Parm14;
01651         typedef typename Base::Parm15 Parm15;
01652         
01653         Chainer(const Fun1& fun1, const Fun2& fun2) : f1_(fun1), f2_(fun2) {}
01654 
01655         LOKI_DEFINE_CLONE_FUNCTORIMPL(Chainer)
01656 
01657 #ifdef LOKI_FUNCTORS_ARE_COMPARABLE
01658                 
01659         bool operator==(const typename Base::Impl::FunctorImplBaseType& rhs) const
01660         {
01661             if(typeid(*this) != typeid(rhs))
01662                 return false; // cannot be equal 
01663             // if this line gives a compiler error, you are using a function object.
01664             // you need to implement bool MyFnObj::operator == (const MyFnObj&) const;
01665             return    f1_ == ((static_cast<const Chainer&> (rhs)).f2_) &&
01666                       f2_ == ((static_cast<const Chainer&> (rhs)).f1_);
01667         }
01668 #endif
01669 
01670         // operator() implementations for up to 15 arguments
01671 
01672         ResultType operator()()
01673         { return f1_(), f2_(); }
01674 
01675         ResultType operator()(Parm1 p1)
01676         { return f1_(p1), f2_(p1); }
01677         
01678         ResultType operator()(Parm1 p1, Parm2 p2)
01679         { return f1_(p1, p2), f2_(p1, p2); }
01680         
01681         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3)
01682         { return f1_(p1, p2, p3), f2_(p1, p2, p3); }
01683         
01684         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4)
01685         { return f1_(p1, p2, p3, p4), f2_(p1, p2, p3, p4); }
01686         
01687         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5)
01688         { return f1_(p1, p2, p3, p4, p5), f2_(p1, p2, p3, p4, p5); }
01689         
01690         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01691             Parm6 p6)
01692         { return f1_(p1, p2, p3, p4, p5, p6), f2_(p1, p2, p3, p4, p5, p6); }
01693         
01694         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01695             Parm6 p6, Parm7 p7)
01696         {
01697             return f1_(p1, p2, p3, p4, p5, p6, p7),
01698                 f2_(p1, p2, p3, p4, p5, p6, p7);
01699         }
01700         
01701         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01702             Parm6 p6, Parm7 p7, Parm8 p8)
01703         {
01704             return f1_(p1, p2, p3, p4, p5, p6, p7, p8),
01705                 f2_(p1, p2, p3, p4, p5, p6, p7, p8);
01706         }
01707         
01708         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01709             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9)
01710         {
01711             return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9),
01712                 f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9);
01713         }
01714         
01715         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01716             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10)
01717         {
01718             return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10),
01719                 f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
01720         }
01721         
01722         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01723             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11)
01724         {
01725             return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11),
01726                 f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11);
01727         }
01728         
01729         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01730             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
01731             Parm12 p12)
01732         {
01733             return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12),
01734                 f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12);
01735         }
01736         
01737         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01738             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
01739             Parm12 p12, Parm13 p13)
01740         {
01741             return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13),
01742                 f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13);
01743         }
01744         
01745         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01746             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
01747             Parm12 p12, Parm13 p13, Parm14 p14)
01748         {
01749             return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, 
01750                     p14),
01751                 f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, 
01752                    p14);
01753         }
01754         
01755         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
01756             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
01757             Parm12 p12, Parm13 p13, Parm14 p14, Parm15 p15)
01758         {
01759             return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, 
01760                     p14, p15),
01761                 f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, 
01762                     p14, p15);
01763         }
01764         
01765     private:
01766         Fun1 f1_;
01767         Fun2 f2_;
01768     };
01769     
01774 
01775 
01776     template <class Fun1, class Fun2>
01777     Fun2 Chain(
01778         const Fun1& fun1,
01779         const Fun2& fun2)
01780     {
01781         return Fun2(std::auto_ptr<typename Fun2::Impl>(
01782             new Chainer<Fun1, Fun2>(fun1, fun2)));
01783     }
01784 
01785 } // namespace Loki
01786 
01787 
01788 #endif // end file guardian
01789 

Generated on Sun Feb 25 16:52:26 2007 for Loki by  doxygen 1.5.1-p1