annotate CSP2/CSP2_env/env-d9b9114564458d9d-741b3de822f2aaca6c6caa4325c4afce/include/unicode/localpointer.h @ 69:33d812a61356

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