localpointer.h 18 KB

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