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#ifndef UNIQUE_PTR_H_included
18#define UNIQUE_PTR_H_included
19
20// Default deleter for pointer types.
21template <typename T>
22struct DefaultDelete {
23    enum { type_must_be_complete = sizeof(T) };
24    DefaultDelete() {}
25    void operator()(T* p) const {
26        delete p;
27    }
28};
29
30// Default deleter for array types.
31template <typename T>
32struct DefaultDelete<T[]> {
33    enum { type_must_be_complete = sizeof(T) };
34    void operator()(T* p) const {
35        delete[] p;
36    }
37};
38
39// A smart pointer that deletes the given pointer on destruction.
40// Equivalent to C++0x's std::unique_ptr (a combination of boost::scoped_ptr
41// and boost::scoped_array).
42// Named to be in keeping with Android style but also to avoid
43// collision with any other implementation, until we can switch over
44// to unique_ptr.
45// Use thus:
46//   UniquePtr<C> c(new C);
47template <typename T, typename D = DefaultDelete<T> >
48class UniquePtr {
49public:
50    // Construct a new UniquePtr, taking ownership of the given raw pointer.
51    explicit UniquePtr(T* ptr = nullptr) : mPtr(ptr) { }
52
53    UniquePtr(UniquePtr<T, D>&& that) {
54      mPtr = that.mPtr;
55      that.mPtr = nullptr;
56    }
57
58    ~UniquePtr() {
59        reset();
60    }
61
62    // Accessors.
63    T& operator*() const { return *mPtr; }
64    T* operator->() const { return mPtr; }
65    T* get() const { return mPtr; }
66
67    // Returns the raw pointer and hands over ownership to the caller.
68    // The pointer will not be deleted by UniquePtr.
69    T* release() __attribute__((warn_unused_result)) {
70        T* result = mPtr;
71        mPtr = nullptr;
72        return result;
73    }
74
75    // Takes ownership of the given raw pointer.
76    // If this smart pointer previously owned a different raw pointer, that
77    // raw pointer will be freed.
78    void reset(T* ptr = nullptr) {
79        if (ptr != mPtr) {
80            D()(mPtr);
81            mPtr = ptr;
82        }
83    }
84
85private:
86    // The raw pointer.
87    T* mPtr;
88
89    // Comparing unique pointers is probably a mistake, since they're unique.
90    template <typename T2> bool operator==(const UniquePtr<T2>& p) const = delete;
91    template <typename T2> bool operator!=(const UniquePtr<T2>& p) const = delete;
92
93    // Disallow copy and assignment.
94    UniquePtr(const UniquePtr&) = delete;
95    void operator=(const UniquePtr&) = delete;
96};
97
98// Partial specialization for array types. Like std::unique_ptr, this removes
99// operator* and operator-> but adds operator[].
100template <typename T, typename D>
101class UniquePtr<T[], D> {
102public:
103    explicit UniquePtr(T* ptr = NULL) : mPtr(ptr) {
104    }
105    UniquePtr(UniquePtr<T, D>&& that) {
106      mPtr = that.mPtr;
107      that.mPtr = nullptr;
108    }
109
110    ~UniquePtr() {
111        reset();
112    }
113
114    T& operator[](size_t i) const {
115        return mPtr[i];
116    }
117    T* get() const { return mPtr; }
118
119    T* release() __attribute__((warn_unused_result)) {
120        T* result = mPtr;
121        mPtr = NULL;
122        return result;
123    }
124
125    void reset(T* ptr = NULL) {
126        if (ptr != mPtr) {
127            D()(mPtr);
128            mPtr = ptr;
129        }
130    }
131
132private:
133    T* mPtr;
134
135    // Disallow copy and assignment.
136    UniquePtr(const UniquePtr&) = delete;
137    void operator=(const UniquePtr&) = delete;
138};
139
140#endif  // UNIQUE_PTR_H_included
141