FastDelegate.h
Go to the documentation of this file.
00001 //                                              FastDelegate.h 
00002 //      Efficient delegates in C++ that generate only two lines of asm code!
00003 //  Documentation is found at http://www.codeproject.com/cpp/FastDelegate.asp
00004 //
00005 //                                              - Don Clugston, Mar 2004.
00006 //              Major contributions were made by Jody Hagins.
00007 // History:
00008 // 24-Apr-04 1.0  * Submitted to CodeProject. 
00009 // 28-Apr-04 1.1  * Prevent most unsafe uses of evil static function hack.
00010 //                                * Improved syntax for horrible_cast (thanks Paul Bludov).
00011 //                                * Tested on Metrowerks MWCC and Intel ICL (IA32)
00012 //                                * Compiled, but not run, on Comeau C++ and Intel Itanium ICL.
00013 //      27-Jun-04 1.2 * Now works on Borland C++ Builder 5.5
00014 //                                * Now works on /clr "managed C++" code on VC7, VC7.1
00015 //                                * Comeau C++ now compiles without warnings.
00016 //                                * Prevent the virtual inheritance case from being used on 
00017 //                                        VC6 and earlier, which generate incorrect code.
00018 //                                * Improved warning and error messages. Non-standard hacks
00019 //                                       now have compile-time checks to make them safer.
00020 //                                * implicit_cast used instead of static_cast in many cases.
00021 //                                * If calling a const member function, a const class pointer can be used.
00022 //                                * MakeDelegate() global helper function added to simplify pass-by-value.
00023 //                                * Added fastdelegate.clear()
00024 // 16-Jul-04 1.2.1* Workaround for gcc bug (const member function pointers in templates)
00025 // 30-Oct-04 1.3  * Support for (non-void) return values.
00026 //                                * No more workarounds in client code!
00027 //                                       MSVC and Intel now use a clever hack invented by John Dlugosz:
00028 //                                   - The FASTDELEGATEDECLARE workaround is no longer necessary.
00029 //                                       - No more warning messages for VC6
00030 //                                * Less use of macros. Error messages should be more comprehensible.
00031 //                                * Added include guards
00032 //                                * Added FastDelegate::empty() to test if invocation is safe (Thanks Neville Franks).
00033 //                                * Now tested on VS 2005 Express Beta, PGI C++
00034 // 24-Dec-04 1.4  * Added DelegateMemento, to allow collections of disparate delegates.
00035 //                * <,>,<=,>= comparison operators to allow storage in ordered containers.
00036 //                                * Substantial reduction of code size, especially the 'Closure' class.
00037 //                                * Standardised all the compiler-specific workarounds.
00038 //                * MFP conversion now works for CodePlay (but not yet supported in the full code).
00039 //                * Now compiles without warnings on _any_ supported compiler, including BCC 5.5.1
00040 //                                * New syntax: FastDelegate< int (char *, double) >. 
00041 // 14-Feb-05 1.4.1* Now treats =0 as equivalent to .clear(), ==0 as equivalent to .empty(). (Thanks elfric).
00042 //                                * Now tested on Intel ICL for AMD64, VS2005 Beta for AMD64 and Itanium.
00043 // 30-Mar-05 1.5  * Safebool idiom: "if (dg)" is now equivalent to "if (!dg.empty())"
00044 //                                * Fully supported by CodePlay VectorC
00045 //                * Bugfix for Metrowerks: empty() was buggy because a valid MFP can be 0 on MWCC!
00046 //                * More optimal assignment,== and != operators for static function pointers.
00047 
00048 #ifndef FASTDELEGATE_H
00049 #define FASTDELEGATE_H
00050 #if _MSC_VER > 1000
00051 #pragma once
00052 #endif // _MSC_VER > 1000
00053 
00054 #include <memory.h> // to allow <,> comparisons
00055 
00057 //                                              Configuration options
00058 //
00060 
00061 // Uncomment the following #define for optimally-sized delegates.
00062 // In this case, the generated asm code is almost identical to the code you'd get
00063 // if the compiler had native support for delegates.
00064 // It will not work on systems where sizeof(dataptr) < sizeof(codeptr). 
00065 // Thus, it will not work for DOS compilers using the medium model.
00066 // It will also probably fail on some DSP systems.
00067 #define FASTDELEGATE_USESTATICFUNCTIONHACK
00068 
00069 // Uncomment the next line to allow function declarator syntax.
00070 // It is automatically enabled for those compilers where it is known to work.
00071 //#define FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX
00072 
00074 //                                              Compiler identification for workarounds
00075 //
00077 
00078 // Compiler identification. It's not easy to identify Visual C++ because
00079 // many vendors fraudulently define Microsoft's identifiers.
00080 #if defined(_MSC_VER) && !defined(__MWERKS__) && !defined(__VECTOR_C) && !defined(__ICL) && !defined(__BORLANDC__)
00081 #define FASTDLGT_ISMSVC
00082 
00083 #if (_MSC_VER <1300) // Many workarounds are required for VC6.
00084 #define FASTDLGT_VC6
00085 #pragma warning(disable:4786) // disable this ridiculous warning
00086 #endif
00087 
00088 #endif
00089 
00090 // Does the compiler uses Microsoft's member function pointer structure?
00091 // If so, it needs special treatment.
00092 // Metrowerks CodeWarrior, Intel, and CodePlay fraudulently define Microsoft's 
00093 // identifier, _MSC_VER. We need to filter Metrowerks out.
00094 #if defined(_MSC_VER) && !defined(__MWERKS__)
00095 #define FASTDLGT_MICROSOFT_MFP
00096 
00097 #if !defined(__VECTOR_C)
00098 // CodePlay doesn't have the __single/multi/virtual_inheritance keywords
00099 #define FASTDLGT_HASINHERITANCE_KEYWORDS
00100 #endif
00101 #endif
00102 
00103 // Does it allow function declarator syntax? The following compilers are known to work:
00104 #if defined(FASTDLGT_ISMSVC) && (_MSC_VER >=1310) // VC 7.1
00105 #define FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX
00106 #endif
00107 
00108 // Gcc(2.95+), and versions of Digital Mars, Intel and Comeau in common use.
00109 #if defined (__DMC__) || defined(__GNUC__) || defined(__ICL) || defined(__COMO__)
00110 #define FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX
00111 #endif
00112 
00113 // It works on Metrowerks MWCC 3.2.2. From boost.Config it should work on earlier ones too.
00114 #if defined (__MWERKS__)
00115 #define FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX
00116 #endif
00117 
00118 #ifdef __GNUC__ // Workaround GCC bug #8271 
00119         // At present, GCC doesn't recognize constness of MFPs in templates
00120 #define FASTDELEGATE_GCC_BUG_8271
00121 #endif
00122 
00123 
00124 
00126 //                                              General tricks used in this code
00127 //
00128 // (a) Error messages are generated by typdefing an array of negative size to
00129 //     generate compile-time errors.
00130 // (b) Warning messages on MSVC are generated by declaring unused variables, and
00131 //          enabling the "variable XXX is never used" warning.
00132 // (c) Unions are used in a few compiler-specific cases to perform illegal casts.
00133 // (d) For Microsoft and Intel, when adjusting the 'this' pointer, it's cast to
00134 //     (char *) first to ensure that the correct number of *bytes* are added.
00135 //
00137 //                                              Helper templates
00138 //
00140 
00141 
00142 namespace fastdelegate {
00143 namespace detail {      // we'll hide the implementation details in a nested namespace.
00144 
00145 //              implicit_cast< >
00146 // I believe this was originally going to be in the C++ standard but 
00147 // was left out by accident. It's even milder than static_cast.
00148 // I use it instead of static_cast<> to emphasize that I'm not doing
00149 // anything nasty. 
00150 // Usage is identical to static_cast<>
00151 template <class OutputClass, class InputClass>
00152 inline OutputClass implicit_cast(InputClass input){
00153         return input;
00154 }
00155 
00156 //              horrible_cast< >
00157 // This is truly evil. It completely subverts C++'s type system, allowing you 
00158 // to cast from any class to any other class. Technically, using a union 
00159 // to perform the cast is undefined behaviour (even in C). But we can see if
00160 // it is OK by checking that the union is the same size as each of its members.
00161 // horrible_cast<> should only be used for compiler-specific workarounds. 
00162 // Usage is identical to reinterpret_cast<>.
00163 
00164 // This union is declared outside the horrible_cast because BCC 5.5.1
00165 // can't inline a function with a nested class, and gives a warning.
00166 template <class OutputClass, class InputClass>
00167 union horrible_union{
00168         OutputClass out;
00169         InputClass in;
00170 };
00171 
00172 template <class OutputClass, class InputClass>
00173 inline OutputClass horrible_cast(const InputClass input){
00174         horrible_union<OutputClass, InputClass> u;
00175         // Cause a compile-time error if in, out and u are not the same size.
00176         // If the compile fails here, it means the compiler has peculiar
00177         // unions which would prevent the cast from working.
00178         typedef int ERROR_CantUseHorrible_cast[sizeof(InputClass)==sizeof(u) 
00179                 && sizeof(InputClass)==sizeof(OutputClass) ? 1 : -1];
00180         u.in = input;
00181         return u.out;
00182 }
00183 
00185 //                                              Workarounds
00186 //
00188 
00189 // Backwards compatibility: This macro used to be necessary in the virtual inheritance
00190 // case for Intel and Microsoft. Now it just forward-declares the class.
00191 #define FASTDELEGATEDECLARE(CLASSNAME)  class CLASSNAME;
00192 
00193 // Prevent use of the static function hack with the DOS medium model.
00194 #ifdef __MEDIUM__
00195 #undef FASTDELEGATE_USESTATICFUNCTIONHACK
00196 #endif
00197 
00198 //                      DefaultVoid - a workaround for 'void' templates in VC6.
00199 //
00200 //  (1) VC6 and earlier do not allow 'void' as a default template argument.
00201 //  (2) They also doesn't allow you to return 'void' from a function.
00202 //
00203 // Workaround for (1): Declare a dummy type 'DefaultVoid' which we use
00204 //   when we'd like to use 'void'. We convert it into 'void' and back
00205 //   using the templates DefaultVoidToVoid<> and VoidToDefaultVoid<>.
00206 // Workaround for (2): On VC6, the code for calling a void function is
00207 //   identical to the code for calling a non-void function in which the
00208 //   return value is never used, provided the return value is returned
00209 //   in the EAX register, rather than on the stack. 
00210 //   This is true for most fundamental types such as int, enum, void *.
00211 //   Const void * is the safest option since it doesn't participate 
00212 //   in any automatic conversions. But on a 16-bit compiler it might
00213 //   cause extra code to be generated, so we disable it for all compilers
00214 //   except for VC6 (and VC5).
00215 #ifdef FASTDLGT_VC6
00216 // VC6 workaround
00217 typedef const void * DefaultVoid;
00218 #else
00219 // On any other compiler, just use a normal void.
00220 typedef void DefaultVoid;
00221 #endif
00222 
00223 // Translate from 'DefaultVoid' to 'void'.
00224 // Everything else is unchanged
00225 template <class T>
00226 struct DefaultVoidToVoid { typedef T type; };
00227 
00228 template <>
00229 struct DefaultVoidToVoid<DefaultVoid> { typedef void type; };
00230 
00231 // Translate from 'void' into 'DefaultVoid'
00232 // Everything else is unchanged
00233 template <class T>
00234 struct VoidToDefaultVoid { typedef T type; };
00235 
00236 template <>
00237 struct VoidToDefaultVoid<void> { typedef DefaultVoid type; };
00238 
00239 
00240 
00242 //                                              Fast Delegates, part 1:
00243 //
00244 //              Conversion of member function pointer to a standard form
00245 //
00247 
00248 // GenericClass is a fake class, ONLY used to provide a type.
00249 // It is vitally important that it is never defined, so that the compiler doesn't
00250 // think it can optimize the invocation. For example, Borland generates simpler
00251 // code if it knows the class only uses single inheritance.
00252 
00253 // Compilers using Microsoft's structure need to be treated as a special case.
00254 #ifdef  FASTDLGT_MICROSOFT_MFP
00255 
00256 #ifdef FASTDLGT_HASINHERITANCE_KEYWORDS
00257         // For Microsoft and Intel, we want to ensure that it's the most efficient type of MFP 
00258         // (4 bytes), even when the /vmg option is used. Declaring an empty class 
00259         // would give 16 byte pointers in this case....
00260         class __single_inheritance GenericClass;
00261 #endif
00262         // ...but for Codeplay, an empty class *always* gives 4 byte pointers.
00263         // If compiled with the /clr option ("managed C++"), the JIT compiler thinks
00264         // it needs to load GenericClass before it can call any of its functions,
00265         // (compiles OK but crashes at runtime!), so we need to declare an 
00266         // empty class to make it happy.
00267         // Codeplay and VC4 can't cope with the unknown_inheritance case either.
00268         class GenericClass {};
00269 #else
00270         class GenericClass;
00271 #endif
00272 
00273 // The size of a single inheritance member function pointer.
00274 const int SINGLE_MEMFUNCPTR_SIZE = sizeof(void (GenericClass::*)());
00275 
00276 //                                              SimplifyMemFunc< >::Convert()
00277 //
00278 //      A template function that converts an arbitrary member function pointer into the 
00279 //      simplest possible form of member function pointer, using a supplied 'this' pointer.
00280 //  According to the standard, this can be done legally with reinterpret_cast<>.
00281 //      For (non-standard) compilers which use member function pointers which vary in size 
00282 //  depending on the class, we need to use      knowledge of the internal structure of a 
00283 //  member function pointer, as used by the compiler. Template specialization is used
00284 //  to distinguish between the sizes. Because some compilers don't support partial 
00285 //      template specialisation, I use full specialisation of a wrapper struct.
00286 
00287 // general case -- don't know how to convert it. Force a compile failure
00288 template <int N>
00289 struct SimplifyMemFunc {
00290         template <class X, class XFuncType, class GenericMemFuncType>
00291         inline static GenericClass *Convert(X *pthis, XFuncType function_to_bind, 
00292                 GenericMemFuncType &bound_func) { 
00293                 // Unsupported member function type -- force a compile failure.
00294             // (it's illegal to have a array with negative size).
00295                 typedef char ERROR_Unsupported_member_function_pointer_on_this_compiler[N-100];
00296                 return 0; 
00297         }
00298 };
00299 
00300 // For compilers where all member func ptrs are the same size, everything goes here.
00301 // For non-standard compilers, only single_inheritance classes go here.
00302 template <>
00303 struct SimplifyMemFunc<SINGLE_MEMFUNCPTR_SIZE>  {       
00304         template <class X, class XFuncType, class GenericMemFuncType>
00305         inline static GenericClass *Convert(X *pthis, XFuncType function_to_bind, 
00306                         GenericMemFuncType &bound_func) {
00307 #if defined __DMC__  
00308                 // Digital Mars doesn't allow you to cast between abitrary PMF's, 
00309                 // even though the standard says you can. The 32-bit compiler lets you
00310                 // static_cast through an int, but the DOS compiler doesn't.
00311                 bound_func = horrible_cast<GenericMemFuncType>(function_to_bind);
00312 #else 
00313         bound_func = reinterpret_cast<GenericMemFuncType>(function_to_bind);
00314 #endif
00315         return reinterpret_cast<GenericClass *>(pthis);
00316         }
00317 };
00318 
00320 //                                              Fast Delegates, part 1b:
00321 //
00322 //                                      Workarounds for Microsoft and Intel
00323 //
00325 
00326 
00327 // Compilers with member function pointers which violate the standard (MSVC, Intel, Codeplay),
00328 // need to be treated as a special case.
00329 #ifdef FASTDLGT_MICROSOFT_MFP
00330 
00331 // We use unions to perform horrible_casts. I would like to use #pragma pack(push, 1)
00332 // at the start of each function for extra safety, but VC6 seems to ICE
00333 // intermittently if you do this inside a template.
00334 
00335 // __multiple_inheritance classes go here
00336 // Nasty hack for Microsoft and Intel (IA32 and Itanium)
00337 template<>
00338 struct SimplifyMemFunc< SINGLE_MEMFUNCPTR_SIZE + sizeof(int) >  {
00339         template <class X, class XFuncType, class GenericMemFuncType>
00340         inline static GenericClass *Convert(X *pthis, XFuncType function_to_bind, 
00341                 GenericMemFuncType &bound_func) { 
00342                 // We need to use a horrible_cast to do this conversion.
00343                 // In MSVC, a multiple inheritance member pointer is internally defined as:
00344         union {
00345                         XFuncType func;
00346                         struct {         
00347                                 GenericMemFuncType funcaddress; // points to the actual member function
00348                                 int delta;           // #BYTES to be added to the 'this' pointer
00349                         }s;
00350         } u;
00351                 // Check that the horrible_cast will work
00352                 typedef int ERROR_CantUsehorrible_cast[sizeof(function_to_bind)==sizeof(u.s)? 1 : -1];
00353         u.func = function_to_bind;
00354                 bound_func = u.s.funcaddress;
00355                 return reinterpret_cast<GenericClass *>(reinterpret_cast<char *>(pthis) + u.s.delta); 
00356         }
00357 };
00358 
00359 // virtual inheritance is a real nuisance. It's inefficient and complicated.
00360 // On MSVC and Intel, there isn't enough information in the pointer itself to
00361 // enable conversion to a closure pointer. Earlier versions of this code didn't
00362 // work for all cases, and generated a compile-time error instead.
00363 // But a very clever hack invented by John M. Dlugosz solves this problem.
00364 // My code is somewhat different to his: I have no asm code, and I make no 
00365 // assumptions about the calling convention that is used.
00366 
00367 // In VC++ and ICL, a virtual_inheritance member pointer 
00368 // is internally defined as:
00369 struct MicrosoftVirtualMFP {
00370         void (GenericClass::*codeptr)(); // points to the actual member function
00371         int delta;              // #bytes to be added to the 'this' pointer
00372         int vtable_index; // or 0 if no virtual inheritance
00373 };
00374 // The CRUCIAL feature of Microsoft/Intel MFPs which we exploit is that the
00375 // m_codeptr member is *always* called, regardless of the values of the other
00376 // members. (This is *not* true for other compilers, eg GCC, which obtain the
00377 // function address from the vtable if a virtual function is being called).
00378 // Dlugosz's trick is to make the codeptr point to a probe function which
00379 // returns the 'this' pointer that was used.
00380 
00381 // Define a generic class that uses virtual inheritance.
00382 // It has a trival member function that returns the value of the 'this' pointer.
00383 struct GenericVirtualClass : virtual public GenericClass
00384 {
00385         typedef GenericVirtualClass * (GenericVirtualClass::*ProbePtrType)();
00386         GenericVirtualClass * GetThis() { return this; }
00387 };
00388 
00389 // __virtual_inheritance classes go here
00390 template <>
00391 struct SimplifyMemFunc<SINGLE_MEMFUNCPTR_SIZE + 2*sizeof(int) >
00392 {
00393 
00394         template <class X, class XFuncType, class GenericMemFuncType>
00395         inline static GenericClass *Convert(X *pthis, XFuncType function_to_bind, 
00396                 GenericMemFuncType &bound_func) {
00397                 union {
00398                         XFuncType func;
00399                         GenericClass* (X::*ProbeFunc)();
00400                         MicrosoftVirtualMFP s;
00401                 } u;
00402                 u.func = function_to_bind;
00403                 bound_func = reinterpret_cast<GenericMemFuncType>(u.s.codeptr);
00404                 union {
00405                         GenericVirtualClass::ProbePtrType virtfunc;
00406                         MicrosoftVirtualMFP s;
00407                 } u2;
00408                 // Check that the horrible_cast<>s will work
00409                 typedef int ERROR_CantUsehorrible_cast[sizeof(function_to_bind)==sizeof(u.s)
00410                         && sizeof(function_to_bind)==sizeof(u.ProbeFunc)
00411                         && sizeof(u2.virtfunc)==sizeof(u2.s) ? 1 : -1];
00412    // Unfortunately, taking the address of a MF prevents it from being inlined, so 
00413    // this next line can't be completely optimised away by the compiler.
00414                 u2.virtfunc = &GenericVirtualClass::GetThis;
00415                 u.s.codeptr = u2.s.codeptr;
00416                 return (pthis->*u.ProbeFunc)();
00417         }
00418 };
00419 
00420 #if (_MSC_VER <1300)
00421 
00422 // Nasty hack for Microsoft Visual C++ 6.0
00423 // unknown_inheritance classes go here
00424 // There is a compiler bug in MSVC6 which generates incorrect code in this case!!
00425 template <>
00426 struct SimplifyMemFunc<SINGLE_MEMFUNCPTR_SIZE + 3*sizeof(int) >
00427 {
00428         template <class X, class XFuncType, class GenericMemFuncType>
00429         inline static GenericClass *Convert(X *pthis, XFuncType function_to_bind, 
00430                 GenericMemFuncType &bound_func) {
00431                 // There is an apalling but obscure compiler bug in MSVC6 and earlier:
00432                 // vtable_index and 'vtordisp' are always set to 0 in the 
00433                 // unknown_inheritance case!
00434                 // This means that an incorrect function could be called!!!
00435                 // Compiling with the /vmg option leads to potentially incorrect code.
00436                 // This is probably the reason that the IDE has a user interface for specifying
00437                 // the /vmg option, but it is disabled -  you can only specify /vmg on 
00438                 // the command line. In VC1.5 and earlier, the compiler would ICE if it ever
00439                 // encountered this situation.
00440                 // It is OK to use the /vmg option if /vmm or /vms is specified.
00441 
00442                 // Fortunately, the wrong function is only called in very obscure cases.
00443                 // It only occurs when a derived class overrides a virtual function declared 
00444                 // in a virtual base class, and the member function 
00445                 // points to the *Derived* version of that function. The problem can be
00446                 // completely averted in 100% of cases by using the *Base class* for the 
00447                 // member fpointer. Ie, if you use the base class as an interface, you'll
00448                 // stay out of trouble.
00449                 // Occasionally, you might want to point directly to a derived class function
00450                 // that isn't an override of a base class. In this case, both vtable_index 
00451                 // and 'vtordisp' are zero, but a virtual_inheritance pointer will be generated.
00452                 // We can generate correct code in this case. To prevent an incorrect call from
00453                 // ever being made, on MSVC6 we generate a warning, and call a function to 
00454                 // make the program crash instantly. 
00455                 typedef char ERROR_VC6CompilerBug[-100];
00456                 return 0; 
00457         }
00458 };
00459 
00460 
00461 #else 
00462 
00463 // Nasty hack for Microsoft and Intel (IA32 and Itanium)
00464 // unknown_inheritance classes go here 
00465 // This is probably the ugliest bit of code I've ever written. Look at the casts!
00466 // There is a compiler bug in MSVC6 which prevents it from using this code.
00467 template <>
00468 struct SimplifyMemFunc<SINGLE_MEMFUNCPTR_SIZE + 3*sizeof(int) >
00469 {
00470         template <class X, class XFuncType, class GenericMemFuncType>
00471         inline static GenericClass *Convert(X *pthis, XFuncType function_to_bind, 
00472                         GenericMemFuncType &bound_func) {
00473                 // The member function pointer is 16 bytes long. We can't use a normal cast, but
00474                 // we can use a union to do the conversion.
00475                 union {
00476                         XFuncType func;
00477                         // In VC++ and ICL, an unknown_inheritance member pointer 
00478                         // is internally defined as:
00479                         struct {
00480                                 GenericMemFuncType m_funcaddress; // points to the actual member function
00481                                 int delta;              // #bytes to be added to the 'this' pointer
00482                                 int vtordisp;           // #bytes to add to 'this' to find the vtable
00483                                 int vtable_index; // or 0 if no virtual inheritance
00484                         } s;
00485                 } u;
00486                 // Check that the horrible_cast will work
00487                 typedef int ERROR_CantUsehorrible_cast[sizeof(XFuncType)==sizeof(u.s)? 1 : -1];
00488                 u.func = function_to_bind;
00489                 bound_func = u.s.funcaddress;
00490                 int virtual_delta = 0;
00491                 if (u.s.vtable_index) { // Virtual inheritance is used
00492                         // First, get to the vtable. 
00493                         // It is 'vtordisp' bytes from the start of the class.
00494                         const int * vtable = *reinterpret_cast<const int *const*>(
00495                                 reinterpret_cast<const char *>(pthis) + u.s.vtordisp );
00496 
00497                         // 'vtable_index' tells us where in the table we should be looking.
00498                         virtual_delta = u.s.vtordisp + *reinterpret_cast<const int *>( 
00499                                 reinterpret_cast<const char *>(vtable) + u.s.vtable_index);
00500                 }
00501                 // The int at 'virtual_delta' gives us the amount to add to 'this'.
00502         // Finally we can add the three components together. Phew!
00503         return reinterpret_cast<GenericClass *>(
00504                         reinterpret_cast<char *>(pthis) + u.s.delta + virtual_delta);
00505         };
00506 };
00507 #endif // MSVC 7 and greater
00508 
00509 #endif // MS/Intel hacks
00510 
00511 }  // namespace detail
00512 
00514 //                                              Fast Delegates, part 2:
00515 //
00516 //      Define the delegate storage, and cope with static functions
00517 //
00519 
00520 // DelegateMemento -- an opaque structure which can hold an arbitary delegate.
00521 // It knows nothing about the calling convention or number of arguments used by
00522 // the function pointed to.
00523 // It supplies comparison operators so that it can be stored in STL collections.
00524 // It cannot be set to anything other than null, nor invoked directly: 
00525 //   it must be converted to a specific delegate.
00526 
00527 // Implementation:
00528 // There are two possible implementations: the Safe method and the Evil method.
00529 //                              DelegateMemento - Safe version
00530 //
00531 // This implementation is standard-compliant, but a bit tricky.
00532 // A static function pointer is stored inside the class. 
00533 // Here are the valid values:
00534 // +-- Static pointer --+--pThis --+-- pMemFunc-+-- Meaning------+
00535 // |   0                                |  0       |   0        | Empty          |
00536 // |   !=0              |(dontcare)|  Invoker   | Static function|
00537 // |   0                |  !=0     |  !=0*      | Method call    |
00538 // +--------------------+----------+------------+----------------+
00539 //  * For Metrowerks, this can be 0. (first virtual function in a 
00540 //       single_inheritance class).
00541 // When stored stored inside a specific delegate, the 'dontcare' entries are replaced
00542 // with a reference to the delegate itself. This complicates the = and == operators
00543 // for the delegate class.
00544 
00545 //                              DelegateMemento - Evil version
00546 //
00547 // For compilers where data pointers are at least as big as code pointers, it is 
00548 // possible to store the function pointer in the this pointer, using another 
00549 // horrible_cast. In this case the DelegateMemento implementation is simple:
00550 // +--pThis --+-- pMemFunc-+-- Meaning---------------------+
00551 // |    0     |  0         | Empty                         |
00552 // |  !=0     |  !=0*      | Static function or method call|
00553 // +----------+------------+-------------------------------+
00554 //  * For Metrowerks, this can be 0. (first virtual function in a 
00555 //       single_inheritance class).
00556 // Note that the Sun C++ and MSVC documentation explicitly state that they 
00557 // support static_cast between void * and function pointers.
00558 
00559 class DelegateMemento {
00560 protected: 
00561         // the data is protected, not private, because many
00562         // compilers have problems with template friends.
00563         typedef void (detail::GenericClass::*GenericMemFuncType)(); // arbitrary MFP.
00564         detail::GenericClass *m_pthis;
00565         GenericMemFuncType m_pFunction;
00566 
00567 #if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK)
00568         typedef void (*GenericFuncPtr)(); // arbitrary code pointer
00569         GenericFuncPtr m_pStaticFunction;
00570 #endif
00571 
00572 public:
00573 #if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK)
00574         DelegateMemento() : m_pthis(0), m_pFunction(0), m_pStaticFunction(0) {};
00575         void clear() {
00576                 m_pthis=0; m_pFunction=0; m_pStaticFunction=0;
00577         }
00578 #else
00579         DelegateMemento() : m_pthis(0), m_pFunction(0) {};
00580         void clear() {  m_pthis=0; m_pFunction=0;       }
00581 #endif
00582 public:
00583 #if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK)
00584         inline bool IsEqual (const DelegateMemento &x) const{
00585             // We have to cope with the static function pointers as a special case
00586                 if (m_pFunction!=x.m_pFunction) return false;
00587                 // the static function ptrs must either both be equal, or both be 0.
00588                 if (m_pStaticFunction!=x.m_pStaticFunction) return false;
00589                 if (m_pStaticFunction!=0) return m_pthis==x.m_pthis;
00590                 else return true;
00591         }
00592 #else // Evil Method
00593         inline bool IsEqual (const DelegateMemento &x) const{
00594                 return m_pthis==x.m_pthis && m_pFunction==x.m_pFunction;
00595         }
00596 #endif
00597         // Provide a strict weak ordering for DelegateMementos.
00598         inline bool IsLess(const DelegateMemento &right) const {
00599                 // deal with static function pointers first
00600 #if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK)
00601                 if (m_pStaticFunction !=0 || right.m_pStaticFunction!=0) 
00602                                 return m_pStaticFunction < right.m_pStaticFunction;
00603 #endif
00604                 if (m_pthis !=right.m_pthis) return m_pthis < right.m_pthis;
00605         // There are no ordering operators for member function pointers, 
00606         // but we can fake one by comparing each byte. The resulting ordering is
00607         // arbitrary (and compiler-dependent), but it permits storage in ordered STL containers.
00608                 return memcmp(&m_pFunction, &right.m_pFunction, sizeof(m_pFunction)) < 0;
00609 
00610         }
00611         // BUGFIX (Mar 2005):
00612         // We can't just compare m_pFunction because on Metrowerks,
00613         // m_pFunction can be zero even if the delegate is not empty!
00614         inline bool operator ! () const         // Is it bound to anything?
00615         { return m_pthis==0 && m_pFunction==0; }
00616         inline bool empty() const               // Is it bound to anything?
00617         { return m_pthis==0 && m_pFunction==0; }
00618 public:
00619         DelegateMemento & operator = (const DelegateMemento &right)  {
00620                 SetMementoFrom(right); 
00621                 return *this;
00622         }
00623         inline bool operator <(const DelegateMemento &right) {
00624                 return IsLess(right);
00625         }
00626         inline bool operator >(const DelegateMemento &right) {
00627                 return right.IsLess(*this);
00628         }
00629         DelegateMemento (const DelegateMemento &right)  : 
00630                 m_pFunction(right.m_pFunction), m_pthis(right.m_pthis)
00631 #if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK)
00632                 , m_pStaticFunction (right.m_pStaticFunction)
00633 #endif
00634                 {}
00635 protected:
00636         void SetMementoFrom(const DelegateMemento &right)  {
00637                 m_pFunction = right.m_pFunction;
00638                 m_pthis = right.m_pthis;
00639 #if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK)
00640                 m_pStaticFunction = right.m_pStaticFunction;
00641 #endif
00642         }
00643 };
00644 
00645 
00646 //                                              ClosurePtr<>
00647 //
00648 // A private wrapper class that adds function signatures to DelegateMemento.
00649 // It's the class that does most of the actual work.
00650 // The signatures are specified by:
00651 // GenericMemFunc: must be a type of GenericClass member function pointer. 
00652 // StaticFuncPtr:  must be a type of function pointer with the same signature 
00653 //                 as GenericMemFunc.
00654 // UnvoidStaticFuncPtr: is the same as StaticFuncPtr, except on VC6
00655 //                 where it never returns void (returns DefaultVoid instead).
00656 
00657 // An outer class, FastDelegateN<>, handles the invoking and creates the
00658 // necessary typedefs.
00659 // This class does everything else.
00660 
00661 namespace detail {
00662 
00663 template < class GenericMemFunc, class StaticFuncPtr, class UnvoidStaticFuncPtr>
00664 class ClosurePtr : public DelegateMemento {
00665 public:
00666         // These functions are for setting the delegate to a member function.
00667 
00668         // Here's the clever bit: we convert an arbitrary member function into a 
00669         // standard form. XMemFunc should be a member function of class X, but I can't 
00670         // enforce that here. It needs to be enforced by the wrapper class.
00671         template < class X, class XMemFunc >
00672         inline void bindmemfunc(X *pthis, XMemFunc function_to_bind ) {
00673                 m_pthis = SimplifyMemFunc< sizeof(function_to_bind) >
00674                         ::Convert(pthis, function_to_bind, m_pFunction);
00675 #if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK)
00676                 m_pStaticFunction = 0;
00677 #endif
00678         }
00679         // For const member functions, we only need a const class pointer.
00680         // Since we know that the member function is const, it's safe to 
00681         // remove the const qualifier from the 'this' pointer with a const_cast.
00682         // VC6 has problems if we just overload 'bindmemfunc', so we give it a different name.
00683         template < class X, class XMemFunc>
00684         inline void bindconstmemfunc(const X *pthis, XMemFunc function_to_bind) {
00685                 m_pthis= SimplifyMemFunc< sizeof(function_to_bind) >
00686                         ::Convert(const_cast<X*>(pthis), function_to_bind, m_pFunction);
00687 #if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK)
00688                 m_pStaticFunction = 0;
00689 #endif
00690         }
00691 #ifdef FASTDELEGATE_GCC_BUG_8271        // At present, GCC doesn't recognize constness of MFPs in templates
00692         template < class X, class XMemFunc>
00693         inline void bindmemfunc(const X *pthis, XMemFunc function_to_bind) {
00694                 bindconstmemfunc(pthis, function_to_bind);
00695 #if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK)
00696                 m_pStaticFunction = 0;
00697 #endif
00698         }
00699 #endif
00700         // These functions are required for invoking the stored function
00701         inline GenericClass *GetClosureThis() const { return m_pthis; }
00702         inline GenericMemFunc GetClosureMemPtr() const { return reinterpret_cast<GenericMemFunc>(m_pFunction); }
00703 
00704 // There are a few ways of dealing with static function pointers.
00705 // There's a standard-compliant, but tricky method.
00706 // There's also a straightforward hack, that won't work on DOS compilers using the
00707 // medium memory model. It's so evil that I can't recommend it, but I've
00708 // implemented it anyway because it produces very nice asm code.
00709 
00710 #if !defined(FASTDELEGATE_USESTATICFUNCTIONHACK)
00711 
00712 //                              ClosurePtr<> - Safe version
00713 //
00714 // This implementation is standard-compliant, but a bit tricky.
00715 // I store the function pointer inside the class, and the delegate then
00716 // points to itself. Whenever the delegate is copied, these self-references
00717 // must be transformed, and this complicates the = and == operators.
00718 public:
00719         // The next two functions are for operator ==, =, and the copy constructor.
00720         // We may need to convert the m_pthis pointers, so that
00721         // they remain as self-references.
00722         template< class DerivedClass >
00723         inline void CopyFrom (DerivedClass *pParent, const DelegateMemento &x) {
00724                 SetMementoFrom(x);
00725                 if (m_pStaticFunction!=0) {
00726                         // transform self references...
00727                         m_pthis=reinterpret_cast<GenericClass *>(pParent);
00728                 }
00729         }
00730         // For static functions, the 'static_function_invoker' class in the parent 
00731         // will be called. The parent then needs to call GetStaticFunction() to find out 
00732         // the actual function to invoke.
00733         template < class DerivedClass, class ParentInvokerSig >
00734         inline void bindstaticfunc(DerivedClass *pParent, ParentInvokerSig static_function_invoker, 
00735                                 StaticFuncPtr function_to_bind ) {
00736                 if (function_to_bind==0) { // cope with assignment to 0
00737                         m_pFunction=0;
00738                 } else { 
00739                         bindmemfunc(pParent, static_function_invoker);
00740         }
00741                 m_pStaticFunction=reinterpret_cast<GenericFuncPtr>(function_to_bind);
00742         }
00743         inline UnvoidStaticFuncPtr GetStaticFunction() const { 
00744                 return reinterpret_cast<UnvoidStaticFuncPtr>(m_pStaticFunction); 
00745         }
00746 #else
00747 
00748 //                              ClosurePtr<> - Evil version
00749 //
00750 // For compilers where data pointers are at least as big as code pointers, it is 
00751 // possible to store the function pointer in the this pointer, using another 
00752 // horrible_cast. Invocation isn't any faster, but it saves 4 bytes, and
00753 // speeds up comparison and assignment. If C++ provided direct language support
00754 // for delegates, they would produce asm code that was almost identical to this.
00755 // Note that the Sun C++ and MSVC documentation explicitly state that they 
00756 // support static_cast between void * and function pointers.
00757 
00758         template< class DerivedClass >
00759         inline void CopyFrom (DerivedClass *pParent, const DelegateMemento &right) {
00760                 SetMementoFrom(right);
00761         }
00762         // For static functions, the 'static_function_invoker' class in the parent 
00763         // will be called. The parent then needs to call GetStaticFunction() to find out 
00764         // the actual function to invoke.
00765         // ******** EVIL, EVIL CODE! *******
00766         template <      class DerivedClass, class ParentInvokerSig>
00767         inline void bindstaticfunc(DerivedClass *pParent, ParentInvokerSig static_function_invoker, 
00768                                 StaticFuncPtr function_to_bind) {
00769                 if (function_to_bind==0) { // cope with assignment to 0
00770                         m_pFunction=0;
00771                 } else { 
00772                    // We'll be ignoring the 'this' pointer, but we need to make sure we pass
00773                    // a valid value to bindmemfunc().
00774                         bindmemfunc(pParent, static_function_invoker);
00775         }
00776 
00777                 // WARNING! Evil hack. We store the function in the 'this' pointer!
00778                 // Ensure that there's a compilation failure if function pointers 
00779                 // and data pointers have different sizes.
00780                 // If you get this error, you need to #undef FASTDELEGATE_USESTATICFUNCTIONHACK.
00781                 typedef int ERROR_CantUseEvilMethod[sizeof(GenericClass *)==sizeof(function_to_bind) ? 1 : -1];
00782                 m_pthis = horrible_cast<GenericClass *>(function_to_bind);
00783                 // MSVC, SunC++ and DMC accept the following (non-standard) code:
00784 //              m_pthis = static_cast<GenericClass *>(static_cast<void *>(function_to_bind));
00785                 // BCC32, Comeau and DMC accept this method. MSVC7.1 needs __int64 instead of long
00786 //              m_pthis = reinterpret_cast<GenericClass *>(reinterpret_cast<long>(function_to_bind));
00787         }
00788         // ******** EVIL, EVIL CODE! *******
00789         // This function will be called with an invalid 'this' pointer!!
00790         // We're just returning the 'this' pointer, converted into
00791         // a function pointer!
00792         inline UnvoidStaticFuncPtr GetStaticFunction() const {
00793                 // Ensure that there's a compilation failure if function pointers 
00794                 // and data pointers have different sizes.
00795                 // If you get this error, you need to #undef FASTDELEGATE_USESTATICFUNCTIONHACK.
00796                 typedef int ERROR_CantUseEvilMethod[sizeof(UnvoidStaticFuncPtr)==sizeof(this) ? 1 : -1];
00797                 return horrible_cast<UnvoidStaticFuncPtr>(this);
00798         }
00799 #endif // !defined(FASTDELEGATE_USESTATICFUNCTIONHACK)
00800 
00801         // Does the closure contain this static function?
00802         inline bool IsEqualToStaticFuncPtr(StaticFuncPtr funcptr){
00803                 if (funcptr==0) return empty(); 
00804         // For the Evil method, if it doesn't actually contain a static function, this will return an arbitrary
00805         // value that is not equal to any valid function pointer.
00806                 else return funcptr==reinterpret_cast<StaticFuncPtr>(GetStaticFunction());
00807         }
00808 };
00809 
00810 
00811 } // namespace detail
00812 
00814 //                                              Fast Delegates, part 3:
00815 //
00816 //                              Wrapper classes to ensure type safety
00817 //
00819 
00820 
00821 // Once we have the member function conversion templates, it's easy to make the
00822 // wrapper classes. So that they will work with as many compilers as possible, 
00823 // the classes are of the form
00824 //   FastDelegate3<int, char *, double>
00825 // They can cope with any combination of parameters. The max number of parameters
00826 // allowed is 8, but it is trivial to increase this limit.
00827 // Note that we need to treat const member functions seperately.
00828 // All this class does is to enforce type safety, and invoke the delegate with
00829 // the correct list of parameters.
00830 
00831 // Because of the weird rule about the class of derived member function pointers,
00832 // you sometimes need to apply a downcast to the 'this' pointer.
00833 // This is the reason for the use of "implicit_cast<X*>(pthis)" in the code below. 
00834 // If CDerivedClass is derived from CBaseClass, but doesn't override SimpleVirtualFunction,
00835 // without this trick you'd need to write:
00836 //              MyDelegate(static_cast<CBaseClass *>(&d), &CDerivedClass::SimpleVirtualFunction);
00837 // but with the trick you can write
00838 //              MyDelegate(&d, &CDerivedClass::SimpleVirtualFunction);
00839 
00840 // RetType is the type the compiler uses in compiling the template. For VC6,
00841 // it cannot be void. DesiredRetType is the real type which is returned from
00842 // all of the functions. It can be void.
00843 
00844 // Implicit conversion to "bool" is achieved using the safe_bool idiom,
00845 // using member data pointers (MDP). This allows "if (dg)..." syntax
00846 // Because some compilers (eg codeplay) don't have a unique value for a zero
00847 // MDP, an extra padding member is added to the SafeBool struct.
00848 // Some compilers (eg VC6) won't implicitly convert from 0 to an MDP, so
00849 // in that case the static function constructor is not made explicit; this
00850 // allows "if (dg==0) ..." to compile.
00851 
00852 //N=0
00853 template<class RetType=detail::DefaultVoid>
00854 class FastDelegate0 {
00855 private:
00856         typedef typename detail::DefaultVoidToVoid<RetType>::type DesiredRetType;
00857         typedef DesiredRetType (*StaticFunctionPtr)();
00858         typedef RetType (*UnvoidStaticFunctionPtr)();
00859         typedef RetType (detail::GenericClass::*GenericMemFn)();
00860         typedef detail::ClosurePtr<GenericMemFn, StaticFunctionPtr, UnvoidStaticFunctionPtr> ClosureType;
00861         ClosureType m_Closure;
00862 public:
00863         // Typedefs to aid generic programming
00864         typedef FastDelegate0 type;
00865 
00866         // Construction and comparison functions
00867         FastDelegate0() { clear(); }
00868         FastDelegate0(const FastDelegate0 &x) {
00869                 m_Closure.CopyFrom(this, x.m_Closure); }
00870         void operator = (const FastDelegate0 &x)  {
00871                 m_Closure.CopyFrom(this, x.m_Closure); }
00872         bool operator ==(const FastDelegate0 &x) const {
00873                 return m_Closure.IsEqual(x.m_Closure);  }
00874         bool operator !=(const FastDelegate0 &x) const {
00875                 return !m_Closure.IsEqual(x.m_Closure); }
00876         bool operator <(const FastDelegate0 &x) const {
00877                 return m_Closure.IsLess(x.m_Closure);   }
00878         bool operator >(const FastDelegate0 &x) const {
00879                 return x.m_Closure.IsLess(m_Closure);   }
00880         // Binding to non-const member functions
00881         template < class X, class Y >
00882         FastDelegate0(Y *pthis, DesiredRetType (X::* function_to_bind)() ) {
00883                 m_Closure.bindmemfunc(detail::implicit_cast<X*>(pthis), function_to_bind); }
00884         template < class X, class Y >
00885         inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)()) {
00886                 m_Closure.bindmemfunc(detail::implicit_cast<X*>(pthis), function_to_bind);      }
00887         // Binding to const member functions.
00888         template < class X, class Y >
00889         FastDelegate0(const Y *pthis, DesiredRetType (X::* function_to_bind)() const) {
00890                 m_Closure.bindconstmemfunc(detail::implicit_cast<const X*>(pthis), function_to_bind);   }
00891         template < class X, class Y >
00892         inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)() const) {
00893                 m_Closure.bindconstmemfunc(detail::implicit_cast<const X *>(pthis), function_to_bind);  }
00894         // Static functions. We convert them into a member function call.
00895         // This constructor also provides implicit conversion
00896         FastDelegate0(DesiredRetType (*function_to_bind)() ) {
00897                 bind(function_to_bind); }
00898         // for efficiency, prevent creation of a temporary
00899         void operator = (DesiredRetType (*function_to_bind)() ) {
00900                 bind(function_to_bind); }
00901         inline void bind(DesiredRetType (*function_to_bind)()) {
00902                 m_Closure.bindstaticfunc(this, &FastDelegate0::InvokeStaticFunction, 
00903                         function_to_bind); }
00904         // Invoke the delegate
00905         RetType operator() () const {
00906         return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(); }
00907         // Implicit conversion to "bool" using the safe_bool idiom
00908 private:
00909         typedef struct SafeBoolStruct {
00910                 int a_data_pointer_to_this_is_0_on_buggy_compilers;
00911                 StaticFunctionPtr m_nonzero;
00912         } UselessTypedef;
00913     typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type;
00914 public:
00915         operator unspecified_bool_type() const {
00916         return empty()? 0: &SafeBoolStruct::m_nonzero;
00917     }
00918         // necessary to allow ==0 to work despite the safe_bool idiom
00919         inline bool operator==(StaticFunctionPtr funcptr) {
00920                 return m_Closure.IsEqualToStaticFuncPtr(funcptr);       }
00921         inline bool operator!=(StaticFunctionPtr funcptr) { 
00922                 return !m_Closure.IsEqualToStaticFuncPtr(funcptr);    }
00923         inline bool operator ! () const {       // Is it bound to anything?
00924                         return !m_Closure; }
00925         inline bool empty() const       {
00926                         return !m_Closure; }
00927         void clear() { m_Closure.clear();}
00928         // Conversion to and from the DelegateMemento storage class
00929         const DelegateMemento & GetMemento() { return m_Closure; }
00930         void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); }
00931 
00932 private:        // Invoker for static functions
00933         RetType InvokeStaticFunction() const {
00934         return (*(m_Closure.GetStaticFunction()))(); }
00935 };
00936 
00937 //N=1
00938 template<class Param1, class RetType=detail::DefaultVoid>
00939 class FastDelegate1 {
00940 private:
00941         typedef typename detail::DefaultVoidToVoid<RetType>::type DesiredRetType;
00942         typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1);
00943         typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1);
00944         typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1);
00945         typedef detail::ClosurePtr<GenericMemFn, StaticFunctionPtr, UnvoidStaticFunctionPtr> ClosureType;
00946         ClosureType m_Closure;
00947 public:
00948         // Typedefs to aid generic programming
00949         typedef FastDelegate1 type;
00950 
00951         // Construction and comparison functions
00952         FastDelegate1() { clear(); }
00953         FastDelegate1(const FastDelegate1 &x) {
00954                 m_Closure.CopyFrom(this, x.m_Closure); }
00955         void operator = (const FastDelegate1 &x)  {
00956                 m_Closure.CopyFrom(this, x.m_Closure); }
00957         bool operator ==(const FastDelegate1 &x) const {
00958                 return m_Closure.IsEqual(x.m_Closure);  }
00959         bool operator !=(const FastDelegate1 &x) const {
00960                 return !m_Closure.IsEqual(x.m_Closure); }
00961         bool operator <(const FastDelegate1 &x) const {
00962                 return m_Closure.IsLess(x.m_Closure);   }
00963         bool operator >(const FastDelegate1 &x) const {
00964                 return x.m_Closure.IsLess(m_Closure);   }
00965         // Binding to non-const member functions
00966         template < class X, class Y >
00967         FastDelegate1(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1) ) {
00968                 m_Closure.bindmemfunc(detail::implicit_cast<X*>(pthis), function_to_bind); }
00969         template < class X, class Y >
00970         inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1)) {
00971                 m_Closure.bindmemfunc(detail::implicit_cast<X*>(pthis), function_to_bind);      }
00972         // Binding to const member functions.
00973         template < class X, class Y >
00974         FastDelegate1(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1) const) {
00975                 m_Closure.bindconstmemfunc(detail::implicit_cast<const X*>(pthis), function_to_bind);   }
00976         template < class X, class Y >
00977         inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1) const) {
00978                 m_Closure.bindconstmemfunc(detail::implicit_cast<const X *>(pthis), function_to_bind);  }
00979         // Static functions. We convert them into a member function call.
00980         // This constructor also provides implicit conversion
00981         FastDelegate1(DesiredRetType (*function_to_bind)(Param1 p1) ) {
00982                 bind(function_to_bind); }
00983         // for efficiency, prevent creation of a temporary
00984         void operator = (DesiredRetType (*function_to_bind)(Param1 p1) ) {
00985                 bind(function_to_bind); }
00986         inline void bind(DesiredRetType (*function_to_bind)(Param1 p1)) {
00987                 m_Closure.bindstaticfunc(this, &FastDelegate1::InvokeStaticFunction, 
00988                         function_to_bind); }
00989         // Invoke the delegate
00990         RetType operator() (Param1 p1) const {
00991         return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1); }
00992         // Implicit conversion to "bool" using the safe_bool idiom
00993 private:
00994         typedef struct SafeBoolStruct {
00995                 int a_data_pointer_to_this_is_0_on_buggy_compilers;
00996                 StaticFunctionPtr m_nonzero;
00997         } UselessTypedef;
00998     typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type;
00999 public:
01000         operator unspecified_bool_type() const {
01001         return empty()? 0: &SafeBoolStruct::m_nonzero;
01002     }
01003         // necessary to allow ==0 to work despite the safe_bool idiom
01004         inline bool operator==(StaticFunctionPtr funcptr) {
01005                 return m_Closure.IsEqualToStaticFuncPtr(funcptr);       }
01006         inline bool operator!=(StaticFunctionPtr funcptr) { 
01007                 return !m_Closure.IsEqualToStaticFuncPtr(funcptr);    }
01008         inline bool operator ! () const {       // Is it bound to anything?
01009                         return !m_Closure; }
01010         inline bool empty() const       {
01011                         return !m_Closure; }
01012         void clear() { m_Closure.clear();}
01013         // Conversion to and from the DelegateMemento storage class
01014         const DelegateMemento & GetMemento() { return m_Closure; }
01015         void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); }
01016 
01017 private:        // Invoker for static functions
01018         RetType InvokeStaticFunction(Param1 p1) const {
01019         return (*(m_Closure.GetStaticFunction()))(p1); }
01020 };
01021 
01022 //N=2
01023 template<class Param1, class Param2, class RetType=detail::DefaultVoid>
01024 class FastDelegate2 {
01025 private:
01026         typedef typename detail::DefaultVoidToVoid<RetType>::type DesiredRetType;
01027         typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2);
01028         typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2);
01029         typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2);
01030         typedef detail::ClosurePtr<GenericMemFn, StaticFunctionPtr, UnvoidStaticFunctionPtr> ClosureType;
01031         ClosureType m_Closure;
01032 public:
01033         // Typedefs to aid generic programming
01034         typedef FastDelegate2 type;
01035 
01036         // Construction and comparison functions
01037         FastDelegate2() { clear(); }
01038         FastDelegate2(const FastDelegate2 &x) {
01039                 m_Closure.CopyFrom(this, x.m_Closure); }
01040         void operator = (const FastDelegate2 &x)  {
01041                 m_Closure.CopyFrom(this, x.m_Closure); }
01042         bool operator ==(const FastDelegate2 &x) const {
01043                 return m_Closure.IsEqual(x.m_Closure);  }
01044         bool operator !=(const FastDelegate2 &x) const {
01045                 return !m_Closure.IsEqual(x.m_Closure); }
01046         bool operator <(const FastDelegate2 &x) const {
01047                 return m_Closure.IsLess(x.m_Closure);   }
01048         bool operator >(const FastDelegate2 &x) const {
01049                 return x.m_Closure.IsLess(m_Closure);   }
01050         // Binding to non-const member functions
01051         template < class X, class Y >
01052         FastDelegate2(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2) ) {
01053                 m_Closure.bindmemfunc(detail::implicit_cast<X*>(pthis), function_to_bind); }
01054         template < class X, class Y >
01055         inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2)) {
01056                 m_Closure.bindmemfunc(detail::implicit_cast<X*>(pthis), function_to_bind);      }
01057         // Binding to const member functions.
01058         template < class X, class Y >
01059         FastDelegate2(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2) const) {
01060                 m_Closure.bindconstmemfunc(detail::implicit_cast<const X*>(pthis), function_to_bind);   }
01061         template < class X, class Y >
01062         inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2) const) {
01063                 m_Closure.bindconstmemfunc(detail::implicit_cast<const X *>(pthis), function_to_bind);  }
01064         // Static functions. We convert them into a member function call.
01065         // This constructor also provides implicit conversion
01066         FastDelegate2(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2) ) {
01067                 bind(function_to_bind); }
01068         // for efficiency, prevent creation of a temporary
01069         void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2) ) {
01070                 bind(function_to_bind); }
01071         inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2)) {
01072                 m_Closure.bindstaticfunc(this, &FastDelegate2::InvokeStaticFunction, 
01073                         function_to_bind); }
01074         // Invoke the delegate
01075         RetType operator() (Param1 p1, Param2 p2) const {
01076         return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2); }
01077         // Implicit conversion to "bool" using the safe_bool idiom
01078 private:
01079         typedef struct SafeBoolStruct {
01080                 int a_data_pointer_to_this_is_0_on_buggy_compilers;
01081                 StaticFunctionPtr m_nonzero;
01082         } UselessTypedef;
01083     typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type;
01084 public:
01085         operator unspecified_bool_type() const {
01086         return empty()? 0: &SafeBoolStruct::m_nonzero;
01087     }
01088         // necessary to allow ==0 to work despite the safe_bool idiom
01089         inline bool operator==(StaticFunctionPtr funcptr) {
01090                 return m_Closure.IsEqualToStaticFuncPtr(funcptr);       }
01091         inline bool operator!=(StaticFunctionPtr funcptr) { 
01092                 return !m_Closure.IsEqualToStaticFuncPtr(funcptr);    }
01093         inline bool operator ! () const {       // Is it bound to anything?
01094                         return !m_Closure; }
01095         inline bool empty() const       {
01096                         return !m_Closure; }
01097         void clear() { m_Closure.clear();}
01098         // Conversion to and from the DelegateMemento storage class
01099         const DelegateMemento & GetMemento() { return m_Closure; }
01100         void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); }
01101 
01102 private:        // Invoker for static functions
01103         RetType InvokeStaticFunction(Param1 p1, Param2 p2) const {
01104         return (*(m_Closure.GetStaticFunction()))(p1, p2); }
01105 };
01106 
01107 //N=3
01108 template<class Param1, class Param2, class Param3, class RetType=detail::DefaultVoid>
01109 class FastDelegate3 {
01110 private:
01111         typedef typename detail::DefaultVoidToVoid<RetType>::type DesiredRetType;
01112         typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3);
01113         typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3);
01114         typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3);
01115         typedef detail::ClosurePtr<GenericMemFn, StaticFunctionPtr, UnvoidStaticFunctionPtr> ClosureType;
01116         ClosureType m_Closure;
01117 public:
01118         // Typedefs to aid generic programming
01119         typedef FastDelegate3 type;
01120 
01121         // Construction and comparison functions
01122         FastDelegate3() { clear(); }
01123         FastDelegate3(const FastDelegate3 &x) {
01124                 m_Closure.CopyFrom(this, x.m_Closure); }
01125         void operator = (const FastDelegate3 &x)  {
01126                 m_Closure.CopyFrom(this, x.m_Closure); }
01127         bool operator ==(const FastDelegate3 &x) const {
01128                 return m_Closure.IsEqual(x.m_Closure);  }
01129         bool operator !=(const FastDelegate3 &x) const {
01130                 return !m_Closure.IsEqual(x.m_Closure); }
01131         bool operator <(const FastDelegate3 &x) const {
01132                 return m_Closure.IsLess(x.m_Closure);   }
01133         bool operator >(const FastDelegate3 &x) const {
01134                 return x.m_Closure.IsLess(m_Closure);   }
01135         // Binding to non-const member functions
01136         template < class X, class Y >
01137         FastDelegate3(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3) ) {
01138                 m_Closure.bindmemfunc(detail::implicit_cast<X*>(pthis), function_to_bind); }
01139         template < class X, class Y >
01140         inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3)) {
01141                 m_Closure.bindmemfunc(detail::implicit_cast<X*>(pthis), function_to_bind);      }
01142         // Binding to const member functions.
01143         template < class X, class Y >
01144         FastDelegate3(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3) const) {
01145                 m_Closure.bindconstmemfunc(detail::implicit_cast<const X*>(pthis), function_to_bind);   }
01146         template < class X, class Y >
01147         inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3) const) {
01148                 m_Closure.bindconstmemfunc(detail::implicit_cast<const X *>(pthis), function_to_bind);  }
01149         // Static functions. We convert them into a member function call.
01150         // This constructor also provides implicit conversion
01151         FastDelegate3(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3) ) {
01152                 bind(function_to_bind); }
01153         // for efficiency, prevent creation of a temporary
01154         void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3) ) {
01155                 bind(function_to_bind); }
01156         inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3)) {
01157                 m_Closure.bindstaticfunc(this, &FastDelegate3::InvokeStaticFunction, 
01158                         function_to_bind); }
01159         // Invoke the delegate
01160         RetType operator() (Param1 p1, Param2 p2, Param3 p3) const {
01161         return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3); }
01162         // Implicit conversion to "bool" using the safe_bool idiom
01163 private:
01164         typedef struct SafeBoolStruct {
01165                 int a_data_pointer_to_this_is_0_on_buggy_compilers;
01166                 StaticFunctionPtr m_nonzero;
01167         } UselessTypedef;
01168     typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type;
01169 public:
01170         operator unspecified_bool_type() const {
01171         return empty()? 0: &SafeBoolStruct::m_nonzero;
01172     }
01173         // necessary to allow ==0 to work despite the safe_bool idiom
01174         inline bool operator==(StaticFunctionPtr funcptr) {
01175                 return m_Closure.IsEqualToStaticFuncPtr(funcptr);       }
01176         inline bool operator!=(StaticFunctionPtr funcptr) { 
01177                 return !m_Closure.IsEqualToStaticFuncPtr(funcptr);    }
01178         inline bool operator ! () const {       // Is it bound to anything?
01179                         return !m_Closure; }
01180         inline bool empty() const       {
01181                         return !m_Closure; }
01182         void clear() { m_Closure.clear();}
01183         // Conversion to and from the DelegateMemento storage class
01184         const DelegateMemento & GetMemento() { return m_Closure; }
01185         void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); }
01186 
01187 private:        // Invoker for static functions
01188         RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3) const {
01189         return (*(m_Closure.GetStaticFunction()))(p1, p2, p3); }
01190 };
01191 
01192 //N=4
01193 template<class Param1, class Param2, class Param3, class Param4, class RetType=detail::DefaultVoid>
01194 class FastDelegate4 {
01195 private:
01196         typedef typename detail::DefaultVoidToVoid<RetType>::type DesiredRetType;
01197         typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4);
01198         typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4);
01199         typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4);
01200         typedef detail::ClosurePtr<GenericMemFn, StaticFunctionPtr, UnvoidStaticFunctionPtr> ClosureType;
01201         ClosureType m_Closure;
01202 public:
01203         // Typedefs to aid generic programming
01204         typedef FastDelegate4 type;
01205 
01206         // Construction and comparison functions
01207         FastDelegate4() { clear(); }
01208         FastDelegate4(const FastDelegate4 &x) {
01209                 m_Closure.CopyFrom(this, x.m_Closure); }
01210         void operator = (const FastDelegate4 &x)  {
01211                 m_Closure.CopyFrom(this, x.m_Closure); }
01212         bool operator ==(const FastDelegate4 &x) const {
01213                 return m_Closure.IsEqual(x.m_Closure);  }
01214         bool operator !=(const FastDelegate4 &x) const {
01215                 return !m_Closure.IsEqual(x.m_Closure); }
01216         bool operator <(const FastDelegate4 &x) const {
01217                 return m_Closure.IsLess(x.m_Closure);   }
01218         bool operator >(const FastDelegate4 &x) const {
01219                 return x.m_Closure.IsLess(m_Closure);   }
01220         // Binding to non-const member functions
01221         template < class X, class Y >
01222         FastDelegate4(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4) ) {
01223                 m_Closure.bindmemfunc(detail::implicit_cast<X*>(pthis), function_to_bind); }
01224         template < class X, class Y >
01225         inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4)) {
01226                 m_Closure.bindmemfunc(detail::implicit_cast<X*>(pthis), function_to_bind);      }
01227         // Binding to const member functions.
01228         template < class X, class Y >
01229         FastDelegate4(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const) {
01230                 m_Closure.bindconstmemfunc(detail::implicit_cast<const X*>(pthis), function_to_bind);   }
01231         template < class X, class Y >
01232         inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const) {
01233                 m_Closure.bindconstmemfunc(detail::implicit_cast<const X *>(pthis), function_to_bind);  }
01234         // Static functions. We convert them into a member function call.
01235         // This constructor also provides implicit conversion
01236         FastDelegate4(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4) ) {
01237                 bind(function_to_bind); }
01238         // for efficiency, prevent creation of a temporary
01239         void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4) ) {
01240                 bind(function_to_bind); }
01241         inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4)) {
01242                 m_Closure.bindstaticfunc(this, &FastDelegate4::InvokeStaticFunction, 
01243                         function_to_bind); }
01244         // Invoke the delegate
01245         RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4) const {
01246         return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4); }
01247         // Implicit conversion to "bool" using the safe_bool idiom
01248 private:
01249         typedef struct SafeBoolStruct {
01250                 int a_data_pointer_to_this_is_0_on_buggy_compilers;
01251                 StaticFunctionPtr m_nonzero;
01252         } UselessTypedef;
01253     typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type;
01254 public:
01255         operator unspecified_bool_type() const {
01256         return empty()? 0: &SafeBoolStruct::m_nonzero;
01257     }
01258         // necessary to allow ==0 to work despite the safe_bool idiom
01259         inline bool operator==(StaticFunctionPtr funcptr) {
01260                 return m_Closure.IsEqualToStaticFuncPtr(funcptr);       }
01261         inline bool operator!=(StaticFunctionPtr funcptr) { 
01262                 return !m_Closure.IsEqualToStaticFuncPtr(funcptr);    }
01263         inline bool operator ! () const {       // Is it bound to anything?
01264                         return !m_Closure; }
01265         inline bool empty() const       {
01266                         return !m_Closure; }
01267         void clear() { m_Closure.clear();}
01268         // Conversion to and from the DelegateMemento storage class
01269         const DelegateMemento & GetMemento() { return m_Closure; }
01270         void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); }
01271 
01272 private:        // Invoker for static functions
01273         RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const {
01274         return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4); }
01275 };
01276 
01277 //N=5
01278 template<class Param1, class Param2, class Param3, class Param4, class Param5, class RetType=detail::DefaultVoid>
01279 class FastDelegate5 {
01280 private:
01281         typedef typename detail::DefaultVoidToVoid<RetType>::type DesiredRetType;
01282         typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5);
01283         typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5);
01284         typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5);
01285         typedef detail::ClosurePtr<GenericMemFn, StaticFunctionPtr, UnvoidStaticFunctionPtr> ClosureType;
01286         ClosureType m_Closure;
01287 public:
01288         // Typedefs to aid generic programming
01289         typedef FastDelegate5 type;
01290 
01291         // Construction and comparison functions
01292         FastDelegate5() { clear(); }
01293         FastDelegate5(const FastDelegate5 &x) {
01294                 m_Closure.CopyFrom(this, x.m_Closure); }
01295         void operator = (const FastDelegate5 &x)  {
01296                 m_Closure.CopyFrom(this, x.m_Closure); }
01297         bool operator ==(const FastDelegate5 &x) const {
01298                 return m_Closure.IsEqual(x.m_Closure);  }
01299         bool operator !=(const FastDelegate5 &x) const {
01300                 return !m_Closure.IsEqual(x.m_Closure); }
01301         bool operator <(const FastDelegate5 &x) const {
01302                 return m_Closure.IsLess(x.m_Closure);   }
01303         bool operator >(const FastDelegate5 &x) const {
01304                 return x.m_Closure.IsLess(m_Closure);   }
01305         // Binding to non-const member functions
01306         template < class X, class Y >
01307         FastDelegate5(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) ) {
01308                 m_Closure.bindmemfunc(detail::implicit_cast<X*>(pthis), function_to_bind); }
01309         template < class X, class Y >
01310         inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5)) {
01311                 m_Closure.bindmemfunc(detail::implicit_cast<X*>(pthis), function_to_bind);      }
01312         // Binding to const member functions.
01313         template < class X, class Y >
01314         FastDelegate5(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const) {
01315                 m_Closure.bindconstmemfunc(detail::implicit_cast<const X*>(pthis), function_to_bind);   }
01316         template < class X, class Y >
01317         inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const) {
01318                 m_Closure.bindconstmemfunc(detail::implicit_cast<const X *>(pthis), function_to_bind);  }
01319         // Static functions. We convert them into a member function call.
01320         // This constructor also provides implicit conversion
01321         FastDelegate5(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) ) {
01322                 bind(function_to_bind); }
01323         // for efficiency, prevent creation of a temporary
01324         void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) ) {
01325                 bind(function_to_bind); }
01326         inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5)) {
01327                 m_Closure.bindstaticfunc(this, &FastDelegate5::InvokeStaticFunction, 
01328                         function_to_bind); }
01329         // Invoke the delegate
01330         RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const {
01331         return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4, p5); }
01332         // Implicit conversion to "bool" using the safe_bool idiom
01333 private:
01334         typedef struct SafeBoolStruct {
01335                 int a_data_pointer_to_this_is_0_on_buggy_compilers;
01336                 StaticFunctionPtr m_nonzero;
01337         } UselessTypedef;
01338     typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type;
01339 public:
01340         operator unspecified_bool_type() const {
01341         return empty()? 0: &SafeBoolStruct::m_nonzero;
01342     }
01343         // necessary to allow ==0 to work despite the safe_bool idiom
01344         inline bool operator==(StaticFunctionPtr funcptr) {
01345                 return m_Closure.IsEqualToStaticFuncPtr(funcptr);       }
01346         inline bool operator!=(StaticFunctionPtr funcptr) { 
01347                 return !m_Closure.IsEqualToStaticFuncPtr(funcptr);    }
01348         inline bool operator ! () const {       // Is it bound to anything?
01349                         return !m_Closure; }
01350         inline bool empty() const       {
01351                         return !m_Closure; }
01352         void clear() { m_Closure.clear();}
01353         // Conversion to and from the DelegateMemento storage class
01354         const DelegateMemento & GetMemento() { return m_Closure; }
01355         void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); }
01356 
01357 private:        // Invoker for static functions
01358         RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const {
01359         return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4, p5); }
01360 };
01361 
01362 //N=6
01363 template<class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class RetType=detail::DefaultVoid>
01364 class FastDelegate6 {
01365 private:
01366         typedef typename detail::DefaultVoidToVoid<RetType>::type DesiredRetType;
01367         typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6);
01368         typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6);
01369         typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6);
01370         typedef detail::ClosurePtr<GenericMemFn, StaticFunctionPtr, UnvoidStaticFunctionPtr> ClosureType;
01371         ClosureType m_Closure;
01372 public:
01373         // Typedefs to aid generic programming
01374         typedef FastDelegate6 type;
01375 
01376         // Construction and comparison functions
01377         FastDelegate6() { clear(); }
01378         FastDelegate6(const FastDelegate6 &x) {
01379                 m_Closure.CopyFrom(this, x.m_Closure); }
01380         void operator = (const FastDelegate6 &x)  {
01381                 m_Closure.CopyFrom(this, x.m_Closure); }
01382         bool operator ==(const FastDelegate6 &x) const {
01383                 return m_Closure.IsEqual(x.m_Closure);  }
01384         bool operator !=(const FastDelegate6 &x) const {
01385                 return !m_Closure.IsEqual(x.m_Closure); }
01386         bool operator <(const FastDelegate6 &x) const {
01387                 return m_Closure.IsLess(x.m_Closure);   }
01388         bool operator >(const FastDelegate6 &x) const {
01389                 return x.m_Closure.IsLess(m_Closure);   }
01390         // Binding to non-const member functions
01391         template < class X, class Y >
01392         FastDelegate6(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) ) {
01393                 m_Closure.bindmemfunc(detail::implicit_cast<X*>(pthis), function_to_bind); }
01394         template < class X, class Y >
01395         inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6)) {
01396                 m_Closure.bindmemfunc(detail::implicit_cast<X*>(pthis), function_to_bind);      }
01397         // Binding to const member functions.
01398         template < class X, class Y >
01399         FastDelegate6(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const) {
01400                 m_Closure.bindconstmemfunc(detail::implicit_cast<const X*>(pthis), function_to_bind);   }
01401         template < class X, class Y >
01402         inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const) {
01403                 m_Closure.bindconstmemfunc(detail::implicit_cast<const X *>(pthis), function_to_bind);  }
01404         // Static functions. We convert them into a member function call.
01405         // This constructor also provides implicit conversion
01406         FastDelegate6(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) ) {
01407                 bind(function_to_bind); }
01408         // for efficiency, prevent creation of a temporary
01409         void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) ) {
01410                 bind(function_to_bind); }
01411         inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6)) {
01412                 m_Closure.bindstaticfunc(this, &FastDelegate6::InvokeStaticFunction, 
01413                         function_to_bind); }
01414         // Invoke the delegate
01415         RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const {
01416         return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4, p5, p6); }
01417         // Implicit conversion to "bool" using the safe_bool idiom
01418 private:
01419         typedef struct SafeBoolStruct {
01420                 int a_data_pointer_to_this_is_0_on_buggy_compilers;
01421                 StaticFunctionPtr m_nonzero;
01422         } UselessTypedef;
01423     typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type;
01424 public:
01425         operator unspecified_bool_type() const {
01426         return empty()? 0: &SafeBoolStruct::m_nonzero;
01427     }
01428         // necessary to allow ==0 to work despite the safe_bool idiom
01429         inline bool operator==(StaticFunctionPtr funcptr) {
01430                 return m_Closure.IsEqualToStaticFuncPtr(funcptr);       }
01431         inline bool operator!=(StaticFunctionPtr funcptr) { 
01432                 return !m_Closure.IsEqualToStaticFuncPtr(funcptr);    }
01433         inline bool operator ! () const {       // Is it bound to anything?
01434                         return !m_Closure; }
01435         inline bool empty() const       {
01436                         return !m_Closure; }
01437         void clear() { m_Closure.clear();}
01438         // Conversion to and from the DelegateMemento storage class
01439         const DelegateMemento & GetMemento() { return m_Closure; }
01440         void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); }
01441 
01442 private:        // Invoker for static functions
01443         RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const {
01444         return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4, p5, p6); }
01445 };
01446 
01447 //N=7
01448 template<class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class RetType=detail::DefaultVoid>
01449 class FastDelegate7 {
01450 private:
01451         typedef typename detail::DefaultVoidToVoid<RetType>::type DesiredRetType;
01452         typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7);
01453         typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7);
01454         typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7);
01455         typedef detail::ClosurePtr<GenericMemFn, StaticFunctionPtr, UnvoidStaticFunctionPtr> ClosureType;
01456         ClosureType m_Closure;
01457 public:
01458         // Typedefs to aid generic programming
01459         typedef FastDelegate7 type;
01460 
01461         // Construction and comparison functions
01462         FastDelegate7() { clear(); }
01463         FastDelegate7(const FastDelegate7 &x) {
01464                 m_Closure.CopyFrom(this, x.m_Closure); }
01465         void operator = (const FastDelegate7 &x)  {
01466                 m_Closure.CopyFrom(this, x.m_Closure); }
01467         bool operator ==(const FastDelegate7 &x) const {
01468                 return m_Closure.IsEqual(x.m_Closure);  }
01469         bool operator !=(const FastDelegate7 &x) const {
01470                 return !m_Closure.IsEqual(x.m_Closure); }
01471         bool operator <(const FastDelegate7 &x) const {
01472                 return m_Closure.IsLess(x.m_Closure);   }
01473         bool operator >(const FastDelegate7 &x) const {
01474                 return x.m_Closure.IsLess(m_Closure);   }
01475         // Binding to non-const member functions
01476         template < class X, class Y >
01477         FastDelegate7(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) ) {
01478                 m_Closure.bindmemfunc(detail::implicit_cast<X*>(pthis), function_to_bind); }
01479         template < class X, class Y >
01480         inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7)) {
01481                 m_Closure.bindmemfunc(detail::implicit_cast<X*>(pthis), function_to_bind);      }
01482         // Binding to const member functions.
01483         template < class X, class Y >
01484         FastDelegate7(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const) {
01485                 m_Closure.bindconstmemfunc(detail::implicit_cast<const X*>(pthis), function_to_bind);   }
01486         template < class X, class Y >
01487         inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const) {
01488                 m_Closure.bindconstmemfunc(detail::implicit_cast<const X *>(pthis), function_to_bind);  }
01489         // Static functions. We convert them into a member function call.
01490         // This constructor also provides implicit conversion
01491         FastDelegate7(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) ) {
01492                 bind(function_to_bind); }
01493         // for efficiency, prevent creation of a temporary
01494         void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) ) {
01495                 bind(function_to_bind); }
01496         inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7)) {
01497                 m_Closure.bindstaticfunc(this, &FastDelegate7::InvokeStaticFunction, 
01498                         function_to_bind); }
01499         // Invoke the delegate
01500         RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const {
01501         return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4, p5, p6, p7); }
01502         // Implicit conversion to "bool" using the safe_bool idiom
01503 private:
01504         typedef struct SafeBoolStruct {
01505                 int a_data_pointer_to_this_is_0_on_buggy_compilers;
01506                 StaticFunctionPtr m_nonzero;
01507         } UselessTypedef;
01508     typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type;
01509 public:
01510         operator unspecified_bool_type() const {
01511         return empty()? 0: &SafeBoolStruct::m_nonzero;
01512     }
01513         // necessary to allow ==0 to work despite the safe_bool idiom
01514         inline bool operator==(StaticFunctionPtr funcptr) {
01515                 return m_Closure.IsEqualToStaticFuncPtr(funcptr);       }
01516         inline bool operator!=(StaticFunctionPtr funcptr) { 
01517                 return !m_Closure.IsEqualToStaticFuncPtr(funcptr);    }
01518         inline bool operator ! () const {       // Is it bound to anything?
01519                         return !m_Closure; }
01520         inline bool empty() const       {
01521                         return !m_Closure; }
01522         void clear() { m_Closure.clear();}
01523         // Conversion to and from the DelegateMemento storage class
01524         const DelegateMemento & GetMemento() { return m_Closure; }
01525         void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); }
01526 
01527 private:        // Invoker for static functions
01528         RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const {
01529         return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4, p5, p6, p7); }
01530 };
01531 
01532 //N=8
01533 template<class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class RetType=detail::DefaultVoid>
01534 class FastDelegate8 {
01535 private:
01536         typedef typename detail::DefaultVoidToVoid<RetType>::type DesiredRetType;
01537         typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8);
01538         typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8);
01539         typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8);
01540         typedef detail::ClosurePtr<GenericMemFn, StaticFunctionPtr, UnvoidStaticFunctionPtr> ClosureType;
01541         ClosureType m_Closure;
01542 public:
01543         // Typedefs to aid generic programming
01544         typedef FastDelegate8 type;
01545 
01546         // Construction and comparison functions
01547         FastDelegate8() { clear(); }
01548         FastDelegate8(const FastDelegate8 &x) {
01549                 m_Closure.CopyFrom(this, x.m_Closure); }
01550         void operator = (const FastDelegate8 &x)  {
01551                 m_Closure.CopyFrom(this, x.m_Closure); }
01552         bool operator ==(const FastDelegate8 &x) const {
01553                 return m_Closure.IsEqual(x.m_Closure);  }
01554         bool operator !=(const FastDelegate8 &x) const {
01555                 return !m_Closure.IsEqual(x.m_Closure); }
01556         bool operator <(const FastDelegate8 &x) const {
01557                 return m_Closure.IsLess(x.m_Closure);   }
01558         bool operator >(const FastDelegate8 &x) const {
01559                 return x.m_Closure.IsLess(m_Closure);   }
01560         // Binding to non-const member functions
01561         template < class X, class Y >
01562         FastDelegate8(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) ) {
01563                 m_Closure.bindmemfunc(detail::implicit_cast<X*>(pthis), function_to_bind); }
01564         template < class X, class Y >
01565         inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8)) {
01566                 m_Closure.bindmemfunc(detail::implicit_cast<X*>(pthis), function_to_bind);      }
01567         // Binding to const member functions.
01568         template < class X, class Y >
01569         FastDelegate8(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const) {
01570                 m_Closure.bindconstmemfunc(detail::implicit_cast<const X*>(pthis), function_to_bind);   }
01571         template < class X, class Y >
01572         inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const) {
01573                 m_Closure.bindconstmemfunc(detail::implicit_cast<const X *>(pthis), function_to_bind);  }
01574         // Static functions. We convert them into a member function call.
01575         // This constructor also provides implicit conversion
01576         FastDelegate8(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) ) {
01577                 bind(function_to_bind); }
01578         // for efficiency, prevent creation of a temporary
01579         void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) ) {
01580                 bind(function_to_bind); }
01581         inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8)) {
01582                 m_Closure.bindstaticfunc(this, &FastDelegate8::InvokeStaticFunction, 
01583                         function_to_bind); }
01584         // Invoke the delegate
01585         RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const {
01586         return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4, p5, p6, p7, p8); }
01587         // Implicit conversion to "bool" using the safe_bool idiom
01588 private:
01589         typedef struct SafeBoolStruct {
01590                 int a_data_pointer_to_this_is_0_on_buggy_compilers;
01591                 StaticFunctionPtr m_nonzero;
01592         } UselessTypedef;
01593     typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type;
01594 public:
01595         operator unspecified_bool_type() const {
01596         return empty()? 0: &SafeBoolStruct::m_nonzero;
01597     }
01598         // necessary to allow ==0 to work despite the safe_bool idiom
01599         inline bool operator==(StaticFunctionPtr funcptr) {
01600                 return m_Closure.IsEqualToStaticFuncPtr(funcptr);       }
01601         inline bool operator!=(StaticFunctionPtr funcptr) { 
01602                 return !m_Closure.IsEqualToStaticFuncPtr(funcptr);    }
01603         inline bool operator ! () const {       // Is it bound to anything?
01604                         return !m_Closure; }
01605         inline bool empty() const       {
01606                         return !m_Closure; }
01607         void clear() { m_Closure.clear();}
01608         // Conversion to and from the DelegateMemento storage class
01609         const DelegateMemento & GetMemento() { return m_Closure; }
01610         void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); }
01611 
01612 private:        // Invoker for static functions
01613         RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const {
01614         return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4, p5, p6, p7, p8); }
01615 };
01616 
01617 
01619 //                                              Fast Delegates, part 4:
01620 // 
01621 //                              FastDelegate<> class (Original author: Jody Hagins)
01622 //      Allows boost::function style syntax like:
01623 //                      FastDelegate< double (int, long) >
01624 // instead of:
01625 //                      FastDelegate2< int, long, double >
01626 //
01628 
01629 #ifdef FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX
01630 
01631 // Declare FastDelegate as a class template.  It will be specialized
01632 // later for all number of arguments.
01633 template <typename Signature>
01634 class FastDelegate;
01635 
01636 //N=0
01637 // Specialization to allow use of
01638 // FastDelegate< R (  ) >
01639 // instead of 
01640 // FastDelegate0 < R >
01641 template<typename R>
01642 class FastDelegate< R (  ) >
01643   // Inherit from FastDelegate0 so that it can be treated just like a FastDelegate0
01644   : public FastDelegate0 < R >
01645 {
01646 public:
01647   // Make using the base type a bit easier via typedef.
01648   typedef FastDelegate0 < R > BaseType;
01649 
01650   // Allow users access to the specific type of this delegate.
01651   typedef FastDelegate SelfType;
01652 
01653   // Mimic the base class constructors.
01654   FastDelegate() : BaseType() { }
01655 
01656   template < class X, class Y >
01657   FastDelegate(Y * pthis, 
01658     R (X::* function_to_bind)(  ))
01659     : BaseType(pthis, function_to_bind)  { }
01660 
01661   template < class X, class Y >
01662   FastDelegate(const Y *pthis,
01663       R (X::* function_to_bind)(  ) const)
01664     : BaseType(pthis, function_to_bind)
01665   {  }
01666 
01667   FastDelegate(R (*function_to_bind)(  ))
01668     : BaseType(function_to_bind)  { }
01669   void operator = (const BaseType &x)  {          
01670                 *static_cast<BaseType*>(this) = x; }
01671 };
01672 
01673 //N=1
01674 // Specialization to allow use of
01675 // FastDelegate< R ( Param1 ) >
01676 // instead of 
01677 // FastDelegate1 < Param1, R >
01678 template<typename R, class Param1>
01679 class FastDelegate< R ( Param1 ) >
01680   // Inherit from FastDelegate1 so that it can be treated just like a FastDelegate1
01681   : public FastDelegate1 < Param1, R >
01682 {
01683 public:
01684   // Make using the base type a bit easier via typedef.
01685   typedef FastDelegate1 < Param1, R > BaseType;
01686 
01687   // Allow users access to the specific type of this delegate.
01688   typedef FastDelegate SelfType;
01689 
01690   // Mimic the base class constructors.
01691   FastDelegate() : BaseType() { }
01692 
01693   template < class X, class Y >
01694   FastDelegate(Y * pthis, 
01695     R (X::* function_to_bind)( Param1 p1 ))
01696     : BaseType(pthis, function_to_bind)  { }
01697 
01698   template < class X, class Y >
01699   FastDelegate(const Y *pthis,
01700       R (X::* function_to_bind)( Param1 p1 ) const)
01701     : BaseType(pthis, function_to_bind)
01702   {  }
01703 
01704   FastDelegate(R (*function_to_bind)( Param1 p1 ))
01705     : BaseType(function_to_bind)  { }
01706   void operator = (const BaseType &x)  {          
01707                 *static_cast<BaseType*>(this) = x; }
01708 };
01709 
01710 //N=2
01711 // Specialization to allow use of
01712 // FastDelegate< R ( Param1, Param2 ) >
01713 // instead of 
01714 // FastDelegate2 < Param1, Param2, R >
01715 template<typename R, class Param1, class Param2>
01716 class FastDelegate< R ( Param1, Param2 ) >
01717   // Inherit from FastDelegate2 so that it can be treated just like a FastDelegate2
01718   : public FastDelegate2 < Param1, Param2, R >
01719 {
01720 public:
01721   // Make using the base type a bit easier via typedef.
01722   typedef FastDelegate2 < Param1, Param2, R > BaseType;
01723 
01724   // Allow users access to the specific type of this delegate.
01725   typedef FastDelegate SelfType;
01726 
01727   // Mimic the base class constructors.
01728   FastDelegate() : BaseType() { }
01729 
01730   template < class X, class Y >
01731   FastDelegate(Y * pthis, 
01732     R (X::* function_to_bind)( Param1 p1, Param2 p2 ))
01733     : BaseType(pthis, function_to_bind)  { }
01734 
01735   template < class X, class Y >
01736   FastDelegate(const Y *pthis,
01737       R (X::* function_to_bind)( Param1 p1, Param2 p2 ) const)
01738     : BaseType(pthis, function_to_bind)
01739   {  }
01740 
01741   FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2 ))
01742     : BaseType(function_to_bind)  { }
01743   void operator = (const BaseType &x)  {          
01744                 *static_cast<BaseType*>(this) = x; }
01745 };
01746 
01747 //N=3
01748 // Specialization to allow use of
01749 // FastDelegate< R ( Param1, Param2, Param3 ) >
01750 // instead of 
01751 // FastDelegate3 < Param1, Param2, Param3, R >
01752 template<typename R, class Param1, class Param2, class Param3>
01753 class FastDelegate< R ( Param1, Param2, Param3 ) >
01754   // Inherit from FastDelegate3 so that it can be treated just like a FastDelegate3
01755   : public FastDelegate3 < Param1, Param2, Param3, R >
01756 {
01757 public:
01758   // Make using the base type a bit easier via typedef.
01759   typedef FastDelegate3 < Param1, Param2, Param3, R > BaseType;
01760 
01761   // Allow users access to the specific type of this delegate.
01762   typedef FastDelegate SelfType;
01763 
01764   // Mimic the base class constructors.
01765   FastDelegate() : BaseType() { }
01766 
01767   template < class X, class Y >
01768   FastDelegate(Y * pthis, 
01769     R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3 ))
01770     : BaseType(pthis, function_to_bind)  { }
01771 
01772   template < class X, class Y >
01773   FastDelegate(const Y *pthis,
01774       R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3 ) const)
01775     : BaseType(pthis, function_to_bind)
01776   {  }
01777 
01778   FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3 ))
01779     : BaseType(function_to_bind)  { }
01780   void operator = (const BaseType &x)  {          
01781                 *static_cast<BaseType*>(this) = x; }
01782 };
01783 
01784 //N=4
01785 // Specialization to allow use of
01786 // FastDelegate< R ( Param1, Param2, Param3, Param4 ) >
01787 // instead of 
01788 // FastDelegate4 < Param1, Param2, Param3, Param4, R >
01789 template<typename R, class Param1, class Param2, class Param3, class Param4>
01790 class FastDelegate< R ( Param1, Param2, Param3, Param4 ) >
01791   // Inherit from FastDelegate4 so that it can be treated just like a FastDelegate4
01792   : public FastDelegate4 < Param1, Param2, Param3, Param4, R >
01793 {
01794 public:
01795   // Make using the base type a bit easier via typedef.
01796   typedef FastDelegate4 < Param1, Param2, Param3, Param4, R > BaseType;
01797 
01798   // Allow users access to the specific type of this delegate.
01799   typedef FastDelegate SelfType;
01800 
01801   // Mimic the base class constructors.
01802   FastDelegate() : BaseType() { }
01803 
01804   template < class X, class Y >
01805   FastDelegate(Y * pthis, 
01806     R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4 ))
01807     : BaseType(pthis, function_to_bind)  { }
01808 
01809   template < class X, class Y >
01810   FastDelegate(const Y *pthis,
01811       R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4 ) const)
01812     : BaseType(pthis, function_to_bind)
01813   {  }
01814 
01815   FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4 ))
01816     : BaseType(function_to_bind)  { }
01817   void operator = (const BaseType &x)  {          
01818                 *static_cast<BaseType*>(this) = x; }
01819 };
01820 
01821 //N=5
01822 // Specialization to allow use of
01823 // FastDelegate< R ( Param1, Param2, Param3, Param4, Param5 ) >
01824 // instead of 
01825 // FastDelegate5 < Param1, Param2, Param3, Param4, Param5, R >
01826 template<typename R, class Param1, class Param2, class Param3, class Param4, class Param5>
01827 class FastDelegate< R ( Param1, Param2, Param3, Param4, Param5 ) >
01828   // Inherit from FastDelegate5 so that it can be treated just like a FastDelegate5
01829   : public FastDelegate5 < Param1, Param2, Param3, Param4, Param5, R >
01830 {
01831 public:
01832   // Make using the base type a bit easier via typedef.
01833   typedef FastDelegate5 < Param1, Param2, Param3, Param4, Param5, R > BaseType;
01834 
01835   // Allow users access to the specific type of this delegate.
01836   typedef FastDelegate SelfType;
01837 
01838   // Mimic the base class constructors.
01839   FastDelegate() : BaseType() { }
01840 
01841   template < class X, class Y >
01842   FastDelegate(Y * pthis, 
01843     R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5 ))
01844     : BaseType(pthis, function_to_bind)  { }
01845 
01846   template < class X, class Y >
01847   FastDelegate(const Y *pthis,
01848       R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5 ) const)
01849     : BaseType(pthis, function_to_bind)
01850   {  }
01851 
01852   FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5 ))
01853     : BaseType(function_to_bind)  { }
01854   void operator = (const BaseType &x)  {          
01855                 *static_cast<BaseType*>(this) = x; }
01856 };
01857 
01858 //N=6
01859 // Specialization to allow use of
01860 // FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6 ) >
01861 // instead of 
01862 // FastDelegate6 < Param1, Param2, Param3, Param4, Param5, Param6, R >
01863 template<typename R, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6>
01864 class FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6 ) >
01865   // Inherit from FastDelegate6 so that it can be treated just like a FastDelegate6
01866   : public FastDelegate6 < Param1, Param2, Param3, Param4, Param5, Param6, R >
01867 {
01868 public:
01869   // Make using the base type a bit easier via typedef.
01870   typedef FastDelegate6 < Param1, Param2, Param3, Param4, Param5, Param6, R > BaseType;
01871 
01872   // Allow users access to the specific type of this delegate.
01873   typedef FastDelegate SelfType;
01874 
01875   // Mimic the base class constructors.
01876   FastDelegate() : BaseType() { }
01877 
01878   template < class X, class Y >
01879   FastDelegate(Y * pthis, 
01880     R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6 ))
01881     : BaseType(pthis, function_to_bind)  { }
01882 
01883   template < class X, class Y >
01884   FastDelegate(const Y *pthis,
01885       R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6 ) const)
01886     : BaseType(pthis, function_to_bind)
01887   {  }
01888 
01889   FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6 ))
01890     : BaseType(function_to_bind)  { }
01891   void operator = (const BaseType &x)  {          
01892                 *static_cast<BaseType*>(this) = x; }
01893 };
01894 
01895 //N=7
01896 // Specialization to allow use of
01897 // FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7 ) >
01898 // instead of 
01899 // FastDelegate7 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, R >
01900 template<typename R, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7>
01901 class FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7 ) >
01902   // Inherit from FastDelegate7 so that it can be treated just like a FastDelegate7
01903   : public FastDelegate7 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, R >
01904 {
01905 public:
01906   // Make using the base type a bit easier via typedef.
01907   typedef FastDelegate7 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, R > BaseType;
01908 
01909   // Allow users access to the specific type of this delegate.
01910   typedef FastDelegate SelfType;
01911 
01912   // Mimic the base class constructors.
01913   FastDelegate() : BaseType() { }
01914 
01915   template < class X, class Y >
01916   FastDelegate(Y * pthis, 
01917     R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7 ))
01918     : BaseType(pthis, function_to_bind)  { }
01919 
01920   template < class X, class Y >
01921   FastDelegate(const Y *pthis,
01922       R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7 ) const)
01923     : BaseType(pthis, function_to_bind)
01924   {  }
01925 
01926   FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7 ))
01927     : BaseType(function_to_bind)  { }
01928   void operator = (const BaseType &x)  {          
01929                 *static_cast<BaseType*>(this) = x; }
01930 };
01931 
01932 //N=8
01933 // Specialization to allow use of
01934 // FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8 ) >
01935 // instead of 
01936 // FastDelegate8 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, R >
01937 template<typename R, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8>
01938 class FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8 ) >
01939   // Inherit from FastDelegate8 so that it can be treated just like a FastDelegate8
01940   : public FastDelegate8 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, R >
01941 {
01942 public:
01943   // Make using the base type a bit easier via typedef.
01944   typedef FastDelegate8 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, R > BaseType;
01945 
01946   // Allow users access to the specific type of this delegate.
01947   typedef FastDelegate SelfType;
01948 
01949   // Mimic the base class constructors.
01950   FastDelegate() : BaseType() { }
01951 
01952   template < class X, class Y >
01953   FastDelegate(Y * pthis, 
01954     R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8 ))
01955     : BaseType(pthis, function_to_bind)  { }
01956 
01957   template < class X, class Y >
01958   FastDelegate(const Y *pthis,
01959       R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8 ) const)
01960     : BaseType(pthis, function_to_bind)
01961   {  }
01962 
01963   FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8 ))
01964     : BaseType(function_to_bind)  { }
01965   void operator = (const BaseType &x)  {          
01966                 *static_cast<BaseType*>(this) = x; }
01967 };
01968 
01969 
01970 #endif //FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX
01971 
01973 //                                              Fast Delegates, part 5:
01974 //
01975 //                              MakeDelegate() helper function
01976 //
01977 //                      MakeDelegate(&x, &X::func) returns a fastdelegate of the type
01978 //                      necessary for calling x.func() with the correct number of arguments.
01979 //                      This makes it possible to eliminate many typedefs from user code.
01980 //
01982 
01983 // Also declare overloads of a MakeDelegate() global function to 
01984 // reduce the need for typedefs.
01985 // We need seperate overloads for const and non-const member functions.
01986 // Also, because of the weird rule about the class of derived member function pointers,
01987 // implicit downcasts may need to be applied later to the 'this' pointer.
01988 // That's why two classes (X and Y) appear in the definitions. Y must be implicitly
01989 // castable to X.
01990 
01991 // Workaround for VC6. VC6 needs void return types converted into DefaultVoid.
01992 // GCC 3.2 and later won't compile this unless it's preceded by 'typename',
01993 // but VC6 doesn't allow 'typename' in this context.
01994 // So, I have to use a macro.
01995 
01996 #ifdef FASTDLGT_VC6
01997 #define FASTDLGT_RETTYPE detail::VoidToDefaultVoid<RetType>::type
01998 #else 
01999 #define FASTDLGT_RETTYPE RetType
02000 #endif
02001 
02002 //N=0
02003 template <class X, class Y, class RetType>
02004 FastDelegate0<FASTDLGT_RETTYPE> MakeDelegate(Y* x, RetType (X::*func)()) { 
02005         return FastDelegate0<FASTDLGT_RETTYPE>(x, func);
02006 }
02007 
02008 template <class X, class Y, class RetType>
02009 FastDelegate0<FASTDLGT_RETTYPE> MakeDelegate(Y* x, RetType (X::*func)() const) { 
02010         return FastDelegate0<FASTDLGT_RETTYPE>(x, func);
02011 }
02012 
02013 //N=1
02014 template <class X, class Y, class Param1, class RetType>
02015 FastDelegate1<Param1, FASTDLGT_RETTYPE> MakeDelegate(Y* x, RetType (X::*func)(Param1 p1)) { 
02016         return FastDelegate1<Param1, FASTDLGT_RETTYPE>(x, func);
02017 }
02018 
02019 template <class X, class Y, class Param1, class RetType>
02020 FastDelegate1<Param1, FASTDLGT_RETTYPE> MakeDelegate(Y* x, RetType (X::*func)(Param1 p1) const) { 
02021         return FastDelegate1<Param1, FASTDLGT_RETTYPE>(x, func);
02022 }
02023 
02024 //N=2
02025 template <class X, class Y, class Param1, class Param2, class RetType>
02026 FastDelegate2<Param1, Param2, FASTDLGT_RETTYPE> MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2)) { 
02027         return FastDelegate2<Param1, Param2, FASTDLGT_RETTYPE>(x, func);
02028 }
02029 
02030 template <class X, class Y, class Param1, class Param2, class RetType>
02031 FastDelegate2<Param1, Param2, FASTDLGT_RETTYPE> MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2) const) { 
02032         return FastDelegate2<Param1, Param2, FASTDLGT_RETTYPE>(x, func);
02033 }
02034 
02035 //N=3
02036 template <class X, class Y, class Param1, class Param2, class Param3, class RetType>
02037 FastDelegate3<Param1, Param2, Param3, FASTDLGT_RETTYPE> MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3)) { 
02038         return FastDelegate3<Param1, Param2, Param3, FASTDLGT_RETTYPE>(x, func);
02039 }
02040 
02041 template <class X, class Y, class Param1, class Param2, class Param3, class RetType>
02042 FastDelegate3<Param1, Param2, Param3, FASTDLGT_RETTYPE> MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3) const) { 
02043         return FastDelegate3<Param1, Param2, Param3, FASTDLGT_RETTYPE>(x, func);
02044 }
02045 
02046 //N=4
02047 template <class X, class Y, class Param1, class Param2, class Param3, class Param4, class RetType>
02048 FastDelegate4<Param1, Param2, Param3, Param4, FASTDLGT_RETTYPE> MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4)) { 
02049         return FastDelegate4<Param1, Param2, Param3, Param4, FASTDLGT_RETTYPE>(x, func);
02050 }
02051 
02052 template <class X, class Y, class Param1, class Param2, class Param3, class Param4, class RetType>
02053 FastDelegate4<Param1, Param2, Param3, Param4, FASTDLGT_RETTYPE> MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4) const) { 
02054         return FastDelegate4<Param1, Param2, Param3, Param4, FASTDLGT_RETTYPE>(x, func);
02055 }
02056 
02057 //N=5
02058 template <class X, class Y, class Param1, class Param2, class Param3, class Param4, class Param5, class RetType>
02059 FastDelegate5<Param1, Param2, Param3, Param4, Param5, FASTDLGT_RETTYPE> MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5)) { 
02060         return FastDelegate5<Param1, Param2, Param3, Param4, Param5, FASTDLGT_RETTYPE>(x, func);
02061 }
02062 
02063 template <class X, class Y, class Param1, class Param2, class Param3, class Param4, class Param5, class RetType>
02064 FastDelegate5<Param1, Param2, Param3, Param4, Param5, FASTDLGT_RETTYPE> MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5) const) { 
02065         return FastDelegate5<Param1, Param2, Param3, Param4, Param5, FASTDLGT_RETTYPE>(x, func);
02066 }
02067 
02068 //N=6
02069 template <class X, class Y, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class RetType>
02070 FastDelegate6<Param1, Param2, Param3, Param4, Param5, Param6, FASTDLGT_RETTYPE> MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6)) { 
02071         return FastDelegate6<Param1, Param2, Param3, Param4, Param5, Param6, FASTDLGT_RETTYPE>(x, func);
02072 }
02073 
02074 template <class X, class Y, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class RetType>
02075 FastDelegate6<Param1, Param2, Param3, Param4, Param5, Param6, FASTDLGT_RETTYPE> MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6) const) { 
02076         return FastDelegate6<Param1, Param2, Param3, Param4, Param5, Param6, FASTDLGT_RETTYPE>(x, func);
02077 }
02078 
02079 //N=7
02080 template <class X, class Y, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class RetType>
02081 FastDelegate7<Param1, Param2, Param3, Param4, Param5, Param6, Param7, FASTDLGT_RETTYPE> MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7)) { 
02082         return FastDelegate7<Param1, Param2, Param3, Param4, Param5, Param6, Param7, FASTDLGT_RETTYPE>(x, func);
02083 }
02084 
02085 template <class X, class Y, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class RetType>
02086 FastDelegate7<Param1, Param2, Param3, Param4, Param5, Param6, Param7, FASTDLGT_RETTYPE> MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7) const) { 
02087         return FastDelegate7<Param1, Param2, Param3, Param4, Param5, Param6, Param7, FASTDLGT_RETTYPE>(x, func);
02088 }
02089 
02090 //N=8
02091 template <class X, class Y, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class RetType>
02092 FastDelegate8<Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, FASTDLGT_RETTYPE> MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8)) { 
02093         return FastDelegate8<Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, FASTDLGT_RETTYPE>(x, func);
02094 }
02095 
02096 template <class X, class Y, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class RetType>
02097 FastDelegate8<Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, FASTDLGT_RETTYPE> MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8) const) { 
02098         return FastDelegate8<Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, FASTDLGT_RETTYPE>(x, func);
02099 }
02100 
02101 
02102  // clean up after ourselves...
02103 #undef FASTDLGT_RETTYPE
02104 
02105 } // namespace fastdelegate
02106 
02107 #endif // !defined(FASTDELEGATE_H)
02108 


socketcan_interface
Author(s): Mathias Lüdtke
autogenerated on Sun Sep 3 2017 03:10:38