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