| 1 | // © 2016 and later: Unicode, Inc. and others. | 
|---|
| 2 | // License & terms of use: http://www.unicode.org/copyright.html | 
|---|
| 3 | /* | 
|---|
| 4 | ****************************************************************************** | 
|---|
| 5 | * | 
|---|
| 6 | *   Copyright (C) 2002-2012, International Business Machines | 
|---|
| 7 | *   Corporation and others.  All Rights Reserved. | 
|---|
| 8 | * | 
|---|
| 9 | ****************************************************************************** | 
|---|
| 10 | *   file name:  uobject.h | 
|---|
| 11 | *   encoding:   UTF-8 | 
|---|
| 12 | *   tab size:   8 (not used) | 
|---|
| 13 | *   indentation:4 | 
|---|
| 14 | * | 
|---|
| 15 | *   created on: 2002jun26 | 
|---|
| 16 | *   created by: Markus W. Scherer | 
|---|
| 17 | */ | 
|---|
| 18 |  | 
|---|
| 19 | #ifndef __UOBJECT_H__ | 
|---|
| 20 | #define __UOBJECT_H__ | 
|---|
| 21 |  | 
|---|
| 22 | #include "unicode/utypes.h" | 
|---|
| 23 |  | 
|---|
| 24 | #if U_SHOW_CPLUSPLUS_API | 
|---|
| 25 |  | 
|---|
| 26 | #include "unicode/platform.h" | 
|---|
| 27 |  | 
|---|
| 28 | /** | 
|---|
| 29 | * \file | 
|---|
| 30 | * \brief C++ API: Common ICU base class UObject. | 
|---|
| 31 | */ | 
|---|
| 32 |  | 
|---|
| 33 | /** | 
|---|
| 34 | * \def U_NO_THROW | 
|---|
| 35 | *         Since ICU 64, use U_NOEXCEPT instead. | 
|---|
| 36 | * | 
|---|
| 37 | *         Previously, define this to define the throw() specification so | 
|---|
| 38 | *                 certain functions do not throw any exceptions | 
|---|
| 39 | * | 
|---|
| 40 | *         UMemory operator new methods should have the throw() specification | 
|---|
| 41 | *         appended to them, so that the compiler adds the additional NULL check | 
|---|
| 42 | *         before calling constructors. Without, if <code>operator new</code> returns NULL the | 
|---|
| 43 | *         constructor is still called, and if the constructor references member | 
|---|
| 44 | *         data, (which it typically does), the result is a segmentation violation. | 
|---|
| 45 | * | 
|---|
| 46 | * @stable ICU 4.2. Since ICU 64, Use U_NOEXCEPT instead. See ICU-20422. | 
|---|
| 47 | */ | 
|---|
| 48 | #ifndef U_NO_THROW | 
|---|
| 49 | #define U_NO_THROW U_NOEXCEPT | 
|---|
| 50 | #endif | 
|---|
| 51 |  | 
|---|
| 52 | /*===========================================================================*/ | 
|---|
| 53 | /* UClassID-based RTTI */ | 
|---|
| 54 | /*===========================================================================*/ | 
|---|
| 55 |  | 
|---|
| 56 | /** | 
|---|
| 57 | * UClassID is used to identify classes without using the compiler's RTTI. | 
|---|
| 58 | * This was used before C++ compilers consistently supported RTTI. | 
|---|
| 59 | * ICU 4.6 requires compiler RTTI to be turned on. | 
|---|
| 60 | * | 
|---|
| 61 | * Each class hierarchy which needs | 
|---|
| 62 | * to implement polymorphic clone() or operator==() defines two methods, | 
|---|
| 63 | * described in detail below.  UClassID values can be compared using | 
|---|
| 64 | * operator==(). Nothing else should be done with them. | 
|---|
| 65 | * | 
|---|
| 66 | * \par | 
|---|
| 67 | * In class hierarchies that implement "poor man's RTTI", | 
|---|
| 68 | * each concrete subclass implements getDynamicClassID() in the same way: | 
|---|
| 69 | * | 
|---|
| 70 | * \code | 
|---|
| 71 | *      class Derived { | 
|---|
| 72 | *      public: | 
|---|
| 73 | *          virtual UClassID getDynamicClassID() const | 
|---|
| 74 | *            { return Derived::getStaticClassID(); } | 
|---|
| 75 | *      } | 
|---|
| 76 | * \endcode | 
|---|
| 77 | * | 
|---|
| 78 | * Each concrete class implements getStaticClassID() as well, which allows | 
|---|
| 79 | * clients to test for a specific type. | 
|---|
| 80 | * | 
|---|
| 81 | * \code | 
|---|
| 82 | *      class Derived { | 
|---|
| 83 | *      public: | 
|---|
| 84 | *          static UClassID U_EXPORT2 getStaticClassID(); | 
|---|
| 85 | *      private: | 
|---|
| 86 | *          static char fgClassID; | 
|---|
| 87 | *      } | 
|---|
| 88 | * | 
|---|
| 89 | *      // In Derived.cpp: | 
|---|
| 90 | *      UClassID Derived::getStaticClassID() | 
|---|
| 91 | *        { return (UClassID)&Derived::fgClassID; } | 
|---|
| 92 | *      char Derived::fgClassID = 0; // Value is irrelevant | 
|---|
| 93 | * \endcode | 
|---|
| 94 | * @stable ICU 2.0 | 
|---|
| 95 | */ | 
|---|
| 96 | typedef void* UClassID; | 
|---|
| 97 |  | 
|---|
| 98 | U_NAMESPACE_BEGIN | 
|---|
| 99 |  | 
|---|
| 100 | /** | 
|---|
| 101 | * UMemory is the common ICU base class. | 
|---|
| 102 | * All other ICU C++ classes are derived from UMemory (starting with ICU 2.4). | 
|---|
| 103 | * | 
|---|
| 104 | * This is primarily to make it possible and simple to override the | 
|---|
| 105 | * C++ memory management by adding new/delete operators to this base class. | 
|---|
| 106 | * | 
|---|
| 107 | * To override ALL ICU memory management, including that from plain C code, | 
|---|
| 108 | * replace the allocation functions declared in cmemory.h | 
|---|
| 109 | * | 
|---|
| 110 | * UMemory does not contain any virtual functions. | 
|---|
| 111 | * Common "boilerplate" functions are defined in UObject. | 
|---|
| 112 | * | 
|---|
| 113 | * @stable ICU 2.4 | 
|---|
| 114 | */ | 
|---|
| 115 | class U_COMMON_API UMemory { | 
|---|
| 116 | public: | 
|---|
| 117 |  | 
|---|
| 118 | /* test versions for debugging shaper heap memory problems */ | 
|---|
| 119 | #ifdef SHAPER_MEMORY_DEBUG | 
|---|
| 120 | static void * NewArray(int size, int count); | 
|---|
| 121 | static void * GrowArray(void * array, int newSize ); | 
|---|
| 122 | static void   FreeArray(void * array ); | 
|---|
| 123 | #endif | 
|---|
| 124 |  | 
|---|
| 125 | #if U_OVERRIDE_CXX_ALLOCATION | 
|---|
| 126 | /** | 
|---|
| 127 | * Override for ICU4C C++ memory management. | 
|---|
| 128 | * simple, non-class types are allocated using the macros in common/cmemory.h | 
|---|
| 129 | * (uprv_malloc(), uprv_free(), uprv_realloc()); | 
|---|
| 130 | * they or something else could be used here to implement C++ new/delete | 
|---|
| 131 | * for ICU4C C++ classes | 
|---|
| 132 | * @stable ICU 2.4 | 
|---|
| 133 | */ | 
|---|
| 134 | static void * U_EXPORT2 operator new(size_t size) U_NOEXCEPT; | 
|---|
| 135 |  | 
|---|
| 136 | /** | 
|---|
| 137 | * Override for ICU4C C++ memory management. | 
|---|
| 138 | * See new(). | 
|---|
| 139 | * @stable ICU 2.4 | 
|---|
| 140 | */ | 
|---|
| 141 | static void * U_EXPORT2 operator new[](size_t size) U_NOEXCEPT; | 
|---|
| 142 |  | 
|---|
| 143 | /** | 
|---|
| 144 | * Override for ICU4C C++ memory management. | 
|---|
| 145 | * simple, non-class types are allocated using the macros in common/cmemory.h | 
|---|
| 146 | * (uprv_malloc(), uprv_free(), uprv_realloc()); | 
|---|
| 147 | * they or something else could be used here to implement C++ new/delete | 
|---|
| 148 | * for ICU4C C++ classes | 
|---|
| 149 | * @stable ICU 2.4 | 
|---|
| 150 | */ | 
|---|
| 151 | static void U_EXPORT2 operator delete(void *p) U_NOEXCEPT; | 
|---|
| 152 |  | 
|---|
| 153 | /** | 
|---|
| 154 | * Override for ICU4C C++ memory management. | 
|---|
| 155 | * See delete(). | 
|---|
| 156 | * @stable ICU 2.4 | 
|---|
| 157 | */ | 
|---|
| 158 | static void U_EXPORT2 operator delete[](void *p) U_NOEXCEPT; | 
|---|
| 159 |  | 
|---|
| 160 | #if U_HAVE_PLACEMENT_NEW | 
|---|
| 161 | /** | 
|---|
| 162 | * Override for ICU4C C++ memory management for STL. | 
|---|
| 163 | * See new(). | 
|---|
| 164 | * @stable ICU 2.6 | 
|---|
| 165 | */ | 
|---|
| 166 | static inline void * U_EXPORT2 operator new(size_t, void *ptr) U_NOEXCEPT { return ptr; } | 
|---|
| 167 |  | 
|---|
| 168 | /** | 
|---|
| 169 | * Override for ICU4C C++ memory management for STL. | 
|---|
| 170 | * See delete(). | 
|---|
| 171 | * @stable ICU 2.6 | 
|---|
| 172 | */ | 
|---|
| 173 | static inline void U_EXPORT2 operator delete(void *, void *) U_NOEXCEPT {} | 
|---|
| 174 | #endif /* U_HAVE_PLACEMENT_NEW */ | 
|---|
| 175 | #if U_HAVE_DEBUG_LOCATION_NEW | 
|---|
| 176 | /** | 
|---|
| 177 | * This method overrides the MFC debug version of the operator new | 
|---|
| 178 | * | 
|---|
| 179 | * @param size   The requested memory size | 
|---|
| 180 | * @param file   The file where the allocation was requested | 
|---|
| 181 | * @param line   The line where the allocation was requested | 
|---|
| 182 | */ | 
|---|
| 183 | static void * U_EXPORT2 operator new(size_t size, const char* file, int line) U_NOEXCEPT; | 
|---|
| 184 | /** | 
|---|
| 185 | * This method provides a matching delete for the MFC debug new | 
|---|
| 186 | * | 
|---|
| 187 | * @param p      The pointer to the allocated memory | 
|---|
| 188 | * @param file   The file where the allocation was requested | 
|---|
| 189 | * @param line   The line where the allocation was requested | 
|---|
| 190 | */ | 
|---|
| 191 | static void U_EXPORT2 operator delete(void* p, const char* file, int line) U_NOEXCEPT; | 
|---|
| 192 | #endif /* U_HAVE_DEBUG_LOCATION_NEW */ | 
|---|
| 193 | #endif /* U_OVERRIDE_CXX_ALLOCATION */ | 
|---|
| 194 |  | 
|---|
| 195 | /* | 
|---|
| 196 | * Assignment operator not declared. The compiler will provide one | 
|---|
| 197 | * which does nothing since this class does not contain any data members. | 
|---|
| 198 | * API/code coverage may show the assignment operator as present and | 
|---|
| 199 | * untested - ignore. | 
|---|
| 200 | * Subclasses need this assignment operator if they use compiler-provided | 
|---|
| 201 | * assignment operators of their own. An alternative to not declaring one | 
|---|
| 202 | * here would be to declare and empty-implement a protected or public one. | 
|---|
| 203 | UMemory &UMemory::operator=(const UMemory &); | 
|---|
| 204 | */ | 
|---|
| 205 | }; | 
|---|
| 206 |  | 
|---|
| 207 | /** | 
|---|
| 208 | * UObject is the common ICU "boilerplate" class. | 
|---|
| 209 | * UObject inherits UMemory (starting with ICU 2.4), | 
|---|
| 210 | * and all other public ICU C++ classes | 
|---|
| 211 | * are derived from UObject (starting with ICU 2.2). | 
|---|
| 212 | * | 
|---|
| 213 | * UObject contains common virtual functions, in particular a virtual destructor. | 
|---|
| 214 | * | 
|---|
| 215 | * The clone() function is not available in UObject because it is not | 
|---|
| 216 | * implemented by all ICU classes. | 
|---|
| 217 | * Many ICU services provide a clone() function for their class trees, | 
|---|
| 218 | * defined on the service's C++ base class | 
|---|
| 219 | * (which itself is a subclass of UObject). | 
|---|
| 220 | * | 
|---|
| 221 | * @stable ICU 2.2 | 
|---|
| 222 | */ | 
|---|
| 223 | class U_COMMON_API UObject : public UMemory { | 
|---|
| 224 | public: | 
|---|
| 225 | /** | 
|---|
| 226 | * Destructor. | 
|---|
| 227 | * | 
|---|
| 228 | * @stable ICU 2.2 | 
|---|
| 229 | */ | 
|---|
| 230 | virtual ~UObject(); | 
|---|
| 231 |  | 
|---|
| 232 | /** | 
|---|
| 233 | * ICU4C "poor man's RTTI", returns a UClassID for the actual ICU class. | 
|---|
| 234 | * The base class implementation returns a dummy value. | 
|---|
| 235 | * | 
|---|
| 236 | * Use compiler RTTI rather than ICU's "poor man's RTTI". | 
|---|
| 237 | * Since ICU 4.6, new ICU C++ class hierarchies do not implement "poor man's RTTI". | 
|---|
| 238 | * | 
|---|
| 239 | * @stable ICU 2.2 | 
|---|
| 240 | */ | 
|---|
| 241 | virtual UClassID getDynamicClassID() const; | 
|---|
| 242 |  | 
|---|
| 243 | protected: | 
|---|
| 244 | // the following functions are protected to prevent instantiation and | 
|---|
| 245 | // direct use of UObject itself | 
|---|
| 246 |  | 
|---|
| 247 | // default constructor | 
|---|
| 248 | // inline UObject() {} | 
|---|
| 249 |  | 
|---|
| 250 | // copy constructor | 
|---|
| 251 | // inline UObject(const UObject &other) {} | 
|---|
| 252 |  | 
|---|
| 253 | #if 0 | 
|---|
| 254 | // TODO Sometime in the future. Implement operator==(). | 
|---|
| 255 | // (This comment inserted in 2.2) | 
|---|
| 256 | // some or all of the following "boilerplate" functions may be made public | 
|---|
| 257 | // in a future ICU4C release when all subclasses implement them | 
|---|
| 258 |  | 
|---|
| 259 | // assignment operator | 
|---|
| 260 | // (not virtual, see "Taligent's Guide to Designing Programs" pp.73..74) | 
|---|
| 261 | // commented out because the implementation is the same as a compiler's default | 
|---|
| 262 | // UObject &operator=(const UObject &other) { return *this; } | 
|---|
| 263 |  | 
|---|
| 264 | // comparison operators | 
|---|
| 265 | virtual inline UBool operator==(const UObject &other) const { return this==&other; } | 
|---|
| 266 | inline UBool operator!=(const UObject &other) const { return !operator==(other); } | 
|---|
| 267 |  | 
|---|
| 268 | // clone() commented out from the base class: | 
|---|
| 269 | // some compilers do not support co-variant return types | 
|---|
| 270 | // (i.e., subclasses would have to return UObject * as well, instead of SubClass *) | 
|---|
| 271 | // see also UObject class documentation. | 
|---|
| 272 | // virtual UObject *clone() const; | 
|---|
| 273 | #endif | 
|---|
| 274 |  | 
|---|
| 275 | /* | 
|---|
| 276 | * Assignment operator not declared. The compiler will provide one | 
|---|
| 277 | * which does nothing since this class does not contain any data members. | 
|---|
| 278 | * API/code coverage may show the assignment operator as present and | 
|---|
| 279 | * untested - ignore. | 
|---|
| 280 | * Subclasses need this assignment operator if they use compiler-provided | 
|---|
| 281 | * assignment operators of their own. An alternative to not declaring one | 
|---|
| 282 | * here would be to declare and empty-implement a protected or public one. | 
|---|
| 283 | UObject &UObject::operator=(const UObject &); | 
|---|
| 284 | */ | 
|---|
| 285 | }; | 
|---|
| 286 |  | 
|---|
| 287 | #ifndef U_HIDE_INTERNAL_API | 
|---|
| 288 | /** | 
|---|
| 289 | * This is a simple macro to add ICU RTTI to an ICU object implementation. | 
|---|
| 290 | * This does not go into the header. This should only be used in *.cpp files. | 
|---|
| 291 | * | 
|---|
| 292 | * @param myClass The name of the class that needs RTTI defined. | 
|---|
| 293 | * @internal | 
|---|
| 294 | */ | 
|---|
| 295 | #define UOBJECT_DEFINE_RTTI_IMPLEMENTATION(myClass) \ | 
|---|
| 296 | UClassID U_EXPORT2 myClass::getStaticClassID() { \ | 
|---|
| 297 | static char classID = 0; \ | 
|---|
| 298 | return (UClassID)&classID; \ | 
|---|
| 299 | } \ | 
|---|
| 300 | UClassID myClass::getDynamicClassID() const \ | 
|---|
| 301 | { return myClass::getStaticClassID(); } | 
|---|
| 302 |  | 
|---|
| 303 |  | 
|---|
| 304 | /** | 
|---|
| 305 | * This macro adds ICU RTTI to an ICU abstract class implementation. | 
|---|
| 306 | * This macro should be invoked in *.cpp files.  The corresponding | 
|---|
| 307 | * header should declare getStaticClassID. | 
|---|
| 308 | * | 
|---|
| 309 | * @param myClass The name of the class that needs RTTI defined. | 
|---|
| 310 | * @internal | 
|---|
| 311 | */ | 
|---|
| 312 | #define UOBJECT_DEFINE_ABSTRACT_RTTI_IMPLEMENTATION(myClass) \ | 
|---|
| 313 | UClassID U_EXPORT2 myClass::getStaticClassID() { \ | 
|---|
| 314 | static char classID = 0; \ | 
|---|
| 315 | return (UClassID)&classID; \ | 
|---|
| 316 | } | 
|---|
| 317 |  | 
|---|
| 318 | #endif  /* U_HIDE_INTERNAL_API */ | 
|---|
| 319 |  | 
|---|
| 320 | U_NAMESPACE_END | 
|---|
| 321 |  | 
|---|
| 322 | #endif /* U_SHOW_CPLUSPLUS_API */ | 
|---|
| 323 |  | 
|---|
| 324 | #endif | 
|---|
| 325 |  | 
|---|