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