1f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/*
2f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*******************************************************************************
3f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*
4f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   Copyright (C) 2009-2010, International Business Machines
5f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   Corporation and others.  All Rights Reserved.
6f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*
7f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*******************************************************************************
8f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   file name:  localpointer.h
9f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   encoding:   US-ASCII
10f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   tab size:   8 (not used)
11f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   indentation:4
12f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*
13f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   created on: 2009nov13
14f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   created by: Markus W. Scherer
15f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/
16f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
17f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#ifndef __LOCALPOINTER_H__
18f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define __LOCALPOINTER_H__
19f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
20f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
21f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * \file
22f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * \brief C++ API: "Smart pointers" for use with and in ICU4C C++ code.
23f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *
24f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * These classes are inspired by
25f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * - std::auto_ptr
26f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * - boost::scoped_ptr & boost::scoped_array
27f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * - Taligent Safe Pointers (TOnlyPointerTo)
28f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *
29f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * but none of those provide for all of the goals for ICU smart pointers:
30f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * - Smart pointer owns the object and releases it when it goes out of scope.
31f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * - No transfer of ownership via copy/assignment to reduce misuse. Simpler & more robust.
32f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * - ICU-compatible: No exceptions.
33f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * - Need to be able to orphan/release the pointer and its ownership.
34f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * - Need variants for normal C++ object pointers, C++ arrays, and ICU C service objects.
35f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *
36f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * For details see http://site.icu-project.org/design/cpp/scoped_ptr
37f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
38f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
39f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/utypes.h"
40f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
41f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if U_SHOW_CPLUSPLUS_API
42f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
43f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_NAMESPACE_BEGIN
44f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
45f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
46f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * "Smart pointer" base class; do not use directly: use LocalPointer etc.
47f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *
48f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Base class for smart pointer classes that do not throw exceptions.
49f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *
50f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Do not use this base class directly, since it does not delete its pointer.
51f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * A subclass must implement methods that delete the pointer:
52f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Destructor and adoptInstead().
53f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *
54f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * There is no operator T *() provided because the programmer must decide
55f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * whether to use getAlias() (without transfer of ownership) or orpan()
56f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * (with transfer of ownership and NULLing of the pointer).
57f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *
58f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @see LocalPointer
59f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @see LocalArray
60f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @see U_DEFINE_LOCAL_OPEN_POINTER
61f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @stable ICU 4.4
62f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
63f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)template<typename T>
64f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)class LocalPointerBase {
65f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)public:
66f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /**
67f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * Constructor takes ownership.
68f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * @param p simple pointer to an object that is adopted
69f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * @stable ICU 4.4
70f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     */
71f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    explicit LocalPointerBase(T *p=NULL) : ptr(p) {}
72f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /**
73f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * Destructor deletes the object it owns.
74f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * Subclass must override: Base class does nothing.
75f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * @stable ICU 4.4
76f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     */
77f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    ~LocalPointerBase() { /* delete ptr; */ }
78f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /**
79f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * NULL check.
80f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * @return TRUE if ==NULL
81f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * @stable ICU 4.4
82f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     */
83f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UBool isNull() const { return ptr==NULL; }
84f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /**
85f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * NULL check.
86f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * @return TRUE if !=NULL
87f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * @stable ICU 4.4
88f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     */
89f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UBool isValid() const { return ptr!=NULL; }
90f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /**
91f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * Comparison with a simple pointer, so that existing code
92f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * with ==NULL need not be changed.
93f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * @param other simple pointer for comparison
94f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * @return true if this pointer value equals other
95f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * @stable ICU 4.4
96f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     */
97f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    bool operator==(const T *other) const { return ptr==other; }
98f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /**
99f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * Comparison with a simple pointer, so that existing code
100f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * with !=NULL need not be changed.
101f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * @param other simple pointer for comparison
102f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * @return true if this pointer value differs from other
103f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * @stable ICU 4.4
104f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     */
105f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    bool operator!=(const T *other) const { return ptr!=other; }
106f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /**
107f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * Access without ownership change.
108f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * @return the pointer value
109f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * @stable ICU 4.4
110f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     */
111f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    T *getAlias() const { return ptr; }
112f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /**
113f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * Access without ownership change.
114f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * @return the pointer value as a reference
115f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * @stable ICU 4.4
116f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     */
117f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    T &operator*() const { return *ptr; }
118f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /**
119f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * Access without ownership change.
120f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * @return the pointer value
121f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * @stable ICU 4.4
122f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     */
123f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    T *operator->() const { return ptr; }
124f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /**
125f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * Gives up ownership; the internal pointer becomes NULL.
126f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * @return the pointer value;
127f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     *         caller becomes responsible for deleting the object
128f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * @stable ICU 4.4
129f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     */
130f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    T *orphan() {
131f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        T *p=ptr;
132f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        ptr=NULL;
133f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return p;
134f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
135f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /**
136f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * Deletes the object it owns,
137f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * and adopts (takes ownership of) the one passed in.
138f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * Subclass must override: Base class does not delete the object.
139f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * @param p simple pointer to an object that is adopted
140f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * @stable ICU 4.4
141f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     */
142f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    void adoptInstead(T *p) {
143f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // delete ptr;
144f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        ptr=p;
145f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
146f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)protected:
147f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    T *ptr;
148f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)private:
149f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // No comparison operators with other LocalPointerBases.
150f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    bool operator==(const LocalPointerBase &other);
151f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    bool operator!=(const LocalPointerBase &other);
152f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // No ownership transfer: No copy constructor, no assignment operator.
153f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    LocalPointerBase(const LocalPointerBase &other);
154f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    void operator=(const LocalPointerBase &other);
155f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // No heap allocation. Use only on the stack.
156f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    static void * U_EXPORT2 operator new(size_t size);
157f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    static void * U_EXPORT2 operator new[](size_t size);
158f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if U_HAVE_PLACEMENT_NEW
159f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    static void * U_EXPORT2 operator new(size_t, void *ptr);
160f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
161f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)};
162f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
163f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
164f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * "Smart pointer" class, deletes objects via the standard C++ delete operator.
165f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * For most methods see the LocalPointerBase base class.
166f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *
167f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Usage example:
168f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * \code
169f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * LocalPointer<UnicodeString> s(new UnicodeString((UChar32)0x50005));
170f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * int32_t length=s->length();  // 2
171f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * UChar lead=s->charAt(0);  // 0xd900
172f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * if(some condition) { return; }  // no need to explicitly delete the pointer
173f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * s.adoptInstead(new UnicodeString((UChar)0xfffc));
174f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * length=s->length();  // 1
175f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * // no need to explicitly delete the pointer
176f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * \endcode
177f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *
178f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @see LocalPointerBase
179f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @stable ICU 4.4
180f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
181f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)template<typename T>
182f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)class LocalPointer : public LocalPointerBase<T> {
183f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)public:
184f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /**
185f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * Constructor takes ownership.
186f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * @param p simple pointer to an object that is adopted
187f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * @stable ICU 4.4
188f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     */
189f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    explicit LocalPointer(T *p=NULL) : LocalPointerBase<T>(p) {}
190f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /**
191f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * Destructor deletes the object it owns.
192f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * @stable ICU 4.4
193f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     */
194f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    ~LocalPointer() {
195f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        delete LocalPointerBase<T>::ptr;
196f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
197f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /**
198f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * Deletes the object it owns,
199f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * and adopts (takes ownership of) the one passed in.
200f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * @param p simple pointer to an object that is adopted
201f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * @stable ICU 4.4
202f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     */
203f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    void adoptInstead(T *p) {
204f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        delete LocalPointerBase<T>::ptr;
205f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        LocalPointerBase<T>::ptr=p;
206f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
207f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)};
208f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
209f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
210f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * "Smart pointer" class, deletes objects via the C++ array delete[] operator.
211f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * For most methods see the LocalPointerBase base class.
212f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Adds operator[] for array item access.
213f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *
214f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Usage example:
215f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * \code
216f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * LocalArray<UnicodeString> a(new UnicodeString[2]);
217f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * a[0].append((UChar)0x61);
218f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * if(some condition) { return; }  // no need to explicitly delete the array
219f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * a.adoptInstead(new UnicodeString[4]);
220f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * a[3].append((UChar)0x62).append((UChar)0x63).reverse();
221f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * // no need to explicitly delete the array
222f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * \endcode
223f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *
224f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @see LocalPointerBase
225f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @stable ICU 4.4
226f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
227f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)template<typename T>
228f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)class LocalArray : public LocalPointerBase<T> {
229f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)public:
230f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /**
231f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * Constructor takes ownership.
232f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * @param p simple pointer to an array of T objects that is adopted
233f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * @stable ICU 4.4
234f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     */
235f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    explicit LocalArray(T *p=NULL) : LocalPointerBase<T>(p) {}
236f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /**
237f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * Destructor deletes the array it owns.
238f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * @stable ICU 4.4
239f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     */
240f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    ~LocalArray() {
241f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        delete[] LocalPointerBase<T>::ptr;
242f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
243f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /**
244f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * Deletes the array it owns,
245f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * and adopts (takes ownership of) the one passed in.
246f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * @param p simple pointer to an array of T objects that is adopted
247f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * @stable ICU 4.4
248f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     */
249f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    void adoptInstead(T *p) {
250f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        delete[] LocalPointerBase<T>::ptr;
251f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        LocalPointerBase<T>::ptr=p;
252f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
253f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /**
254f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * Array item access (writable).
255f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * No index bounds check.
256f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * @param i array index
257f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * @return reference to the array item
258f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * @stable ICU 4.4
259f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     */
260f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    T &operator[](ptrdiff_t i) const { return LocalPointerBase<T>::ptr[i]; }
261f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)};
262f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
263f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
264f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * \def U_DEFINE_LOCAL_OPEN_POINTER
265f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * "Smart pointer" definition macro, deletes objects via the closeFunction.
266f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Defines a subclass of LocalPointerBase which works just
267f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * like LocalPointer<Type> except that this subclass will use the closeFunction
268f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * rather than the C++ delete operator.
269f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *
270f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Requirement: The closeFunction must tolerate a NULL pointer.
271f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * (We could add a NULL check here but it is normally redundant.)
272f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *
273f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Usage example:
274f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * \code
275f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * LocalUCaseMapPointer csm(ucasemap_open(localeID, options, &errorCode));
276f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * utf8OutLength=ucasemap_utf8ToLower(csm.getAlias(),
277f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *     utf8Out, (int32_t)sizeof(utf8Out),
278f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *     utf8In, utf8InLength, &errorCode);
279f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * if(U_FAILURE(errorCode)) { return; }  // no need to explicitly delete the UCaseMap
280f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * \endcode
281f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *
282f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @see LocalPointerBase
283f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @see LocalPointer
284f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @stable ICU 4.4
285f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
286f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define U_DEFINE_LOCAL_OPEN_POINTER(LocalPointerClassName, Type, closeFunction) \
287f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    class LocalPointerClassName : public LocalPointerBase<Type> { \
288f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    public: \
289f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        explicit LocalPointerClassName(Type *p=NULL) : LocalPointerBase<Type>(p) {} \
290f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        ~LocalPointerClassName() { closeFunction(ptr); } \
291f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        void adoptInstead(Type *p) { \
292f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            closeFunction(ptr); \
293f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            ptr=p; \
294f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        } \
295f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
296f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
297f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_NAMESPACE_END
298f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
299f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif  /* U_SHOW_CPLUSPLUS_API */
300f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif  /* __LOCALPOINTER_H__ */
301