Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  *  * Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  *  * Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in
     12  *    the documentation and/or other materials provided with the
     13  *    distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     18  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     19  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
     22  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     25  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26  * SUCH DAMAGE.
     27  */
     28 #ifndef ANDROID_SUPPORT_UNIQUE_PTR_H
     29 #define ANDROID_SUPPORT_UNIQUE_PTR_H
     30 
     31 namespace {
     32 
     33 #define DISALLOW_COPY_AND_ASSIGN(TypeName) \
     34   TypeName(const TypeName&) = delete;      \
     35   void operator=(const TypeName&) = delete
     36 
     37 template <typename T>
     38 struct DefaultDelete {
     39   enum { type_must_be_complete = sizeof(T) };
     40   DefaultDelete() {
     41   }
     42   void operator()(T* p) const {
     43     delete p;
     44   }
     45 };
     46 
     47 template <typename T>
     48 struct DefaultDelete<T[]> {
     49   enum { type_must_be_complete = sizeof(T) };
     50   void operator()(T* p) const {
     51     delete[] p;
     52   }
     53 };
     54 
     55 template <typename T, typename D = DefaultDelete<T> >
     56 class UniquePtr {
     57  public:
     58   explicit UniquePtr(T* ptr = NULL) : mPtr(ptr) {
     59   }
     60 
     61   ~UniquePtr() {
     62     reset();
     63   }
     64 
     65   T& operator*() const {
     66     return *mPtr;
     67   }
     68   T* operator->() const {
     69     return mPtr;
     70   }
     71   T* get() const {
     72     return mPtr;
     73   }
     74 
     75   T* release() __attribute__((warn_unused_result)) {
     76     T* result = mPtr;
     77     mPtr = NULL;
     78     return result;
     79   }
     80 
     81   void reset(T* ptr = NULL) {
     82     if (ptr != mPtr) {
     83       D()(mPtr);
     84       mPtr = ptr;
     85     }
     86   }
     87 
     88  private:
     89   T* mPtr;
     90 
     91   template <typename T2>
     92   bool operator==(const UniquePtr<T2>& p) const;
     93   template <typename T2>
     94   bool operator!=(const UniquePtr<T2>& p) const;
     95 
     96   DISALLOW_COPY_AND_ASSIGN(UniquePtr);
     97 };
     98 
     99 // Partial specialization for array types. Like std::unique_ptr, this removes
    100 // operator* and operator-> but adds operator[].
    101 template <typename T, typename D>
    102 class UniquePtr<T[], D> {
    103  public:
    104   explicit UniquePtr(T* ptr = NULL) : mPtr(ptr) {
    105   }
    106 
    107   ~UniquePtr() {
    108     reset();
    109   }
    110 
    111   T& operator[](size_t i) const {
    112     return mPtr[i];
    113   }
    114   T* get() const {
    115     return mPtr;
    116   }
    117 
    118   T* release() __attribute__((warn_unused_result)) {
    119     T* result = mPtr;
    120     mPtr = NULL;
    121     return result;
    122   }
    123 
    124   void reset(T* ptr = NULL) {
    125     if (ptr != mPtr) {
    126       D()(mPtr);
    127       mPtr = ptr;
    128     }
    129   }
    130 
    131  private:
    132   T* mPtr;
    133 
    134   DISALLOW_COPY_AND_ASSIGN(UniquePtr);
    135 };
    136 
    137 } // anonymous namespace
    138 
    139 #endif  /* ANDROID_SUPPORT_UNIQUE_PTR_H */
    140