13e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root/* 23e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root * Copyright (C) 2010 The Android Open Source Project 33e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root * 43e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root * Licensed under the Apache License, Version 2.0 (the "License"); 53e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root * you may not use this file except in compliance with the License. 63e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root * You may obtain a copy of the License at 73e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root * 83e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root * http://www.apache.org/licenses/LICENSE-2.0 93e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root * 103e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root * Unless required by applicable law or agreed to in writing, software 113e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root * distributed under the License is distributed on an "AS IS" BASIS, 123e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root * See the License for the specific language governing permissions and 143e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root * limitations under the License. 153e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root */ 163e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root 173e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root#ifndef UNIQUE_PTR_H_included 183e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root#define UNIQUE_PTR_H_included 193e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root 203e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root#include <cstdlib> // For NULL. 213e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root 223e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root// This is a fake declaration of std::swap to avoid including <algorithm> 233e46e4ee56c8e37158f46941dedd5b436d724baaKenny Rootnamespace std { 243e46e4ee56c8e37158f46941dedd5b436d724baaKenny Roottemplate <class T> void swap(T&, T&); 253e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root} 263e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root 273e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root// Default deleter for pointer types. 283e46e4ee56c8e37158f46941dedd5b436d724baaKenny Roottemplate <typename T> 293e46e4ee56c8e37158f46941dedd5b436d724baaKenny Rootstruct DefaultDelete { 303e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root enum { type_must_be_complete = sizeof(T) }; 313e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root DefaultDelete() {} 323e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root void operator()(T* p) const { 333e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root delete p; 343e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root } 353e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root}; 363e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root 373e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root// Default deleter for array types. 383e46e4ee56c8e37158f46941dedd5b436d724baaKenny Roottemplate <typename T> 393e46e4ee56c8e37158f46941dedd5b436d724baaKenny Rootstruct DefaultDelete<T[]> { 403e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root enum { type_must_be_complete = sizeof(T) }; 413e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root void operator()(T* p) const { 423e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root delete[] p; 433e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root } 443e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root}; 453e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root 463e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root// A smart pointer that deletes the given pointer on destruction. 473e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root// Equivalent to C++0x's std::unique_ptr (a combination of boost::scoped_ptr 483e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root// and boost::scoped_array). 493e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root// Named to be in keeping with Android style but also to avoid 503e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root// collision with any other implementation, until we can switch over 513e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root// to unique_ptr. 523e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root// Use thus: 533e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root// UniquePtr<C> c(new C); 543e46e4ee56c8e37158f46941dedd5b436d724baaKenny Roottemplate <typename T, typename D = DefaultDelete<T> > 553e46e4ee56c8e37158f46941dedd5b436d724baaKenny Rootclass UniquePtr { 563e46e4ee56c8e37158f46941dedd5b436d724baaKenny Rootpublic: 573e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root // Construct a new UniquePtr, taking ownership of the given raw pointer. 583e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root explicit UniquePtr(T* ptr = NULL) : mPtr(ptr) { 593e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root } 603e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root 613e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root ~UniquePtr() { 623e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root reset(); 633e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root } 643e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root 653e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root // Accessors. 663e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root T& operator*() const { return *mPtr; } 673e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root T* operator->() const { return mPtr; } 683e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root T* get() const { return mPtr; } 693e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root 703e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root // Returns the raw pointer and hands over ownership to the caller. 713e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root // The pointer will not be deleted by UniquePtr. 723e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root T* release() __attribute__((warn_unused_result)) { 733e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root T* result = mPtr; 743e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root mPtr = NULL; 753e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root return result; 763e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root } 773e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root 783e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root // Takes ownership of the given raw pointer. 793e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root // If this smart pointer previously owned a different raw pointer, that 803e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root // raw pointer will be freed. 813e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root void reset(T* ptr = NULL) { 823e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root if (ptr != mPtr) { 833e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root D()(mPtr); 843e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root mPtr = ptr; 853e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root } 863e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root } 873e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root 883e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root // Swap with another unique pointer. 893e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root void swap(UniquePtr<T>& other) { 903e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root std::swap(mPtr, other.mPtr); 913e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root } 923e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root 933e46e4ee56c8e37158f46941dedd5b436d724baaKenny Rootprivate: 943e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root // The raw pointer. 953e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root T* mPtr; 963e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root 973e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root // Comparing unique pointers is probably a mistake, since they're unique. 983e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root template <typename T2> bool operator==(const UniquePtr<T2>& p) const; 993e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root template <typename T2> bool operator!=(const UniquePtr<T2>& p) const; 1003e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root 1013e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root // Disallow copy and assignment. 1023e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root UniquePtr(const UniquePtr&); 1033e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root void operator=(const UniquePtr&); 1043e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root}; 1053e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root 1063e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root// Partial specialization for array types. Like std::unique_ptr, this removes 1073e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root// operator* and operator-> but adds operator[]. 1083e46e4ee56c8e37158f46941dedd5b436d724baaKenny Roottemplate <typename T, typename D> 1093e46e4ee56c8e37158f46941dedd5b436d724baaKenny Rootclass UniquePtr<T[], D> { 1103e46e4ee56c8e37158f46941dedd5b436d724baaKenny Rootpublic: 1113e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root explicit UniquePtr(T* ptr = NULL) : mPtr(ptr) { 1123e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root } 1133e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root 1143e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root ~UniquePtr() { 1153e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root reset(); 1163e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root } 1173e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root 1183e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root T& operator[](size_t i) const { 1193e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root return mPtr[i]; 1203e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root } 1213e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root T* get() const { return mPtr; } 1223e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root 1233e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root T* release() __attribute__((warn_unused_result)) { 1243e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root T* result = mPtr; 1253e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root mPtr = NULL; 1263e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root return result; 1273e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root } 1283e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root 1293e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root void reset(T* ptr = NULL) { 1303e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root if (ptr != mPtr) { 1313e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root D()(mPtr); 1323e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root mPtr = ptr; 1333e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root } 1343e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root } 1353e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root 1363e46e4ee56c8e37158f46941dedd5b436d724baaKenny Rootprivate: 1373e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root T* mPtr; 1383e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root 1393e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root // Disallow copy and assignment. 1403e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root UniquePtr(const UniquePtr&); 1413e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root void operator=(const UniquePtr&); 1423e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root}; 1433e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root 1443e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root#if UNIQUE_PTR_TESTS 1453e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root 1463e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root// Run these tests with: 1473e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root// g++ -g -DUNIQUE_PTR_TESTS -x c++ UniquePtr.h && ./a.out 1483e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root 1493e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root#include <stdio.h> 1503e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root 1513e46e4ee56c8e37158f46941dedd5b436d724baaKenny Rootstatic void assert(bool b) { 1523e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root if (!b) { 1533e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root fprintf(stderr, "FAIL\n"); 1543e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root abort(); 1553e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root } 1563e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root fprintf(stderr, "OK\n"); 1573e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root} 1583e46e4ee56c8e37158f46941dedd5b436d724baaKenny Rootstatic int cCount = 0; 1593e46e4ee56c8e37158f46941dedd5b436d724baaKenny Rootstruct C { 1603e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root C() { ++cCount; } 1613e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root ~C() { --cCount; } 1623e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root}; 1633e46e4ee56c8e37158f46941dedd5b436d724baaKenny Rootstatic bool freed = false; 1643e46e4ee56c8e37158f46941dedd5b436d724baaKenny Rootstruct Freer { 1653e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root void operator()(int* p) { 1663e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root assert(*p == 123); 1673e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root free(p); 1683e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root freed = true; 1693e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root } 1703e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root}; 1713e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root 1723e46e4ee56c8e37158f46941dedd5b436d724baaKenny Rootint main(int argc, char* argv[]) { 1733e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root // 1743e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root // UniquePtr<T> tests... 1753e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root // 1763e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root 1773e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root // Can we free a single object? 1783e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root { 1793e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root UniquePtr<C> c(new C); 1803e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root assert(cCount == 1); 1813e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root } 1823e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root assert(cCount == 0); 1833e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root // Does release work? 1843e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root C* rawC; 1853e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root { 1863e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root UniquePtr<C> c(new C); 1873e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root assert(cCount == 1); 1883e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root rawC = c.release(); 1893e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root } 1903e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root assert(cCount == 1); 1913e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root delete rawC; 1923e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root // Does reset work? 1933e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root { 1943e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root UniquePtr<C> c(new C); 1953e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root assert(cCount == 1); 1963e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root c.reset(new C); 1973e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root assert(cCount == 1); 1983e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root } 1993e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root assert(cCount == 0); 2003e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root 2013e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root // 2023e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root // UniquePtr<T[]> tests... 2033e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root // 2043e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root 2053e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root // Can we free an array? 2063e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root { 2073e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root UniquePtr<C[]> cs(new C[4]); 2083e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root assert(cCount == 4); 2093e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root } 2103e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root assert(cCount == 0); 2113e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root // Does release work? 2123e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root { 2133e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root UniquePtr<C[]> c(new C[4]); 2143e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root assert(cCount == 4); 2153e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root rawC = c.release(); 2163e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root } 2173e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root assert(cCount == 4); 2183e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root delete[] rawC; 2193e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root // Does reset work? 2203e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root { 2213e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root UniquePtr<C[]> c(new C[4]); 2223e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root assert(cCount == 4); 2233e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root c.reset(new C[2]); 2243e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root assert(cCount == 2); 2253e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root } 2263e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root assert(cCount == 0); 2273e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root 2283e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root // 2293e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root // Custom deleter tests... 2303e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root // 2313e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root assert(!freed); 2323e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root { 2333e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root UniquePtr<int, Freer> i(reinterpret_cast<int*>(malloc(sizeof(int)))); 2343e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root *i = 123; 2353e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root } 2363e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root assert(freed); 2373e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root return 0; 2383e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root} 2393e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root#endif 2403e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root 2413e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root#endif // UNIQUE_PTR_H_included 242