1 #ifndef _DEUNIQUEPTR_HPP
2 #define _DEUNIQUEPTR_HPP
3 /*-------------------------------------------------------------------------
4 * drawElements C++ Base Library
5 * -----------------------------
7 * Copyright 2014 The Android Open Source Project
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
23 * \brief Unique pointer.
24 *//*--------------------------------------------------------------------*/
31 //! Unique pointer self-test.
32 void UniquePtr_selfTest (void);
34 // Hide implementation-private types in a details namespace.
38 //! Auxiliary struct used to pass references between unique pointers. To
39 //! ensure that managed pointers are deleted exactly once, this type should
40 //! not appear in user code.
41 template<typename T, class D>
44 PtrData (T* p, D d) : ptr(p), deleter(d) {}
46 template <typename T2, class D2>
47 PtrData (const PtrData<T2, D2>& d) : ptr(d.ptr), deleter(d.deleter) {}
53 template<typename T, class D>
57 typedef T element_type;
58 typedef D deleter_type;
60 T* get (void) const throw() { return m_data.ptr; } //!< Get stored pointer.
61 D getDeleter (void) const throw() { return m_data.deleter; }
62 T* operator-> (void) const throw() { return get(); } //!< Get stored pointer.
63 T& operator* (void) const throw() { return *get(); } //!< De-reference stored pointer.
64 operator bool (void) const throw() { return !!get(); }
67 UniqueBase (T* ptr, D deleter) : m_data(ptr, deleter) {}
68 UniqueBase (PtrData<T, D> data) : m_data(data) {}
71 void reset (void); //!< Delete previous pointer, set to null.
72 PtrData<T, D> releaseData (void) throw(); //!< Relinquish ownership, return pointer data.
73 void assignData (PtrData<T, D> data); //!< Set new pointer, delete previous pointer.
79 template <typename T, class D>
80 UniqueBase<T, D>::~UniqueBase (void)
85 template <typename T, class D>
86 void UniqueBase<T, D>::reset (void)
88 if (m_data.ptr != DE_NULL)
90 m_data.deleter(m_data.ptr);
95 template <typename T, class D>
96 PtrData<T, D> UniqueBase<T, D>::releaseData (void) throw()
98 PtrData<T, D> data = m_data;
103 template <typename T, class D>
104 void UniqueBase<T, D>::assignData (PtrData<T, D> data)
106 if (data.ptr != m_data.ptr)
113 /*--------------------------------------------------------------------*//*!
114 * \brief Movable unique pointer
116 * A MovePtr is smart pointer that retains sole ownership of a pointer and
117 * destroys it when it is destroyed (for example when it goes out of scope).
119 * A MovePtr can be copied and assigned to. The pointer ownership is moved to
120 * the newly constructer or assigned-to MovePtr. Upon assignment to a
121 * MovePtr, the previously managed pointer is deleted.
123 *//*--------------------------------------------------------------------*/
124 template<typename T, class Deleter = DefaultDeleter<T> >
125 class MovePtr : public UniqueBase<T, Deleter>
128 MovePtr (void) : UniqueBase<T, Deleter> (DE_NULL, Deleter()) {}
129 explicit MovePtr (T* ptr, Deleter deleter = Deleter()) : UniqueBase<T, Deleter> (ptr, deleter) {}
130 MovePtr (MovePtr<T, Deleter>& other) : UniqueBase<T, Deleter> (other.releaseData()) {}
132 MovePtr& operator= (MovePtr<T, Deleter>& other);
133 T* release (void) throw();
134 void clear (void) { this->reset(); }
136 // These implicit by-value conversions to and from a PtrData are used to
137 // allow copying a MovePtr by value when returning from a function. To
138 // ensure that the managed pointer gets deleted exactly once, the PtrData
139 // should only exist as a temporary conversion step between two MovePtrs.
140 MovePtr (PtrData<T, Deleter> data) : UniqueBase<T, Deleter> (data) {}
141 MovePtr& operator= (PtrData<T, Deleter> data);
143 template<typename U, class Del2>
144 operator PtrData<U, Del2> (void) { return this->releaseData(); }
147 template<typename T, class D>
148 MovePtr<T, D>& MovePtr<T,D>::operator= (PtrData<T, D> data)
150 this->assignData(data);
154 template<typename T, class D>
155 MovePtr<T, D>& MovePtr<T,D>::operator= (MovePtr<T, D>& other)
157 return (*this = other.releaseData());
160 //! Steal the managed pointer. The caller is responsible for explicitly
161 //! deleting the returned pointer.
162 template<typename T, class D>
163 inline T* MovePtr<T,D>::release (void) throw()
165 return this->releaseData().ptr;
168 //! Construct a MovePtr from a pointer.
170 inline MovePtr<T> movePtr (T* ptr) { return MovePtr<T>(ptr); }
172 //! Allocate and construct an object and return its address as a MovePtr.
174 inline MovePtr<T> newMovePtr (void) { return MovePtr<T>(new T()); }
175 template<typename T, typename P0>
176 inline MovePtr<T> newMovePtr (P0 p0) { return MovePtr<T>(new T(p0)); }
177 template<typename T, typename P0, typename P1>
178 inline MovePtr<T> newMovePtr (P0 p0, P1 p1) { return MovePtr<T>(new T(p0, p1)); }
179 template<typename T, typename P0, typename P1, typename P2>
180 inline MovePtr<T> newMovePtr (P0 p0, P1 p1, P2 p2) { return MovePtr<T>(new T(p0, p1, p2)); }
182 /*--------------------------------------------------------------------*//*!
183 * \brief Unique pointer
185 * UniquePtr is smart pointer that retains sole ownership of a pointer
186 * and destroys it when UniquePtr is destroyed (for example when UniquePtr
187 * goes out of scope).
189 * UniquePtr is not copyable or assignable. Pointer ownership can be transferred
190 * from a UniquePtr only explicitly with the move() member function.
192 * A UniquePtr can be constructed from a MovePtr. In this case it assumes
193 * ownership of the pointer from the MovePtr. Because a UniquePtr cannot be
194 * copied, direct initialization syntax must be used, i.e.:
196 * MovePtr<Foo> createFoo (void);
197 * UniquePtr<Foo> fooPtr(createFoo()); // NOT fooPtr = createFoo();
199 *//*--------------------------------------------------------------------*/
200 template<typename T, class Deleter = DefaultDeleter<T> >
201 class UniquePtr : public UniqueBase<T, Deleter>
204 explicit UniquePtr (T* ptr, Deleter deleter = Deleter());
205 UniquePtr (PtrData<T, Deleter> data);
206 MovePtr<T, Deleter> move (void);
209 UniquePtr (const UniquePtr<T>& other); // Not allowed!
210 UniquePtr operator= (const UniquePtr<T>& other); // Not allowed!
213 /*--------------------------------------------------------------------*//*!
214 * \brief Construct unique pointer.
215 * \param ptr Pointer to be managed.
217 * Pointer ownership is transferred to the UniquePtr.
218 *//*--------------------------------------------------------------------*/
219 template<typename T, class Deleter>
220 inline UniquePtr<T, Deleter>::UniquePtr (T* ptr, Deleter deleter)
221 : UniqueBase<T, Deleter> (ptr, deleter)
225 template<typename T, class Deleter>
226 inline UniquePtr<T, Deleter>::UniquePtr (PtrData<T, Deleter> data)
227 : UniqueBase<T, Deleter> (data)
231 /*--------------------------------------------------------------------*//*!
232 * \brief Relinquish ownership of pointer.
234 * This method returns a MovePtr that now owns the pointer. The pointer in
235 * the UniquePtr is set to null.
236 *//*--------------------------------------------------------------------*/
237 template<typename T, class Deleter>
238 inline MovePtr<T, Deleter> UniquePtr<T, Deleter>::move (void)
240 return MovePtr<T, Deleter>(this->releaseData());
245 using details::UniquePtr;
246 using details::MovePtr;
247 using details::newMovePtr;
251 #endif // _DEUNIQUEPTR_HPP