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 <cstdlib> // For NULL. 21 #include "JNIHelp.h" // For DISALLOW_COPY_AND_ASSIGN. 22 23 // Default deleter for pointer types. 24 template <typename T> 25 struct DefaultDelete { 26 enum { type_must_be_complete = sizeof(T) }; DefaultDeleteDefaultDelete27 DefaultDelete() {} operatorDefaultDelete28 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 private: 85 // The raw pointer. 86 T* mPtr; 87 88 // Comparing unique pointers is probably a mistake, since they're unique. 89 template <typename T2> bool operator==(const UniquePtr<T2>& p) const; 90 template <typename T2> bool operator!=(const UniquePtr<T2>& p) const; 91 92 DISALLOW_COPY_AND_ASSIGN(UniquePtr); 93 }; 94 95 // Partial specialization for array types. Like std::unique_ptr, this removes 96 // operator* and operator-> but adds operator[]. 97 template <typename T, typename D> 98 class UniquePtr<T[], D> { 99 public: 100 explicit UniquePtr(T* ptr = NULL) : mPtr(ptr) { 101 } 102 103 ~UniquePtr() { 104 reset(); 105 } 106 107 T& operator[](size_t i) const { 108 return mPtr[i]; 109 } 110 T* get() const { return mPtr; } 111 112 T* release() __attribute__((warn_unused_result)) { 113 T* result = mPtr; 114 mPtr = NULL; 115 return result; 116 } 117 118 void reset(T* ptr = NULL) { 119 if (ptr != mPtr) { 120 D()(mPtr); 121 mPtr = ptr; 122 } 123 } 124 125 private: 126 T* mPtr; 127 128 DISALLOW_COPY_AND_ASSIGN(UniquePtr); 129 }; 130 131 #if UNIQUE_PTR_TESTS 132 133 // Run these tests with: 134 // g++ -g -DUNIQUE_PTR_TESTS -x c++ UniquePtr.h && ./a.out 135 136 #include <stdio.h> 137 138 static void assert(bool b) { 139 if (!b) { 140 fprintf(stderr, "FAIL\n"); 141 abort(); 142 } 143 fprintf(stderr, "OK\n"); 144 } 145 static int cCount = 0; 146 struct C { 147 C() { ++cCount; } 148 ~C() { --cCount; } 149 }; 150 static bool freed = false; 151 struct Freer { 152 void operator()(int* p) { 153 assert(*p == 123); 154 free(p); 155 freed = true; 156 } 157 }; 158 159 int main(int argc, char* argv[]) { 160 // 161 // UniquePtr<T> tests... 162 // 163 164 // Can we free a single object? 165 { 166 UniquePtr<C> c(new C); 167 assert(cCount == 1); 168 } 169 assert(cCount == 0); 170 // Does release work? 171 C* rawC; 172 { 173 UniquePtr<C> c(new C); 174 assert(cCount == 1); 175 rawC = c.release(); 176 } 177 assert(cCount == 1); 178 delete rawC; 179 // Does reset work? 180 { 181 UniquePtr<C> c(new C); 182 assert(cCount == 1); 183 c.reset(new C); 184 assert(cCount == 1); 185 } 186 assert(cCount == 0); 187 188 // 189 // UniquePtr<T[]> tests... 190 // 191 192 // Can we free an array? 193 { 194 UniquePtr<C[]> cs(new C[4]); 195 assert(cCount == 4); 196 } 197 assert(cCount == 0); 198 // Does release work? 199 { 200 UniquePtr<C[]> c(new C[4]); 201 assert(cCount == 4); 202 rawC = c.release(); 203 } 204 assert(cCount == 4); 205 delete[] rawC; 206 // Does reset work? 207 { 208 UniquePtr<C[]> c(new C[4]); 209 assert(cCount == 4); 210 c.reset(new C[2]); 211 assert(cCount == 2); 212 } 213 assert(cCount == 0); 214 215 // 216 // Custom deleter tests... 217 // 218 assert(!freed); 219 { 220 UniquePtr<int, Freer> i(reinterpret_cast<int*>(malloc(sizeof(int)))); 221 *i = 123; 222 } 223 assert(freed); 224 return 0; 225 } 226 #endif 227 228 #endif // UNIQUE_PTR_H_included 229