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) 2009-2016, International Business Machines 7 * Corporation and others. All Rights Reserved. 8 * 9 ******************************************************************************* 10 * file name: localpointer.h 11 * encoding: UTF-8 12 * tab size: 8 (not used) 13 * indentation:4 14 * 15 * created on: 2009nov13 16 * created by: Markus W. Scherer 17 */ 18 19 #ifndef __LOCALPOINTER_H__ 20 #define __LOCALPOINTER_H__ 21 22 /** 23 * \file 24 * \brief C++ API: "Smart pointers" for use with and in ICU4C C++ code. 25 * 26 * These classes are inspired by 27 * - std::auto_ptr 28 * - boost::scoped_ptr & boost::scoped_array 29 * - Taligent Safe Pointers (TOnlyPointerTo) 30 * 31 * but none of those provide for all of the goals for ICU smart pointers: 32 * - Smart pointer owns the object and releases it when it goes out of scope. 33 * - No transfer of ownership via copy/assignment to reduce misuse. Simpler & more robust. 34 * - ICU-compatible: No exceptions. 35 * - Need to be able to orphan/release the pointer and its ownership. 36 * - Need variants for normal C++ object pointers, C++ arrays, and ICU C service objects. 37 * 38 * For details see http://site.icu-project.org/design/cpp/scoped_ptr 39 */ 40 41 #include "unicode/utypes.h" 42 43 #if U_SHOW_CPLUSPLUS_API 44 45 #include <memory> 46 47 U_NAMESPACE_BEGIN 48 49 /** 50 * "Smart pointer" base class; do not use directly: use LocalPointer etc. 51 * 52 * Base class for smart pointer classes that do not throw exceptions. 53 * 54 * Do not use this base class directly, since it does not delete its pointer. 55 * A subclass must implement methods that delete the pointer: 56 * Destructor and adoptInstead(). 57 * 58 * There is no operator T *() provided because the programmer must decide 59 * whether to use getAlias() (without transfer of ownership) or orphan() 60 * (with transfer of ownership and NULLing of the pointer). 61 * 62 * @see LocalPointer 63 * @see LocalArray 64 * @see U_DEFINE_LOCAL_OPEN_POINTER 65 * @stable ICU 4.4 66 */ 67 template<typename T> 68 class LocalPointerBase { 69 public: 70 // No heap allocation. Use only on the stack. 71 static void* U_EXPORT2 operator new(size_t) = delete; 72 static void* U_EXPORT2 operator new[](size_t) = delete; 73 #if U_HAVE_PLACEMENT_NEW 74 static void* U_EXPORT2 operator new(size_t, void*) = delete; 75 #endif 76 77 /** 78 * Constructor takes ownership. 79 * @param p simple pointer to an object that is adopted 80 * @stable ICU 4.4 81 */ ptr(p)82 explicit LocalPointerBase(T *p=NULL) : ptr(p) {} 83 /** 84 * Destructor deletes the object it owns. 85 * Subclass must override: Base class does nothing. 86 * @stable ICU 4.4 87 */ ~LocalPointerBase()88 ~LocalPointerBase() { /* delete ptr; */ } 89 /** 90 * NULL check. 91 * @return true if ==NULL 92 * @stable ICU 4.4 93 */ isNull()94 UBool isNull() const { return ptr==NULL; } 95 /** 96 * NULL check. 97 * @return true if !=NULL 98 * @stable ICU 4.4 99 */ isValid()100 UBool isValid() const { return ptr!=NULL; } 101 /** 102 * Comparison with a simple pointer, so that existing code 103 * with ==NULL need not be changed. 104 * @param other simple pointer for comparison 105 * @return true if this pointer value equals other 106 * @stable ICU 4.4 107 */ 108 bool operator==(const T *other) const { return ptr==other; } 109 /** 110 * Comparison with a simple pointer, so that existing code 111 * with !=NULL need not be changed. 112 * @param other simple pointer for comparison 113 * @return true if this pointer value differs from other 114 * @stable ICU 4.4 115 */ 116 bool operator!=(const T *other) const { return ptr!=other; } 117 /** 118 * Access without ownership change. 119 * @return the pointer value 120 * @stable ICU 4.4 121 */ getAlias()122 T *getAlias() const { return ptr; } 123 /** 124 * Access without ownership change. 125 * @return the pointer value as a reference 126 * @stable ICU 4.4 127 */ 128 T &operator*() const { return *ptr; } 129 /** 130 * Access without ownership change. 131 * @return the pointer value 132 * @stable ICU 4.4 133 */ 134 T *operator->() const { return ptr; } 135 /** 136 * Gives up ownership; the internal pointer becomes NULL. 137 * @return the pointer value; 138 * caller becomes responsible for deleting the object 139 * @stable ICU 4.4 140 */ orphan()141 T *orphan() { 142 T *p=ptr; 143 ptr=NULL; 144 return p; 145 } 146 /** 147 * Deletes the object it owns, 148 * and adopts (takes ownership of) the one passed in. 149 * Subclass must override: Base class does not delete the object. 150 * @param p simple pointer to an object that is adopted 151 * @stable ICU 4.4 152 */ adoptInstead(T * p)153 void adoptInstead(T *p) { 154 // delete ptr; 155 ptr=p; 156 } 157 protected: 158 /** 159 * Actual pointer. 160 * @internal 161 */ 162 T *ptr; 163 private: 164 // No comparison operators with other LocalPointerBases. 165 bool operator==(const LocalPointerBase<T> &other); 166 bool operator!=(const LocalPointerBase<T> &other); 167 // No ownership sharing: No copy constructor, no assignment operator. 168 LocalPointerBase(const LocalPointerBase<T> &other); 169 void operator=(const LocalPointerBase<T> &other); 170 }; 171 172 /** 173 * "Smart pointer" class, deletes objects via the standard C++ delete operator. 174 * For most methods see the LocalPointerBase base class. 175 * 176 * Usage example: 177 * \code 178 * LocalPointer<UnicodeString> s(new UnicodeString((UChar32)0x50005)); 179 * int32_t length=s->length(); // 2 180 * char16_t lead=s->charAt(0); // 0xd900 181 * if(some condition) { return; } // no need to explicitly delete the pointer 182 * s.adoptInstead(new UnicodeString((char16_t)0xfffc)); 183 * length=s->length(); // 1 184 * // no need to explicitly delete the pointer 185 * \endcode 186 * 187 * @see LocalPointerBase 188 * @stable ICU 4.4 189 */ 190 template<typename T> 191 class LocalPointer : public LocalPointerBase<T> { 192 public: 193 using LocalPointerBase<T>::operator*; 194 using LocalPointerBase<T>::operator->; 195 /** 196 * Constructor takes ownership. 197 * @param p simple pointer to an object that is adopted 198 * @stable ICU 4.4 199 */ 200 explicit LocalPointer(T *p=NULL) : LocalPointerBase<T>(p) {} 201 /** 202 * Constructor takes ownership and reports an error if NULL. 203 * 204 * This constructor is intended to be used with other-class constructors 205 * that may report a failure UErrorCode, 206 * so that callers need to check only for U_FAILURE(errorCode) 207 * and not also separately for isNull(). 208 * 209 * @param p simple pointer to an object that is adopted 210 * @param errorCode in/out UErrorCode, set to U_MEMORY_ALLOCATION_ERROR 211 * if p==NULL and no other failure code had been set 212 * @stable ICU 55 213 */ LocalPointer(T * p,UErrorCode & errorCode)214 LocalPointer(T *p, UErrorCode &errorCode) : LocalPointerBase<T>(p) { 215 if(p==NULL && U_SUCCESS(errorCode)) { 216 errorCode=U_MEMORY_ALLOCATION_ERROR; 217 } 218 } 219 /** 220 * Move constructor, leaves src with isNull(). 221 * @param src source smart pointer 222 * @stable ICU 56 223 */ LocalPointer(LocalPointer<T> && src)224 LocalPointer(LocalPointer<T> &&src) U_NOEXCEPT : LocalPointerBase<T>(src.ptr) { 225 src.ptr=NULL; 226 } 227 228 /** 229 * Constructs a LocalPointer from a C++11 std::unique_ptr. 230 * The LocalPointer steals the object owned by the std::unique_ptr. 231 * 232 * This constructor works via move semantics. If your std::unique_ptr is 233 * in a local variable, you must use std::move. 234 * 235 * @param p The std::unique_ptr from which the pointer will be stolen. 236 * @stable ICU 64 237 */ LocalPointer(std::unique_ptr<T> && p)238 explicit LocalPointer(std::unique_ptr<T> &&p) 239 : LocalPointerBase<T>(p.release()) {} 240 241 /** 242 * Destructor deletes the object it owns. 243 * @stable ICU 4.4 244 */ ~LocalPointer()245 ~LocalPointer() { 246 delete LocalPointerBase<T>::ptr; 247 } 248 /** 249 * Move assignment operator, leaves src with isNull(). 250 * The behavior is undefined if *this and src are the same object. 251 * @param src source smart pointer 252 * @return *this 253 * @stable ICU 56 254 */ 255 LocalPointer<T> &operator=(LocalPointer<T> &&src) U_NOEXCEPT { 256 delete LocalPointerBase<T>::ptr; 257 LocalPointerBase<T>::ptr=src.ptr; 258 src.ptr=NULL; 259 return *this; 260 } 261 262 /** 263 * Move-assign from an std::unique_ptr to this LocalPointer. 264 * Steals the pointer from the std::unique_ptr. 265 * 266 * @param p The std::unique_ptr from which the pointer will be stolen. 267 * @return *this 268 * @stable ICU 64 269 */ 270 LocalPointer<T> &operator=(std::unique_ptr<T> &&p) U_NOEXCEPT { 271 adoptInstead(p.release()); 272 return *this; 273 } 274 275 /** 276 * Swap pointers. 277 * @param other other smart pointer 278 * @stable ICU 56 279 */ swap(LocalPointer<T> & other)280 void swap(LocalPointer<T> &other) U_NOEXCEPT { 281 T *temp=LocalPointerBase<T>::ptr; 282 LocalPointerBase<T>::ptr=other.ptr; 283 other.ptr=temp; 284 } 285 /** 286 * Non-member LocalPointer swap function. 287 * @param p1 will get p2's pointer 288 * @param p2 will get p1's pointer 289 * @stable ICU 56 290 */ swap(LocalPointer<T> & p1,LocalPointer<T> & p2)291 friend inline void swap(LocalPointer<T> &p1, LocalPointer<T> &p2) U_NOEXCEPT { 292 p1.swap(p2); 293 } 294 /** 295 * Deletes the object it owns, 296 * and adopts (takes ownership of) the one passed in. 297 * @param p simple pointer to an object that is adopted 298 * @stable ICU 4.4 299 */ adoptInstead(T * p)300 void adoptInstead(T *p) { 301 delete LocalPointerBase<T>::ptr; 302 LocalPointerBase<T>::ptr=p; 303 } 304 /** 305 * Deletes the object it owns, 306 * and adopts (takes ownership of) the one passed in. 307 * 308 * If U_FAILURE(errorCode), then the current object is retained and the new one deleted. 309 * 310 * If U_SUCCESS(errorCode) but the input pointer is NULL, 311 * then U_MEMORY_ALLOCATION_ERROR is set, 312 * the current object is deleted, and NULL is set. 313 * 314 * @param p simple pointer to an object that is adopted 315 * @param errorCode in/out UErrorCode, set to U_MEMORY_ALLOCATION_ERROR 316 * if p==NULL and no other failure code had been set 317 * @stable ICU 55 318 */ adoptInsteadAndCheckErrorCode(T * p,UErrorCode & errorCode)319 void adoptInsteadAndCheckErrorCode(T *p, UErrorCode &errorCode) { 320 if(U_SUCCESS(errorCode)) { 321 delete LocalPointerBase<T>::ptr; 322 LocalPointerBase<T>::ptr=p; 323 if(p==NULL) { 324 errorCode=U_MEMORY_ALLOCATION_ERROR; 325 } 326 } else { 327 delete p; 328 } 329 } 330 331 /** 332 * Conversion operator to a C++11 std::unique_ptr. 333 * Disowns the object and gives it to the returned std::unique_ptr. 334 * 335 * This operator works via move semantics. If your LocalPointer is 336 * in a local variable, you must use std::move. 337 * 338 * @return An std::unique_ptr owning the pointer previously owned by this 339 * icu::LocalPointer. 340 * @stable ICU 64 341 */ 342 operator std::unique_ptr<T> () && { 343 return std::unique_ptr<T>(LocalPointerBase<T>::orphan()); 344 } 345 }; 346 347 /** 348 * "Smart pointer" class, deletes objects via the C++ array delete[] operator. 349 * For most methods see the LocalPointerBase base class. 350 * Adds operator[] for array item access. 351 * 352 * Usage example: 353 * \code 354 * LocalArray<UnicodeString> a(new UnicodeString[2]); 355 * a[0].append((char16_t)0x61); 356 * if(some condition) { return; } // no need to explicitly delete the array 357 * a.adoptInstead(new UnicodeString[4]); 358 * a[3].append((char16_t)0x62).append((char16_t)0x63).reverse(); 359 * // no need to explicitly delete the array 360 * \endcode 361 * 362 * @see LocalPointerBase 363 * @stable ICU 4.4 364 */ 365 template<typename T> 366 class LocalArray : public LocalPointerBase<T> { 367 public: 368 using LocalPointerBase<T>::operator*; 369 using LocalPointerBase<T>::operator->; 370 /** 371 * Constructor takes ownership. 372 * @param p simple pointer to an array of T objects that is adopted 373 * @stable ICU 4.4 374 */ 375 explicit LocalArray(T *p=NULL) : LocalPointerBase<T>(p) {} 376 /** 377 * Constructor takes ownership and reports an error if NULL. 378 * 379 * This constructor is intended to be used with other-class constructors 380 * that may report a failure UErrorCode, 381 * so that callers need to check only for U_FAILURE(errorCode) 382 * and not also separately for isNull(). 383 * 384 * @param p simple pointer to an array of T objects that is adopted 385 * @param errorCode in/out UErrorCode, set to U_MEMORY_ALLOCATION_ERROR 386 * if p==NULL and no other failure code had been set 387 * @stable ICU 56 388 */ LocalArray(T * p,UErrorCode & errorCode)389 LocalArray(T *p, UErrorCode &errorCode) : LocalPointerBase<T>(p) { 390 if(p==NULL && U_SUCCESS(errorCode)) { 391 errorCode=U_MEMORY_ALLOCATION_ERROR; 392 } 393 } 394 /** 395 * Move constructor, leaves src with isNull(). 396 * @param src source smart pointer 397 * @stable ICU 56 398 */ LocalArray(LocalArray<T> && src)399 LocalArray(LocalArray<T> &&src) U_NOEXCEPT : LocalPointerBase<T>(src.ptr) { 400 src.ptr=NULL; 401 } 402 403 /** 404 * Constructs a LocalArray from a C++11 std::unique_ptr of an array type. 405 * The LocalPointer steals the array owned by the std::unique_ptr. 406 * 407 * This constructor works via move semantics. If your std::unique_ptr is 408 * in a local variable, you must use std::move. 409 * 410 * @param p The std::unique_ptr from which the array will be stolen. 411 * @stable ICU 64 412 */ LocalArray(std::unique_ptr<T[]> && p)413 explicit LocalArray(std::unique_ptr<T[]> &&p) 414 : LocalPointerBase<T>(p.release()) {} 415 416 /** 417 * Destructor deletes the array it owns. 418 * @stable ICU 4.4 419 */ ~LocalArray()420 ~LocalArray() { 421 delete[] LocalPointerBase<T>::ptr; 422 } 423 /** 424 * Move assignment operator, leaves src with isNull(). 425 * The behavior is undefined if *this and src are the same object. 426 * @param src source smart pointer 427 * @return *this 428 * @stable ICU 56 429 */ 430 LocalArray<T> &operator=(LocalArray<T> &&src) U_NOEXCEPT { 431 delete[] LocalPointerBase<T>::ptr; 432 LocalPointerBase<T>::ptr=src.ptr; 433 src.ptr=NULL; 434 return *this; 435 } 436 437 /** 438 * Move-assign from an std::unique_ptr to this LocalPointer. 439 * Steals the array from the std::unique_ptr. 440 * 441 * @param p The std::unique_ptr from which the array will be stolen. 442 * @return *this 443 * @stable ICU 64 444 */ 445 LocalArray<T> &operator=(std::unique_ptr<T[]> &&p) U_NOEXCEPT { 446 adoptInstead(p.release()); 447 return *this; 448 } 449 450 /** 451 * Swap pointers. 452 * @param other other smart pointer 453 * @stable ICU 56 454 */ swap(LocalArray<T> & other)455 void swap(LocalArray<T> &other) U_NOEXCEPT { 456 T *temp=LocalPointerBase<T>::ptr; 457 LocalPointerBase<T>::ptr=other.ptr; 458 other.ptr=temp; 459 } 460 /** 461 * Non-member LocalArray swap function. 462 * @param p1 will get p2's pointer 463 * @param p2 will get p1's pointer 464 * @stable ICU 56 465 */ swap(LocalArray<T> & p1,LocalArray<T> & p2)466 friend inline void swap(LocalArray<T> &p1, LocalArray<T> &p2) U_NOEXCEPT { 467 p1.swap(p2); 468 } 469 /** 470 * Deletes the array it owns, 471 * and adopts (takes ownership of) the one passed in. 472 * @param p simple pointer to an array of T objects that is adopted 473 * @stable ICU 4.4 474 */ adoptInstead(T * p)475 void adoptInstead(T *p) { 476 delete[] LocalPointerBase<T>::ptr; 477 LocalPointerBase<T>::ptr=p; 478 } 479 /** 480 * Deletes the array it owns, 481 * and adopts (takes ownership of) the one passed in. 482 * 483 * If U_FAILURE(errorCode), then the current array is retained and the new one deleted. 484 * 485 * If U_SUCCESS(errorCode) but the input pointer is NULL, 486 * then U_MEMORY_ALLOCATION_ERROR is set, 487 * the current array is deleted, and NULL is set. 488 * 489 * @param p simple pointer to an array of T objects that is adopted 490 * @param errorCode in/out UErrorCode, set to U_MEMORY_ALLOCATION_ERROR 491 * if p==NULL and no other failure code had been set 492 * @stable ICU 56 493 */ adoptInsteadAndCheckErrorCode(T * p,UErrorCode & errorCode)494 void adoptInsteadAndCheckErrorCode(T *p, UErrorCode &errorCode) { 495 if(U_SUCCESS(errorCode)) { 496 delete[] LocalPointerBase<T>::ptr; 497 LocalPointerBase<T>::ptr=p; 498 if(p==NULL) { 499 errorCode=U_MEMORY_ALLOCATION_ERROR; 500 } 501 } else { 502 delete[] p; 503 } 504 } 505 /** 506 * Array item access (writable). 507 * No index bounds check. 508 * @param i array index 509 * @return reference to the array item 510 * @stable ICU 4.4 511 */ 512 T &operator[](ptrdiff_t i) const { return LocalPointerBase<T>::ptr[i]; } 513 514 /** 515 * Conversion operator to a C++11 std::unique_ptr. 516 * Disowns the object and gives it to the returned std::unique_ptr. 517 * 518 * This operator works via move semantics. If your LocalPointer is 519 * in a local variable, you must use std::move. 520 * 521 * @return An std::unique_ptr owning the pointer previously owned by this 522 * icu::LocalPointer. 523 * @stable ICU 64 524 */ 525 operator std::unique_ptr<T[]> () && { 526 return std::unique_ptr<T[]>(LocalPointerBase<T>::orphan()); 527 } 528 }; 529 530 /** 531 * \def U_DEFINE_LOCAL_OPEN_POINTER 532 * "Smart pointer" definition macro, deletes objects via the closeFunction. 533 * Defines a subclass of LocalPointerBase which works just 534 * like LocalPointer<Type> except that this subclass will use the closeFunction 535 * rather than the C++ delete operator. 536 * 537 * Usage example: 538 * \code 539 * LocalUCaseMapPointer csm(ucasemap_open(localeID, options, &errorCode)); 540 * utf8OutLength=ucasemap_utf8ToLower(csm.getAlias(), 541 * utf8Out, (int32_t)sizeof(utf8Out), 542 * utf8In, utf8InLength, &errorCode); 543 * if(U_FAILURE(errorCode)) { return; } // no need to explicitly delete the UCaseMap 544 * \endcode 545 * 546 * @see LocalPointerBase 547 * @see LocalPointer 548 * @stable ICU 4.4 549 */ 550 #define U_DEFINE_LOCAL_OPEN_POINTER(LocalPointerClassName, Type, closeFunction) \ 551 class LocalPointerClassName : public LocalPointerBase<Type> { \ 552 public: \ 553 using LocalPointerBase<Type>::operator*; \ 554 using LocalPointerBase<Type>::operator->; \ 555 explicit LocalPointerClassName(Type *p=NULL) : LocalPointerBase<Type>(p) {} \ 556 LocalPointerClassName(LocalPointerClassName &&src) U_NOEXCEPT \ 557 : LocalPointerBase<Type>(src.ptr) { \ 558 src.ptr=NULL; \ 559 } \ 560 /* TODO: Be agnostic of the deleter function signature from the user-provided std::unique_ptr? */ \ 561 explicit LocalPointerClassName(std::unique_ptr<Type, decltype(&closeFunction)> &&p) \ 562 : LocalPointerBase<Type>(p.release()) {} \ 563 ~LocalPointerClassName() { if (ptr != NULL) { closeFunction(ptr); } } \ 564 LocalPointerClassName &operator=(LocalPointerClassName &&src) U_NOEXCEPT { \ 565 if (ptr != NULL) { closeFunction(ptr); } \ 566 LocalPointerBase<Type>::ptr=src.ptr; \ 567 src.ptr=NULL; \ 568 return *this; \ 569 } \ 570 /* TODO: Be agnostic of the deleter function signature from the user-provided std::unique_ptr? */ \ 571 LocalPointerClassName &operator=(std::unique_ptr<Type, decltype(&closeFunction)> &&p) { \ 572 adoptInstead(p.release()); \ 573 return *this; \ 574 } \ 575 void swap(LocalPointerClassName &other) U_NOEXCEPT { \ 576 Type *temp=LocalPointerBase<Type>::ptr; \ 577 LocalPointerBase<Type>::ptr=other.ptr; \ 578 other.ptr=temp; \ 579 } \ 580 friend inline void swap(LocalPointerClassName &p1, LocalPointerClassName &p2) U_NOEXCEPT { \ 581 p1.swap(p2); \ 582 } \ 583 void adoptInstead(Type *p) { \ 584 if (ptr != NULL) { closeFunction(ptr); } \ 585 ptr=p; \ 586 } \ 587 operator std::unique_ptr<Type, decltype(&closeFunction)> () && { \ 588 return std::unique_ptr<Type, decltype(&closeFunction)>(LocalPointerBase<Type>::orphan(), closeFunction); \ 589 } \ 590 } 591 592 U_NAMESPACE_END 593 594 #endif /* U_SHOW_CPLUSPLUS_API */ 595 #endif /* __LOCALPOINTER_H__ */ 596