1587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root/* 2587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root * Copyright (C) 2010 The Android Open Source Project 3587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root * 4587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root * Licensed under the Apache License, Version 2.0 (the "License"); 5587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root * you may not use this file except in compliance with the License. 6587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root * You may obtain a copy of the License at 7587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root * 8587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root * http://www.apache.org/licenses/LICENSE-2.0 9587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root * 10587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root * Unless required by applicable law or agreed to in writing, software 11587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root * distributed under the License is distributed on an "AS IS" BASIS, 12587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root * See the License for the specific language governing permissions and 14587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root * limitations under the License. 15587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root */ 16587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root 17587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root#ifndef UNIQUE_PTR_H_included 18587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root#define UNIQUE_PTR_H_included 19587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root 20587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root#include <cstdlib> // For NULL. 21587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root 22587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root// This is a fake declaration of std::swap to avoid including <algorithm> 23587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Rootnamespace std { 24587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Roottemplate <class T> void swap(T&, T&); 25587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root} 26587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root 27587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root// Default deleter for pointer types. 28587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Roottemplate <typename T> 29587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Rootstruct DefaultDelete { 30587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root enum { type_must_be_complete = sizeof(T) }; 31587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root DefaultDelete() {} 32587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root void operator()(T* p) const { 33587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root delete p; 34587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root } 35587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root}; 36587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root 37587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root// Default deleter for array types. 38587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Roottemplate <typename T> 39587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Rootstruct DefaultDelete<T[]> { 40587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root enum { type_must_be_complete = sizeof(T) }; 41587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root void operator()(T* p) const { 42587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root delete[] p; 43587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root } 44587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root}; 45587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root 46587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root// A smart pointer that deletes the given pointer on destruction. 47587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root// Equivalent to C++0x's std::unique_ptr (a combination of boost::scoped_ptr 48587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root// and boost::scoped_array). 49587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root// Named to be in keeping with Android style but also to avoid 50587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root// collision with any other implementation, until we can switch over 51587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root// to unique_ptr. 52587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root// Use thus: 53587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root// UniquePtr<C> c(new C); 54587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Roottemplate <typename T, typename D = DefaultDelete<T> > 55587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Rootclass UniquePtr { 56587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Rootpublic: 57587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root // Construct a new UniquePtr, taking ownership of the given raw pointer. 58587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root explicit UniquePtr(T* ptr = NULL) : mPtr(ptr) { 59587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root } 60587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root 61587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root ~UniquePtr() { 62587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root reset(); 63587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root } 64587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root 65587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root // Accessors. 66587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root T& operator*() const { return *mPtr; } 67587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root T* operator->() const { return mPtr; } 68587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root T* get() const { return mPtr; } 69587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root 70587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root // Returns the raw pointer and hands over ownership to the caller. 71587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root // The pointer will not be deleted by UniquePtr. 72587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root T* release() __attribute__((warn_unused_result)) { 73587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root T* result = mPtr; 74587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root mPtr = NULL; 75587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root return result; 76587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root } 77587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root 78587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root // Takes ownership of the given raw pointer. 79587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root // If this smart pointer previously owned a different raw pointer, that 80587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root // raw pointer will be freed. 81587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root void reset(T* ptr = NULL) { 82587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root if (ptr != mPtr) { 83587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root D()(mPtr); 84587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root mPtr = ptr; 85587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root } 86587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root } 87587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root 88587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root // Swap with another unique pointer. 89587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root void swap(UniquePtr<T>& other) { 90587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root std::swap(mPtr, other.mPtr); 91587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root } 92587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root 93587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Rootprivate: 94587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root // The raw pointer. 95587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root T* mPtr; 96587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root 97587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root // Comparing unique pointers is probably a mistake, since they're unique. 98587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root template <typename T2> bool operator==(const UniquePtr<T2>& p) const; 99587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root template <typename T2> bool operator!=(const UniquePtr<T2>& p) const; 100587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root 101587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root // Disallow copy and assignment. 102587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root UniquePtr(const UniquePtr&); 103587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root void operator=(const UniquePtr&); 104587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root}; 105587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root 106587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root// Partial specialization for array types. Like std::unique_ptr, this removes 107587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root// operator* and operator-> but adds operator[]. 108587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Roottemplate <typename T, typename D> 109587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Rootclass UniquePtr<T[], D> { 110587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Rootpublic: 111587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root explicit UniquePtr(T* ptr = NULL) : mPtr(ptr) { 112587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root } 113587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root 114587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root ~UniquePtr() { 115587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root reset(); 116587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root } 117587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root 118587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root T& operator[](size_t i) const { 119587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root return mPtr[i]; 120587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root } 121587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root T* get() const { return mPtr; } 122587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root 123587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root T* release() __attribute__((warn_unused_result)) { 124587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root T* result = mPtr; 125587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root mPtr = NULL; 126587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root return result; 127587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root } 128587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root 129587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root void reset(T* ptr = NULL) { 130587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root if (ptr != mPtr) { 131587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root D()(mPtr); 132587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root mPtr = ptr; 133587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root } 134587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root } 135587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root 136587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Rootprivate: 137587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root T* mPtr; 138587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root 139587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root // Disallow copy and assignment. 140587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root UniquePtr(const UniquePtr&); 141587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root void operator=(const UniquePtr&); 142587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root}; 143587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root 144587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root#if UNIQUE_PTR_TESTS 145587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root 146587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root// Run these tests with: 147587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root// g++ -g -DUNIQUE_PTR_TESTS -x c++ UniquePtr.h && ./a.out 148587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root 149587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root#include <stdio.h> 150587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root 151587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Rootstatic void assert(bool b) { 152587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root if (!b) { 153587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root fprintf(stderr, "FAIL\n"); 154587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root abort(); 155587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root } 156587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root fprintf(stderr, "OK\n"); 157587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root} 158587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Rootstatic int cCount = 0; 159587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Rootstruct C { 160587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root C() { ++cCount; } 161587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root ~C() { --cCount; } 162587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root}; 163587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Rootstatic bool freed = false; 164587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Rootstruct Freer { 165587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root void operator()(int* p) { 166587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root assert(*p == 123); 167587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root free(p); 168587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root freed = true; 169587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root } 170587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root}; 171587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root 172587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Rootint main(int argc, char* argv[]) { 173587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root // 174587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root // UniquePtr<T> tests... 175587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root // 176587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root 177587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root // Can we free a single object? 178587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root { 179587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root UniquePtr<C> c(new C); 180587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root assert(cCount == 1); 181587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root } 182587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root assert(cCount == 0); 183587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root // Does release work? 184587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root C* rawC; 185587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root { 186587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root UniquePtr<C> c(new C); 187587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root assert(cCount == 1); 188587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root rawC = c.release(); 189587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root } 190587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root assert(cCount == 1); 191587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root delete rawC; 192587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root // Does reset work? 193587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root { 194587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root UniquePtr<C> c(new C); 195587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root assert(cCount == 1); 196587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root c.reset(new C); 197587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root assert(cCount == 1); 198587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root } 199587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root assert(cCount == 0); 200587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root 201587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root // 202587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root // UniquePtr<T[]> tests... 203587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root // 204587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root 205587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root // Can we free an array? 206587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root { 207587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root UniquePtr<C[]> cs(new C[4]); 208587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root assert(cCount == 4); 209587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root } 210587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root assert(cCount == 0); 211587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root // Does release work? 212587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root { 213587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root UniquePtr<C[]> c(new C[4]); 214587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root assert(cCount == 4); 215587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root rawC = c.release(); 216587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root } 217587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root assert(cCount == 4); 218587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root delete[] rawC; 219587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root // Does reset work? 220587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root { 221587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root UniquePtr<C[]> c(new C[4]); 222587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root assert(cCount == 4); 223587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root c.reset(new C[2]); 224587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root assert(cCount == 2); 225587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root } 226587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root assert(cCount == 0); 227587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root 228587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root // 229587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root // Custom deleter tests... 230587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root // 231587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root assert(!freed); 232587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root { 233587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root UniquePtr<int, Freer> i(reinterpret_cast<int*>(malloc(sizeof(int)))); 234587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root *i = 123; 235587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root } 236587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root assert(freed); 237587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root return 0; 238587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root} 239587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root#endif 240587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root 241587c1456f884c4dd0a7b287d7c193da829d8a296Kenny Root#endif // UNIQUE_PTR_H_included 242