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