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. 31template <typename T> 32struct 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. 41template <typename T> 42struct 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); 57template <typename T, typename D = DefaultDelete<T> > 58class UniquePtr { 59public: 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 91private: 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[]. 106template <typename T, typename D> 107class UniquePtr<T[], D> { 108public: 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 134private: 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 149static void assert(bool b) { 150 if (!b) { 151 fprintf(stderr, "FAIL\n"); 152 abort(); 153 } 154 fprintf(stderr, "OK\n"); 155} 156static int cCount = 0; 157struct C { 158 C() { ++cCount; } 159 ~C() { --cCount; } 160}; 161static bool freed = false; 162struct Freer { 163 void operator()(int* p) { 164 assert(*p == 123); 165 free(p); 166 freed = true; 167 } 168}; 169 170int 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