1e5c31af7Sopenharmony_ci#ifndef _DEUNIQUEPTR_HPP 2e5c31af7Sopenharmony_ci#define _DEUNIQUEPTR_HPP 3e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 4e5c31af7Sopenharmony_ci * drawElements C++ Base Library 5e5c31af7Sopenharmony_ci * ----------------------------- 6e5c31af7Sopenharmony_ci * 7e5c31af7Sopenharmony_ci * Copyright 2014 The Android Open Source Project 8e5c31af7Sopenharmony_ci * 9e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 10e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 11e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 12e5c31af7Sopenharmony_ci * 13e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 14e5c31af7Sopenharmony_ci * 15e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 16e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 17e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 19e5c31af7Sopenharmony_ci * limitations under the License. 20e5c31af7Sopenharmony_ci * 21e5c31af7Sopenharmony_ci *//*! 22e5c31af7Sopenharmony_ci * \file 23e5c31af7Sopenharmony_ci * \brief Unique pointer. 24e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 25e5c31af7Sopenharmony_ci 26e5c31af7Sopenharmony_ci#include "deDefs.hpp" 27e5c31af7Sopenharmony_ci 28e5c31af7Sopenharmony_cinamespace de 29e5c31af7Sopenharmony_ci{ 30e5c31af7Sopenharmony_ci 31e5c31af7Sopenharmony_ci//! Unique pointer self-test. 32e5c31af7Sopenharmony_civoid UniquePtr_selfTest (void); 33e5c31af7Sopenharmony_ci 34e5c31af7Sopenharmony_ci// Hide implementation-private types in a details namespace. 35e5c31af7Sopenharmony_cinamespace details 36e5c31af7Sopenharmony_ci{ 37e5c31af7Sopenharmony_ci 38e5c31af7Sopenharmony_ci//! Auxiliary struct used to pass references between unique pointers. To 39e5c31af7Sopenharmony_ci//! ensure that managed pointers are deleted exactly once, this type should 40e5c31af7Sopenharmony_ci//! not appear in user code. 41e5c31af7Sopenharmony_citemplate<typename T, class D> 42e5c31af7Sopenharmony_cistruct PtrData 43e5c31af7Sopenharmony_ci{ 44e5c31af7Sopenharmony_ci PtrData (T* p, D d) : ptr(p), deleter(d) {} 45e5c31af7Sopenharmony_ci 46e5c31af7Sopenharmony_ci template <typename T2, class D2> 47e5c31af7Sopenharmony_ci PtrData (const PtrData<T2, D2>& d) : ptr(d.ptr), deleter(d.deleter) {} 48e5c31af7Sopenharmony_ci 49e5c31af7Sopenharmony_ci T* ptr; 50e5c31af7Sopenharmony_ci D deleter; 51e5c31af7Sopenharmony_ci}; 52e5c31af7Sopenharmony_ci 53e5c31af7Sopenharmony_citemplate<typename T, class D> 54e5c31af7Sopenharmony_ciclass UniqueBase 55e5c31af7Sopenharmony_ci{ 56e5c31af7Sopenharmony_cipublic: 57e5c31af7Sopenharmony_ci typedef T element_type; 58e5c31af7Sopenharmony_ci typedef D deleter_type; 59e5c31af7Sopenharmony_ci 60e5c31af7Sopenharmony_ci T* get (void) const throw() { return m_data.ptr; } //!< Get stored pointer. 61e5c31af7Sopenharmony_ci D getDeleter (void) const throw() { return m_data.deleter; } 62e5c31af7Sopenharmony_ci T* operator-> (void) const throw() { return get(); } //!< Get stored pointer. 63e5c31af7Sopenharmony_ci T& operator* (void) const throw() { return *get(); } //!< De-reference stored pointer. 64e5c31af7Sopenharmony_ci operator bool (void) const throw() { return !!get(); } 65e5c31af7Sopenharmony_ci 66e5c31af7Sopenharmony_ciprotected: 67e5c31af7Sopenharmony_ci UniqueBase (T* ptr, D deleter) : m_data(ptr, deleter) {} 68e5c31af7Sopenharmony_ci UniqueBase (PtrData<T, D> data) : m_data(data) {} 69e5c31af7Sopenharmony_ci ~UniqueBase (void); 70e5c31af7Sopenharmony_ci 71e5c31af7Sopenharmony_ci void reset (void); //!< Delete previous pointer, set to null. 72e5c31af7Sopenharmony_ci PtrData<T, D> releaseData (void) throw(); //!< Relinquish ownership, return pointer data. 73e5c31af7Sopenharmony_ci void assignData (PtrData<T, D> data); //!< Set new pointer, delete previous pointer. 74e5c31af7Sopenharmony_ci 75e5c31af7Sopenharmony_ciprivate: 76e5c31af7Sopenharmony_ci PtrData<T, D> m_data; 77e5c31af7Sopenharmony_ci}; 78e5c31af7Sopenharmony_ci 79e5c31af7Sopenharmony_citemplate <typename T, class D> 80e5c31af7Sopenharmony_ciUniqueBase<T, D>::~UniqueBase (void) 81e5c31af7Sopenharmony_ci{ 82e5c31af7Sopenharmony_ci reset(); 83e5c31af7Sopenharmony_ci} 84e5c31af7Sopenharmony_ci 85e5c31af7Sopenharmony_citemplate <typename T, class D> 86e5c31af7Sopenharmony_civoid UniqueBase<T, D>::reset (void) 87e5c31af7Sopenharmony_ci{ 88e5c31af7Sopenharmony_ci if (m_data.ptr != DE_NULL) 89e5c31af7Sopenharmony_ci { 90e5c31af7Sopenharmony_ci m_data.deleter(m_data.ptr); 91e5c31af7Sopenharmony_ci m_data.ptr = DE_NULL; 92e5c31af7Sopenharmony_ci } 93e5c31af7Sopenharmony_ci} 94e5c31af7Sopenharmony_ci 95e5c31af7Sopenharmony_citemplate <typename T, class D> 96e5c31af7Sopenharmony_ciPtrData<T, D> UniqueBase<T, D>::releaseData (void) throw() 97e5c31af7Sopenharmony_ci{ 98e5c31af7Sopenharmony_ci PtrData<T, D> data = m_data; 99e5c31af7Sopenharmony_ci m_data.ptr = DE_NULL; 100e5c31af7Sopenharmony_ci return data; 101e5c31af7Sopenharmony_ci} 102e5c31af7Sopenharmony_ci 103e5c31af7Sopenharmony_citemplate <typename T, class D> 104e5c31af7Sopenharmony_civoid UniqueBase<T, D>::assignData (PtrData<T, D> data) 105e5c31af7Sopenharmony_ci{ 106e5c31af7Sopenharmony_ci if (data.ptr != m_data.ptr) 107e5c31af7Sopenharmony_ci { 108e5c31af7Sopenharmony_ci reset(); 109e5c31af7Sopenharmony_ci m_data = data; 110e5c31af7Sopenharmony_ci } 111e5c31af7Sopenharmony_ci} 112e5c31af7Sopenharmony_ci 113e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 114e5c31af7Sopenharmony_ci * \brief Movable unique pointer 115e5c31af7Sopenharmony_ci * 116e5c31af7Sopenharmony_ci * A MovePtr is smart pointer that retains sole ownership of a pointer and 117e5c31af7Sopenharmony_ci * destroys it when it is destroyed (for example when it goes out of scope). 118e5c31af7Sopenharmony_ci * 119e5c31af7Sopenharmony_ci * A MovePtr can be copied and assigned to. The pointer ownership is moved to 120e5c31af7Sopenharmony_ci * the newly constructer or assigned-to MovePtr. Upon assignment to a 121e5c31af7Sopenharmony_ci * MovePtr, the previously managed pointer is deleted. 122e5c31af7Sopenharmony_ci * 123e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 124e5c31af7Sopenharmony_citemplate<typename T, class Deleter = DefaultDeleter<T> > 125e5c31af7Sopenharmony_ciclass MovePtr : public UniqueBase<T, Deleter> 126e5c31af7Sopenharmony_ci{ 127e5c31af7Sopenharmony_cipublic: 128e5c31af7Sopenharmony_ci MovePtr (void) : UniqueBase<T, Deleter> (DE_NULL, Deleter()) {} 129e5c31af7Sopenharmony_ci explicit MovePtr (T* ptr, Deleter deleter = Deleter()) : UniqueBase<T, Deleter> (ptr, deleter) {} 130e5c31af7Sopenharmony_ci MovePtr (MovePtr<T, Deleter>& other) : UniqueBase<T, Deleter> (other.releaseData()) {} 131e5c31af7Sopenharmony_ci 132e5c31af7Sopenharmony_ci MovePtr& operator= (MovePtr<T, Deleter>& other); 133e5c31af7Sopenharmony_ci T* release (void) throw(); 134e5c31af7Sopenharmony_ci void clear (void) { this->reset(); } 135e5c31af7Sopenharmony_ci 136e5c31af7Sopenharmony_ci // These implicit by-value conversions to and from a PtrData are used to 137e5c31af7Sopenharmony_ci // allow copying a MovePtr by value when returning from a function. To 138e5c31af7Sopenharmony_ci // ensure that the managed pointer gets deleted exactly once, the PtrData 139e5c31af7Sopenharmony_ci // should only exist as a temporary conversion step between two MovePtrs. 140e5c31af7Sopenharmony_ci MovePtr (PtrData<T, Deleter> data) : UniqueBase<T, Deleter> (data) {} 141e5c31af7Sopenharmony_ci MovePtr& operator= (PtrData<T, Deleter> data); 142e5c31af7Sopenharmony_ci 143e5c31af7Sopenharmony_ci template<typename U, class Del2> 144e5c31af7Sopenharmony_ci operator PtrData<U, Del2> (void) { return this->releaseData(); } 145e5c31af7Sopenharmony_ci}; 146e5c31af7Sopenharmony_ci 147e5c31af7Sopenharmony_citemplate<typename T, class D> 148e5c31af7Sopenharmony_ciMovePtr<T, D>& MovePtr<T,D>::operator= (PtrData<T, D> data) 149e5c31af7Sopenharmony_ci{ 150e5c31af7Sopenharmony_ci this->assignData(data); 151e5c31af7Sopenharmony_ci return *this; 152e5c31af7Sopenharmony_ci} 153e5c31af7Sopenharmony_ci 154e5c31af7Sopenharmony_citemplate<typename T, class D> 155e5c31af7Sopenharmony_ciMovePtr<T, D>& MovePtr<T,D>::operator= (MovePtr<T, D>& other) 156e5c31af7Sopenharmony_ci{ 157e5c31af7Sopenharmony_ci return (*this = other.releaseData()); 158e5c31af7Sopenharmony_ci} 159e5c31af7Sopenharmony_ci 160e5c31af7Sopenharmony_ci//! Steal the managed pointer. The caller is responsible for explicitly 161e5c31af7Sopenharmony_ci//! deleting the returned pointer. 162e5c31af7Sopenharmony_citemplate<typename T, class D> 163e5c31af7Sopenharmony_ciinline T* MovePtr<T,D>::release (void) throw() 164e5c31af7Sopenharmony_ci{ 165e5c31af7Sopenharmony_ci return this->releaseData().ptr; 166e5c31af7Sopenharmony_ci} 167e5c31af7Sopenharmony_ci 168e5c31af7Sopenharmony_ci//! Construct a MovePtr from a pointer. 169e5c31af7Sopenharmony_citemplate<typename T> 170e5c31af7Sopenharmony_ciinline MovePtr<T> movePtr (T* ptr) { return MovePtr<T>(ptr); } 171e5c31af7Sopenharmony_ci 172e5c31af7Sopenharmony_ci//! Allocate and construct an object and return its address as a MovePtr. 173e5c31af7Sopenharmony_citemplate<typename T> 174e5c31af7Sopenharmony_ciinline MovePtr<T> newMovePtr (void) { return MovePtr<T>(new T()); } 175e5c31af7Sopenharmony_citemplate<typename T, typename P0> 176e5c31af7Sopenharmony_ciinline MovePtr<T> newMovePtr (P0 p0) { return MovePtr<T>(new T(p0)); } 177e5c31af7Sopenharmony_citemplate<typename T, typename P0, typename P1> 178e5c31af7Sopenharmony_ciinline MovePtr<T> newMovePtr (P0 p0, P1 p1) { return MovePtr<T>(new T(p0, p1)); } 179e5c31af7Sopenharmony_citemplate<typename T, typename P0, typename P1, typename P2> 180e5c31af7Sopenharmony_ciinline MovePtr<T> newMovePtr (P0 p0, P1 p1, P2 p2) { return MovePtr<T>(new T(p0, p1, p2)); } 181e5c31af7Sopenharmony_ci 182e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 183e5c31af7Sopenharmony_ci * \brief Unique pointer 184e5c31af7Sopenharmony_ci * 185e5c31af7Sopenharmony_ci * UniquePtr is smart pointer that retains sole ownership of a pointer 186e5c31af7Sopenharmony_ci * and destroys it when UniquePtr is destroyed (for example when UniquePtr 187e5c31af7Sopenharmony_ci * goes out of scope). 188e5c31af7Sopenharmony_ci * 189e5c31af7Sopenharmony_ci * UniquePtr is not copyable or assignable. Pointer ownership can be transferred 190e5c31af7Sopenharmony_ci * from a UniquePtr only explicitly with the move() member function. 191e5c31af7Sopenharmony_ci * 192e5c31af7Sopenharmony_ci * A UniquePtr can be constructed from a MovePtr. In this case it assumes 193e5c31af7Sopenharmony_ci * ownership of the pointer from the MovePtr. Because a UniquePtr cannot be 194e5c31af7Sopenharmony_ci * copied, direct initialization syntax must be used, i.e.: 195e5c31af7Sopenharmony_ci * 196e5c31af7Sopenharmony_ci * MovePtr<Foo> createFoo (void); 197e5c31af7Sopenharmony_ci * UniquePtr<Foo> fooPtr(createFoo()); // NOT fooPtr = createFoo(); 198e5c31af7Sopenharmony_ci * 199e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 200e5c31af7Sopenharmony_citemplate<typename T, class Deleter = DefaultDeleter<T> > 201e5c31af7Sopenharmony_ciclass UniquePtr : public UniqueBase<T, Deleter> 202e5c31af7Sopenharmony_ci{ 203e5c31af7Sopenharmony_cipublic: 204e5c31af7Sopenharmony_ci explicit UniquePtr (T* ptr, Deleter deleter = Deleter()); 205e5c31af7Sopenharmony_ci UniquePtr (PtrData<T, Deleter> data); 206e5c31af7Sopenharmony_ci MovePtr<T, Deleter> move (void); 207e5c31af7Sopenharmony_ci 208e5c31af7Sopenharmony_ciprivate: 209e5c31af7Sopenharmony_ci UniquePtr (const UniquePtr<T>& other); // Not allowed! 210e5c31af7Sopenharmony_ci UniquePtr operator= (const UniquePtr<T>& other); // Not allowed! 211e5c31af7Sopenharmony_ci}; 212e5c31af7Sopenharmony_ci 213e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 214e5c31af7Sopenharmony_ci * \brief Construct unique pointer. 215e5c31af7Sopenharmony_ci * \param ptr Pointer to be managed. 216e5c31af7Sopenharmony_ci * 217e5c31af7Sopenharmony_ci * Pointer ownership is transferred to the UniquePtr. 218e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 219e5c31af7Sopenharmony_citemplate<typename T, class Deleter> 220e5c31af7Sopenharmony_ciinline UniquePtr<T, Deleter>::UniquePtr (T* ptr, Deleter deleter) 221e5c31af7Sopenharmony_ci : UniqueBase<T, Deleter> (ptr, deleter) 222e5c31af7Sopenharmony_ci{ 223e5c31af7Sopenharmony_ci} 224e5c31af7Sopenharmony_ci 225e5c31af7Sopenharmony_citemplate<typename T, class Deleter> 226e5c31af7Sopenharmony_ciinline UniquePtr<T, Deleter>::UniquePtr (PtrData<T, Deleter> data) 227e5c31af7Sopenharmony_ci : UniqueBase<T, Deleter> (data) 228e5c31af7Sopenharmony_ci{ 229e5c31af7Sopenharmony_ci} 230e5c31af7Sopenharmony_ci 231e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 232e5c31af7Sopenharmony_ci * \brief Relinquish ownership of pointer. 233e5c31af7Sopenharmony_ci * 234e5c31af7Sopenharmony_ci * This method returns a MovePtr that now owns the pointer. The pointer in 235e5c31af7Sopenharmony_ci * the UniquePtr is set to null. 236e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 237e5c31af7Sopenharmony_citemplate<typename T, class Deleter> 238e5c31af7Sopenharmony_ciinline MovePtr<T, Deleter> UniquePtr<T, Deleter>::move (void) 239e5c31af7Sopenharmony_ci{ 240e5c31af7Sopenharmony_ci return MovePtr<T, Deleter>(this->releaseData()); 241e5c31af7Sopenharmony_ci} 242e5c31af7Sopenharmony_ci 243e5c31af7Sopenharmony_ci} // details 244e5c31af7Sopenharmony_ci 245e5c31af7Sopenharmony_ciusing details::UniquePtr; 246e5c31af7Sopenharmony_ciusing details::MovePtr; 247e5c31af7Sopenharmony_ciusing details::newMovePtr; 248e5c31af7Sopenharmony_ci 249e5c31af7Sopenharmony_ci} // de 250e5c31af7Sopenharmony_ci 251e5c31af7Sopenharmony_ci#endif // _DEUNIQUEPTR_HPP 252