ICU 78.1  78.1
localpointer.h
Go to the documentation of this file.
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 
41 #include "unicode/utypes.h"
42 
43 #if U_SHOW_CPLUSPLUS_API
44 
45 #include <memory>
46 
47 U_NAMESPACE_BEGIN
48 
67 template<typename T>
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  static void* U_EXPORT2 operator new(size_t, void*) = delete;
74 
80  explicit LocalPointerBase(T *p=nullptr) : ptr(p) {}
86  ~LocalPointerBase() { /* delete ptr; */ }
92  UBool isNull() const { return ptr==nullptr; }
98  UBool isValid() const { return ptr!=nullptr; }
106  bool operator==(const T *other) const { return ptr==other; }
114  bool operator!=(const T *other) const { return ptr!=other; }
120  T *getAlias() const { return ptr; }
126  T &operator*() const { return *ptr; }
132  T *operator->() const { return ptr; }
139  T *orphan() {
140  T *p=ptr;
141  ptr=nullptr;
142  return p;
143  }
151  void adoptInstead(T *p) {
152  // delete ptr;
153  ptr=p;
154  }
155 protected:
160  T *ptr;
161 private:
162  // No comparison operators with other LocalPointerBases.
163  bool operator==(const LocalPointerBase<T> &other) = delete;
164  bool operator!=(const LocalPointerBase<T> &other) = delete;
165  // No ownership sharing: No copy constructor, no assignment operator.
166  LocalPointerBase(const LocalPointerBase<T> &other) = delete;
167  void operator=(const LocalPointerBase<T> &other) = delete;
168 };
169 
188 template<typename T>
189 class LocalPointer : public LocalPointerBase<T> {
190 public:
198  explicit LocalPointer(T *p=nullptr) : LocalPointerBase<T>(p) {}
212  LocalPointer(T *p, UErrorCode &errorCode) : LocalPointerBase<T>(p) {
213  if(p==nullptr && U_SUCCESS(errorCode)) {
214  errorCode=U_MEMORY_ALLOCATION_ERROR;
215  }
216  }
222  LocalPointer(LocalPointer<T> &&src) noexcept : LocalPointerBase<T>(src.ptr) {
223  src.ptr=nullptr;
224  }
225 
236  explicit LocalPointer(std::unique_ptr<T> &&p)
237  : LocalPointerBase<T>(p.release()) {}
238 
245  }
256  src.ptr=nullptr;
257  return *this;
258  }
259 
268  LocalPointer<T> &operator=(std::unique_ptr<T> &&p) noexcept {
269  adoptInstead(p.release());
270  return *this;
271  }
272 
278  void swap(LocalPointer<T> &other) noexcept {
279  T *temp=LocalPointerBase<T>::ptr;
281  other.ptr=temp;
282  }
289  friend inline void swap(LocalPointer<T> &p1, LocalPointer<T> &p2) noexcept {
290  p1.swap(p2);
291  }
298  void adoptInstead(T *p) {
301  }
317  void adoptInsteadAndCheckErrorCode(T *p, UErrorCode &errorCode) {
318  if(U_SUCCESS(errorCode)) {
321  if(p==nullptr) {
322  errorCode=U_MEMORY_ALLOCATION_ERROR;
323  }
324  } else {
325  delete p;
326  }
327  }
328 
340  operator std::unique_ptr<T> () && {
341  return std::unique_ptr<T>(LocalPointerBase<T>::orphan());
342  }
343 };
344 
363 template<typename T>
364 class LocalArray : public LocalPointerBase<T> {
365 public:
373  explicit LocalArray(T *p=nullptr) : LocalPointerBase<T>(p) {}
387  LocalArray(T *p, UErrorCode &errorCode) : LocalPointerBase<T>(p) {
388  if(p==nullptr && U_SUCCESS(errorCode)) {
389  errorCode=U_MEMORY_ALLOCATION_ERROR;
390  }
391  }
397  LocalArray(LocalArray<T> &&src) noexcept : LocalPointerBase<T>(src.ptr) {
398  src.ptr=nullptr;
399  }
400 
411  explicit LocalArray(std::unique_ptr<T[]> &&p)
412  : LocalPointerBase<T>(p.release()) {}
413 
419  delete[] LocalPointerBase<T>::ptr;
420  }
429  delete[] LocalPointerBase<T>::ptr;
431  src.ptr=nullptr;
432  return *this;
433  }
434 
443  LocalArray<T> &operator=(std::unique_ptr<T[]> &&p) noexcept {
444  adoptInstead(p.release());
445  return *this;
446  }
447 
453  void swap(LocalArray<T> &other) noexcept {
454  T *temp=LocalPointerBase<T>::ptr;
456  other.ptr=temp;
457  }
464  friend inline void swap(LocalArray<T> &p1, LocalArray<T> &p2) noexcept {
465  p1.swap(p2);
466  }
473  void adoptInstead(T *p) {
474  delete[] LocalPointerBase<T>::ptr;
476  }
492  void adoptInsteadAndCheckErrorCode(T *p, UErrorCode &errorCode) {
493  if(U_SUCCESS(errorCode)) {
494  delete[] LocalPointerBase<T>::ptr;
496  if(p==nullptr) {
497  errorCode=U_MEMORY_ALLOCATION_ERROR;
498  }
499  } else {
500  delete[] p;
501  }
502  }
510  T &operator[](ptrdiff_t i) const { return LocalPointerBase<T>::ptr[i]; }
511 
523  operator std::unique_ptr<T[]> () && {
524  return std::unique_ptr<T[]>(LocalPointerBase<T>::orphan());
525  }
526 };
527 
548 #define U_DEFINE_LOCAL_OPEN_POINTER(LocalPointerClassName, Type, closeFunction) \
549  using LocalPointerClassName = internal::LocalOpenPointer<Type, closeFunction>
550 
551 #ifndef U_IN_DOXYGEN
552 namespace internal {
559 template <typename Type, auto closeFunction>
560 class LocalOpenPointer : public LocalPointerBase<Type> {
561  using LocalPointerBase<Type>::ptr;
562 public:
563  using LocalPointerBase<Type>::operator*;
564  using LocalPointerBase<Type>::operator->;
565  explicit LocalOpenPointer(Type *p=nullptr) : LocalPointerBase<Type>(p) {}
566  LocalOpenPointer(LocalOpenPointer &&src) noexcept
567  : LocalPointerBase<Type>(src.ptr) {
568  src.ptr=nullptr;
569  }
570  /* TODO: Be agnostic of the deleter function signature from the user-provided std::unique_ptr? */
571  explicit LocalOpenPointer(std::unique_ptr<Type, decltype(closeFunction)> &&p)
572  : LocalPointerBase<Type>(p.release()) {}
573  ~LocalOpenPointer() { if (ptr != nullptr) { closeFunction(ptr); } }
574  LocalOpenPointer &operator=(LocalOpenPointer &&src) noexcept {
575  if (ptr != nullptr) { closeFunction(ptr); }
576  LocalPointerBase<Type>::ptr=src.ptr;
577  src.ptr=nullptr;
578  return *this;
579  }
580  /* TODO: Be agnostic of the deleter function signature from the user-provided std::unique_ptr? */
581  LocalOpenPointer &operator=(std::unique_ptr<Type, decltype(closeFunction)> &&p) {
582  adoptInstead(p.release());
583  return *this;
584  }
585  void swap(LocalOpenPointer &other) noexcept {
586  Type *temp=LocalPointerBase<Type>::ptr;
587  LocalPointerBase<Type>::ptr=other.ptr;
588  other.ptr=temp;
589  }
590  friend inline void swap(LocalOpenPointer &p1, LocalOpenPointer &p2) noexcept {
591  p1.swap(p2);
592  }
593  void adoptInstead(Type *p) {
594  if (ptr != nullptr) { closeFunction(ptr); }
595  ptr=p;
596  }
597  operator std::unique_ptr<Type, decltype(closeFunction)> () && {
598  return std::unique_ptr<Type, decltype(closeFunction)>(LocalPointerBase<Type>::orphan(), closeFunction);
599  }
600 };
601 } // namespace internal
602 #endif
603 
604 U_NAMESPACE_END
605 
606 #endif /* U_SHOW_CPLUSPLUS_API */
607 #endif /* __LOCALPOINTER_H__ */
"Smart pointer" class, deletes objects via the C++ array delete[] operator.
Definition: localpointer.h:364
LocalArray(T *p=nullptr)
Constructor takes ownership.
Definition: localpointer.h:373
LocalArray< T > & operator=(LocalArray< T > &&src) noexcept
Move assignment operator, leaves src with isNull().
Definition: localpointer.h:428
~LocalArray()
Destructor deletes the array it owns.
Definition: localpointer.h:418
LocalArray(LocalArray< T > &&src) noexcept
Move constructor, leaves src with isNull().
Definition: localpointer.h:397
friend void swap(LocalArray< T > &p1, LocalArray< T > &p2) noexcept
Non-member LocalArray swap function.
Definition: localpointer.h:464
void adoptInsteadAndCheckErrorCode(T *p, UErrorCode &errorCode)
Deletes the array it owns, and adopts (takes ownership of) the one passed in.
Definition: localpointer.h:492
T & operator[](ptrdiff_t i) const
Array item access (writable).
Definition: localpointer.h:510
void adoptInstead(T *p)
Deletes the array it owns, and adopts (takes ownership of) the one passed in.
Definition: localpointer.h:473
LocalArray(T *p, UErrorCode &errorCode)
Constructor takes ownership and reports an error if nullptr.
Definition: localpointer.h:387
void swap(LocalArray< T > &other) noexcept
Swap pointers.
Definition: localpointer.h:453
LocalArray(std::unique_ptr< T[]> &&p)
Constructs a LocalArray from a C++11 std::unique_ptr of an array type.
Definition: localpointer.h:411
LocalArray< T > & operator=(std::unique_ptr< T[]> &&p) noexcept
Move-assign from an std::unique_ptr to this LocalPointer.
Definition: localpointer.h:443
"Smart pointer" base class; do not use directly: use LocalPointer etc.
Definition: localpointer.h:68
bool operator!=(const T *other) const
Comparison with a simple pointer, so that existing code with !=nullptr need not be changed.
Definition: localpointer.h:114
UBool isValid() const
nullptr check.
Definition: localpointer.h:98
T * getAlias() const
Access without ownership change.
Definition: localpointer.h:120
T & operator*() const
Access without ownership change.
Definition: localpointer.h:126
T * orphan()
Gives up ownership; the internal pointer becomes nullptr.
Definition: localpointer.h:139
UBool isNull() const
nullptr check.
Definition: localpointer.h:92
T * operator->() const
Access without ownership change.
Definition: localpointer.h:132
T * ptr
Actual pointer.
Definition: localpointer.h:160
LocalPointerBase(T *p=nullptr)
Constructor takes ownership.
Definition: localpointer.h:80
bool operator==(const T *other) const
Comparison with a simple pointer, so that existing code with ==nullptr need not be changed.
Definition: localpointer.h:106
void adoptInstead(T *p)
Deletes the object it owns, and adopts (takes ownership of) the one passed in.
Definition: localpointer.h:151
~LocalPointerBase()
Destructor deletes the object it owns.
Definition: localpointer.h:86
"Smart pointer" class, deletes objects via the standard C++ delete operator.
Definition: localpointer.h:189
friend void swap(LocalPointer< T > &p1, LocalPointer< T > &p2) noexcept
Non-member LocalPointer swap function.
Definition: localpointer.h:289
LocalPointer< T > & operator=(LocalPointer< T > &&src) noexcept
Move assignment operator, leaves src with isNull().
Definition: localpointer.h:253
void adoptInsteadAndCheckErrorCode(T *p, UErrorCode &errorCode)
Deletes the object it owns, and adopts (takes ownership of) the one passed in.
Definition: localpointer.h:317
LocalPointer< T > & operator=(std::unique_ptr< T > &&p) noexcept
Move-assign from an std::unique_ptr to this LocalPointer.
Definition: localpointer.h:268
LocalPointer(T *p, UErrorCode &errorCode)
Constructor takes ownership and reports an error if nullptr.
Definition: localpointer.h:212
LocalPointer(std::unique_ptr< T > &&p)
Constructs a LocalPointer from a C++11 std::unique_ptr.
Definition: localpointer.h:236
LocalPointer(T *p=nullptr)
Constructor takes ownership.
Definition: localpointer.h:198
void swap(LocalPointer< T > &other) noexcept
Swap pointers.
Definition: localpointer.h:278
~LocalPointer()
Destructor deletes the object it owns.
Definition: localpointer.h:243
LocalPointer(LocalPointer< T > &&src) noexcept
Move constructor, leaves src with isNull().
Definition: localpointer.h:222
void adoptInstead(T *p)
Deletes the object it owns, and adopts (takes ownership of) the one passed in.
Definition: localpointer.h:298
U_COMMON_API UBool operator==(const StringPiece &x, const StringPiece &y)
Global operator == for StringPiece.
bool operator!=(const StringPiece &x, const StringPiece &y)
Global operator != for StringPiece.
Definition: stringpiece.h:346
int8_t UBool
The ICU boolean type, a signed-byte integer.
Definition: umachine.h:269
Basic definitions for ICU, for both C and C++ APIs.
UErrorCode
Standard ICU4C error code type, a substitute for exceptions.
Definition: utypes.h:509
@ U_MEMORY_ALLOCATION_ERROR
Memory allocation error.
Definition: utypes.h:552
#define U_SUCCESS(x)
Does the error code indicate success?
Definition: utypes.h:822