Home | History | Annotate | Download | only in utils
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 /* === NOTE === NOTE === NOTE === NOTE === NOTE === NOTE === NOTE === NOTE ===
     18  *
     19  * THIS IS A COPY OF libcore/include/UniquePtr.h AND AS SUCH THAT IS THE
     20  * CANONICAL SOURCE OF THIS FILE. PLEASE KEEP THEM IN SYNC.
     21  *
     22  * === NOTE === NOTE === NOTE === NOTE === NOTE === NOTE === NOTE === NOTE ===
     23  */
     24 
     25 #ifndef UNIQUE_PTR_H_included
     26 #define UNIQUE_PTR_H_included
     27 
     28 #include <cstdlib> // For NULL.
     29 
     30 // Default deleter for pointer types.
     31 template <typename T>
     32 struct DefaultDelete {
     33     enum { type_must_be_complete = sizeof(T) };
     34     DefaultDelete() {}
     35     void operator()(T* p) const {
     36         delete p;
     37     }
     38 };
     39 
     40 // Default deleter for array types.
     41 template <typename T>
     42 struct DefaultDelete<T[]> {
     43     enum { type_must_be_complete = sizeof(T) };
     44     void operator()(T* p) const {
     45         delete[] p;
     46     }
     47 };
     48 
     49 // A smart pointer that deletes the given pointer on destruction.
     50 // Equivalent to C++0x's std::unique_ptr (a combination of boost::scoped_ptr
     51 // and boost::scoped_array).
     52 // Named to be in keeping with Android style but also to avoid
     53 // collision with any other implementation, until we can switch over
     54 // to unique_ptr.
     55 // Use thus:
     56 //   UniquePtr<C> c(new C);
     57 template <typename T, typename D = DefaultDelete<T> >
     58 class UniquePtr {
     59 public:
     60     // Construct a new UniquePtr, taking ownership of the given raw pointer.
     61     explicit UniquePtr(T* ptr = NULL) : mPtr(ptr) {
     62     }
     63 
     64     ~UniquePtr() {
     65         reset();
     66     }
     67 
     68     // Accessors.
     69     T& operator*() const { return *mPtr; }
     70     T* operator->() const { return mPtr; }
     71     T* get() const { return mPtr; }
     72 
     73     // Returns the raw pointer and hands over ownership to the caller.
     74     // The pointer will not be deleted by UniquePtr.
     75     T* release() __attribute__((warn_unused_result)) {
     76         T* result = mPtr;
     77         mPtr = NULL;
     78         return result;
     79     }
     80 
     81     // Takes ownership of the given raw pointer.
     82     // If this smart pointer previously owned a different raw pointer, that
     83     // raw pointer will be freed.
     84     void reset(T* ptr = NULL) {
     85         if (ptr != mPtr) {
     86             D()(mPtr);
     87             mPtr = ptr;
     88         }
     89     }
     90 
     91 private:
     92     // The raw pointer.
     93     T* mPtr;
     94 
     95     // Comparing unique pointers is probably a mistake, since they're unique.
     96     template <typename T2> bool operator==(const UniquePtr<T2>& p) const;
     97     template <typename T2> bool operator!=(const UniquePtr<T2>& p) const;
     98 
     99     // Disallow copy and assignment.
    100     UniquePtr(const UniquePtr&);
    101     void operator=(const UniquePtr&);
    102 };
    103 
    104 // Partial specialization for array types. Like std::unique_ptr, this removes
    105 // operator* and operator-> but adds operator[].
    106 template <typename T, typename D>
    107 class UniquePtr<T[], D> {
    108 public:
    109     explicit UniquePtr(T* ptr = NULL) : mPtr(ptr) {
    110     }
    111 
    112     ~UniquePtr() {
    113         reset();
    114     }
    115 
    116     T& operator[](size_t i) const {
    117         return mPtr[i];
    118     }
    119     T* get() const { return mPtr; }
    120 
    121     T* release() __attribute__((warn_unused_result)) {
    122         T* result = mPtr;
    123         mPtr = NULL;
    124         return result;
    125     }
    126 
    127     void reset(T* ptr = NULL) {
    128         if (ptr != mPtr) {
    129             D()(mPtr);
    130             mPtr = ptr;
    131         }
    132     }
    133 
    134 private:
    135     T* mPtr;
    136 
    137     // Disallow copy and assignment.
    138     UniquePtr(const UniquePtr&);
    139     void operator=(const UniquePtr&);
    140 };
    141 
    142 #if UNIQUE_PTR_TESTS
    143 
    144 // Run these tests with:
    145 // g++ -g -DUNIQUE_PTR_TESTS -x c++ UniquePtr.h && ./a.out
    146 
    147 #include <stdio.h>
    148 
    149 static void assert(bool b) {
    150     if (!b) {
    151         fprintf(stderr, "FAIL\n");
    152         abort();
    153     }
    154     fprintf(stderr, "OK\n");
    155 }
    156 static int cCount = 0;
    157 struct C {
    158     C() { ++cCount; }
    159     ~C() { --cCount; }
    160 };
    161 static bool freed = false;
    162 struct Freer {
    163     void operator()(int* p) {
    164         assert(*p == 123);
    165         free(p);
    166         freed = true;
    167     }
    168 };
    169 
    170 int main(int argc, char* argv[]) {
    171     //
    172     // UniquePtr<T> tests...
    173     //
    174 
    175     // Can we free a single object?
    176     {
    177         UniquePtr<C> c(new C);
    178         assert(cCount == 1);
    179     }
    180     assert(cCount == 0);
    181     // Does release work?
    182     C* rawC;
    183     {
    184         UniquePtr<C> c(new C);
    185         assert(cCount == 1);
    186         rawC = c.release();
    187     }
    188     assert(cCount == 1);
    189     delete rawC;
    190     // Does reset work?
    191     {
    192         UniquePtr<C> c(new C);
    193         assert(cCount == 1);
    194         c.reset(new C);
    195         assert(cCount == 1);
    196     }
    197     assert(cCount == 0);
    198 
    199     //
    200     // UniquePtr<T[]> tests...
    201     //
    202 
    203     // Can we free an array?
    204     {
    205         UniquePtr<C[]> cs(new C[4]);
    206         assert(cCount == 4);
    207     }
    208     assert(cCount == 0);
    209     // Does release work?
    210     {
    211         UniquePtr<C[]> c(new C[4]);
    212         assert(cCount == 4);
    213         rawC = c.release();
    214     }
    215     assert(cCount == 4);
    216     delete[] rawC;
    217     // Does reset work?
    218     {
    219         UniquePtr<C[]> c(new C[4]);
    220         assert(cCount == 4);
    221         c.reset(new C[2]);
    222         assert(cCount == 2);
    223     }
    224     assert(cCount == 0);
    225 
    226     //
    227     // Custom deleter tests...
    228     //
    229     assert(!freed);
    230     {
    231         UniquePtr<int, Freer> i(reinterpret_cast<int*>(malloc(sizeof(int))));
    232         *i = 123;
    233     }
    234     assert(freed);
    235     return 0;
    236 }
    237 #endif
    238 
    239 #endif  // UNIQUE_PTR_H_included
    240