| 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 bool operator==(const UObject &other) const { return this==&other; } | 
| 266 |     inline bool 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 |  |