Callable.h

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 2005-2007 by Peter Dimov.
00004 
00005 This file is part of Calitko (http://www.calitko.org).
00006 
00007 Calitko is free software; you can redistribute it and/or modify
00008 it under the terms of the GNU General Public License as published by
00009 the Free Software Foundation; either version 2 of the License, or
00010 (at your option) any later version.
00011 
00012 Calitko is distributed in the hope that it will be useful,
00013 but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Calitko; if not, write to the Free Software
00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020 
00021 */
00022 
00023 #ifndef UTILS__CALLABLE_H
00024 #define UTILS__CALLABLE_H
00025 
00026 #include "Imports.h"
00027 #include "AbstractValue.h"
00028 
00029 namespace Utils {
00030 
00032 
00034 template <typename T = void()>
00035 class Callable;
00036 
00037 
00038 template <typename R>
00039 class Callable <R ()>
00040 {
00041     struct CallableImpl
00042     {
00043         virtual                         ~CallableImpl() {}
00044         virtual auto_ptr <CallableImpl> copy() const = 0;
00045         virtual bool                    isEqualTo (const CallableImpl &) = 0;
00046         virtual R                       doCall() = 0;
00047     };
00048 
00049     struct NullCallableImpl : public CallableImpl
00050     {
00051         NullCallableImpl() {}
00052         ~NullCallableImpl() {}
00053 
00054         auto_ptr <CallableImpl> copy() const
00055         { return auto_ptr <CallableImpl> (new NullCallableImpl ()); }
00056 
00057         bool isEqualTo (const CallableImpl &) { return true; }
00058         R doCall () { return R(); }
00059     };
00060 
00061     typedef R (*Function)();
00062     struct FunctionCallableImpl : public CallableImpl
00063     {
00064         Function function;
00065 
00066         FunctionCallableImpl (Function f) : function (f) {}
00067         ~FunctionCallableImpl() {}
00068 
00069         auto_ptr <CallableImpl> copy() const
00070         { return auto_ptr <CallableImpl> (new FunctionCallableImpl (*this)); }
00071 
00072         bool isEqualTo (const CallableImpl &other_)
00073         {
00074             const FunctionCallableImpl &other =
00075                 dynamic_cast <const FunctionCallableImpl &> (other_);
00076             return other.function == other.function;
00077         }
00078 
00079         R doCall() { return function(); }
00080     };
00081 
00082     template <typename Class>
00083     struct MemberFunctionCallableImpl : public CallableImpl
00084     {
00085         typedef R (Class::*MemberFunction) ();
00086 
00087         Class           &object;
00088         MemberFunction  function;
00089 
00090         MemberFunctionCallableImpl() {}
00091         MemberFunctionCallableImpl (Class &o, MemberFunction f)
00092         : object (o), function (f) {}
00093         ~MemberFunctionCallableImpl() {}
00094 
00095         auto_ptr <CallableImpl> copy() const
00096         { return auto_ptr <CallableImpl>
00097                                     (new MemberFunctionCallableImpl (*this)); }
00098 
00099         bool isEqualTo (const CallableImpl &other_)
00100         {
00101             const MemberFunctionCallableImpl &other =
00102                 dynamic_cast <const MemberFunctionCallableImpl &> (other_);
00103             return &other.object == &other.object
00104                     && other.function == other.function;
00105         }
00106 
00107         R doCall() { return (object.*function)(); }
00108     };
00109 
00110     template <typename Class>
00111     struct ConstMemberFunctionCallableImpl : public CallableImpl
00112     {
00113         typedef R (Class::*ConstMemberFunction) () const;
00114 
00115         const Class             &object;
00116         ConstMemberFunction     function;
00117 
00118         ConstMemberFunctionCallableImpl() {}
00119         ConstMemberFunctionCallableImpl (const Class &o, ConstMemberFunction f)
00120         : object (o), function (f) {}
00121         ~ConstMemberFunctionCallableImpl() {}
00122 
00123         auto_ptr <CallableImpl> copy() const
00124         { return auto_ptr <CallableImpl>
00125                                 (new ConstMemberFunctionCallableImpl (*this)); }
00126 
00127         bool isEqualTo (const CallableImpl &other_)
00128         {
00129             const ConstMemberFunctionCallableImpl &other =
00130                 dynamic_cast <const ConstMemberFunctionCallableImpl &> (other_);
00131             return &other.object == &other.object
00132                     && other.function == other.function;
00133         }
00134 
00135         R doCall() { return (object.*function)(); }
00136     };
00137 
00138 public:
00139     typedef R       ReturnType;
00140 
00141     Callable() : impl () {}
00142 
00143     Callable (const Callable &other) : impl (other.impl) {}
00144 
00145     Callable (Function f) : impl (FunctionCallableImpl (f)) {}
00146 
00147     template <typename Class>
00148     Callable (Class &o, R (Class::*f) ())
00149     : impl (MemberFunctionCallableImpl <Class> (o, f)) {}
00150 
00151     template <typename Class>
00152     Callable (Class *o, R (Class::*f) ())
00153     : impl (MemberFunctionCallableImpl <Class> (*o, f)) {}
00154 
00155     template <typename Class>
00156     Callable (const Class &o, R (Class::*f) () const)
00157     : impl (ConstMemberFunctionCallableImpl <Class> (o, f)) {}
00158 
00159     template <typename Class>
00160     Callable (const Class *o, R (Class::*f) () const)
00161     : impl (ConstMemberFunctionCallableImpl <Class> (*o, f)) {}
00162 
00163     R operator()() { return impl->doCall(); }
00164 
00165     bool operator== (const Callable &other) const { return impl == other.impl; }
00166 
00167     bool operator!= (const Callable &other) const { return impl != other.impl; }
00168 
00169 private:
00170     AbstractValue <CallableImpl, NullCallableImpl> impl;
00171 };
00172 
00173 template <typename R, typename P1>
00174 class Callable <R (P1)>
00175 {
00176     struct CallableImpl
00177     {
00178         virtual                         ~CallableImpl() {}
00179         virtual auto_ptr <CallableImpl> copy() const = 0;
00180         virtual bool                    isEqualTo (const CallableImpl &) = 0;
00181         virtual R                       doCall(P1) = 0;
00182     };
00183 
00184     struct NullCallableImpl : public CallableImpl
00185     {
00186         NullCallableImpl() {}
00187         ~NullCallableImpl() {}
00188 
00189         auto_ptr <CallableImpl> copy() const
00190         { return auto_ptr <CallableImpl> (new NullCallableImpl ()); }
00191 
00192         bool isEqualTo (const CallableImpl &) { return true; }
00193         R doCall (P1 a1) { return R(a1); }
00194     };
00195 
00196     typedef R (*Function)(P1);
00197     struct FunctionCallableImpl : public CallableImpl
00198     {
00199         Function function;
00200 
00201         FunctionCallableImpl (Function f) : function (f) {}
00202         ~FunctionCallableImpl() {}
00203 
00204         auto_ptr <CallableImpl> copy() const
00205         { return auto_ptr <CallableImpl> (new FunctionCallableImpl (*this)); }
00206 
00207         bool isEqualTo (const CallableImpl &other_)
00208         {
00209             const FunctionCallableImpl &other =
00210                 dynamic_cast <const FunctionCallableImpl &> (other_);
00211             return other.function == other.function;
00212         }
00213 
00214         R doCall(P1 a1) { return function(a1); }
00215     };
00216 
00217     template <typename Class>
00218     struct MemberFunctionCallableImpl : public CallableImpl
00219     {
00220         typedef R (Class::*MemberFunction) (P1);
00221 
00222         Class           &object;
00223         MemberFunction  function;
00224 
00225         MemberFunctionCallableImpl() {}
00226         MemberFunctionCallableImpl (Class &o, MemberFunction f)
00227         : object (o), function (f) {}
00228         ~MemberFunctionCallableImpl() {}
00229 
00230         auto_ptr <CallableImpl> copy() const
00231         { return auto_ptr <CallableImpl>
00232                                     (new MemberFunctionCallableImpl (*this)); }
00233 
00234         bool isEqualTo (const CallableImpl &other_)
00235         {
00236             const MemberFunctionCallableImpl &other =
00237                 dynamic_cast <const MemberFunctionCallableImpl &> (other_);
00238             return &other.object == &other.object
00239                     && other.function == other.function;
00240         }
00241 
00242         R doCall(P1 a1) { return (object.*function)(a1); }
00243     };
00244 
00245     template <typename Class>
00246     struct ConstMemberFunctionCallableImpl : public CallableImpl
00247     {
00248         typedef R (Class::*ConstMemberFunction) (P1) const;
00249 
00250         const Class             &object;
00251         ConstMemberFunction     function;
00252 
00253         ConstMemberFunctionCallableImpl() {}
00254         ConstMemberFunctionCallableImpl (const Class &o, ConstMemberFunction f)
00255         : object (o), function (f) {}
00256         ~ConstMemberFunctionCallableImpl() {}
00257 
00258         auto_ptr <CallableImpl> copy() const
00259         { return auto_ptr <CallableImpl>
00260                                 (new ConstMemberFunctionCallableImpl (*this)); }
00261 
00262         bool isEqualTo (const CallableImpl &other_)
00263         {
00264             const ConstMemberFunctionCallableImpl &other =
00265                 dynamic_cast <const ConstMemberFunctionCallableImpl &> (other_);
00266             return &other.object == &other.object
00267                     && other.function == other.function;
00268         }
00269 
00270         R doCall(P1 a1) { return (object.*function)(a1); }
00271     };
00272 
00273 public:
00274     typedef R       ReturnType;
00275     typedef P1      ParameterType1;
00276 
00277     Callable() : impl () {}
00278 
00279     Callable (const Callable &other) : impl (other.impl) {}
00280 
00281     Callable (Function f) : impl (FunctionCallableImpl (f)) {}
00282 
00283     template <typename Class>
00284     Callable (Class &o, R (Class::*f) (P1))
00285     : impl (MemberFunctionCallableImpl <Class> (o, f)) {}
00286 
00287     template <typename Class>
00288     Callable (Class *o, R (Class::*f) (P1))
00289     : impl (MemberFunctionCallableImpl <Class> (*o, f)) {}
00290 
00291     template <typename Class>
00292     Callable (const Class &o, R (Class::*f) (P1) const)
00293     : impl (ConstMemberFunctionCallableImpl <Class> (o, f)) {}
00294 
00295     template <typename Class>
00296     Callable (const Class *o, R (Class::*f) (P1) const)
00297     : impl (ConstMemberFunctionCallableImpl <Class> (*o, f)) {}
00298 
00299     R operator()(P1 a1) { return impl->doCall(a1); }
00300 
00301     bool operator== (const Callable &other) const { return impl == other.impl; }
00302 
00303     bool operator!= (const Callable &other) const { return impl != other.impl; }
00304 
00305 private:
00306     AbstractValue <CallableImpl, NullCallableImpl> impl;
00307 };
00308 
00309 template <typename R, typename P1, typename P2>
00310 class Callable <R (P1, P2)>
00311 {
00312     struct CallableImpl
00313     {
00314         virtual                         ~CallableImpl() {}
00315         virtual auto_ptr <CallableImpl> copy() const = 0;
00316         virtual bool                    isEqualTo (const CallableImpl &) = 0;
00317         virtual R                       doCall(P1, P2) = 0;
00318     };
00319 
00320     struct NullCallableImpl : public CallableImpl
00321     {
00322         NullCallableImpl() {}
00323         ~NullCallableImpl() {}
00324 
00325         auto_ptr <CallableImpl> copy() const
00326         { return auto_ptr <CallableImpl> (new NullCallableImpl ()); }
00327 
00328         bool isEqualTo (const CallableImpl &) { return true; }
00329         R doCall (P1 a1, P2 a2) { return R(a1, a2); }
00330     };
00331 
00332     typedef R (*Function)(P1, P2);
00333     struct FunctionCallableImpl : public CallableImpl
00334     {
00335         Function function;
00336 
00337         FunctionCallableImpl (Function f) : function (f) {}
00338         ~FunctionCallableImpl() {}
00339 
00340         auto_ptr <CallableImpl> copy() const
00341         { return auto_ptr <CallableImpl> (new FunctionCallableImpl (*this)); }
00342 
00343         bool isEqualTo (const CallableImpl &other_)
00344         {
00345             const FunctionCallableImpl &other =
00346                 dynamic_cast <const FunctionCallableImpl &> (other_);
00347             return other.function == other.function;
00348         }
00349 
00350         R doCall(P1 a1, P2 a2) { return function(a1, a2); }
00351     };
00352 
00353     template <typename Class>
00354     struct MemberFunctionCallableImpl : public CallableImpl
00355     {
00356         typedef R (Class::*MemberFunction) (P1, P2);
00357 
00358         Class           &object;
00359         MemberFunction  function;
00360 
00361         MemberFunctionCallableImpl() {}
00362         MemberFunctionCallableImpl (Class &o, MemberFunction f)
00363         : object (o), function (f) {}
00364         ~MemberFunctionCallableImpl() {}
00365 
00366         auto_ptr <CallableImpl> copy() const
00367         { return auto_ptr <CallableImpl>
00368                                     (new MemberFunctionCallableImpl (*this)); }
00369 
00370         bool isEqualTo (const CallableImpl &other_)
00371         {
00372             const MemberFunctionCallableImpl &other =
00373                 dynamic_cast <const MemberFunctionCallableImpl &> (other_);
00374             return &other.object == &other.object
00375                     && other.function == other.function;
00376         }
00377 
00378         R doCall(P1 a1, P2 a2) { return (object.*function)(a1, a2); }
00379     };
00380 
00381     template <typename Class>
00382     struct ConstMemberFunctionCallableImpl : public CallableImpl
00383     {
00384         typedef R (Class::*ConstMemberFunction) (P1, P2) const;
00385 
00386         const Class             &object;
00387         ConstMemberFunction     function;
00388 
00389         ConstMemberFunctionCallableImpl() {}
00390         ConstMemberFunctionCallableImpl (const Class &o, ConstMemberFunction f)
00391         : object (o), function (f) {}
00392         ~ConstMemberFunctionCallableImpl() {}
00393 
00394         auto_ptr <CallableImpl> copy() const
00395         { return auto_ptr <CallableImpl>
00396                                 (new ConstMemberFunctionCallableImpl (*this)); }
00397 
00398         bool isEqualTo (const CallableImpl &other_)
00399         {
00400             const ConstMemberFunctionCallableImpl &other =
00401                 dynamic_cast <const ConstMemberFunctionCallableImpl &> (other_);
00402             return &other.object == &other.object
00403                     && other.function == other.function;
00404         }
00405 
00406         R doCall(P1 a1, P2 a2) { return (object.*function)(a1, a2); }
00407     };
00408 
00409 public:
00410     typedef R       ReturnType;
00411     typedef P1      ParameterType1;
00412     typedef P2      ParameterType2;
00413 
00414     Callable() : impl () {}
00415 
00416     Callable (const Callable &other) : impl (other.impl) {}
00417 
00418     Callable (Function f) : impl (FunctionCallableImpl (f)) {}
00419 
00420     template <typename Class>
00421     Callable (Class &o, R (Class::*f) (P1, P2))
00422     : impl (MemberFunctionCallableImpl <Class> (o, f)) {}
00423 
00424     template <typename Class>
00425     Callable (Class *o, R (Class::*f) (P1, P2))
00426     : impl (MemberFunctionCallableImpl <Class> (*o, f)) {}
00427 
00428     template <typename Class>
00429     Callable (const Class &o, R (Class::*f) (P1, P2) const)
00430     : impl (ConstMemberFunctionCallableImpl <Class> (o, f)) {}
00431 
00432     template <typename Class>
00433     Callable (const Class *o, R (Class::*f) (P1, P2) const)
00434     : impl (ConstMemberFunctionCallableImpl <Class> (*o, f)) {}
00435 
00436     R operator()(P1 a1, P2 a2) { return impl->doCall(a1, a2); }
00437 
00438     bool operator== (const Callable &other) const { return impl == other.impl; }
00439 
00440     bool operator!= (const Callable &other) const { return impl != other.impl; }
00441 
00442 private:
00443     AbstractValue <CallableImpl, NullCallableImpl> impl;
00444 };
00445 
00446 template <typename R, typename P1, typename P2, typename P3>
00447 class Callable <R (P1, P2, P3)>
00448 {
00449     struct CallableImpl
00450     {
00451         virtual                         ~CallableImpl() {}
00452         virtual auto_ptr <CallableImpl> copy() const = 0;
00453         virtual bool                    isEqualTo (const CallableImpl &) = 0;
00454         virtual R                       doCall(P1, P2, P3) = 0;
00455     };
00456 
00457     struct NullCallableImpl : public CallableImpl
00458     {
00459         NullCallableImpl() {}
00460         ~NullCallableImpl() {}
00461 
00462         auto_ptr <CallableImpl> copy() const
00463         { return auto_ptr <CallableImpl> (new NullCallableImpl ()); }
00464 
00465         bool isEqualTo (const CallableImpl &) { return true; }
00466         R doCall (P1 a1, P2 a2, P3 a3) { return R(a1, a2, a3); }
00467     };
00468 
00469     typedef R (*Function)(P1, P2, P3);
00470     struct FunctionCallableImpl : public CallableImpl
00471     {
00472         Function function;
00473 
00474         FunctionCallableImpl (Function f) : function (f) {}
00475         ~FunctionCallableImpl() {}
00476 
00477         auto_ptr <CallableImpl> copy() const
00478         { return auto_ptr <CallableImpl> (new FunctionCallableImpl (*this)); }
00479 
00480         bool isEqualTo (const CallableImpl &other_)
00481         {
00482             const FunctionCallableImpl &other =
00483                 dynamic_cast <const FunctionCallableImpl &> (other_);
00484             return other.function == other.function;
00485         }
00486 
00487         R doCall(P1 a1, P2 a2, P3 a3) { return function(a1, a2, a3); }
00488     };
00489 
00490     template <typename Class>
00491     struct MemberFunctionCallableImpl : public CallableImpl
00492     {
00493         typedef R (Class::*MemberFunction) (P1, P2, P3);
00494 
00495         Class           &object;
00496         MemberFunction  function;
00497 
00498         MemberFunctionCallableImpl() {}
00499         MemberFunctionCallableImpl (Class &o, MemberFunction f)
00500         : object (o), function (f) {}
00501         ~MemberFunctionCallableImpl() {}
00502 
00503         auto_ptr <CallableImpl> copy() const
00504         { return auto_ptr <CallableImpl>
00505                                     (new MemberFunctionCallableImpl (*this)); }
00506 
00507         bool isEqualTo (const CallableImpl &other_)
00508         {
00509             const MemberFunctionCallableImpl &other =
00510                 dynamic_cast <const MemberFunctionCallableImpl &> (other_);
00511             return &other.object == &other.object
00512                     && other.function == other.function;
00513         }
00514 
00515         R doCall(P1 a1, P2 a2, P3 a3) { return (object.*function)(a1, a2, a3); }
00516     };
00517 
00518     template <typename Class>
00519     struct ConstMemberFunctionCallableImpl : public CallableImpl
00520     {
00521         typedef R (Class::*ConstMemberFunction) (P1, P2, P3) const;
00522 
00523         const Class             &object;
00524         ConstMemberFunction     function;
00525 
00526         ConstMemberFunctionCallableImpl() {}
00527         ConstMemberFunctionCallableImpl (const Class &o, ConstMemberFunction f)
00528         : object (o), function (f) {}
00529         ~ConstMemberFunctionCallableImpl() {}
00530 
00531         auto_ptr <CallableImpl> copy() const
00532         { return auto_ptr <CallableImpl>
00533                                 (new ConstMemberFunctionCallableImpl (*this)); }
00534 
00535         bool isEqualTo (const CallableImpl &other_)
00536         {
00537             const ConstMemberFunctionCallableImpl &other =
00538                 dynamic_cast <const ConstMemberFunctionCallableImpl &> (other_);
00539             return &other.object == &other.object
00540                     && other.function == other.function;
00541         }
00542 
00543         R doCall(P1 a1, P2 a2, P3 a3) { return (object.*function)(a1, a2, a3); }
00544     };
00545 
00546 public:
00547     typedef R       ReturnType;
00548     typedef P1      ParameterType1;
00549     typedef P2      ParameterType2;
00550     typedef P3      ParameterType3;
00551 
00552     Callable() : impl () {}
00553 
00554     Callable (const Callable &other) : impl (other.impl) {}
00555 
00556     Callable (Function f) : impl (FunctionCallableImpl (f)) {}
00557 
00558     template <typename Class>
00559     Callable (Class &o, R (Class::*f) (P1, P2, P3))
00560     : impl (MemberFunctionCallableImpl <Class> (o, f)) {}
00561 
00562     template <typename Class>
00563     Callable (Class *o, R (Class::*f) (P1, P2, P3))
00564     : impl (MemberFunctionCallableImpl <Class> (*o, f)) {}
00565 
00566     template <typename Class>
00567     Callable (const Class &o, R (Class::*f) (P1, P2, P3) const)
00568     : impl (ConstMemberFunctionCallableImpl <Class> (o, f)) {}
00569 
00570     template <typename Class>
00571     Callable (const Class *o, R (Class::*f) (P1, P2, P3) const)
00572     : impl (ConstMemberFunctionCallableImpl <Class> (*o, f)) {}
00573 
00574     R operator()(P1 a1, P2 a2, P3 a3) { return impl->doCall(a1, a2, a3); }
00575 
00576     bool operator== (const Callable &other) const { return impl == other.impl; }
00577 
00578     bool operator!= (const Callable &other) const { return impl != other.impl; }
00579 
00580 private:
00581     AbstractValue <CallableImpl, NullCallableImpl> impl;
00582 };
00583 
00584 template <typename R, typename P1, typename P2, typename P3, typename P4>
00585 class Callable <R (P1, P2, P3, P4)>
00586 {
00587     struct CallableImpl
00588     {
00589         virtual                         ~CallableImpl() {}
00590         virtual auto_ptr <CallableImpl> copy() const = 0;
00591         virtual bool                    isEqualTo (const CallableImpl &) = 0;
00592         virtual R                       doCall(P1, P2, P3, P4) = 0;
00593     };
00594 
00595     struct NullCallableImpl : public CallableImpl
00596     {
00597         NullCallableImpl() {}
00598         ~NullCallableImpl() {}
00599 
00600         auto_ptr <CallableImpl> copy() const
00601         { return auto_ptr <CallableImpl> (new NullCallableImpl ()); }
00602 
00603         bool isEqualTo (const CallableImpl &) { return true; }
00604         R doCall (P1 a1, P2 a2, P3 a3, P4 a4) { return R(a1, a2, a3, a4); }
00605     };
00606 
00607     typedef R (*Function)(P1, P2, P3, P4);
00608     struct FunctionCallableImpl : public CallableImpl
00609     {
00610         Function function;
00611 
00612         FunctionCallableImpl (Function f) : function (f) {}
00613         ~FunctionCallableImpl() {}
00614 
00615         auto_ptr <CallableImpl> copy() const
00616         { return auto_ptr <CallableImpl> (new FunctionCallableImpl (*this)); }
00617 
00618         bool isEqualTo (const CallableImpl &other_)
00619         {
00620             const FunctionCallableImpl &other =
00621                 dynamic_cast <const FunctionCallableImpl &> (other_);
00622             return other.function == other.function;
00623         }
00624 
00625         R doCall(P1 a1, P2 a2, P3 a3, P4 a4) { return function(a1, a2, a3, a4); }
00626     };
00627 
00628     template <typename Class>
00629     struct MemberFunctionCallableImpl : public CallableImpl
00630     {
00631         typedef R (Class::*MemberFunction) (P1, P2, P3, P4);
00632 
00633         Class           &object;
00634         MemberFunction  function;
00635 
00636         MemberFunctionCallableImpl() {}
00637         MemberFunctionCallableImpl (Class &o, MemberFunction f)
00638         : object (o), function (f) {}
00639         ~MemberFunctionCallableImpl() {}
00640 
00641         auto_ptr <CallableImpl> copy() const
00642         { return auto_ptr <CallableImpl>
00643                                     (new MemberFunctionCallableImpl (*this)); }
00644 
00645         bool isEqualTo (const CallableImpl &other_)
00646         {
00647             const MemberFunctionCallableImpl &other =
00648                 dynamic_cast <const MemberFunctionCallableImpl &> (other_);
00649             return &other.object == &other.object
00650                     && other.function == other.function;
00651         }
00652 
00653         R doCall(P1 a1, P2 a2, P3 a3, P4 a4) { return (object.*function)(a1, a2, a3, a4); }
00654     };
00655 
00656     template <typename Class>
00657     struct ConstMemberFunctionCallableImpl : public CallableImpl
00658     {
00659         typedef R (Class::*ConstMemberFunction) (P1, P2, P3, P4) const;
00660 
00661         const Class             &object;
00662         ConstMemberFunction     function;
00663 
00664         ConstMemberFunctionCallableImpl() {}
00665         ConstMemberFunctionCallableImpl (const Class &o, ConstMemberFunction f)
00666         : object (o), function (f) {}
00667         ~ConstMemberFunctionCallableImpl() {}
00668 
00669         auto_ptr <CallableImpl> copy() const
00670         { return auto_ptr <CallableImpl>
00671                                 (new ConstMemberFunctionCallableImpl (*this)); }
00672 
00673         bool isEqualTo (const CallableImpl &other_)
00674         {
00675             const ConstMemberFunctionCallableImpl &other =
00676                 dynamic_cast <const ConstMemberFunctionCallableImpl &> (other_);
00677             return &other.object == &other.object
00678                     && other.function == other.function;
00679         }
00680 
00681         R doCall(P1 a1, P2 a2, P3 a3, P4 a4) { return (object.*function)(a1, a2, a3, a4); }
00682     };
00683 
00684 public:
00685     typedef R       ReturnType;
00686     typedef P1      ParameterType1;
00687     typedef P2      ParameterType2;
00688     typedef P3      ParameterType3;
00689     typedef P4      ParameterType4;
00690 
00691     Callable() : impl () {}
00692 
00693     Callable (const Callable &other) : impl (other.impl) {}
00694 
00695     Callable (Function f) : impl (FunctionCallableImpl (f)) {}
00696 
00697     template <typename Class>
00698     Callable (Class &o, R (Class::*f) (P1, P2, P3, P4))
00699     : impl (MemberFunctionCallableImpl <Class> (o, f)) {}
00700 
00701     template <typename Class>
00702     Callable (Class *o, R (Class::*f) (P1, P2, P3, P4))
00703     : impl (MemberFunctionCallableImpl <Class> (*o, f)) {}
00704 
00705     template <typename Class>
00706     Callable (const Class &o, R (Class::*f) (P1, P2, P3, P4) const)
00707     : impl (ConstMemberFunctionCallableImpl <Class> (o, f)) {}
00708 
00709     template <typename Class>
00710     Callable (const Class *o, R (Class::*f) (P1, P2, P3, P4) const)
00711     : impl (ConstMemberFunctionCallableImpl <Class> (*o, f)) {}
00712 
00713     R operator()(P1 a1, P2 a2, P3 a3, P4 a4) { return impl->doCall(a1, a2, a3, a4); }
00714 
00715     bool operator== (const Callable &other) const { return impl == other.impl; }
00716 
00717     bool operator!= (const Callable &other) const { return impl != other.impl; }
00718 
00719 private:
00720     AbstractValue <CallableImpl, NullCallableImpl> impl;
00721 };
00722 
00723 template <typename R, typename P1, typename P2, typename P3, typename P4, typename P5>
00724 class Callable <R (P1, P2, P3, P4, P5)>
00725 {
00726     struct CallableImpl
00727     {
00728         virtual                         ~CallableImpl() {}
00729         virtual auto_ptr <CallableImpl> copy() const = 0;
00730         virtual bool                    isEqualTo (const CallableImpl &) = 0;
00731         virtual R                       doCall(P1, P2, P3, P4, P5) = 0;
00732     };
00733 
00734     struct NullCallableImpl : public CallableImpl
00735     {
00736         NullCallableImpl() {}
00737         ~NullCallableImpl() {}
00738 
00739         auto_ptr <CallableImpl> copy() const
00740         { return auto_ptr <CallableImpl> (new NullCallableImpl ()); }
00741 
00742         bool isEqualTo (const CallableImpl &) { return true; }
00743         R doCall (P1 a1, P2 a2, P3 a3, P4 a4, P5 a5) { return R(a1, a2, a3, a4, a5); }
00744     };
00745 
00746     typedef R (*Function)(P1, P2, P3, P4, P5);
00747     struct FunctionCallableImpl : public CallableImpl
00748     {
00749         Function function;
00750 
00751         FunctionCallableImpl (Function f) : function (f) {}
00752         ~FunctionCallableImpl() {}
00753 
00754         auto_ptr <CallableImpl> copy() const
00755         { return auto_ptr <CallableImpl> (new FunctionCallableImpl (*this)); }
00756 
00757         bool isEqualTo (const CallableImpl &other_)
00758         {
00759             const FunctionCallableImpl &other =
00760                 dynamic_cast <const FunctionCallableImpl &> (other_);
00761             return other.function == other.function;
00762         }
00763 
00764         R doCall(P1 a1, P2 a2, P3 a3, P4 a4, P5 a5) { return function(a1, a2, a3, a4, a5); }
00765     };
00766 
00767     template <typename Class>
00768     struct MemberFunctionCallableImpl : public CallableImpl
00769     {
00770         typedef R (Class::*MemberFunction) (P1, P2, P3, P4, P5);
00771 
00772         Class           &object;
00773         MemberFunction  function;
00774 
00775         MemberFunctionCallableImpl() {}
00776         MemberFunctionCallableImpl (Class &o, MemberFunction f)
00777         : object (o), function (f) {}
00778         ~MemberFunctionCallableImpl() {}
00779 
00780         auto_ptr <CallableImpl> copy() const
00781         { return auto_ptr <CallableImpl>
00782                                     (new MemberFunctionCallableImpl (*this)); }
00783 
00784         bool isEqualTo (const CallableImpl &other_)
00785         {
00786             const MemberFunctionCallableImpl &other =
00787                 dynamic_cast <const MemberFunctionCallableImpl &> (other_);
00788             return &other.object == &other.object
00789                     && other.function == other.function;
00790         }
00791 
00792         R doCall(P1 a1, P2 a2, P3 a3, P4 a4, P5 a5) { return (object.*function)(a1, a2, a3, a4, a5); }
00793     };
00794 
00795     template <typename Class>
00796     struct ConstMemberFunctionCallableImpl : public CallableImpl
00797     {
00798         typedef R (Class::*ConstMemberFunction) (P1, P2, P3, P4, P5) const;
00799 
00800         const Class             &object;
00801         ConstMemberFunction     function;
00802 
00803         ConstMemberFunctionCallableImpl() {}
00804         ConstMemberFunctionCallableImpl (const Class &o, ConstMemberFunction f)
00805         : object (o), function (f) {}
00806         ~ConstMemberFunctionCallableImpl() {}
00807 
00808         auto_ptr <CallableImpl> copy() const
00809         { return auto_ptr <CallableImpl>
00810                                 (new ConstMemberFunctionCallableImpl (*this)); }
00811 
00812         bool isEqualTo (const CallableImpl &other_)
00813         {
00814             const ConstMemberFunctionCallableImpl &other =
00815                 dynamic_cast <const ConstMemberFunctionCallableImpl &> (other_);
00816             return &other.object == &other.object
00817                     && other.function == other.function;
00818         }
00819 
00820         R doCall(P1 a1, P2 a2, P3 a3, P4 a4, P5 a5) { return (object.*function)(a1, a2, a3, a4, a5); }
00821     };
00822 
00823 public:
00824     typedef R       ReturnType;
00825     typedef P1      ParameterType1;
00826     typedef P2      ParameterType2;
00827     typedef P3      ParameterType3;
00828     typedef P4      ParameterType4;
00829     typedef P5      ParameterType5;
00830 
00831     Callable() : impl () {}
00832 
00833     Callable (const Callable &other) : impl (other.impl) {}
00834 
00835     Callable (Function f) : impl (FunctionCallableImpl (f)) {}
00836 
00837     template <typename Class>
00838     Callable (Class &o, R (Class::*f) (P1, P2, P3, P4, P5))
00839     : impl (MemberFunctionCallableImpl <Class> (o, f)) {}
00840 
00841     template <typename Class>
00842     Callable (Class *o, R (Class::*f) (P1, P2, P3, P4, P5))
00843     : impl (MemberFunctionCallableImpl <Class> (*o, f)) {}
00844 
00845     template <typename Class>
00846     Callable (const Class &o, R (Class::*f) (P1, P2, P3, P4, P5) const)
00847     : impl (ConstMemberFunctionCallableImpl <Class> (o, f)) {}
00848 
00849     template <typename Class>
00850     Callable (const Class *o, R (Class::*f) (P1, P2, P3, P4, P5) const)
00851     : impl (ConstMemberFunctionCallableImpl <Class> (*o, f)) {}
00852 
00853     R operator()(P1 a1, P2 a2, P3 a3, P4 a4, P5 a5) { return impl->doCall(a1, a2, a3, a4, a5); }
00854 
00855     bool operator== (const Callable &other) const { return impl == other.impl; }
00856 
00857     bool operator!= (const Callable &other) const { return impl != other.impl; }
00858 
00859 private:
00860     AbstractValue <CallableImpl, NullCallableImpl> impl;
00861 };
00862 
00863 template <typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
00864 class Callable <R (P1, P2, P3, P4, P5, P6)>
00865 {
00866     struct CallableImpl
00867     {
00868         virtual                         ~CallableImpl() {}
00869         virtual auto_ptr <CallableImpl> copy() const = 0;
00870         virtual bool                    isEqualTo (const CallableImpl &) = 0;
00871         virtual R                       doCall(P1, P2, P3, P4, P5, P6) = 0;
00872     };
00873 
00874     struct NullCallableImpl : public CallableImpl
00875     {
00876         NullCallableImpl() {}
00877         ~NullCallableImpl() {}
00878 
00879         auto_ptr <CallableImpl> copy() const
00880         { return auto_ptr <CallableImpl> (new NullCallableImpl ()); }
00881 
00882         bool isEqualTo (const CallableImpl &) { return true; }
00883         R doCall (P1 a1, P2 a2, P3 a3, P4 a4, P5 a5, P6 a6) { return R(a1, a2, a3, a4, a5, a6); }
00884     };
00885 
00886     typedef R (*Function)(P1, P2, P3, P4, P5, P6);
00887     struct FunctionCallableImpl : public CallableImpl
00888     {
00889         Function function;
00890 
00891         FunctionCallableImpl (Function f) : function (f) {}
00892         ~FunctionCallableImpl() {}
00893 
00894         auto_ptr <CallableImpl> copy() const
00895         { return auto_ptr <CallableImpl> (new FunctionCallableImpl (*this)); }
00896 
00897         bool isEqualTo (const CallableImpl &other_)
00898         {
00899             const FunctionCallableImpl &other =
00900                 dynamic_cast <const FunctionCallableImpl &> (other_);
00901             return other.function == other.function;
00902         }
00903 
00904         R doCall(P1 a1, P2 a2, P3 a3, P4 a4, P5 a5, P6 a6) { return function(a1, a2, a3, a4, a5, a6); }
00905     };
00906 
00907     template <typename Class>
00908     struct MemberFunctionCallableImpl : public CallableImpl
00909     {
00910         typedef R (Class::*MemberFunction) (P1, P2, P3, P4, P5, P6);
00911 
00912         Class           &object;
00913         MemberFunction  function;
00914 
00915         MemberFunctionCallableImpl() {}
00916         MemberFunctionCallableImpl (Class &o, MemberFunction f)
00917         : object (o), function (f) {}
00918         ~MemberFunctionCallableImpl() {}
00919 
00920         auto_ptr <CallableImpl> copy() const
00921         { return auto_ptr <CallableImpl>
00922                                     (new MemberFunctionCallableImpl (*this)); }
00923 
00924         bool isEqualTo (const CallableImpl &other_)
00925         {
00926             const MemberFunctionCallableImpl &other =
00927                 dynamic_cast <const MemberFunctionCallableImpl &> (other_);
00928             return &other.object == &other.object
00929                     && other.function == other.function;
00930         }
00931 
00932         R doCall(P1 a1, P2 a2, P3 a3, P4 a4, P5 a5, P6 a6) { return (object.*function)(a1, a2, a3, a4, a5, a6); }
00933     };
00934 
00935     template <typename Class>
00936     struct ConstMemberFunctionCallableImpl : public CallableImpl
00937     {
00938         typedef R (Class::*ConstMemberFunction) (P1, P2, P3, P4, P5, P6) const;
00939 
00940         const Class             &object;
00941         ConstMemberFunction     function;
00942 
00943         ConstMemberFunctionCallableImpl() {}
00944         ConstMemberFunctionCallableImpl (const Class &o, ConstMemberFunction f)
00945         : object (o), function (f) {}
00946         ~ConstMemberFunctionCallableImpl() {}
00947 
00948         auto_ptr <CallableImpl> copy() const
00949         { return auto_ptr <CallableImpl>
00950                                 (new ConstMemberFunctionCallableImpl (*this)); }
00951 
00952         bool isEqualTo (const CallableImpl &other_)
00953         {
00954             const ConstMemberFunctionCallableImpl &other =
00955                 dynamic_cast <const ConstMemberFunctionCallableImpl &> (other_);
00956             return &other.object == &other.object
00957                     && other.function == other.function;
00958         }
00959 
00960         R doCall(P1 a1, P2 a2, P3 a3, P4 a4, P5 a5, P6 a6) { return (object.*function)(a1, a2, a3, a4, a5, a6); }
00961     };
00962 
00963 public:
00964     typedef R       ReturnType;
00965     typedef P1      ParameterType1;
00966     typedef P2      ParameterType2;
00967     typedef P3      ParameterType3;
00968     typedef P4      ParameterType4;
00969     typedef P5      ParameterType5;
00970     typedef P6      ParameterType6;
00971 
00972     Callable() : impl () {}
00973 
00974     Callable (const Callable &other) : impl (other.impl) {}
00975 
00976     Callable (Function f) : impl (FunctionCallableImpl (f)) {}
00977 
00978     template <typename Class>
00979     Callable (Class &o, R (Class::*f) (P1, P2, P3, P4, P5, P6))
00980     : impl (MemberFunctionCallableImpl <Class> (o, f)) {}
00981 
00982     template <typename Class>
00983     Callable (Class *o, R (Class::*f) (P1, P2, P3, P4, P5, P6))
00984     : impl (MemberFunctionCallableImpl <Class> (*o, f)) {}
00985 
00986     template <typename Class>
00987     Callable (const Class &o, R (Class::*f) (P1, P2, P3, P4, P5, P6) const)
00988     : impl (ConstMemberFunctionCallableImpl <Class> (o, f)) {}
00989 
00990     template <typename Class>
00991     Callable (const Class *o, R (Class::*f) (P1, P2, P3, P4, P5, P6) const)
00992     : impl (ConstMemberFunctionCallableImpl <Class> (*o, f)) {}
00993 
00994     R operator()(P1 a1, P2 a2, P3 a3, P4 a4, P5 a5, P6 a6) { return impl->doCall(a1, a2, a3, a4, a5, a6); }
00995 
00996     bool operator== (const Callable &other) const { return impl == other.impl; }
00997 
00998     bool operator!= (const Callable &other) const { return impl != other.impl; }
00999 
01000 private:
01001     AbstractValue <CallableImpl, NullCallableImpl> impl;
01002 };
01003 
01004 template <typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
01005 class Callable <R (P1, P2, P3, P4, P5, P6, P7)>
01006 {
01007     struct CallableImpl
01008     {
01009         virtual                         ~CallableImpl() {}
01010         virtual auto_ptr <CallableImpl> copy() const = 0;
01011         virtual bool                    isEqualTo (const CallableImpl &) = 0;
01012         virtual R                       doCall(P1, P2, P3, P4, P5, P6, P7) = 0;
01013     };
01014 
01015     struct NullCallableImpl : public CallableImpl
01016     {
01017         NullCallableImpl() {}
01018         ~NullCallableImpl() {}
01019 
01020         auto_ptr <CallableImpl> copy() const
01021         { return auto_ptr <CallableImpl> (new NullCallableImpl ()); }
01022 
01023         bool isEqualTo (const CallableImpl &) { return true; }
01024         R doCall (P1 a1, P2 a2, P3 a3, P4 a4, P5 a5, P6 a6, P7 a7) { return R(a1, a2, a3, a4, a5, a6, a7); }
01025     };
01026 
01027     typedef R (*Function)(P1, P2, P3, P4, P5, P6, P7);
01028     struct FunctionCallableImpl : public CallableImpl
01029     {
01030         Function function;
01031 
01032         FunctionCallableImpl (Function f) : function (f) {}
01033         ~FunctionCallableImpl() {}
01034 
01035         auto_ptr <CallableImpl> copy() const
01036         { return auto_ptr <CallableImpl> (new FunctionCallableImpl (*this)); }
01037 
01038         bool isEqualTo (const CallableImpl &other_)
01039         {
01040             const FunctionCallableImpl &other =
01041                 dynamic_cast <const FunctionCallableImpl &> (other_);
01042             return other.function == other.function;
01043         }
01044 
01045         R doCall(P1 a1, P2 a2, P3 a3, P4 a4, P5 a5, P6 a6, P7 a7) { return function(a1, a2, a3, a4, a5, a6, a7); }
01046     };
01047 
01048     template <typename Class>
01049     struct MemberFunctionCallableImpl : public CallableImpl
01050     {
01051         typedef R (Class::*MemberFunction) (P1, P2, P3, P4, P5, P6, P7);
01052 
01053         Class           &object;
01054         MemberFunction  function;
01055 
01056         MemberFunctionCallableImpl() {}
01057         MemberFunctionCallableImpl (Class &o, MemberFunction f)
01058         : object (o), function (f) {}
01059         ~MemberFunctionCallableImpl() {}
01060 
01061         auto_ptr <CallableImpl> copy() const
01062         { return auto_ptr <CallableImpl>
01063                                     (new MemberFunctionCallableImpl (*this)); }
01064 
01065         bool isEqualTo (const CallableImpl &other_)
01066         {
01067             const MemberFunctionCallableImpl &other =
01068                 dynamic_cast <const MemberFunctionCallableImpl &> (other_);
01069             return &other.object == &other.object
01070                     && other.function == other.function;
01071         }
01072 
01073         R doCall(P1 a1, P2 a2, P3 a3, P4 a4, P5 a5, P6 a6, P7 a7) { return (object.*function)(a1, a2, a3, a4, a5, a6, a7); }
01074     };
01075 
01076     template <typename Class>
01077     struct ConstMemberFunctionCallableImpl : public CallableImpl
01078     {
01079         typedef R (Class::*ConstMemberFunction) (P1, P2, P3, P4, P5, P6, P7) const;
01080 
01081         const Class             &object;
01082         ConstMemberFunction     function;
01083 
01084         ConstMemberFunctionCallableImpl() {}
01085         ConstMemberFunctionCallableImpl (const Class &o, ConstMemberFunction f)
01086         : object (o), function (f) {}
01087         ~ConstMemberFunctionCallableImpl() {}
01088 
01089         auto_ptr <CallableImpl> copy() const
01090         { return auto_ptr <CallableImpl>
01091                                 (new ConstMemberFunctionCallableImpl (*this)); }
01092 
01093         bool isEqualTo (const CallableImpl &other_)
01094         {
01095             const ConstMemberFunctionCallableImpl &other =
01096                 dynamic_cast <const ConstMemberFunctionCallableImpl &> (other_);
01097             return &other.object == &other.object
01098                     && other.function == other.function;
01099         }
01100 
01101         R doCall(P1 a1, P2 a2, P3 a3, P4 a4, P5 a5, P6 a6, P7 a7) { return (object.*function)(a1, a2, a3, a4, a5, a6, a7); }
01102     };
01103 
01104 public:
01105     typedef R       ReturnType;
01106     typedef P1      ParameterType1;
01107     typedef P2      ParameterType2;
01108     typedef P3      ParameterType3;
01109     typedef P4      ParameterType4;
01110     typedef P5      ParameterType5;
01111     typedef P6      ParameterType6;
01112     typedef P7      ParameterType7;
01113 
01114     Callable() : impl () {}
01115 
01116     Callable (const Callable &other) : impl (other.impl) {}
01117 
01118     Callable (Function f) : impl (FunctionCallableImpl (f)) {}
01119 
01120     template <typename Class>
01121     Callable (Class &o, R (Class::*f) (P1, P2, P3, P4, P5, P6, P7))
01122     : impl (MemberFunctionCallableImpl <Class> (o, f)) {}
01123 
01124     template <typename Class>
01125     Callable (Class *o, R (Class::*f) (P1, P2, P3, P4, P5, P6, P7))
01126     : impl (MemberFunctionCallableImpl <Class> (*o, f)) {}
01127 
01128     template <typename Class>
01129     Callable (const Class &o, R (Class::*f) (P1, P2, P3, P4, P5, P6, P7) const)
01130     : impl (ConstMemberFunctionCallableImpl <Class> (o, f)) {}
01131 
01132     template <typename Class>
01133     Callable (const Class *o, R (Class::*f) (P1, P2, P3, P4, P5, P6, P7) const)
01134     : impl (ConstMemberFunctionCallableImpl <Class> (*o, f)) {}
01135 
01136     R operator()(P1 a1, P2 a2, P3 a3, P4 a4, P5 a5, P6 a6, P7 a7) { return impl->doCall(a1, a2, a3, a4, a5, a6, a7); }
01137 
01138     bool operator== (const Callable &other) const { return impl == other.impl; }
01139 
01140     bool operator!= (const Callable &other) const { return impl != other.impl; }
01141 
01142 private:
01143     AbstractValue <CallableImpl, NullCallableImpl> impl;
01144 };
01145 
01146 template <typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8>
01147 class Callable <R (P1, P2, P3, P4, P5, P6, P7, P8)>
01148 {
01149     struct CallableImpl
01150     {
01151         virtual                         ~CallableImpl() {}
01152         virtual auto_ptr <CallableImpl> copy() const = 0;
01153         virtual bool                    isEqualTo (const CallableImpl &) = 0;
01154         virtual R                       doCall(P1, P2, P3, P4, P5, P6, P7, P8) = 0;
01155     };
01156 
01157     struct NullCallableImpl : public CallableImpl
01158     {
01159         NullCallableImpl() {}
01160         ~NullCallableImpl() {}
01161 
01162         auto_ptr <CallableImpl> copy() const
01163         { return auto_ptr <CallableImpl> (new NullCallableImpl ()); }
01164 
01165         bool isEqualTo (const CallableImpl &) { return true; }
01166         R doCall (P1 a1, P2 a2, P3 a3, P4 a4, P5 a5, P6 a6, P7 a7, P8 a8) { return R(a1, a2, a3, a4, a5, a6, a7, a8); }
01167     };
01168 
01169     typedef R (*Function)(P1, P2, P3, P4, P5, P6, P7, P8);
01170     struct FunctionCallableImpl : public CallableImpl
01171     {
01172         Function function;
01173 
01174         FunctionCallableImpl (Function f) : function (f) {}
01175         ~FunctionCallableImpl() {}
01176 
01177         auto_ptr <CallableImpl> copy() const
01178         { return auto_ptr <CallableImpl> (new FunctionCallableImpl (*this)); }
01179 
01180         bool isEqualTo (const CallableImpl &other_)
01181         {
01182             const FunctionCallableImpl &other =
01183                 dynamic_cast <const FunctionCallableImpl &> (other_);
01184             return other.function == other.function;
01185         }
01186 
01187         R doCall(P1 a1, P2 a2, P3 a3, P4 a4, P5 a5, P6 a6, P7 a7, P8 a8) { return function(a1, a2, a3, a4, a5, a6, a7, a8); }
01188     };
01189 
01190     template <typename Class>
01191     struct MemberFunctionCallableImpl : public CallableImpl
01192     {
01193         typedef R (Class::*MemberFunction) (P1, P2, P3, P4, P5, P6, P7, P8);
01194 
01195         Class           &object;
01196         MemberFunction  function;
01197 
01198         MemberFunctionCallableImpl() {}
01199         MemberFunctionCallableImpl (Class &o, MemberFunction f)
01200         : object (o), function (f) {}
01201         ~MemberFunctionCallableImpl() {}
01202 
01203         auto_ptr <CallableImpl> copy() const
01204         { return auto_ptr <CallableImpl>
01205                                     (new MemberFunctionCallableImpl (*this)); }
01206 
01207         bool isEqualTo (const CallableImpl &other_)
01208         {
01209             const MemberFunctionCallableImpl &other =
01210                 dynamic_cast <const MemberFunctionCallableImpl &> (other_);
01211             return &other.object == &other.object
01212                     && other.function == other.function;
01213         }
01214 
01215         R doCall(P1 a1, P2 a2, P3 a3, P4 a4, P5 a5, P6 a6, P7 a7, P8 a8) { return (object.*function)(a1, a2, a3, a4, a5, a6, a7, a8); }
01216     };
01217 
01218     template <typename Class>
01219     struct ConstMemberFunctionCallableImpl : public CallableImpl
01220     {
01221         typedef R (Class::*ConstMemberFunction) (P1, P2, P3, P4, P5, P6, P7, P8) const;
01222 
01223         const Class             &object;
01224         ConstMemberFunction     function;
01225 
01226         ConstMemberFunctionCallableImpl() {}
01227         ConstMemberFunctionCallableImpl (const Class &o, ConstMemberFunction f)
01228         : object (o), function (f) {}
01229         ~ConstMemberFunctionCallableImpl() {}
01230 
01231         auto_ptr <CallableImpl> copy() const
01232         { return auto_ptr <CallableImpl>
01233                                 (new ConstMemberFunctionCallableImpl (*this)); }
01234 
01235         bool isEqualTo (const CallableImpl &other_)
01236         {
01237             const ConstMemberFunctionCallableImpl &other =
01238                 dynamic_cast <const ConstMemberFunctionCallableImpl &> (other_);
01239             return &other.object == &other.object
01240                     && other.function == other.function;
01241         }
01242 
01243         R doCall(P1 a1, P2 a2, P3 a3, P4 a4, P5 a5, P6 a6, P7 a7, P8 a8) { return (object.*function)(a1, a2, a3, a4, a5, a6, a7, a8); }
01244     };
01245 
01246 public:
01247     typedef R       ReturnType;
01248     typedef P1      ParameterType1;
01249     typedef P2      ParameterType2;
01250     typedef P3      ParameterType3;
01251     typedef P4      ParameterType4;
01252     typedef P5      ParameterType5;
01253     typedef P6      ParameterType6;
01254     typedef P7      ParameterType7;
01255     typedef P8      ParameterType8;
01256 
01257     Callable() : impl () {}
01258 
01259     Callable (const Callable &other) : impl (other.impl) {}
01260 
01261     Callable (Function f) : impl (FunctionCallableImpl (f)) {}
01262 
01263     template <typename Class>
01264     Callable (Class &o, R (Class::*f) (P1, P2, P3, P4, P5, P6, P7, P8))
01265     : impl (MemberFunctionCallableImpl <Class> (o, f)) {}
01266 
01267     template <typename Class>
01268     Callable (Class *o, R (Class::*f) (P1, P2, P3, P4, P5, P6, P7, P8))
01269     : impl (MemberFunctionCallableImpl <Class> (*o, f)) {}
01270 
01271     template <typename Class>
01272     Callable (const Class &o, R (Class::*f) (P1, P2, P3, P4, P5, P6, P7, P8) const)
01273     : impl (ConstMemberFunctionCallableImpl <Class> (o, f)) {}
01274 
01275     template <typename Class>
01276     Callable (const Class *o, R (Class::*f) (P1, P2, P3, P4, P5, P6, P7, P8) const)
01277     : impl (ConstMemberFunctionCallableImpl <Class> (*o, f)) {}
01278 
01279     R operator()(P1 a1, P2 a2, P3 a3, P4 a4, P5 a5, P6 a6, P7 a7, P8 a8) { return impl->doCall(a1, a2, a3, a4, a5, a6, a7, a8); }
01280 
01281     bool operator== (const Callable &other) const { return impl == other.impl; }
01282 
01283     bool operator!= (const Callable &other) const { return impl != other.impl; }
01284 
01285 private:
01286     AbstractValue <CallableImpl, NullCallableImpl> impl;
01287 };
01288 
01289 template <typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9>
01290 class Callable <R (P1, P2, P3, P4, P5, P6, P7, P8, P9)>
01291 {
01292     struct CallableImpl
01293     {
01294         virtual                         ~CallableImpl() {}
01295         virtual auto_ptr <CallableImpl> copy() const = 0;
01296         virtual bool                    isEqualTo (const CallableImpl &) = 0;
01297         virtual R                       doCall(P1, P2, P3, P4, P5, P6, P7, P8, P9) = 0;
01298     };
01299 
01300     struct NullCallableImpl : public CallableImpl
01301     {
01302         NullCallableImpl() {}
01303         ~NullCallableImpl() {}
01304 
01305         auto_ptr <CallableImpl> copy() const
01306         { return auto_ptr <CallableImpl> (new NullCallableImpl ()); }
01307 
01308         bool isEqualTo (const CallableImpl &) { return true; }
01309         R doCall (P1 a1, P2 a2, P3 a3, P4 a4, P5 a5, P6 a6, P7 a7, P8 a8, P9 a9) { return R(a1, a2, a3, a4, a5, a6, a7, a8, a9); }
01310     };
01311 
01312     typedef R (*Function)(P1, P2, P3, P4, P5, P6, P7, P8, P9);
01313     struct FunctionCallableImpl : public CallableImpl
01314     {
01315         Function function;
01316 
01317         FunctionCallableImpl (Function f) : function (f) {}
01318         ~FunctionCallableImpl() {}
01319 
01320         auto_ptr <CallableImpl> copy() const
01321         { return auto_ptr <CallableImpl> (new FunctionCallableImpl (*this)); }
01322 
01323         bool isEqualTo (const CallableImpl &other_)
01324         {
01325             const FunctionCallableImpl &other =
01326                 dynamic_cast <const FunctionCallableImpl &> (other_);
01327             return other.function == other.function;
01328         }
01329 
01330         R doCall(P1 a1, P2 a2, P3 a3, P4 a4, P5 a5, P6 a6, P7 a7, P8 a8, P9 a9) { return function(a1, a2, a3, a4, a5, a6, a7, a8, a9); }
01331     };
01332 
01333     template <typename Class>
01334     struct MemberFunctionCallableImpl : public CallableImpl
01335     {
01336         typedef R (Class::*MemberFunction) (P1, P2, P3, P4, P5, P6, P7, P8, P9);
01337 
01338         Class           &object;
01339         MemberFunction  function;
01340 
01341         MemberFunctionCallableImpl() {}
01342         MemberFunctionCallableImpl (Class &o, MemberFunction f)
01343         : object (o), function (f) {}
01344         ~MemberFunctionCallableImpl() {}
01345 
01346         auto_ptr <CallableImpl> copy() const
01347         { return auto_ptr <CallableImpl>
01348                                     (new MemberFunctionCallableImpl (*this)); }
01349 
01350         bool isEqualTo (const CallableImpl &other_)
01351         {
01352             const MemberFunctionCallableImpl &other =
01353                 dynamic_cast <const MemberFunctionCallableImpl &> (other_);
01354             return &other.object == &other.object
01355                     && other.function == other.function;
01356         }
01357 
01358         R doCall(P1 a1, P2 a2, P3 a3, P4 a4, P5 a5, P6 a6, P7 a7, P8 a8, P9 a9) { return (object.*function)(a1, a2, a3, a4, a5, a6, a7, a8, a9); }
01359     };
01360 
01361     template <typename Class>
01362     struct ConstMemberFunctionCallableImpl : public CallableImpl
01363     {
01364         typedef R (Class::*ConstMemberFunction) (P1, P2, P3, P4, P5, P6, P7, P8, P9) const;
01365 
01366         const Class             &object;
01367         ConstMemberFunction     function;
01368 
01369         ConstMemberFunctionCallableImpl() {}
01370         ConstMemberFunctionCallableImpl (const Class &o, ConstMemberFunction f)
01371         : object (o), function (f) {}
01372         ~ConstMemberFunctionCallableImpl() {}
01373 
01374         auto_ptr <CallableImpl> copy() const
01375         { return auto_ptr <CallableImpl>
01376                                 (new ConstMemberFunctionCallableImpl (*this)); }
01377 
01378         bool isEqualTo (const CallableImpl &other_)
01379         {
01380             const ConstMemberFunctionCallableImpl &other =
01381                 dynamic_cast <const ConstMemberFunctionCallableImpl &> (other_);
01382             return &other.object == &other.object
01383                     && other.function == other.function;
01384         }
01385 
01386         R doCall(P1 a1, P2 a2, P3 a3, P4 a4, P5 a5, P6 a6, P7 a7, P8 a8, P9 a9) { return (object.*function)(a1, a2, a3, a4, a5, a6, a7, a8, a9); }
01387     };
01388 
01389 public:
01390     typedef R       ReturnType;
01391     typedef P1      ParameterType1;
01392     typedef P2      ParameterType2;
01393     typedef P3      ParameterType3;
01394     typedef P4      ParameterType4;
01395     typedef P5      ParameterType5;
01396     typedef P6      ParameterType6;
01397     typedef P7      ParameterType7;
01398     typedef P8      ParameterType8;
01399     typedef P9      ParameterType9;
01400 
01401     Callable() : impl () {}
01402 
01403     Callable (const Callable &other) : impl (other.impl) {}
01404 
01405     Callable (Function f) : impl (FunctionCallableImpl (f)) {}
01406 
01407     template <typename Class>
01408     Callable (Class &o, R (Class::*f) (P1, P2, P3, P4, P5, P6, P7, P8, P9))
01409     : impl (MemberFunctionCallableImpl <Class> (o, f)) {}
01410 
01411     template <typename Class>
01412     Callable (Class *o, R (Class::*f) (P1, P2, P3, P4, P5, P6, P7, P8, P9))
01413     : impl (MemberFunctionCallableImpl <Class> (*o, f)) {}
01414 
01415     template <typename Class>
01416     Callable (const Class &o, R (Class::*f) (P1, P2, P3, P4, P5, P6, P7, P8, P9) const)
01417     : impl (ConstMemberFunctionCallableImpl <Class> (o, f)) {}
01418 
01419     template <typename Class>
01420     Callable (const Class *o, R (Class::*f) (P1, P2, P3, P4, P5, P6, P7, P8, P9) const)
01421     : impl (ConstMemberFunctionCallableImpl <Class> (*o, f)) {}
01422 
01423     R operator()(P1 a1, P2 a2, P3 a3, P4 a4, P5 a5, P6 a6, P7 a7, P8 a8, P9 a9) { return impl->doCall(a1, a2, a3, a4, a5, a6, a7, a8, a9); }
01424 
01425     bool operator== (const Callable &other) const { return impl == other.impl; }
01426 
01427     bool operator!= (const Callable &other) const { return impl != other.impl; }
01428 
01429 private:
01430     AbstractValue <CallableImpl, NullCallableImpl> impl;
01431 };
01432 
01433 
01434 } // namespace Utils
01435 
01436 #endif // UTILS__CALLABLE_H
01437