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.
21 template <typename T>
22 struct DefaultDelete {
23     enum { type_must_be_complete = sizeof(T) };
DefaultDeleteDefaultDelete24     DefaultDelete() {}
operatorDefaultDelete25     void operator()(T* p) const {
26         delete p;
27     }
28 };
29 
30 // Default deleter for array types.
31 template <typename T>
32 struct 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);
47 template <typename T, typename D = DefaultDelete<T> >
48 class UniquePtr {
49 public:
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 
85 private:
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[].
100 template <typename T, typename D>
101 class UniquePtr<T[], D> {
102 public:
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 
132 private:
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