Functor.h

   1 ////////////////////////////////////////////////////////////////////////////////
   2 // The Loki Library
   3 // Copyright (c) 2001 by Andrei Alexandrescu
   4 // This code accompanies the book:
   5 // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 
   6 //     Patterns Applied". Copyright (c) 2001. Addison-Wesley.
   7 // Permission to use, copy, modify, distribute and sell this software for any 
   8 //     purpose is hereby granted without fee, provided that the above copyright 
   9 //     notice appear in all copies and that both that copyright notice and this 
  10 //     permission notice appear in supporting documentation.
  11 // The author or Addison-Welsey Longman make no representations about the 
  12 //     suitability of this software for any purpose. It is provided "as is" 
  13 //     without express or implied warranty.
  14 ////////////////////////////////////////////////////////////////////////////////
  15 
  16 // Last update: June 20, 2001
  17 
  18 #ifndef FUNCTOR_INC_
  19 #define FUNCTOR_INC_
  20 
  21 #include "Typelist.h"
  22 #include "EmptyType.h"
  23 #include "SmallObj.h"
  24 #include "TypeTraits.h"
  25 #include <typeinfo>
  26 #include <memory>
  27 
  28 namespace Loki
  29 {
  30 ////////////////////////////////////////////////////////////////////////////////
  31 // class template FunctorImpl (internal)
  32 ////////////////////////////////////////////////////////////////////////////////
  33 
  34     namespace Private
  35     {
  36         template <typename R, template <class> class ThreadingModel>
  37         struct FunctorImplBase : public SmallObject<ThreadingModel>
  38         {
  39             typedef R ResultType;
  40             
  41             typedef EmptyType Parm1;
  42             typedef EmptyType Parm2;
  43             typedef EmptyType Parm3;
  44             typedef EmptyType Parm4;
  45             typedef EmptyType Parm5;
  46             typedef EmptyType Parm6;
  47             typedef EmptyType Parm7;
  48             typedef EmptyType Parm8;
  49             typedef EmptyType Parm9;
  50             typedef EmptyType Parm10;
  51             typedef EmptyType Parm11;
  52             typedef EmptyType Parm12;
  53             typedef EmptyType Parm13;
  54             typedef EmptyType Parm14;
  55             typedef EmptyType Parm15;
  56 
  57             virtual FunctorImplBase* DoClone() const = 0;
  58             template <class U>
  59             static U* Clone(U* pObj)
  60             {
  61                 if (!pObj) return 0;
  62                 U* pClone = static_cast<U*>(pObj->DoClone());
  63                 assert(typeid(*pClone) == typeid(*pObj));
  64                 return pClone;
  65             }
  66         };
  67     }
  68     
  69 ////////////////////////////////////////////////////////////////////////////////
  70 // macro DEFINE_CLONE_FUNCTORIMPL
  71 // Implements the DoClone function for a functor implementation
  72 ////////////////////////////////////////////////////////////////////////////////
  73 
  74 #define DEFINE_CLONE_FUNCTORIMPL(Cls) \
  75     virtual Cls* DoClone() const { return new Cls(*this); }
  76 
  77 ////////////////////////////////////////////////////////////////////////////////
  78 // class template FunctorImpl
  79 // The base class for a hierarchy of functors. The FunctorImpl class is not used
  80 //     directly; rather, the Functor class manages and forwards to a pointer to
  81 //     FunctorImpl
  82 // You may want to derive your own functors from FunctorImpl.
  83 // Specializations of FunctorImpl for up to 15 parameters follow
  84 ////////////////////////////////////////////////////////////////////////////////
  85 
  86     template <typename R, class TList, 
  87         template <class> class ThreadingModel = DEFAULT_THREADING>
  88     class FunctorImpl;
  89 
  90 ////////////////////////////////////////////////////////////////////////////////
  91 // class template FunctorImpl
  92 // Specialization for 0 (zero) parameters
  93 ////////////////////////////////////////////////////////////////////////////////
  94 
  95     template <typename R, template <class> class ThreadingModel>
  96     class FunctorImpl<R, NullType, ThreadingModel>
  97         : public Private::FunctorImplBase<R, ThreadingModel>
  98     {
  99     public:
 100         typedef R ResultType;
 101         virtual R operator()() = 0;
 102     };
 103 
 104 ////////////////////////////////////////////////////////////////////////////////
 105 // class template FunctorImpl
 106 // Specialization for 1 parameter
 107 ////////////////////////////////////////////////////////////////////////////////
 108 
 109     template <typename R, typename P1, template <class> class ThreadingModel>
 110     class FunctorImpl<R, TYPELIST_1(P1), ThreadingModel>
 111         : public Private::FunctorImplBase<R, ThreadingModel>
 112     {
 113     public:
 114         typedef R ResultType;
 115         typedef typename TypeTraits<P1>::ParameterType Parm1;
 116         virtual R operator()(Parm1) = 0;
 117     };
 118 
 119 ////////////////////////////////////////////////////////////////////////////////
 120 // class template FunctorImpl
 121 // Specialization for 2 parameters
 122 ////////////////////////////////////////////////////////////////////////////////
 123 
 124     template <typename R, typename P1, typename P2, 
 125         template <class> class ThreadingModel>
 126     class FunctorImpl<R, TYPELIST_2(P1, P2), ThreadingModel>
 127         : public Private::FunctorImplBase<R, ThreadingModel>
 128     {
 129     public:
 130         typedef R ResultType;
 131         typedef typename TypeTraits<P1>::ParameterType Parm1;
 132         typedef typename TypeTraits<P2>::ParameterType Parm2;
 133         virtual R operator()(Parm1, Parm2) = 0;
 134     };
 135 
 136 ////////////////////////////////////////////////////////////////////////////////
 137 // class template FunctorImpl
 138 // Specialization for 3 parameters
 139 ////////////////////////////////////////////////////////////////////////////////
 140 
 141     template <typename R, typename P1, typename P2, typename P3,
 142         template <class> class ThreadingModel>
 143     class FunctorImpl<R, TYPELIST_3(P1, P2, P3), ThreadingModel>
 144         : public Private::FunctorImplBase<R, ThreadingModel>
 145     {
 146     public:
 147         typedef R ResultType;
 148         typedef typename TypeTraits<P1>::ParameterType Parm1;
 149         typedef typename TypeTraits<P2>::ParameterType Parm2;
 150         typedef typename TypeTraits<P3>::ParameterType Parm3;
 151         virtual R operator()(Parm1, Parm2, Parm3) = 0;
 152     };
 153 
 154 ////////////////////////////////////////////////////////////////////////////////
 155 // class template FunctorImpl
 156 // Specialization for 4 parameters
 157 ////////////////////////////////////////////////////////////////////////////////
 158 
 159     template <typename R, typename P1, typename P2, typename P3, typename P4,
 160         template <class> class ThreadingModel>
 161     class FunctorImpl<R, TYPELIST_4(P1, P2, P3, P4), ThreadingModel>
 162         : public Private::FunctorImplBase<R, ThreadingModel>
 163     {
 164     public:
 165         typedef R ResultType;
 166         typedef typename TypeTraits<P1>::ParameterType Parm1;
 167         typedef typename TypeTraits<P2>::ParameterType Parm2;
 168         typedef typename TypeTraits<P3>::ParameterType Parm3;
 169         typedef typename TypeTraits<P4>::ParameterType Parm4;
 170         virtual R operator()(Parm1, Parm2, Parm3, Parm4) = 0;
 171     };
 172 
 173 ////////////////////////////////////////////////////////////////////////////////
 174 // class template FunctorImpl
 175 // Specialization for 5 parameters
 176 ////////////////////////////////////////////////////////////////////////////////
 177 
 178     template <typename R, typename P1, typename P2, typename P3, typename P4,
 179         typename P5,
 180         template <class> class ThreadingModel>
 181     class FunctorImpl<R, TYPELIST_5(P1, P2, P3, P4, P5), ThreadingModel>
 182         : public Private::FunctorImplBase<R, ThreadingModel>
 183     {
 184     public:
 185         typedef R ResultType;
 186         typedef typename TypeTraits<P1>::ParameterType Parm1;
 187         typedef typename TypeTraits<P2>::ParameterType Parm2;
 188         typedef typename TypeTraits<P3>::ParameterType Parm3;
 189         typedef typename TypeTraits<P4>::ParameterType Parm4;
 190         typedef typename TypeTraits<P5>::ParameterType Parm5;
 191         virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5) = 0;
 192     };
 193 
 194 ////////////////////////////////////////////////////////////////////////////////
 195 // class template FunctorImpl
 196 // Specialization for 6 parameters
 197 ////////////////////////////////////////////////////////////////////////////////
 198 
 199     template <typename R, typename P1, typename P2, typename P3, typename P4,
 200         typename P5, typename P6,
 201         template <class> class ThreadingModel>
 202     class FunctorImpl<R, TYPELIST_6(P1, P2, P3, P4, P5, P6), ThreadingModel>
 203         : public Private::FunctorImplBase<R, ThreadingModel>
 204     {
 205     public:
 206         typedef R ResultType;
 207         typedef typename TypeTraits<P1>::ParameterType Parm1;
 208         typedef typename TypeTraits<P2>::ParameterType Parm2;
 209         typedef typename TypeTraits<P3>::ParameterType Parm3;
 210         typedef typename TypeTraits<P4>::ParameterType Parm4;
 211         typedef typename TypeTraits<P5>::ParameterType Parm5;
 212         typedef typename TypeTraits<P6>::ParameterType Parm6;
 213         virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6) = 0;
 214     };
 215 
 216 ////////////////////////////////////////////////////////////////////////////////
 217 // class template FunctorImpl
 218 // Specialization for 7 parameters
 219 ////////////////////////////////////////////////////////////////////////////////
 220 
 221     template <typename R, typename P1, typename P2, typename P3, typename P4,
 222         typename P5, typename P6, typename P7,
 223         template <class> class ThreadingModel>
 224     class FunctorImpl<R, TYPELIST_7(P1, P2, P3, P4, P5, P6, P7), ThreadingModel>
 225         : public Private::FunctorImplBase<R, ThreadingModel>
 226     {
 227     public:
 228         typedef R ResultType;
 229         typedef typename TypeTraits<P1>::ParameterType Parm1;
 230         typedef typename TypeTraits<P2>::ParameterType Parm2;
 231         typedef typename TypeTraits<P3>::ParameterType Parm3;
 232         typedef typename TypeTraits<P4>::ParameterType Parm4;
 233         typedef typename TypeTraits<P5>::ParameterType Parm5;
 234         typedef typename TypeTraits<P6>::ParameterType Parm6;
 235         typedef typename TypeTraits<P7>::ParameterType Parm7;
 236         virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, 
 237             Parm7) = 0;
 238     };
 239 
 240 ////////////////////////////////////////////////////////////////////////////////
 241 // class template FunctorImpl
 242 // Specialization for 8 parameters
 243 ////////////////////////////////////////////////////////////////////////////////
 244 
 245     template <typename R, typename P1, typename P2, typename P3, typename P4,
 246         typename P5, typename P6, typename P7, typename P8,
 247         template <class> class ThreadingModel>
 248     class FunctorImpl<R, TYPELIST_8(P1, P2, P3, P4, P5, P6, P7, P8),
 249             ThreadingModel>
 250         : public Private::FunctorImplBase<R, ThreadingModel>
 251     {
 252     public:
 253         typedef R ResultType;
 254         typedef typename TypeTraits<P1>::ParameterType Parm1;
 255         typedef typename TypeTraits<P2>::ParameterType Parm2;
 256         typedef typename TypeTraits<P3>::ParameterType Parm3;
 257         typedef typename TypeTraits<P4>::ParameterType Parm4;
 258         typedef typename TypeTraits<P5>::ParameterType Parm5;
 259         typedef typename TypeTraits<P6>::ParameterType Parm6;
 260         typedef typename TypeTraits<P7>::ParameterType Parm7;
 261         typedef typename TypeTraits<P8>::ParameterType Parm8;
 262         virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, 
 263             Parm7, Parm8) = 0;
 264     };
 265 
 266 ////////////////////////////////////////////////////////////////////////////////
 267 // class template FunctorImpl
 268 // Specialization for 9 parameters
 269 ////////////////////////////////////////////////////////////////////////////////
 270 
 271     template <typename R, typename P1, typename P2, typename P3, typename P4,
 272         typename P5, typename P6, typename P7, typename P8, typename P9,
 273         template <class> class ThreadingModel>
 274     class FunctorImpl<R, TYPELIST_9(P1, P2, P3, P4, P5, P6, P7, P8, P9),
 275             ThreadingModel>
 276         : public Private::FunctorImplBase<R, ThreadingModel>
 277     {
 278     public:
 279         typedef R ResultType;
 280         typedef typename TypeTraits<P1>::ParameterType Parm1;
 281         typedef typename TypeTraits<P2>::ParameterType Parm2;
 282         typedef typename TypeTraits<P3>::ParameterType Parm3;
 283         typedef typename TypeTraits<P4>::ParameterType Parm4;
 284         typedef typename TypeTraits<P5>::ParameterType Parm5;
 285         typedef typename TypeTraits<P6>::ParameterType Parm6;
 286         typedef typename TypeTraits<P7>::ParameterType Parm7;
 287         typedef typename TypeTraits<P8>::ParameterType Parm8;
 288         typedef typename TypeTraits<P9>::ParameterType Parm9;
 289         virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, 
 290             Parm7, Parm8, Parm9) = 0;
 291     };
 292 
 293 ////////////////////////////////////////////////////////////////////////////////
 294 // class template FunctorImpl
 295 // Specialization for 10 parameters
 296 ////////////////////////////////////////////////////////////////////////////////
 297 
 298     template <typename R, typename P1, typename P2, typename P3, typename P4,
 299         typename P5, typename P6, typename P7, typename P8, typename P9,
 300         typename P10,
 301         template <class> class ThreadingModel>
 302     class FunctorImpl<R, TYPELIST_10(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10),
 303             ThreadingModel>
 304         : public Private::FunctorImplBase<R, ThreadingModel>
 305     {
 306     public:
 307         typedef R ResultType;
 308         typedef typename TypeTraits<P1>::ParameterType Parm1;
 309         typedef typename TypeTraits<P2>::ParameterType Parm2;
 310         typedef typename TypeTraits<P3>::ParameterType Parm3;
 311         typedef typename TypeTraits<P4>::ParameterType Parm4;
 312         typedef typename TypeTraits<P5>::ParameterType Parm5;
 313         typedef typename TypeTraits<P6>::ParameterType Parm6;
 314         typedef typename TypeTraits<P7>::ParameterType Parm7;
 315         typedef typename TypeTraits<P8>::ParameterType Parm8;
 316         typedef typename TypeTraits<P9>::ParameterType Parm9;
 317         typedef typename TypeTraits<P10>::ParameterType Parm10;
 318         virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, 
 319             Parm7, Parm8, Parm9, Parm10) = 0;
 320     };
 321 
 322 ////////////////////////////////////////////////////////////////////////////////
 323 // class template FunctorImpl
 324 // Specialization for 11 parameters
 325 ////////////////////////////////////////////////////////////////////////////////
 326 
 327     template <typename R, typename P1, typename P2, typename P3, typename P4,
 328         typename P5, typename P6, typename P7, typename P8, typename P9,
 329         typename P10, typename P11,
 330         template <class> class ThreadingModel>
 331     class FunctorImpl<R,
 332             TYPELIST_11(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11),
 333             ThreadingModel>
 334         : public Private::FunctorImplBase<R, ThreadingModel>
 335     {
 336     public:
 337         typedef R ResultType;
 338         typedef typename TypeTraits<P1>::ParameterType Parm1;
 339         typedef typename TypeTraits<P2>::ParameterType Parm2;
 340         typedef typename TypeTraits<P3>::ParameterType Parm3;
 341         typedef typename TypeTraits<P4>::ParameterType Parm4;
 342         typedef typename TypeTraits<P5>::ParameterType Parm5;
 343         typedef typename TypeTraits<P6>::ParameterType Parm6;
 344         typedef typename TypeTraits<P7>::ParameterType Parm7;
 345         typedef typename TypeTraits<P8>::ParameterType Parm8;
 346         typedef typename TypeTraits<P9>::ParameterType Parm9;
 347         typedef typename TypeTraits<P10>::ParameterType Parm10;
 348         typedef typename TypeTraits<P11>::ParameterType Parm11;
 349         virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, 
 350             Parm7, Parm8, Parm9, Parm10, Parm11) = 0;
 351     };
 352 
 353 ////////////////////////////////////////////////////////////////////////////////
 354 // class template FunctorImpl
 355 // Specialization for 12 parameters
 356 ////////////////////////////////////////////////////////////////////////////////
 357 
 358     template <typename R, typename P1, typename P2, typename P3, typename P4,
 359         typename P5, typename P6, typename P7, typename P8, typename P9,
 360         typename P10, typename P11, typename P12,
 361         template <class> class ThreadingModel>
 362     class FunctorImpl<R,
 363             TYPELIST_12(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12),
 364             ThreadingModel>
 365         : public Private::FunctorImplBase<R, ThreadingModel>
 366     {
 367     public:
 368         typedef R ResultType;
 369         typedef typename TypeTraits<P1>::ParameterType Parm1;
 370         typedef typename TypeTraits<P2>::ParameterType Parm2;
 371         typedef typename TypeTraits<P3>::ParameterType Parm3;
 372         typedef typename TypeTraits<P4>::ParameterType Parm4;
 373         typedef typename TypeTraits<P5>::ParameterType Parm5;
 374         typedef typename TypeTraits<P6>::ParameterType Parm6;
 375         typedef typename TypeTraits<P7>::ParameterType Parm7;
 376         typedef typename TypeTraits<P8>::ParameterType Parm8;
 377         typedef typename TypeTraits<P9>::ParameterType Parm9;
 378         typedef typename TypeTraits<P10>::ParameterType Parm10;
 379         typedef typename TypeTraits<P11>::ParameterType Parm11;
 380         typedef typename TypeTraits<P12>::ParameterType Parm12;
 381         virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, 
 382             Parm7, Parm8, Parm9, Parm10, Parm11, Parm12) = 0;
 383     };
 384 
 385 ////////////////////////////////////////////////////////////////////////////////
 386 // class template FunctorImpl
 387 // Specialization for 13 parameters
 388 ////////////////////////////////////////////////////////////////////////////////
 389 
 390     template <typename R, typename P1, typename P2, typename P3, typename P4,
 391         typename P5, typename P6, typename P7, typename P8, typename P9,
 392         typename P10, typename P11, typename P12, typename P13,
 393         template <class> class ThreadingModel>
 394     class FunctorImpl<R,
 395             TYPELIST_13(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13),
 396             ThreadingModel>
 397         : public Private::FunctorImplBase<R, ThreadingModel>
 398     {
 399     public:
 400         typedef R ResultType;
 401         typedef typename TypeTraits<P1>::ParameterType Parm1;
 402         typedef typename TypeTraits<P2>::ParameterType Parm2;
 403         typedef typename TypeTraits<P3>::ParameterType Parm3;
 404         typedef typename TypeTraits<P4>::ParameterType Parm4;
 405         typedef typename TypeTraits<P5>::ParameterType Parm5;
 406         typedef typename TypeTraits<P6>::ParameterType Parm6;
 407         typedef typename TypeTraits<P7>::ParameterType Parm7;
 408         typedef typename TypeTraits<P8>::ParameterType Parm8;
 409         typedef typename TypeTraits<P9>::ParameterType Parm9;
 410         typedef typename TypeTraits<P10>::ParameterType Parm10;
 411         typedef typename TypeTraits<P11>::ParameterType Parm11;
 412         typedef typename TypeTraits<P12>::ParameterType Parm12;
 413         typedef typename TypeTraits<P13>::ParameterType Parm13;
 414         virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, 
 415             Parm7, Parm8, Parm9, Parm10, Parm11, Parm12, Parm13) = 0;
 416     };
 417 
 418 ////////////////////////////////////////////////////////////////////////////////
 419 // class template FunctorImpl
 420 // Specialization for 14 parameters
 421 ////////////////////////////////////////////////////////////////////////////////
 422 
 423     template <typename R, typename P1, typename P2, typename P3, typename P4,
 424         typename P5, typename P6, typename P7, typename P8, typename P9,
 425         typename P10, typename P11, typename P12, typename P13, typename P14,
 426         template <class> class ThreadingModel>
 427     class FunctorImpl<R,
 428             TYPELIST_14(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13,
 429                 P14),
 430             ThreadingModel>
 431         : public Private::FunctorImplBase<R, ThreadingModel>
 432     {
 433     public:
 434         typedef R ResultType;
 435         typedef typename TypeTraits<P1>::ParameterType Parm1;
 436         typedef typename TypeTraits<P2>::ParameterType Parm2;
 437         typedef typename TypeTraits<P3>::ParameterType Parm3;
 438         typedef typename TypeTraits<P4>::ParameterType Parm4;
 439         typedef typename TypeTraits<P5>::ParameterType Parm5;
 440         typedef typename TypeTraits<P6>::ParameterType Parm6;
 441         typedef typename TypeTraits<P7>::ParameterType Parm7;
 442         typedef typename TypeTraits<P8>::ParameterType Parm8;
 443         typedef typename TypeTraits<P9>::ParameterType Parm9;
 444         typedef typename TypeTraits<P10>::ParameterType Parm10;
 445         typedef typename TypeTraits<P11>::ParameterType Parm11;
 446         typedef typename TypeTraits<P12>::ParameterType Parm12;
 447         typedef typename TypeTraits<P13>::ParameterType Parm13;
 448         typedef typename TypeTraits<P14>::ParameterType Parm14;
 449         virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, 
 450             Parm7, Parm8, Parm9, Parm10, Parm11, Parm12, Parm13, Parm14) = 0;
 451     };
 452 
 453 ////////////////////////////////////////////////////////////////////////////////
 454 // class template FunctorImpl
 455 // Specialization for 15 parameters
 456 ////////////////////////////////////////////////////////////////////////////////
 457 
 458     template <typename R, typename P1, typename P2, typename P3, typename P4,
 459         typename P5, typename P6, typename P7, typename P8, typename P9,
 460         typename P10, typename P11, typename P12, typename P13, typename P14,
 461         typename P15, template <class> class ThreadingModel>
 462     class FunctorImpl<R,
 463             TYPELIST_15(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13,
 464                 P14, P15),
 465             ThreadingModel>
 466         : public Private::FunctorImplBase<R, ThreadingModel>
 467     {
 468     public:
 469         typedef R ResultType;
 470         typedef typename TypeTraits<P1>::ParameterType Parm1;
 471         typedef typename TypeTraits<P2>::ParameterType Parm2;
 472         typedef typename TypeTraits<P3>::ParameterType Parm3;
 473         typedef typename TypeTraits<P4>::ParameterType Parm4;
 474         typedef typename TypeTraits<P5>::ParameterType Parm5;
 475         typedef typename TypeTraits<P6>::ParameterType Parm6;
 476         typedef typename TypeTraits<P7>::ParameterType Parm7;
 477         typedef typename TypeTraits<P8>::ParameterType Parm8;
 478         typedef typename TypeTraits<P9>::ParameterType Parm9;
 479         typedef typename TypeTraits<P10>::ParameterType Parm10;
 480         typedef typename TypeTraits<P11>::ParameterType Parm11;
 481         typedef typename TypeTraits<P12>::ParameterType Parm12;
 482         typedef typename TypeTraits<P13>::ParameterType Parm13;
 483         typedef typename TypeTraits<P14>::ParameterType Parm14;
 484         typedef typename TypeTraits<P15>::ParameterType Parm15;
 485         virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, 
 486             Parm7, Parm8, Parm9, Parm10, Parm11, Parm12, Parm13, Parm14,
 487             Parm15) = 0;
 488     };
 489 
 490 ////////////////////////////////////////////////////////////////////////////////
 491 // class template FunctorHandler
 492 // Wraps functors and pointers to functions
 493 ////////////////////////////////////////////////////////////////////////////////
 494 
 495     template <class ParentFunctor, typename Fun>
 496     class FunctorHandler
 497         : public ParentFunctor::Impl
 498     {
 499         typedef typename ParentFunctor::Impl Base;
 500 
 501     public:
 502         typedef typename Base::ResultType ResultType;
 503         typedef typename Base::Parm1 Parm1;
 504         typedef typename Base::Parm2 Parm2;
 505         typedef typename Base::Parm3 Parm3;
 506         typedef typename Base::Parm4 Parm4;
 507         typedef typename Base::Parm5 Parm5;
 508         typedef typename Base::Parm6 Parm6;
 509         typedef typename Base::Parm7 Parm7;
 510         typedef typename Base::Parm8 Parm8;
 511         typedef typename Base::Parm9 Parm9;
 512         typedef typename Base::Parm10 Parm10;
 513         typedef typename Base::Parm11 Parm11;
 514         typedef typename Base::Parm12 Parm12;
 515         typedef typename Base::Parm13 Parm13;
 516         typedef typename Base::Parm14 Parm14;
 517         typedef typename Base::Parm15 Parm15;
 518         
 519         FunctorHandler(const Fun& fun) : f_(fun) {}
 520         
 521         DEFINE_CLONE_FUNCTORIMPL(FunctorHandler)
 522 
 523         // operator() implementations for up to 15 arguments
 524                 
 525         ResultType operator()()
 526         { return f_(); }
 527 
 528         ResultType operator()(Parm1 p1)
 529         { return f_(p1); }
 530         
 531         ResultType operator()(Parm1 p1, Parm2 p2)
 532         { return f_(p1, p2); }
 533         
 534         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3)
 535         { return f_(p1, p2, p3); }
 536         
 537         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4)
 538         { return f_(p1, p2, p3, p4); }
 539         
 540         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5)
 541         { return f_(p1, p2, p3, p4, p5); }
 542         
 543         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
 544             Parm6 p6)
 545         { return f_(p1, p2, p3, p4, p5, p6); }
 546         
 547         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
 548             Parm6 p6, Parm7 p7)
 549         { return f_(p1, p2, p3, p4, p5, p6, p7); }
 550         
 551         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
 552             Parm6 p6, Parm7 p7, Parm8 p8)
 553         { return f_(p1, p2, p3, p4, p5, p6, p7, p8); }
 554         
 555         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
 556             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9)
 557         { return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9); }
 558         
 559         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
 560             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10)
 561         { return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); }
 562         
 563         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
 564             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11)
 565         { return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); }
 566         
 567         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
 568             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
 569             Parm12 p12)
 570         { return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); }
 571         
 572         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
 573             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
 574             Parm12 p12, Parm13 p13)
 575         { return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); }
 576         
 577         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
 578             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
 579             Parm12 p12, Parm13 p13, Parm14 p14)
 580         {
 581             return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, 
 582                 p14);
 583         }
 584         
 585         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
 586             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
 587             Parm12 p12, Parm13 p13, Parm14 p14, Parm15 p15)
 588         {
 589             return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, 
 590                 p14, p15);
 591         }
 592         
 593     private:
 594         Fun f_;
 595     };
 596         
 597 ////////////////////////////////////////////////////////////////////////////////
 598 // class template FunctorHandler
 599 // Wraps pointers to member functions
 600 ////////////////////////////////////////////////////////////////////////////////
 601 
 602     template <class ParentFunctor, typename PointerToObj,
 603         typename PointerToMemFn>
 604     class MemFunHandler : public ParentFunctor::Impl
 605     {
 606         typedef typename ParentFunctor::Impl Base;
 607 
 608     public:
 609         typedef typename Base::ResultType ResultType;
 610         typedef typename Base::Parm1 Parm1;
 611         typedef typename Base::Parm2 Parm2;
 612         typedef typename Base::Parm3 Parm3;
 613         typedef typename Base::Parm4 Parm4;
 614         typedef typename Base::Parm5 Parm5;
 615         typedef typename Base::Parm6 Parm6;
 616         typedef typename Base::Parm7 Parm7;
 617         typedef typename Base::Parm8 Parm8;
 618         typedef typename Base::Parm9 Parm9;
 619         typedef typename Base::Parm10 Parm10;
 620         typedef typename Base::Parm11 Parm11;
 621         typedef typename Base::Parm12 Parm12;
 622         typedef typename Base::Parm13 Parm13;
 623         typedef typename Base::Parm14 Parm14;
 624         typedef typename Base::Parm15 Parm15;
 625 
 626         MemFunHandler(const PointerToObj& pObj, PointerToMemFn pMemFn) 
 627         : pObj_(pObj), pMemFn_(pMemFn)
 628         {}
 629         
 630         DEFINE_CLONE_FUNCTORIMPL(MemFunHandler)
 631         
 632         ResultType operator()()
 633         { return ((*pObj_).*pMemFn_)(); }
 634 
 635         ResultType operator()(Parm1 p1)
 636         { return ((*pObj_).*pMemFn_)(p1); }
 637         
 638         ResultType operator()(Parm1 p1, Parm2 p2)
 639         { return ((*pObj_).*pMemFn_)(p1, p2); }
 640         
 641         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3)
 642         { return ((*pObj_).*pMemFn_)(p1, p2, p3); }
 643         
 644         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4)
 645         { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4); }
 646         
 647         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5)
 648         { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5); }
 649         
 650         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
 651             Parm6 p6)
 652         { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6); }
 653         
 654         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
 655             Parm6 p6, Parm7 p7)
 656         { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7); }
 657         
 658         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
 659             Parm6 p6, Parm7 p7, Parm8 p8)
 660         { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8); }
 661         
 662         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
 663             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9)
 664         { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9); }
 665         
 666         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
 667             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10)
 668         { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); }
 669         
 670         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
 671             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11)
 672         {
 673             return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, 
 674                 p11);
 675         }
 676         
 677         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
 678             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
 679             Parm12 p12)
 680         {
 681             return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, 
 682                 p11, p12);
 683         }
 684         
 685         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
 686             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
 687             Parm12 p12, Parm13 p13)
 688         {
 689             return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, 
 690                 p11, p12, p13);
 691         }
 692         
 693         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
 694             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
 695             Parm12 p12, Parm13 p13, Parm14 p14)
 696         {
 697             return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, 
 698                 p11, p12, p13, p14);
 699         }
 700         
 701         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
 702             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
 703             Parm12 p12, Parm13 p13, Parm14 p14, Parm15 p15)
 704         {
 705             return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, 
 706                 p11, p12, p13, p14, p15);
 707         }
 708         
 709     private:
 710         PointerToObj pObj_;
 711         PointerToMemFn pMemFn_;
 712     };
 713         
 714 ////////////////////////////////////////////////////////////////////////////////
 715 // class template Functor
 716 // A generalized functor implementation with value semantics
 717 ////////////////////////////////////////////////////////////////////////////////
 718        
 719     template <typename R, class TList = NullType,
 720         template<class> class ThreadingModel = DEFAULT_THREADING>
 721     class Functor
 722     {
 723     public:
 724         // Handy type definitions for the body type
 725         typedef FunctorImpl<R, TList, ThreadingModel> Impl;
 726         typedef R ResultType;
 727         typedef TList ParmList;
 728         typedef typename Impl::Parm1 Parm1;
 729         typedef typename Impl::Parm2 Parm2;
 730         typedef typename Impl::Parm3 Parm3;
 731         typedef typename Impl::Parm4 Parm4;
 732         typedef typename Impl::Parm5 Parm5;
 733         typedef typename Impl::Parm6 Parm6;
 734         typedef typename Impl::Parm7 Parm7;
 735         typedef typename Impl::Parm8 Parm8;
 736         typedef typename Impl::Parm9 Parm9;
 737         typedef typename Impl::Parm10 Parm10;
 738         typedef typename Impl::Parm11 Parm11;
 739         typedef typename Impl::Parm12 Parm12;
 740         typedef typename Impl::Parm13 Parm13;
 741         typedef typename Impl::Parm14 Parm14;
 742         typedef typename Impl::Parm15 Parm15;
 743 
 744         // Member functions
 745 
 746         Functor() : spImpl_(0)
 747         {}
 748         
 749         Functor(const Functor& rhs) : spImpl_(Impl::Clone(rhs.spImpl_.get()))
 750         {}
 751         
 752         Functor(std::auto_ptr<Impl> spImpl) : spImpl_(spImpl)
 753         {}
 754         
 755         template <typename Fun>
 756         Functor(Fun fun)
 757         : spImpl_(new FunctorHandler<Functor, Fun>(fun))
 758         {}
 759 
 760         template <class PtrObj, typename MemFn>
 761         Functor(const PtrObj& p, MemFn memFn)
 762         : spImpl_(new MemFunHandler<Functor, PtrObj, MemFn>(p, memFn))
 763         {}
 764 
 765         Functor& operator=(const Functor& rhs)
 766         {
 767             Functor copy(rhs);
 768             // swap auto_ptrs by hand
 769             Impl* p = spImpl_.release();
 770             spImpl_.reset(copy.spImpl_.release());
 771             copy.spImpl_.reset(p);
 772             return *this;
 773         }
 774         
 775         ResultType operator()()
 776         { return (*spImpl_)(); }
 777 
 778         ResultType operator()(Parm1 p1)
 779         { return (*spImpl_)(p1); }
 780         
 781         ResultType operator()(Parm1 p1, Parm2 p2)
 782         { return (*spImpl_)(p1, p2); }
 783         
 784         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3)
 785         { return (*spImpl_)(p1, p2, p3); }
 786         
 787         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4)
 788         { return (*spImpl_)(p1, p2, p3, p4); }
 789         
 790         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5)
 791         { return (*spImpl_)(p1, p2, p3, p4, p5); }
 792         
 793         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
 794             Parm6 p6)
 795         { return (*spImpl_)(p1, p2, p3, p4, p5, p6); }
 796         
 797         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
 798             Parm6 p6, Parm7 p7)
 799         { return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7); }
 800         
 801         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
 802             Parm6 p6, Parm7 p7, Parm8 p8)
 803         { return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8); }
 804         
 805         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
 806             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9)
 807         { return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9); }
 808         
 809         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
 810             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10)
 811         { return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); }
 812         
 813         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
 814             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11)
 815         { return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); }
 816         
 817         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
 818             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
 819             Parm12 p12)
 820         {
 821             return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, 
 822                 p12);
 823         }
 824         
 825         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
 826             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
 827             Parm12 p12, Parm13 p13)
 828         {
 829             return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11,
 830             p12, p13);
 831         }
 832         
 833         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
 834             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
 835             Parm12 p12, Parm13 p13, Parm14 p14)
 836         {
 837             return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, 
 838                 p12, p13, p14);
 839         }
 840         
 841         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
 842             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
 843             Parm12 p12, Parm13 p13, Parm14 p14, Parm15 p15)
 844         {
 845             return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, 
 846                 p12, p13, p14, p15);
 847         }
 848 
 849     private:
 850         std::auto_ptr<Impl> spImpl_;
 851     };
 852     
 853     namespace Private
 854     {
 855         template <class Fctor> struct BinderFirstTraits;
 856 
 857         template <typename R, class TList, template <class> class ThreadingModel>
 858         struct BinderFirstTraits< Functor<R, TList, ThreadingModel> >
 859         {
 860             typedef typename TL::Erase<TList, 
 861                     typename TL::TypeAt<TList, 0>::Result>::Result
 862                 ParmList;
 863             typedef Functor<R, ParmList, ThreadingModel> BoundFunctorType;
 864             typedef typename BoundFunctorType::Impl Impl;
 865         };        
 866     }
 867 
 868 ////////////////////////////////////////////////////////////////////////////////
 869 // class template BinderFirst
 870 // Binds the first parameter of a Functor object to a specific value
 871 ////////////////////////////////////////////////////////////////////////////////
 872 
 873     template <class OriginalFunctor>
 874     class BinderFirst 
 875         : public Private::BinderFirstTraits<OriginalFunctor>::Impl
 876     {
 877         typedef typename Private::BinderFirstTraits<OriginalFunctor>::Impl Base;
 878         typedef typename OriginalFunctor::ResultType ResultType;
 879 
 880         typedef typename OriginalFunctor::Parm1 BoundType;
 881 
 882         typedef typename OriginalFunctor::Parm2 Parm1;
 883         typedef typename OriginalFunctor::Parm3 Parm2;
 884         typedef typename OriginalFunctor::Parm4 Parm3;
 885         typedef typename OriginalFunctor::Parm5 Parm4;
 886         typedef typename OriginalFunctor::Parm6 Parm5;
 887         typedef typename OriginalFunctor::Parm7 Parm6;
 888         typedef typename OriginalFunctor::Parm8 Parm7;
 889         typedef typename OriginalFunctor::Parm9 Parm8;
 890         typedef typename OriginalFunctor::Parm10 Parm9;
 891         typedef typename OriginalFunctor::Parm11 Parm10;
 892         typedef typename OriginalFunctor::Parm12 Parm11;
 893         typedef typename OriginalFunctor::Parm13 Parm12;
 894         typedef typename OriginalFunctor::Parm14 Parm13;
 895         typedef typename OriginalFunctor::Parm15 Parm14;
 896         typedef EmptyType Parm15;
 897 
 898     public:
 899         BinderFirst(const OriginalFunctor& fun, BoundType bound)
 900         : f_(fun), b_(bound)
 901         {}
 902         
 903         DEFINE_CLONE_FUNCTORIMPL(BinderFirst)
 904         
 905         // operator() implementations for up to 15 arguments
 906                 
 907         ResultType operator()()
 908         { return f_(b_); }
 909 
 910         ResultType operator()(Parm1 p1)
 911         { return f_(b_, p1); }
 912         
 913         ResultType operator()(Parm1 p1, Parm2 p2)
 914         { return f_(b_, p1, p2); }
 915         
 916         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3)
 917         { return f_(b_, p1, p2, p3); }
 918         
 919         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4)
 920         { return f_(b_, p1, p2, p3, p4); }
 921         
 922         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5)
 923         { return f_(b_, p1, p2, p3, p4, p5); }
 924         
 925         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
 926             Parm6 p6)
 927         { return f_(b_, p1, p2, p3, p4, p5, p6); }
 928         
 929         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
 930             Parm6 p6, Parm7 p7)
 931         { return f_(b_, p1, p2, p3, p4, p5, p6, p7); }
 932         
 933         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
 934             Parm6 p6, Parm7 p7, Parm8 p8)
 935         { return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8); }
 936         
 937         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
 938             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9)
 939         { return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8, p9); }
 940         
 941         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
 942             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10)
 943         { return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); }
 944         
 945         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
 946             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11)
 947         { return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); }
 948         
 949         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
 950             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
 951             Parm12 p12)
 952         { return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); }
 953         
 954         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
 955             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
 956             Parm12 p12, Parm13 p13)
 957         { return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); }
 958         
 959         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
 960             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
 961             Parm12 p12, Parm13 p13, Parm14 p14)
 962         {
 963             return f_(b_, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, 
 964                 p14);
 965         }
 966         
 967     private:
 968         OriginalFunctor f_;
 969         BoundType b_;
 970     };
 971     
 972 ////////////////////////////////////////////////////////////////////////////////
 973 // function template BindFirst
 974 // Binds the first parameter of a Functor object to a specific value
 975 ////////////////////////////////////////////////////////////////////////////////
 976 
 977     template <class Fctor>
 978     typename Private::BinderFirstTraits<Fctor>::BoundFunctorType
 979     BindFirst(
 980         const Fctor& fun,
 981         typename Fctor::Parm1 bound)
 982     {
 983         typedef typename Private::BinderFirstTraits<Fctor>::BoundFunctorType
 984             Outgoing;
 985         
 986         return Outgoing(std::auto_ptr<typename Outgoing::Impl>(
 987             new BinderFirst<Fctor>(fun, bound)));
 988     }
 989 
 990 ////////////////////////////////////////////////////////////////////////////////
 991 // class template Chainer
 992 // Chains two functor calls one after another
 993 ////////////////////////////////////////////////////////////////////////////////
 994 
 995     template <typename Fun1, typename Fun2>
 996     class Chainer : public Fun2::Impl
 997     {
 998         typedef Fun2 Base;
 999 
1000     public:
1001         typedef typename Base::ResultType ResultType;
1002         typedef typename Base::Parm1 Parm1;
1003         typedef typename Base::Parm2 Parm2;
1004         typedef typename Base::Parm3 Parm3;
1005         typedef typename Base::Parm4 Parm4;
1006         typedef typename Base::Parm5 Parm5;
1007         typedef typename Base::Parm6 Parm6;
1008         typedef typename Base::Parm7 Parm7;
1009         typedef typename Base::Parm8 Parm8;
1010         typedef typename Base::Parm9 Parm9;
1011         typedef typename Base::Parm10 Parm10;
1012         typedef typename Base::Parm11 Parm11;
1013         typedef typename Base::Parm12 Parm12;
1014         typedef typename Base::Parm13 Parm13;
1015         typedef typename Base::Parm14 Parm14;
1016         typedef typename Base::Parm15 Parm15;
1017         
1018         Chainer(const Fun1& fun1, const Fun2& fun2) : f1_(fun1), f2_(fun2) {}
1019 
1020         DEFINE_CLONE_FUNCTORIMPL(Chainer)
1021 
1022         // operator() implementations for up to 15 arguments
1023 
1024         ResultType operator()()
1025         { return f1_(), f2_(); }
1026 
1027         ResultType operator()(Parm1 p1)
1028         { return f1_(p1), f2_(p1); }
1029         
1030         ResultType operator()(Parm1 p1, Parm2 p2)
1031         { return f1_(p1, p2), f2_(p1, p2); }
1032         
1033         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3)
1034         { return f1_(p1, p2, p3), f2_(p1, p2, p3); }
1035         
1036         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4)
1037         { return f1_(p1, p2, p3, p4), f2_(p1, p2, p3, p4); }
1038         
1039         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5)
1040         { return f1_(p1, p2, p3, p4, p5), f2_(p1, p2, p3, p4, p5); }
1041         
1042         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
1043             Parm6 p6)
1044         { return f1_(p1, p2, p3, p4, p5, p6), f2_(p1, p2, p3, p4, p5, p6); }
1045         
1046         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
1047             Parm6 p6, Parm7 p7)
1048         {
1049             return f1_(p1, p2, p3, p4, p5, p6, p7),
1050                 f2_(p1, p2, p3, p4, p5, p6, p7);
1051         }
1052         
1053         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
1054             Parm6 p6, Parm7 p7, Parm8 p8)
1055         {
1056             return f1_(p1, p2, p3, p4, p5, p6, p7, p8),
1057                 f2_(p1, p2, p3, p4, p5, p6, p7, p8);
1058         }
1059         
1060         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
1061             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9)
1062         {
1063             return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9),
1064                 f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9);
1065         }
1066         
1067         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
1068             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10)
1069         {
1070             return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10),
1071                 f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
1072         }
1073         
1074         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
1075             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11)
1076         {
1077             return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11),
1078                 f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11);
1079         }
1080         
1081         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
1082             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
1083             Parm12 p12)
1084         {
1085             return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12),
1086                 f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12);
1087         }
1088         
1089         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
1090             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
1091             Parm12 p12, Parm13 p13)
1092         {
1093             return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13),
1094                 f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13);
1095         }
1096         
1097         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
1098             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
1099             Parm12 p12, Parm13 p13, Parm14 p14)
1100         {
1101             return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, 
1102                     p14),
1103                 f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, 
1104                    p14);
1105         }
1106         
1107         ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
1108             Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
1109             Parm12 p12, Parm13 p13, Parm14 p14, Parm15 p15)
1110         {
1111             return f1_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, 
1112                     p14, p15),
1113                 f2_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, 
1114                     p14, p15);
1115         }
1116         
1117     private:
1118         Fun1 f1_;
1119         Fun2 f2_;
1120     };
1121     
1122 ////////////////////////////////////////////////////////////////////////////////
1123 // function template Chain
1124 // Chains two functor calls one after another
1125 ////////////////////////////////////////////////////////////////////////////////
1126 
1127 
1128     template <class Fun1, class Fun2>
1129     Fun2 Chain(
1130         const Fun1& fun1,
1131         const Fun2& fun2)
1132     {
1133         return Fun2(std::auto_ptr<typename Fun2::Impl>(
1134             new Chainer<Fun1, Fun2>(fun1, fun2)));
1135     }
1136 
1137 } // namespace Loki
1138 
1139 ////////////////////////////////////////////////////////////////////////////////
1140 // Change log:
1141 // June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
1142 ////////////////////////////////////////////////////////////////////////////////
1143 
1144 #endif  // FUNCTOR_INC_
posted @ 2012-10-31 15:14  crazylhf  阅读(181)  评论(0)    收藏  举报