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