X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/b75a7d8f3b4adbae880cab104ce2c6a50eee4db2..08b89b0a244153b9f5bbb2f49c55ab0f7298122e:/icuSources/common/unicode/uobject.h diff --git a/icuSources/common/unicode/uobject.h b/icuSources/common/unicode/uobject.h index 51cc5437..54ceace6 100644 --- a/icuSources/common/unicode/uobject.h +++ b/icuSources/common/unicode/uobject.h @@ -1,7 +1,7 @@ /* ****************************************************************************** * -* Copyright (C) 2002-2003, International Business Machines +* Copyright (C) 2002-2012, International Business Machines * Corporation and others. All Rights Reserved. * ****************************************************************************** @@ -19,35 +19,78 @@ #include "unicode/utypes.h" -U_NAMESPACE_BEGIN - /** * \file * \brief C++ API: Common ICU base class UObject. */ -/** U_OVERRIDE_CXX_ALLOCATION - Define this to override operator new and - * delete in UMemory. Enabled by default for ICU. +/** + * @{ + * \def U_NO_THROW + * Define this to define the throw() specification so + * certain functions do not throw any exceptions * - * Enabling forces all allocation of ICU object types to use ICU's - * memory allocation. On Windows, this allows the ICU DLL to be used by - * applications that statically link the C Runtime library, meaning that - * the app and ICU will be using different heaps. + * UMemory operator new methods should have the throw() specification + * appended to them, so that the compiler adds the additional NULL check + * before calling constructors. Without, if operator new returns NULL the + * constructor is still called, and if the constructor references member + * data, (which it typically does), the result is a segmentation violation. * - * @draft ICU 2.2 - */ -#ifndef U_OVERRIDE_CXX_ALLOCATION -#define U_OVERRIDE_CXX_ALLOCATION 1 + * @stable ICU 4.2 + */ +#ifndef U_NO_THROW +#define U_NO_THROW throw() #endif -/** U_HAVE_PLACEMENT_NEW - Define this to define the placement new and - * delete in UMemory for STL. +/** @} */ + +/*===========================================================================*/ +/* UClassID-based RTTI */ +/*===========================================================================*/ + +/** + * UClassID is used to identify classes without using the compiler's RTTI. + * This was used before C++ compilers consistently supported RTTI. + * ICU 4.6 requires compiler RTTI to be turned on. * - * @draft ICU 2.6 - */ -#ifndef U_HAVE_PLACEMENT_NEW -#define U_HAVE_PLACEMENT_NEW 1 -#endif + * Each class hierarchy which needs + * to implement polymorphic clone() or operator==() defines two methods, + * described in detail below. UClassID values can be compared using + * operator==(). Nothing else should be done with them. + * + * \par + * In class hierarchies that implement "poor man's RTTI", + * each concrete subclass implements getDynamicClassID() in the same way: + * + * \code + * class Derived { + * public: + * virtual UClassID getDynamicClassID() const + * { return Derived::getStaticClassID(); } + * } + * \endcode + * + * Each concrete class implements getStaticClassID() as well, which allows + * clients to test for a specific type. + * + * \code + * class Derived { + * public: + * static UClassID U_EXPORT2 getStaticClassID(); + * private: + * static char fgClassID; + * } + * + * // In Derived.cpp: + * UClassID Derived::getStaticClassID() + * { return (UClassID)&Derived::fgClassID; } + * char Derived::fgClassID = 0; // Value is irrelevant + * \endcode + * @stable ICU 2.0 + */ +typedef void* UClassID; + +U_NAMESPACE_BEGIN /** * UMemory is the common ICU base class. @@ -62,11 +105,18 @@ U_NAMESPACE_BEGIN * UMemory does not contain any virtual functions. * Common "boilerplate" functions are defined in UObject. * - * @draft ICU 2.4 + * @stable ICU 2.4 */ class U_COMMON_API UMemory { public: +/* test versions for debugging shaper heap memory problems */ +#ifdef SHAPER_MEMORY_DEBUG + static void * NewArray(int size, int count); + static void * GrowArray(void * array, int newSize ); + static void FreeArray(void * array ); +#endif + #if U_OVERRIDE_CXX_ALLOCATION /** * Override for ICU4C C++ memory management. @@ -74,16 +124,16 @@ public: * (uprv_malloc(), uprv_free(), uprv_realloc()); * they or something else could be used here to implement C++ new/delete * for ICU4C C++ classes - * @draft ICU 2.4 + * @stable ICU 2.4 */ - static void *operator new(size_t size); + static void * U_EXPORT2 operator new(size_t size) U_NO_THROW; /** * Override for ICU4C C++ memory management. * See new(). - * @draft ICU 2.4 + * @stable ICU 2.4 */ - static void *operator new[](size_t size); + static void * U_EXPORT2 operator new[](size_t size) U_NO_THROW; /** * Override for ICU4C C++ memory management. @@ -91,32 +141,50 @@ public: * (uprv_malloc(), uprv_free(), uprv_realloc()); * they or something else could be used here to implement C++ new/delete * for ICU4C C++ classes - * @draft ICU 2.4 + * @stable ICU 2.4 */ - static void operator delete(void *p); + static void U_EXPORT2 operator delete(void *p) U_NO_THROW; /** * Override for ICU4C C++ memory management. * See delete(). - * @draft ICU 2.4 + * @stable ICU 2.4 */ - static void operator delete[](void *p); + static void U_EXPORT2 operator delete[](void *p) U_NO_THROW; #if U_HAVE_PLACEMENT_NEW /** * Override for ICU4C C++ memory management for STL. * See new(). - * @draft ICU 2.6 + * @stable ICU 2.6 */ - static inline void * operator new(size_t, void *ptr) { return ptr; } + static inline void * U_EXPORT2 operator new(size_t, void *ptr) U_NO_THROW { return ptr; } /** * Override for ICU4C C++ memory management for STL. * See delete(). - * @draft ICU 2.6 + * @stable ICU 2.6 */ - static inline void operator delete(void *, void *) {} + static inline void U_EXPORT2 operator delete(void *, void *) U_NO_THROW {} #endif /* U_HAVE_PLACEMENT_NEW */ +#if U_HAVE_DEBUG_LOCATION_NEW + /** + * This method overrides the MFC debug version of the operator new + * + * @param size The requested memory size + * @param file The file where the allocation was requested + * @param line The line where the allocation was requested + */ + static void * U_EXPORT2 operator new(size_t size, const char* file, int line) U_NO_THROW; + /** + * This method provides a matching delete for the MFC debug new + * + * @param p The pointer to the allocated memory + * @param file The file where the allocation was requested + * @param line The line where the allocation was requested + */ + static void U_EXPORT2 operator delete(void* p, const char* file, int line) U_NO_THROW; +#endif /* U_HAVE_DEBUG_LOCATION_NEW */ #endif /* U_OVERRIDE_CXX_ALLOCATION */ /* @@ -137,10 +205,7 @@ public: * and all other public ICU C++ classes * are derived from UObject (starting with ICU 2.2). * - * UObject contains common virtual functions like for ICU's "poor man's RTTI". - * It does not contain default implementations of virtual methods - * like getDynamicClassID to allow derived classes such as Format - * to declare these as pure virtual. + * UObject contains common virtual functions, in particular a virtual destructor. * * The clone() function is not available in UObject because it is not * implemented by all ICU classes. @@ -151,38 +216,41 @@ public: * This is because some compilers do not support covariant (same-as-this) * return types; cast to the appropriate subclass if necessary. * - * @draft ICU 2.2 + * @stable ICU 2.2 */ class U_COMMON_API UObject : public UMemory { public: /** * Destructor. * - * @draft ICU 2.2 + * @stable ICU 2.2 */ - virtual inline ~UObject() {} + virtual ~UObject(); /** * ICU4C "poor man's RTTI", returns a UClassID for the actual ICU class. + * The base class implementation returns a dummy value. * - * @draft ICU 2.2 + * Use compiler RTTI rather than ICU's "poor man's RTTI". + * Since ICU 4.6, new ICU C++ class hierarchies do not implement "poor man's RTTI". + * + * @stable ICU 2.2 */ - virtual inline UClassID getDynamicClassID() const = 0; + virtual UClassID getDynamicClassID() const; protected: // the following functions are protected to prevent instantiation and // direct use of UObject itself // default constructor - // commented out because UObject is abstract (see getDynamicClassID) // inline UObject() {} // copy constructor - // commented out because UObject is abstract (see getDynamicClassID) // inline UObject(const UObject &other) {} -#if U_ICU_VERSION_MAJOR_NUM>2 || (U_ICU_VERSION_MAJOR_NUM==2 && U_ICU_VERSION_MINOR_NUM>6) - // TODO post ICU 2.4 (This comment inserted in 2.2) +#if 0 + // TODO Sometime in the future. Implement operator==(). + // (This comment inserted in 2.2) // some or all of the following "boilerplate" functions may be made public // in a future ICU4C release when all subclasses implement them @@ -214,6 +282,39 @@ protected: */ }; +#ifndef U_HIDE_INTERNAL_API +/** + * This is a simple macro to add ICU RTTI to an ICU object implementation. + * This does not go into the header. This should only be used in *.cpp files. + * + * @param myClass The name of the class that needs RTTI defined. + * @internal + */ +#define UOBJECT_DEFINE_RTTI_IMPLEMENTATION(myClass) \ + UClassID U_EXPORT2 myClass::getStaticClassID() { \ + static char classID = 0; \ + return (UClassID)&classID; \ + } \ + UClassID myClass::getDynamicClassID() const \ + { return myClass::getStaticClassID(); } + + +/** + * This macro adds ICU RTTI to an ICU abstract class implementation. + * This macro should be invoked in *.cpp files. The corresponding + * header should declare getStaticClassID. + * + * @param myClass The name of the class that needs RTTI defined. + * @internal + */ +#define UOBJECT_DEFINE_ABSTRACT_RTTI_IMPLEMENTATION(myClass) \ + UClassID U_EXPORT2 myClass::getStaticClassID() { \ + static char classID = 0; \ + return (UClassID)&classID; \ + } + +#endif /* U_HIDE_INTERNAL_API */ + U_NAMESPACE_END #endif