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