150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/*
250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*******************************************************************************
350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*
4c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert*   Copyright (C) 2009-2015, International Business Machines
550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*   Corporation and others.  All Rights Reserved.
650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*
750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*******************************************************************************
850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*   file name:  localpointer.h
950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*   encoding:   US-ASCII
1050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*   tab size:   8 (not used)
1150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*   indentation:4
1250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*
1350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*   created on: 2009nov13
1450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*   created by: Markus W. Scherer
1550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*/
1650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
1750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#ifndef __LOCALPOINTER_H__
1850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define __LOCALPOINTER_H__
1950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
2050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/**
2150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * \file
2250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * \brief C++ API: "Smart pointers" for use with and in ICU4C C++ code.
2350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *
2450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * These classes are inspired by
2550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * - std::auto_ptr
2650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * - boost::scoped_ptr & boost::scoped_array
2750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * - Taligent Safe Pointers (TOnlyPointerTo)
2850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *
2950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * but none of those provide for all of the goals for ICU smart pointers:
3050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * - Smart pointer owns the object and releases it when it goes out of scope.
3150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * - No transfer of ownership via copy/assignment to reduce misuse. Simpler & more robust.
3250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * - ICU-compatible: No exceptions.
3350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * - Need to be able to orphan/release the pointer and its ownership.
3450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * - Need variants for normal C++ object pointers, C++ arrays, and ICU C service objects.
3550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *
3650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * For details see http://site.icu-project.org/design/cpp/scoped_ptr
3750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */
3850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
3950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/utypes.h"
4050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
4150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#if U_SHOW_CPLUSPLUS_API
4250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
4350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_NAMESPACE_BEGIN
4450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
4550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/**
4650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * "Smart pointer" base class; do not use directly: use LocalPointer etc.
4750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *
4850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Base class for smart pointer classes that do not throw exceptions.
4950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *
5050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Do not use this base class directly, since it does not delete its pointer.
5150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * A subclass must implement methods that delete the pointer:
5250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Destructor and adoptInstead().
5350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *
5450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * There is no operator T *() provided because the programmer must decide
5550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * whether to use getAlias() (without transfer of ownership) or orpan()
5650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * (with transfer of ownership and NULLing of the pointer).
5750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *
5850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @see LocalPointer
5950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @see LocalArray
6050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @see U_DEFINE_LOCAL_OPEN_POINTER
6127f654740f2a26ad62a5c155af9199af9e69b889claireho * @stable ICU 4.4
6250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */
6350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehotemplate<typename T>
6450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoclass LocalPointerBase {
6550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehopublic:
6650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /**
6750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * Constructor takes ownership.
6850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * @param p simple pointer to an object that is adopted
6927f654740f2a26ad62a5c155af9199af9e69b889claireho     * @stable ICU 4.4
7050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     */
7150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    explicit LocalPointerBase(T *p=NULL) : ptr(p) {}
7250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /**
7350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * Destructor deletes the object it owns.
7450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * Subclass must override: Base class does nothing.
7527f654740f2a26ad62a5c155af9199af9e69b889claireho     * @stable ICU 4.4
7650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     */
7750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    ~LocalPointerBase() { /* delete ptr; */ }
7850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /**
7950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * NULL check.
8050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * @return TRUE if ==NULL
8127f654740f2a26ad62a5c155af9199af9e69b889claireho     * @stable ICU 4.4
8250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     */
8350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UBool isNull() const { return ptr==NULL; }
8450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /**
8550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * NULL check.
8650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * @return TRUE if !=NULL
8727f654740f2a26ad62a5c155af9199af9e69b889claireho     * @stable ICU 4.4
8850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     */
8950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UBool isValid() const { return ptr!=NULL; }
9050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /**
9150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * Comparison with a simple pointer, so that existing code
9250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * with ==NULL need not be changed.
9350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * @param other simple pointer for comparison
9450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * @return true if this pointer value equals other
9527f654740f2a26ad62a5c155af9199af9e69b889claireho     * @stable ICU 4.4
9650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     */
9750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    bool operator==(const T *other) const { return ptr==other; }
9850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /**
9950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * Comparison with a simple pointer, so that existing code
10050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * with !=NULL need not be changed.
10150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * @param other simple pointer for comparison
10250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * @return true if this pointer value differs from other
10327f654740f2a26ad62a5c155af9199af9e69b889claireho     * @stable ICU 4.4
10450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     */
10550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    bool operator!=(const T *other) const { return ptr!=other; }
10650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /**
10750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * Access without ownership change.
10850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * @return the pointer value
10927f654740f2a26ad62a5c155af9199af9e69b889claireho     * @stable ICU 4.4
11050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     */
11150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    T *getAlias() const { return ptr; }
11250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /**
11350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * Access without ownership change.
11450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * @return the pointer value as a reference
11527f654740f2a26ad62a5c155af9199af9e69b889claireho     * @stable ICU 4.4
11650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     */
11750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    T &operator*() const { return *ptr; }
11850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /**
11950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * Access without ownership change.
12050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * @return the pointer value
12127f654740f2a26ad62a5c155af9199af9e69b889claireho     * @stable ICU 4.4
12250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     */
12350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    T *operator->() const { return ptr; }
12450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /**
12550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * Gives up ownership; the internal pointer becomes NULL.
12650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * @return the pointer value;
12750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     *         caller becomes responsible for deleting the object
12827f654740f2a26ad62a5c155af9199af9e69b889claireho     * @stable ICU 4.4
12950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     */
13050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    T *orphan() {
13150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        T *p=ptr;
13250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        ptr=NULL;
13350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return p;
13450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
13550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /**
13650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * Deletes the object it owns,
13750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * and adopts (takes ownership of) the one passed in.
13850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * Subclass must override: Base class does not delete the object.
13950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * @param p simple pointer to an object that is adopted
14027f654740f2a26ad62a5c155af9199af9e69b889claireho     * @stable ICU 4.4
14150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     */
14250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    void adoptInstead(T *p) {
14350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // delete ptr;
14450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        ptr=p;
14550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
14650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoprotected:
14754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    /**
14854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius     * Actual pointer.
14954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius     * @internal
15054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius     */
15150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    T *ptr;
15250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoprivate:
15350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // No comparison operators with other LocalPointerBases.
154c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    bool operator==(const LocalPointerBase<T> &other);
155c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    bool operator!=(const LocalPointerBase<T> &other);
156c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    // No ownership sharing: No copy constructor, no assignment operator.
157c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    LocalPointerBase(const LocalPointerBase<T> &other);
158c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    void operator=(const LocalPointerBase<T> &other);
15950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // No heap allocation. Use only on the stack.
16050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    static void * U_EXPORT2 operator new(size_t size);
16150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    static void * U_EXPORT2 operator new[](size_t size);
16250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#if U_HAVE_PLACEMENT_NEW
16350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    static void * U_EXPORT2 operator new(size_t, void *ptr);
16450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif
16550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho};
16650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
16750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/**
16850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * "Smart pointer" class, deletes objects via the standard C++ delete operator.
16950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * For most methods see the LocalPointerBase base class.
17050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *
17150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Usage example:
17250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * \code
17350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * LocalPointer<UnicodeString> s(new UnicodeString((UChar32)0x50005));
17450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * int32_t length=s->length();  // 2
17550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * UChar lead=s->charAt(0);  // 0xd900
17650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * if(some condition) { return; }  // no need to explicitly delete the pointer
17750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * s.adoptInstead(new UnicodeString((UChar)0xfffc));
17850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * length=s->length();  // 1
17950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * // no need to explicitly delete the pointer
18050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * \endcode
18150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *
18250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @see LocalPointerBase
18327f654740f2a26ad62a5c155af9199af9e69b889claireho * @stable ICU 4.4
18450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */
18550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehotemplate<typename T>
18650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoclass LocalPointer : public LocalPointerBase<T> {
18750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehopublic:
18850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /**
18950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * Constructor takes ownership.
19050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * @param p simple pointer to an object that is adopted
19127f654740f2a26ad62a5c155af9199af9e69b889claireho     * @stable ICU 4.4
19250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     */
19350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    explicit LocalPointer(T *p=NULL) : LocalPointerBase<T>(p) {}
1941b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert#ifndef U_HIDE_DRAFT_API
1951b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    /**
1961b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert     * Constructor takes ownership and reports an error if NULL.
1971b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert     *
1981b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert     * This constructor is intended to be used with other-class constructors
1991b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert     * that may report a failure UErrorCode,
2001b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert     * so that callers need to check only for U_FAILURE(errorCode)
2011b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert     * and not also separately for isNull().
2021b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert     *
2031b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert     * @param p simple pointer to an object that is adopted
2041b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert     * @param errorCode in/out UErrorCode, set to U_MEMORY_ALLOCATION_ERROR
2051b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert     *     if p==NULL and no other failure code had been set
2061b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert     * @draft ICU 55
2071b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert     */
2081b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    LocalPointer(T *p, UErrorCode &errorCode) : LocalPointerBase<T>(p) {
2091b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        if(p==NULL && U_SUCCESS(errorCode)) {
2101b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            errorCode=U_MEMORY_ALLOCATION_ERROR;
2111b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        }
2121b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    }
213c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#if U_HAVE_RVALUE_REFERENCES
214c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    /**
215c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * Move constructor, leaves src with isNull().
216c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * @param src source smart pointer
217c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * @draft ICU 56
218c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     */
219c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    LocalPointer(LocalPointer<T> &&src) U_NOEXCEPT : LocalPointerBase<T>(src.ptr) {
220c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        src.ptr=NULL;
221c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    }
222c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#endif
2231b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert#endif  /* U_HIDE_DRAFT_API */
22450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /**
22550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * Destructor deletes the object it owns.
22627f654740f2a26ad62a5c155af9199af9e69b889claireho     * @stable ICU 4.4
22750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     */
22850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    ~LocalPointer() {
22950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        delete LocalPointerBase<T>::ptr;
23050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
231c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#ifndef U_HIDE_DRAFT_API
232c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#if U_HAVE_RVALUE_REFERENCES
233c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    /**
234c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * Move assignment operator, leaves src with isNull().
235c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * The behavior is undefined if *this and src are the same object.
236c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * @param src source smart pointer
237c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * @return *this
238c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * @draft ICU 56
239c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     */
240c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    LocalPointer<T> &operator=(LocalPointer<T> &&src) U_NOEXCEPT {
241c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        return moveFrom(src);
242c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    }
243c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#endif
244c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    /**
245c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * Move assignment, leaves src with isNull().
246c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * The behavior is undefined if *this and src are the same object.
247c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     *
248c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * Can be called explicitly, does not need C++11 support.
249c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * @param src source smart pointer
250c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * @return *this
251c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * @draft ICU 56
252c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     */
253c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    LocalPointer<T> &moveFrom(LocalPointer<T> &src) U_NOEXCEPT {
254c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        delete LocalPointerBase<T>::ptr;
255c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        LocalPointerBase<T>::ptr=src.ptr;
256c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        src.ptr=NULL;
257c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        return *this;
258c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    }
259c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    /**
260c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * Swap pointers.
261c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * @param other other smart pointer
262c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * @draft ICU 56
263c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     */
264c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    void swap(LocalPointer<T> &other) U_NOEXCEPT {
265c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        T *temp=LocalPointerBase<T>::ptr;
266c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        LocalPointerBase<T>::ptr=other.ptr;
267c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        other.ptr=temp;
268c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    }
269c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    /**
270c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * Non-member LocalPointer swap function.
271c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * @param p1 will get p2's pointer
272c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * @param p2 will get p1's pointer
273c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * @draft ICU 56
274c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     */
275c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    friend inline void swap(LocalPointer<T> &p1, LocalPointer<T> &p2) U_NOEXCEPT {
276c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        p1.swap(p2);
277c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    }
278c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#endif  /* U_HIDE_DRAFT_API */
27950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /**
28050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * Deletes the object it owns,
28150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * and adopts (takes ownership of) the one passed in.
28250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * @param p simple pointer to an object that is adopted
28327f654740f2a26ad62a5c155af9199af9e69b889claireho     * @stable ICU 4.4
28450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     */
28550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    void adoptInstead(T *p) {
28650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        delete LocalPointerBase<T>::ptr;
28750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        LocalPointerBase<T>::ptr=p;
28850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
2891b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert#ifndef U_HIDE_DRAFT_API
2901b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    /**
2911b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert     * Deletes the object it owns,
2921b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert     * and adopts (takes ownership of) the one passed in.
2931b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert     *
2941b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert     * If U_FAILURE(errorCode), then the current object is retained and the new one deleted.
2951b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert     *
2961b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert     * If U_SUCCESS(errorCode) but the input pointer is NULL,
2971b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert     * then U_MEMORY_ALLOCATION_ERROR is set,
2981b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert     * the current object is deleted, and NULL is set.
2991b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert     *
3001b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert     * @param p simple pointer to an object that is adopted
3011b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert     * @param errorCode in/out UErrorCode, set to U_MEMORY_ALLOCATION_ERROR
3021b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert     *     if p==NULL and no other failure code had been set
3031b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert     * @draft ICU 55
3041b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert     */
3051b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    void adoptInsteadAndCheckErrorCode(T *p, UErrorCode &errorCode) {
3061b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        if(U_SUCCESS(errorCode)) {
3071b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            delete LocalPointerBase<T>::ptr;
3081b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            LocalPointerBase<T>::ptr=p;
3091b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            if(p==NULL) {
3101b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                errorCode=U_MEMORY_ALLOCATION_ERROR;
3111b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            }
3121b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        } else {
3131b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            delete p;
3141b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        }
3151b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    }
3161b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert#endif  /* U_HIDE_DRAFT_API */
31750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho};
31850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
31950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/**
32050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * "Smart pointer" class, deletes objects via the C++ array delete[] operator.
32150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * For most methods see the LocalPointerBase base class.
32250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Adds operator[] for array item access.
32350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *
32450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Usage example:
32550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * \code
32650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * LocalArray<UnicodeString> a(new UnicodeString[2]);
32750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * a[0].append((UChar)0x61);
32850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * if(some condition) { return; }  // no need to explicitly delete the array
32950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * a.adoptInstead(new UnicodeString[4]);
33050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * a[3].append((UChar)0x62).append((UChar)0x63).reverse();
33150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * // no need to explicitly delete the array
33250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * \endcode
33350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *
33450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @see LocalPointerBase
33527f654740f2a26ad62a5c155af9199af9e69b889claireho * @stable ICU 4.4
33650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */
33750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehotemplate<typename T>
33850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoclass LocalArray : public LocalPointerBase<T> {
33950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehopublic:
34050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /**
34150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * Constructor takes ownership.
34250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * @param p simple pointer to an array of T objects that is adopted
34327f654740f2a26ad62a5c155af9199af9e69b889claireho     * @stable ICU 4.4
34450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     */
34550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    explicit LocalArray(T *p=NULL) : LocalPointerBase<T>(p) {}
346c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#ifndef U_HIDE_DRAFT_API
347c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    /**
348c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * Constructor takes ownership and reports an error if NULL.
349c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     *
350c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * This constructor is intended to be used with other-class constructors
351c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * that may report a failure UErrorCode,
352c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * so that callers need to check only for U_FAILURE(errorCode)
353c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * and not also separately for isNull().
354c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     *
355c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * @param p simple pointer to an array of T objects that is adopted
356c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * @param errorCode in/out UErrorCode, set to U_MEMORY_ALLOCATION_ERROR
357c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     *     if p==NULL and no other failure code had been set
358c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * @draft ICU 56
359c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     */
360c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    LocalArray(T *p, UErrorCode &errorCode) : LocalPointerBase<T>(p) {
361c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        if(p==NULL && U_SUCCESS(errorCode)) {
362c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert            errorCode=U_MEMORY_ALLOCATION_ERROR;
363c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        }
364c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    }
365c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#if U_HAVE_RVALUE_REFERENCES
366c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    /**
367c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * Move constructor, leaves src with isNull().
368c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * @param src source smart pointer
369c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * @draft ICU 56
370c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     */
371c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    LocalArray(LocalArray<T> &&src) U_NOEXCEPT : LocalPointerBase<T>(src.ptr) {
372c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        src.ptr=NULL;
373c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    }
374c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#endif
375c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#endif  /* U_HIDE_DRAFT_API */
37650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /**
37750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * Destructor deletes the array it owns.
37827f654740f2a26ad62a5c155af9199af9e69b889claireho     * @stable ICU 4.4
37950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     */
38050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    ~LocalArray() {
38150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        delete[] LocalPointerBase<T>::ptr;
38250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
383c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#ifndef U_HIDE_DRAFT_API
384c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#if U_HAVE_RVALUE_REFERENCES
385c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    /**
386c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * Move assignment operator, leaves src with isNull().
387c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * The behavior is undefined if *this and src are the same object.
388c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * @param src source smart pointer
389c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * @return *this
390c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * @draft ICU 56
391c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     */
392c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    LocalArray<T> &operator=(LocalArray<T> &&src) U_NOEXCEPT {
393c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        return moveFrom(src);
394c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    }
395c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#endif
396c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    /**
397c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * Move assignment, leaves src with isNull().
398c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * The behavior is undefined if *this and src are the same object.
399c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     *
400c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * Can be called explicitly, does not need C++11 support.
401c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * @param src source smart pointer
402c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * @return *this
403c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * @draft ICU 56
404c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     */
405c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    LocalArray<T> &moveFrom(LocalArray<T> &src) U_NOEXCEPT {
406c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        delete[] LocalPointerBase<T>::ptr;
407c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        LocalPointerBase<T>::ptr=src.ptr;
408c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        src.ptr=NULL;
409c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        return *this;
410c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    }
411c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    /**
412c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * Swap pointers.
413c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * @param other other smart pointer
414c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * @draft ICU 56
415c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     */
416c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    void swap(LocalArray<T> &other) U_NOEXCEPT {
417c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        T *temp=LocalPointerBase<T>::ptr;
418c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        LocalPointerBase<T>::ptr=other.ptr;
419c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        other.ptr=temp;
420c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    }
421c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    /**
422c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * Non-member LocalArray swap function.
423c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * @param p1 will get p2's pointer
424c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * @param p2 will get p1's pointer
425c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * @draft ICU 56
426c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     */
427c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    friend inline void swap(LocalArray<T> &p1, LocalArray<T> &p2) U_NOEXCEPT {
428c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        p1.swap(p2);
429c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    }
430c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#endif  /* U_HIDE_DRAFT_API */
43150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /**
43250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * Deletes the array it owns,
43350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * and adopts (takes ownership of) the one passed in.
43450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * @param p simple pointer to an array of T objects that is adopted
43527f654740f2a26ad62a5c155af9199af9e69b889claireho     * @stable ICU 4.4
43650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     */
43750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    void adoptInstead(T *p) {
43850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        delete[] LocalPointerBase<T>::ptr;
43950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        LocalPointerBase<T>::ptr=p;
44050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
441c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#ifndef U_HIDE_DRAFT_API
442c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    /**
443c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * Deletes the array it owns,
444c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * and adopts (takes ownership of) the one passed in.
445c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     *
446c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * If U_FAILURE(errorCode), then the current array is retained and the new one deleted.
447c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     *
448c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * If U_SUCCESS(errorCode) but the input pointer is NULL,
449c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * then U_MEMORY_ALLOCATION_ERROR is set,
450c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * the current array is deleted, and NULL is set.
451c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     *
452c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * @param p simple pointer to an array of T objects that is adopted
453c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * @param errorCode in/out UErrorCode, set to U_MEMORY_ALLOCATION_ERROR
454c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     *     if p==NULL and no other failure code had been set
455c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     * @draft ICU 56
456c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert     */
457c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    void adoptInsteadAndCheckErrorCode(T *p, UErrorCode &errorCode) {
458c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        if(U_SUCCESS(errorCode)) {
459c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert            delete[] LocalPointerBase<T>::ptr;
460c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert            LocalPointerBase<T>::ptr=p;
461c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert            if(p==NULL) {
462c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert                errorCode=U_MEMORY_ALLOCATION_ERROR;
463c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert            }
464c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        } else {
465c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert            delete[] p;
466c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        }
467c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    }
468c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#endif  /* U_HIDE_DRAFT_API */
46950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /**
47050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * Array item access (writable).
47150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * No index bounds check.
47250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * @param i array index
47350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * @return reference to the array item
47427f654740f2a26ad62a5c155af9199af9e69b889claireho     * @stable ICU 4.4
47550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     */
47650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    T &operator[](ptrdiff_t i) const { return LocalPointerBase<T>::ptr[i]; }
47750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho};
47850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
47950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/**
48050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * \def U_DEFINE_LOCAL_OPEN_POINTER
48150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * "Smart pointer" definition macro, deletes objects via the closeFunction.
48250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Defines a subclass of LocalPointerBase which works just
48350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * like LocalPointer<Type> except that this subclass will use the closeFunction
48450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * rather than the C++ delete operator.
48550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *
48650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Requirement: The closeFunction must tolerate a NULL pointer.
48750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * (We could add a NULL check here but it is normally redundant.)
48850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *
48950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Usage example:
49050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * \code
49150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * LocalUCaseMapPointer csm(ucasemap_open(localeID, options, &errorCode));
49250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * utf8OutLength=ucasemap_utf8ToLower(csm.getAlias(),
49350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *     utf8Out, (int32_t)sizeof(utf8Out),
49450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *     utf8In, utf8InLength, &errorCode);
49550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * if(U_FAILURE(errorCode)) { return; }  // no need to explicitly delete the UCaseMap
49650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * \endcode
49750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *
49850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @see LocalPointerBase
49950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @see LocalPointer
50027f654740f2a26ad62a5c155af9199af9e69b889claireho * @stable ICU 4.4
50150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */
502c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#if U_HAVE_RVALUE_REFERENCES
503c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#define U_DEFINE_LOCAL_OPEN_POINTER(LocalPointerClassName, Type, closeFunction) \
504c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    class LocalPointerClassName : public LocalPointerBase<Type> { \
505c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    public: \
506c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        explicit LocalPointerClassName(Type *p=NULL) : LocalPointerBase<Type>(p) {} \
507c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        LocalPointerClassName(LocalPointerClassName &&src) U_NOEXCEPT \
508c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert                : LocalPointerBase<Type>(src.ptr) { \
509c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert            src.ptr=NULL; \
510c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        } \
511c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        ~LocalPointerClassName() { closeFunction(ptr); } \
512c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        LocalPointerClassName &operator=(LocalPointerClassName &&src) U_NOEXCEPT { \
513c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert            return moveFrom(src); \
514c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        } \
515c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        LocalPointerClassName &moveFrom(LocalPointerClassName &src) U_NOEXCEPT { \
516c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert            closeFunction(ptr); \
517c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert            LocalPointerBase<Type>::ptr=src.ptr; \
518c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert            src.ptr=NULL; \
519c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert            return *this; \
520c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        } \
521c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        void swap(LocalPointerClassName &other) U_NOEXCEPT { \
522c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert            Type *temp=LocalPointerBase<Type>::ptr; \
523c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert            LocalPointerBase<Type>::ptr=other.ptr; \
524c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert            other.ptr=temp; \
525c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        } \
526c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        friend inline void swap(LocalPointerClassName &p1, LocalPointerClassName &p2) U_NOEXCEPT { \
527c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert            p1.swap(p2); \
528c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        } \
529c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        void adoptInstead(Type *p) { \
530c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert            closeFunction(ptr); \
531c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert            ptr=p; \
532c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        } \
533c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    }
534c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#else
53550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define U_DEFINE_LOCAL_OPEN_POINTER(LocalPointerClassName, Type, closeFunction) \
53650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    class LocalPointerClassName : public LocalPointerBase<Type> { \
53750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    public: \
53850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        explicit LocalPointerClassName(Type *p=NULL) : LocalPointerBase<Type>(p) {} \
53950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        ~LocalPointerClassName() { closeFunction(ptr); } \
540c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        LocalPointerClassName &moveFrom(LocalPointerClassName &src) U_NOEXCEPT { \
541c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert            closeFunction(ptr); \
542c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert            LocalPointerBase<Type>::ptr=src.ptr; \
543c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert            src.ptr=NULL; \
544c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert            return *this; \
545c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        } \
546c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        void swap(LocalPointerClassName &other) U_NOEXCEPT { \
547c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert            Type *temp=LocalPointerBase<Type>::ptr; \
548c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert            LocalPointerBase<Type>::ptr=other.ptr; \
549c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert            other.ptr=temp; \
550c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        } \
551c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        friend inline void swap(LocalPointerClassName &p1, LocalPointerClassName &p2) U_NOEXCEPT { \
552c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert            p1.swap(p2); \
553c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        } \
55450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        void adoptInstead(Type *p) { \
55550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            closeFunction(ptr); \
55650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            ptr=p; \
55750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        } \
55850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
559c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#endif
56050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
56150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_NAMESPACE_END
56250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
56350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif  /* U_SHOW_CPLUSPLUS_API */
56450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif  /* __LOCALPOINTER_H__ */
565