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