fastdelegate.h.svn-base

来自「ffshow源码」· SVN-BASE 代码 · 共 1,415 行 · 第 1/5 页

SVN-BASE
1,415
字号
//						FastDelegate.h //	Efficient delegates in C++ that generate only two lines of asm code!//  Documentation is found at http://www.codeproject.com/cpp/FastDelegate.asp////						- Don Clugston, Mar 2004.//		Major contributions were made by Jody Hagins.// History:// 24-Apr-04 1.0  * Submitted to CodeProject. // 28-Apr-04 1.1  * Prevent most unsafe uses of evil static function hack.//				  * Improved syntax for horrible_cast (thanks Paul Bludov).//				  * Tested on Metrowerks MWCC and Intel ICL (IA32)//				  * Compiled, but not run, on Comeau C++ and Intel Itanium ICL.//	27-Jun-04 1.2 * Now works on Borland C++ Builder 5.5//				  * Now works on /clr "managed C++" code on VC7, VC7.1//				  * Comeau C++ now compiles without warnings.//				  * Prevent the virtual inheritance case from being used on //					  VC6 and earlier, which generate incorrect code.//				  * Improved warning and error messages. Non-standard hacks//					 now have compile-time checks to make them safer.//				  * implicit_cast used instead of static_cast in many cases.//				  * If calling a const member function, a const class pointer can be used.//				  * MakeDelegate() global helper function added to simplify pass-by-value.//				  * Added fastdelegate.clear()// 16-Jul-04 1.2.1* Workaround for gcc bug (const member function pointers in templates)// 30-Oct-04 1.3  * Support for (non-void) return values.//				  * No more workarounds in client code!//					 MSVC and Intel now use a clever hack invented by John Dlugosz://				     - The FASTDELEGATEDECLARE workaround is no longer necessary.//					 - No more warning messages for VC6//				  * Less use of macros. Error messages should be more comprehensible.//				  * Added include guards//				  * Added FastDelegate::empty() to test if invocation is safe (Thanks Neville Franks).//				  * Now tested on VS 2005 Express Beta, PGI C++// 24-Dec-04 1.4  * Added DelegateMemento, to allow collections of disparate delegates.//                * <,>,<=,>= comparison operators to allow storage in ordered containers.//				  * Substantial reduction of code size, especially the 'Closure' class.//				  * Standardised all the compiler-specific workarounds.//                * MFP conversion now works for CodePlay (but not yet supported in the full code).//                * Now compiles without warnings on _any_ supported compiler, including BCC 5.5.1//				  * New syntax: FastDelegate< int (char *, double) >. // 14-Feb-05 1.4.1* Now treats =0 as equivalent to .clear(), ==0 as equivalent to .empty(). (Thanks elfric).//				  * Now tested on Intel ICL for AMD64, VS2005 Beta for AMD64 and Itanium.// 30-Mar-05 1.5  * Safebool idiom: "if (dg)" is now equivalent to "if (!dg.empty())"//				  * Fully supported by CodePlay VectorC//                * Bugfix for Metrowerks: empty() was buggy because a valid MFP can be 0 on MWCC!//                * More optimal assignment,== and != operators for static function pointers.#ifndef FASTDELEGATE_H#define FASTDELEGATE_H#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000#include <memory.h> // to allow <,> comparisons//////////////////////////////////////////////////////////////////////////////////						Configuration options//////////////////////////////////////////////////////////////////////////////////// Uncomment the following #define for optimally-sized delegates.// In this case, the generated asm code is almost identical to the code you'd get// if the compiler had native support for delegates.// It will not work on systems where sizeof(dataptr) < sizeof(codeptr). // Thus, it will not work for DOS compilers using the medium model.// It will also probably fail on some DSP systems.#define FASTDELEGATE_USESTATICFUNCTIONHACK// Uncomment the next line to allow function declarator syntax.// It is automatically enabled for those compilers where it is known to work.//#define FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX//////////////////////////////////////////////////////////////////////////////////						Compiler identification for workarounds//////////////////////////////////////////////////////////////////////////////////// Compiler identification. It's not easy to identify Visual C++ because// many vendors fraudulently define Microsoft's identifiers.#if defined(_MSC_VER) && !defined(__MWERKS__) && !defined(__VECTOR_C) && !defined(__ICL) && !defined(__BORLANDC__)#define FASTDLGT_ISMSVC#if (_MSC_VER <1300) // Many workarounds are required for VC6.#define FASTDLGT_VC6#pragma warning(disable:4786) // disable this ridiculous warning#endif#endif// Does the compiler uses Microsoft's member function pointer structure?// If so, it needs special treatment.// Metrowerks CodeWarrior, Intel, and CodePlay fraudulently define Microsoft's // identifier, _MSC_VER. We need to filter Metrowerks out.#if defined(_MSC_VER) && !defined(__MWERKS__)#define FASTDLGT_MICROSOFT_MFP#if !defined(__VECTOR_C)// CodePlay doesn't have the __single/multi/virtual_inheritance keywords#define FASTDLGT_HASINHERITANCE_KEYWORDS#endif#endif// Does it allow function declarator syntax? The following compilers are known to work:#if defined(FASTDLGT_ISMSVC) && (_MSC_VER >=1310) // VC 7.1#define FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX#endif// Gcc(2.95+), and versions of Digital Mars, Intel and Comeau in common use.#if defined (__DMC__) || defined(__GNUC__) || defined(__ICL) || defined(__COMO__)#define FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX#endif// It works on Metrowerks MWCC 3.2.2. From boost.Config it should work on earlier ones too.#if defined (__MWERKS__)#define FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX#endif#ifdef __GNUC__ // Workaround GCC bug #8271 	// At present, GCC doesn't recognize constness of MFPs in templates#define FASTDELEGATE_GCC_BUG_8271#endif//////////////////////////////////////////////////////////////////////////////////						General tricks used in this code//// (a) Error messages are generated by typdefing an array of negative size to//     generate compile-time errors.// (b) Warning messages on MSVC are generated by declaring unused variables, and//	    enabling the "variable XXX is never used" warning.// (c) Unions are used in a few compiler-specific cases to perform illegal casts.// (d) For Microsoft and Intel, when adjusting the 'this' pointer, it's cast to//     (char *) first to ensure that the correct number of *bytes* are added.////////////////////////////////////////////////////////////////////////////////////						Helper templates//////////////////////////////////////////////////////////////////////////////////namespace fastdelegate {namespace detail {	// we'll hide the implementation details in a nested namespace.//		implicit_cast< >// I believe this was originally going to be in the C++ standard but // was left out by accident. It's even milder than static_cast.// I use it instead of static_cast<> to emphasize that I'm not doing// anything nasty. // Usage is identical to static_cast<>template <class OutputClass, class InputClass>inline OutputClass implicit_cast(InputClass input){	return input;}//		horrible_cast< >// This is truly evil. It completely subverts C++'s type system, allowing you // to cast from any class to any other class. Technically, using a union // to perform the cast is undefined behaviour (even in C). But we can see if// it is OK by checking that the union is the same size as each of its members.// horrible_cast<> should only be used for compiler-specific workarounds. // Usage is identical to reinterpret_cast<>.// This union is declared outside the horrible_cast because BCC 5.5.1// can't inline a function with a nested class, and gives a warning.template <class OutputClass, class InputClass>union horrible_union{	OutputClass out;	InputClass in;};template <class OutputClass, class InputClass>inline OutputClass horrible_cast(const InputClass input){	horrible_union<OutputClass, InputClass> u;	// Cause a compile-time error if in, out and u are not the same size.	// If the compile fails here, it means the compiler has peculiar	// unions which would prevent the cast from working.	typedef int ERROR_CantUseHorrible_cast[sizeof(InputClass)==sizeof(u) 		&& sizeof(InputClass)==sizeof(OutputClass) ? 1 : -1];	u.in = input;	return u.out;}//////////////////////////////////////////////////////////////////////////////////						Workarounds//////////////////////////////////////////////////////////////////////////////////// Backwards compatibility: This macro used to be necessary in the virtual inheritance// case for Intel and Microsoft. Now it just forward-declares the class.#define FASTDELEGATEDECLARE(CLASSNAME)	class CLASSNAME;// Prevent use of the static function hack with the DOS medium model.#ifdef __MEDIUM__#undef FASTDELEGATE_USESTATICFUNCTIONHACK#endif//			DefaultVoid - a workaround for 'void' templates in VC6.////  (1) VC6 and earlier do not allow 'void' as a default template argument.//  (2) They also doesn't allow you to return 'void' from a function.//// Workaround for (1): Declare a dummy type 'DefaultVoid' which we use//   when we'd like to use 'void'. We convert it into 'void' and back//   using the templates DefaultVoidToVoid<> and VoidToDefaultVoid<>.// Workaround for (2): On VC6, the code for calling a void function is//   identical to the code for calling a non-void function in which the//   return value is never used, provided the return value is returned//   in the EAX register, rather than on the stack. //   This is true for most fundamental types such as int, enum, void *.//   Const void * is the safest option since it doesn't participate //   in any automatic conversions. But on a 16-bit compiler it might//   cause extra code to be generated, so we disable it for all compilers//   except for VC6 (and VC5).#ifdef FASTDLGT_VC6// VC6 workaroundtypedef const void * DefaultVoid;#else// On any other compiler, just use a normal void.typedef void DefaultVoid;#endif// Translate from 'DefaultVoid' to 'void'.// Everything else is unchangedtemplate <class T>struct DefaultVoidToVoid { typedef T type; };template <>struct DefaultVoidToVoid<DefaultVoid> {	typedef void type; };// Translate from 'void' into 'DefaultVoid'// Everything else is unchangedtemplate <class T>struct VoidToDefaultVoid { typedef T type; };template <>struct VoidToDefaultVoid<void> { typedef DefaultVoid type; };//////////////////////////////////////////////////////////////////////////////////						Fast Delegates, part 1:////		Conversion of member function pointer to a standard form//////////////////////////////////////////////////////////////////////////////////// GenericClass is a fake class, ONLY used to provide a type.// It is vitally important that it is never defined, so that the compiler doesn't// think it can optimize the invocation. For example, Borland generates simpler// code if it knows the class only uses single inheritance.// Compilers using Microsoft's structure need to be treated as a special case.#ifdef  FASTDLGT_MICROSOFT_MFP#ifdef FASTDLGT_HASINHERITANCE_KEYWORDS	// For Microsoft and Intel, we want to ensure that it's the most efficient type of MFP 	// (4 bytes), even when the /vmg option is used. Declaring an empty class 	// would give 16 byte pointers in this case....	class __single_inheritance GenericClass;#endif	// ...but for Codeplay, an empty class *always* gives 4 byte pointers.	// If compiled with the /clr option ("managed C++"), the JIT compiler thinks	// it needs to load GenericClass before it can call any of its functions,	// (compiles OK but crashes at runtime!), so we need to declare an 	// empty class to make it happy.	// Codeplay and VC4 can't cope with the unknown_inheritance case either.	class GenericClass {};#else	class GenericClass;#endif// The size of a single inheritance member function pointer.const int SINGLE_MEMFUNCPTR_SIZE = sizeof(void (GenericClass::*)());//						SimplifyMemFunc< >::Convert()////	A template function that converts an arbitrary member function pointer into the //	simplest possible form of member function pointer, using a supplied 'this' pointer.//  According to the standard, this can be done legally with reinterpret_cast<>.//	For (non-standard) compilers which use member function pointers which vary in size //  depending on the class, we need to use	knowledge of the internal structure of a //  member function pointer, as used by the compiler. Template specialization is used

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?