1e5c31af7Sopenharmony_ci#ifndef _DESHAREDPTR_HPP 2e5c31af7Sopenharmony_ci#define _DESHAREDPTR_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 Shared pointer. 24e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 25e5c31af7Sopenharmony_ci 26e5c31af7Sopenharmony_ci#include "deDefs.hpp" 27e5c31af7Sopenharmony_ci#include "deAtomic.h" 28e5c31af7Sopenharmony_ci 29e5c31af7Sopenharmony_ci#include <exception> 30e5c31af7Sopenharmony_ci#include <algorithm> 31e5c31af7Sopenharmony_ci 32e5c31af7Sopenharmony_cinamespace de 33e5c31af7Sopenharmony_ci{ 34e5c31af7Sopenharmony_ci 35e5c31af7Sopenharmony_ci//! Shared pointer self-test. 36e5c31af7Sopenharmony_civoid SharedPtr_selfTest (void); 37e5c31af7Sopenharmony_ci 38e5c31af7Sopenharmony_ciclass DeadReferenceException : public std::exception 39e5c31af7Sopenharmony_ci{ 40e5c31af7Sopenharmony_cipublic: 41e5c31af7Sopenharmony_ci DeadReferenceException (void) throw() 42e5c31af7Sopenharmony_ci : std::exception() 43e5c31af7Sopenharmony_ci { 44e5c31af7Sopenharmony_ci } 45e5c31af7Sopenharmony_ci 46e5c31af7Sopenharmony_ci const char* what (void) const throw() 47e5c31af7Sopenharmony_ci { 48e5c31af7Sopenharmony_ci return "DeadReferenceException"; 49e5c31af7Sopenharmony_ci } 50e5c31af7Sopenharmony_ci}; 51e5c31af7Sopenharmony_ci 52e5c31af7Sopenharmony_cistruct SharedPtrStateBase 53e5c31af7Sopenharmony_ci{ 54e5c31af7Sopenharmony_ci SharedPtrStateBase (void) 55e5c31af7Sopenharmony_ci : strongRefCount (0) 56e5c31af7Sopenharmony_ci , weakRefCount (0) 57e5c31af7Sopenharmony_ci { 58e5c31af7Sopenharmony_ci } 59e5c31af7Sopenharmony_ci 60e5c31af7Sopenharmony_ci virtual ~SharedPtrStateBase (void) throw() {} 61e5c31af7Sopenharmony_ci virtual void deletePtr (void) throw() = 0; 62e5c31af7Sopenharmony_ci 63e5c31af7Sopenharmony_ci volatile deInt32 strongRefCount; 64e5c31af7Sopenharmony_ci volatile deInt32 weakRefCount; //!< WeakPtr references + StrongPtr references. 65e5c31af7Sopenharmony_ci}; 66e5c31af7Sopenharmony_ci 67e5c31af7Sopenharmony_citemplate<typename Type, typename Deleter> 68e5c31af7Sopenharmony_cistruct SharedPtrState : public SharedPtrStateBase 69e5c31af7Sopenharmony_ci{ 70e5c31af7Sopenharmony_ci SharedPtrState (Type* ptr, Deleter deleter) 71e5c31af7Sopenharmony_ci : m_ptr (ptr) 72e5c31af7Sopenharmony_ci , m_deleter (deleter) 73e5c31af7Sopenharmony_ci { 74e5c31af7Sopenharmony_ci } 75e5c31af7Sopenharmony_ci 76e5c31af7Sopenharmony_ci virtual ~SharedPtrState (void) throw() 77e5c31af7Sopenharmony_ci { 78e5c31af7Sopenharmony_ci DE_ASSERT(!m_ptr); 79e5c31af7Sopenharmony_ci } 80e5c31af7Sopenharmony_ci 81e5c31af7Sopenharmony_ci virtual void deletePtr (void) throw() 82e5c31af7Sopenharmony_ci { 83e5c31af7Sopenharmony_ci m_deleter(m_ptr); 84e5c31af7Sopenharmony_ci m_ptr = DE_NULL; 85e5c31af7Sopenharmony_ci } 86e5c31af7Sopenharmony_ci 87e5c31af7Sopenharmony_ciprivate: 88e5c31af7Sopenharmony_ci Type* m_ptr; 89e5c31af7Sopenharmony_ci Deleter m_deleter; 90e5c31af7Sopenharmony_ci}; 91e5c31af7Sopenharmony_ci 92e5c31af7Sopenharmony_citemplate<typename T> 93e5c31af7Sopenharmony_ciclass SharedPtr; 94e5c31af7Sopenharmony_ci 95e5c31af7Sopenharmony_citemplate<typename T> 96e5c31af7Sopenharmony_ciclass WeakPtr; 97e5c31af7Sopenharmony_ci 98e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 99e5c31af7Sopenharmony_ci * \brief Shared pointer 100e5c31af7Sopenharmony_ci * 101e5c31af7Sopenharmony_ci * SharedPtr is smart pointer for managing shared ownership to a pointer. 102e5c31af7Sopenharmony_ci * Multiple SharedPtrs can maintain ownership to the pointer and it is 103e5c31af7Sopenharmony_ci * destructed when last SharedPtr is destroyed. 104e5c31af7Sopenharmony_ci * 105e5c31af7Sopenharmony_ci * SharedPtr can also be NULL. 106e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 107e5c31af7Sopenharmony_citemplate<typename T> 108e5c31af7Sopenharmony_ciclass SharedPtr 109e5c31af7Sopenharmony_ci{ 110e5c31af7Sopenharmony_cipublic: 111e5c31af7Sopenharmony_ci SharedPtr (void); 112e5c31af7Sopenharmony_ci SharedPtr (const SharedPtr<T>& other); 113e5c31af7Sopenharmony_ci explicit SharedPtr (T* ptr); 114e5c31af7Sopenharmony_ci 115e5c31af7Sopenharmony_ci template<typename Deleter> 116e5c31af7Sopenharmony_ci SharedPtr (T* ptr, Deleter deleter); 117e5c31af7Sopenharmony_ci 118e5c31af7Sopenharmony_ci template<typename Y> 119e5c31af7Sopenharmony_ci explicit SharedPtr (const SharedPtr<Y>& other); 120e5c31af7Sopenharmony_ci 121e5c31af7Sopenharmony_ci template<typename Y> 122e5c31af7Sopenharmony_ci explicit SharedPtr (const WeakPtr<Y>& other); 123e5c31af7Sopenharmony_ci 124e5c31af7Sopenharmony_ci ~SharedPtr (void); 125e5c31af7Sopenharmony_ci 126e5c31af7Sopenharmony_ci template<typename Y> 127e5c31af7Sopenharmony_ci SharedPtr& operator= (const SharedPtr<Y>& other); 128e5c31af7Sopenharmony_ci SharedPtr& operator= (const SharedPtr<T>& other); 129e5c31af7Sopenharmony_ci 130e5c31af7Sopenharmony_ci template<typename Y> 131e5c31af7Sopenharmony_ci SharedPtr& operator= (const WeakPtr<Y>& other); 132e5c31af7Sopenharmony_ci 133e5c31af7Sopenharmony_ci T* get (void) const throw() { return m_ptr; } //!< Get stored pointer. 134e5c31af7Sopenharmony_ci T* operator-> (void) const throw() { return m_ptr; } //!< Get stored pointer. 135e5c31af7Sopenharmony_ci T& operator* (void) const throw() { return *m_ptr; } //!< De-reference pointer. 136e5c31af7Sopenharmony_ci 137e5c31af7Sopenharmony_ci operator bool (void) const throw() { return !!m_ptr; } 138e5c31af7Sopenharmony_ci 139e5c31af7Sopenharmony_ci void swap (SharedPtr<T>& other); 140e5c31af7Sopenharmony_ci 141e5c31af7Sopenharmony_ci void clear (void); 142e5c31af7Sopenharmony_ci 143e5c31af7Sopenharmony_ci template<typename Y> 144e5c31af7Sopenharmony_ci operator SharedPtr<Y> (void) const; 145e5c31af7Sopenharmony_ci 146e5c31af7Sopenharmony_ciprivate: 147e5c31af7Sopenharmony_ci void acquire (void); 148e5c31af7Sopenharmony_ci void acquireFromWeak (const WeakPtr<T>& other); 149e5c31af7Sopenharmony_ci void release (void); 150e5c31af7Sopenharmony_ci 151e5c31af7Sopenharmony_ci T* m_ptr; 152e5c31af7Sopenharmony_ci SharedPtrStateBase* m_state; 153e5c31af7Sopenharmony_ci 154e5c31af7Sopenharmony_ci friend class WeakPtr<T>; 155e5c31af7Sopenharmony_ci 156e5c31af7Sopenharmony_ci template<typename U> 157e5c31af7Sopenharmony_ci friend class SharedPtr; 158e5c31af7Sopenharmony_ci}; 159e5c31af7Sopenharmony_ci 160e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 161e5c31af7Sopenharmony_ci * \brief Weak pointer 162e5c31af7Sopenharmony_ci * 163e5c31af7Sopenharmony_ci * WeakPtr manages weak references to objects owned by SharedPtr. Shared 164e5c31af7Sopenharmony_ci * pointer can be converted to weak pointer and vice versa. Weak pointer 165e5c31af7Sopenharmony_ci * differs from SharedPtr by not affecting the lifetime of the managed 166e5c31af7Sopenharmony_ci * object. 167e5c31af7Sopenharmony_ci * 168e5c31af7Sopenharmony_ci * WeakPtr can be converted back to SharedPtr but that operation can fail 169e5c31af7Sopenharmony_ci * if the object is no longer live. In such case DeadReferenceException 170e5c31af7Sopenharmony_ci * will be thrown. 171e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 172e5c31af7Sopenharmony_citemplate<typename T> 173e5c31af7Sopenharmony_ciclass WeakPtr 174e5c31af7Sopenharmony_ci{ 175e5c31af7Sopenharmony_cipublic: 176e5c31af7Sopenharmony_ci WeakPtr (void); 177e5c31af7Sopenharmony_ci WeakPtr (const WeakPtr<T>& other); 178e5c31af7Sopenharmony_ci 179e5c31af7Sopenharmony_ci explicit WeakPtr (const SharedPtr<T>& other); 180e5c31af7Sopenharmony_ci ~WeakPtr (void); 181e5c31af7Sopenharmony_ci 182e5c31af7Sopenharmony_ci WeakPtr& operator= (const WeakPtr<T>& other); 183e5c31af7Sopenharmony_ci WeakPtr& operator= (const SharedPtr<T>& other); 184e5c31af7Sopenharmony_ci 185e5c31af7Sopenharmony_ci SharedPtr<T> lock (void); 186e5c31af7Sopenharmony_ci 187e5c31af7Sopenharmony_ciprivate: 188e5c31af7Sopenharmony_ci void acquire (void); 189e5c31af7Sopenharmony_ci void release (void); 190e5c31af7Sopenharmony_ci 191e5c31af7Sopenharmony_ci T* m_ptr; 192e5c31af7Sopenharmony_ci SharedPtrStateBase* m_state; 193e5c31af7Sopenharmony_ci 194e5c31af7Sopenharmony_ci friend class SharedPtr<T>; 195e5c31af7Sopenharmony_ci}; 196e5c31af7Sopenharmony_ci 197e5c31af7Sopenharmony_ci// SharedPtr template implementation. 198e5c31af7Sopenharmony_ci 199e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 200e5c31af7Sopenharmony_ci * \brief Construct empty shared pointer. 201e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 202e5c31af7Sopenharmony_citemplate<typename T> 203e5c31af7Sopenharmony_ciinline SharedPtr<T>::SharedPtr (void) 204e5c31af7Sopenharmony_ci : m_ptr (DE_NULL) 205e5c31af7Sopenharmony_ci , m_state (DE_NULL) 206e5c31af7Sopenharmony_ci{ 207e5c31af7Sopenharmony_ci} 208e5c31af7Sopenharmony_ci 209e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 210e5c31af7Sopenharmony_ci * \brief Construct shared pointer from pointer. 211e5c31af7Sopenharmony_ci * \param ptr Pointer to be managed. 212e5c31af7Sopenharmony_ci * 213e5c31af7Sopenharmony_ci * Ownership of the pointer will be transferred to SharedPtr and future 214e5c31af7Sopenharmony_ci * SharedPtr's initialized or assigned from this SharedPtr. 215e5c31af7Sopenharmony_ci * 216e5c31af7Sopenharmony_ci * If allocation of shared state fails. The "ptr" argument will not be 217e5c31af7Sopenharmony_ci * released. 218e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 219e5c31af7Sopenharmony_citemplate<typename T> 220e5c31af7Sopenharmony_ciinline SharedPtr<T>::SharedPtr (T* ptr) 221e5c31af7Sopenharmony_ci : m_ptr (DE_NULL) 222e5c31af7Sopenharmony_ci , m_state (DE_NULL) 223e5c31af7Sopenharmony_ci{ 224e5c31af7Sopenharmony_ci try 225e5c31af7Sopenharmony_ci { 226e5c31af7Sopenharmony_ci m_ptr = ptr; 227e5c31af7Sopenharmony_ci m_state = new SharedPtrState<T, DefaultDeleter<T> >(ptr, DefaultDeleter<T>()); 228e5c31af7Sopenharmony_ci m_state->strongRefCount = 1; 229e5c31af7Sopenharmony_ci m_state->weakRefCount = 1; 230e5c31af7Sopenharmony_ci } 231e5c31af7Sopenharmony_ci catch (...) 232e5c31af7Sopenharmony_ci { 233e5c31af7Sopenharmony_ci // \note ptr is not released. 234e5c31af7Sopenharmony_ci delete m_state; 235e5c31af7Sopenharmony_ci throw; 236e5c31af7Sopenharmony_ci } 237e5c31af7Sopenharmony_ci} 238e5c31af7Sopenharmony_ci 239e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 240e5c31af7Sopenharmony_ci * \brief Construct shared pointer from pointer. 241e5c31af7Sopenharmony_ci * \param ptr Pointer to be managed. 242e5c31af7Sopenharmony_ci * 243e5c31af7Sopenharmony_ci * Ownership of the pointer will be transferred to SharedPtr and future 244e5c31af7Sopenharmony_ci * SharedPtr's initialized or assigned from this SharedPtr. 245e5c31af7Sopenharmony_ci * 246e5c31af7Sopenharmony_ci * Deleter must be callable type and deleter is called with the pointer 247e5c31af7Sopenharmony_ci * argument when the reference count becomes 0. 248e5c31af7Sopenharmony_ci * 249e5c31af7Sopenharmony_ci * If allocation of shared state fails. The "ptr" argument will not be 250e5c31af7Sopenharmony_ci * released. 251e5c31af7Sopenharmony_ci * 252e5c31af7Sopenharmony_ci * Calling deleter or calling destructor for deleter should never throw. 253e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 254e5c31af7Sopenharmony_citemplate<typename T> 255e5c31af7Sopenharmony_citemplate<typename Deleter> 256e5c31af7Sopenharmony_ciinline SharedPtr<T>::SharedPtr (T* ptr, Deleter deleter) 257e5c31af7Sopenharmony_ci : m_ptr (DE_NULL) 258e5c31af7Sopenharmony_ci , m_state (DE_NULL) 259e5c31af7Sopenharmony_ci{ 260e5c31af7Sopenharmony_ci try 261e5c31af7Sopenharmony_ci { 262e5c31af7Sopenharmony_ci m_ptr = ptr; 263e5c31af7Sopenharmony_ci m_state = new SharedPtrState<T, Deleter>(ptr, deleter); 264e5c31af7Sopenharmony_ci m_state->strongRefCount = 1; 265e5c31af7Sopenharmony_ci m_state->weakRefCount = 1; 266e5c31af7Sopenharmony_ci } 267e5c31af7Sopenharmony_ci catch (...) 268e5c31af7Sopenharmony_ci { 269e5c31af7Sopenharmony_ci // \note ptr is not released. 270e5c31af7Sopenharmony_ci delete m_state; 271e5c31af7Sopenharmony_ci throw; 272e5c31af7Sopenharmony_ci } 273e5c31af7Sopenharmony_ci} 274e5c31af7Sopenharmony_ci 275e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 276e5c31af7Sopenharmony_ci * \brief Initialize shared pointer from another SharedPtr. 277e5c31af7Sopenharmony_ci * \param other Pointer to be shared. 278e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 279e5c31af7Sopenharmony_citemplate<typename T> 280e5c31af7Sopenharmony_ciinline SharedPtr<T>::SharedPtr (const SharedPtr<T>& other) 281e5c31af7Sopenharmony_ci : m_ptr (other.m_ptr) 282e5c31af7Sopenharmony_ci , m_state (other.m_state) 283e5c31af7Sopenharmony_ci{ 284e5c31af7Sopenharmony_ci acquire(); 285e5c31af7Sopenharmony_ci} 286e5c31af7Sopenharmony_ci 287e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 288e5c31af7Sopenharmony_ci * \brief Initialize shared pointer from another SharedPtr. 289e5c31af7Sopenharmony_ci * \param other Pointer to be shared. 290e5c31af7Sopenharmony_ci * 291e5c31af7Sopenharmony_ci * Y* must be convertible to T*. 292e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 293e5c31af7Sopenharmony_citemplate<typename T> 294e5c31af7Sopenharmony_citemplate<typename Y> 295e5c31af7Sopenharmony_ciinline SharedPtr<T>::SharedPtr (const SharedPtr<Y>& other) 296e5c31af7Sopenharmony_ci : m_ptr (other.m_ptr) 297e5c31af7Sopenharmony_ci , m_state (other.m_state) 298e5c31af7Sopenharmony_ci{ 299e5c31af7Sopenharmony_ci acquire(); 300e5c31af7Sopenharmony_ci} 301e5c31af7Sopenharmony_ci 302e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 303e5c31af7Sopenharmony_ci * \brief Initialize shared pointer from weak reference. 304e5c31af7Sopenharmony_ci * \param other Pointer to be shared. 305e5c31af7Sopenharmony_ci * 306e5c31af7Sopenharmony_ci * Y* must be convertible to T*. 307e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 308e5c31af7Sopenharmony_citemplate<typename T> 309e5c31af7Sopenharmony_citemplate<typename Y> 310e5c31af7Sopenharmony_ciinline SharedPtr<T>::SharedPtr (const WeakPtr<Y>& other) 311e5c31af7Sopenharmony_ci : m_ptr (DE_NULL) 312e5c31af7Sopenharmony_ci , m_state (DE_NULL) 313e5c31af7Sopenharmony_ci{ 314e5c31af7Sopenharmony_ci acquireFromWeak(other); 315e5c31af7Sopenharmony_ci} 316e5c31af7Sopenharmony_ci 317e5c31af7Sopenharmony_citemplate<typename T> 318e5c31af7Sopenharmony_ciinline SharedPtr<T>::~SharedPtr (void) 319e5c31af7Sopenharmony_ci{ 320e5c31af7Sopenharmony_ci release(); 321e5c31af7Sopenharmony_ci} 322e5c31af7Sopenharmony_ci 323e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 324e5c31af7Sopenharmony_ci * \brief Assign from other shared pointer. 325e5c31af7Sopenharmony_ci * \param other Pointer to be shared. 326e5c31af7Sopenharmony_ci * \return Reference to this SharedPtr. 327e5c31af7Sopenharmony_ci * 328e5c31af7Sopenharmony_ci * Reference to current pointer is released and reference to new pointer is 329e5c31af7Sopenharmony_ci * acquired. 330e5c31af7Sopenharmony_ci * 331e5c31af7Sopenharmony_ci * Y* must be convertible to T*. 332e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 333e5c31af7Sopenharmony_citemplate<typename T> 334e5c31af7Sopenharmony_citemplate<typename Y> 335e5c31af7Sopenharmony_ciinline SharedPtr<T>& SharedPtr<T>::operator= (const SharedPtr<Y>& other) 336e5c31af7Sopenharmony_ci{ 337e5c31af7Sopenharmony_ci if (m_state == other.m_state) 338e5c31af7Sopenharmony_ci return *this; 339e5c31af7Sopenharmony_ci 340e5c31af7Sopenharmony_ci // Release current reference. 341e5c31af7Sopenharmony_ci release(); 342e5c31af7Sopenharmony_ci 343e5c31af7Sopenharmony_ci // Copy from other and acquire reference. 344e5c31af7Sopenharmony_ci m_ptr = other.m_ptr; 345e5c31af7Sopenharmony_ci m_state = other.m_state; 346e5c31af7Sopenharmony_ci 347e5c31af7Sopenharmony_ci acquire(); 348e5c31af7Sopenharmony_ci 349e5c31af7Sopenharmony_ci return *this; 350e5c31af7Sopenharmony_ci} 351e5c31af7Sopenharmony_ci 352e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 353e5c31af7Sopenharmony_ci * \brief Assign from other shared pointer. 354e5c31af7Sopenharmony_ci * \param other Pointer to be shared. 355e5c31af7Sopenharmony_ci * \return Reference to this SharedPtr. 356e5c31af7Sopenharmony_ci * 357e5c31af7Sopenharmony_ci * Reference to current pointer is released and reference to new pointer is 358e5c31af7Sopenharmony_ci * acquired. 359e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 360e5c31af7Sopenharmony_citemplate<typename T> 361e5c31af7Sopenharmony_ciinline SharedPtr<T>& SharedPtr<T>::operator= (const SharedPtr<T>& other) 362e5c31af7Sopenharmony_ci{ 363e5c31af7Sopenharmony_ci if (m_state == other.m_state) 364e5c31af7Sopenharmony_ci return *this; 365e5c31af7Sopenharmony_ci 366e5c31af7Sopenharmony_ci // Release current reference. 367e5c31af7Sopenharmony_ci release(); 368e5c31af7Sopenharmony_ci 369e5c31af7Sopenharmony_ci // Copy from other and acquire reference. 370e5c31af7Sopenharmony_ci m_ptr = other.m_ptr; 371e5c31af7Sopenharmony_ci m_state = other.m_state; 372e5c31af7Sopenharmony_ci 373e5c31af7Sopenharmony_ci acquire(); 374e5c31af7Sopenharmony_ci 375e5c31af7Sopenharmony_ci return *this; 376e5c31af7Sopenharmony_ci} 377e5c31af7Sopenharmony_ci 378e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 379e5c31af7Sopenharmony_ci * \brief Assign from weak pointer. 380e5c31af7Sopenharmony_ci * \param other Weak reference. 381e5c31af7Sopenharmony_ci * \return Reference to this SharedPtr. 382e5c31af7Sopenharmony_ci * 383e5c31af7Sopenharmony_ci * Tries to acquire reference to WeakPtr, releases current reference and 384e5c31af7Sopenharmony_ci * holds reference to new pointer. 385e5c31af7Sopenharmony_ci * 386e5c31af7Sopenharmony_ci * If WeakPtr can't be acquired, throws DeadReferenceException and doesn't 387e5c31af7Sopenharmony_ci * release the current reference. 388e5c31af7Sopenharmony_ci * 389e5c31af7Sopenharmony_ci * If WeakPtr references same pointer as SharedPtr this call will always 390e5c31af7Sopenharmony_ci * succeed. 391e5c31af7Sopenharmony_ci * 392e5c31af7Sopenharmony_ci * Y* must be convertible to T*. 393e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 394e5c31af7Sopenharmony_citemplate<typename T> 395e5c31af7Sopenharmony_citemplate<typename Y> 396e5c31af7Sopenharmony_ciinline SharedPtr<T>& SharedPtr<T>::operator= (const WeakPtr<Y>& other) 397e5c31af7Sopenharmony_ci{ 398e5c31af7Sopenharmony_ci if (m_state == other.m_state) 399e5c31af7Sopenharmony_ci return *this; 400e5c31af7Sopenharmony_ci 401e5c31af7Sopenharmony_ci { 402e5c31af7Sopenharmony_ci SharedPtr<T> sharedOther(other); 403e5c31af7Sopenharmony_ci *this = other; 404e5c31af7Sopenharmony_ci } 405e5c31af7Sopenharmony_ci 406e5c31af7Sopenharmony_ci return *this; 407e5c31af7Sopenharmony_ci} 408e5c31af7Sopenharmony_ci 409e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 410e5c31af7Sopenharmony_ci * \brief Type conversion operator. 411e5c31af7Sopenharmony_ci * 412e5c31af7Sopenharmony_ci * T* must be convertible to Y*. 413e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 414e5c31af7Sopenharmony_citemplate<class T> 415e5c31af7Sopenharmony_citemplate<typename Y> 416e5c31af7Sopenharmony_ciinline SharedPtr<T>::operator SharedPtr<Y> (void) const 417e5c31af7Sopenharmony_ci{ 418e5c31af7Sopenharmony_ci return SharedPtr<Y>(*this); 419e5c31af7Sopenharmony_ci} 420e5c31af7Sopenharmony_ci 421e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 422e5c31af7Sopenharmony_ci * \brief Compare pointers. 423e5c31af7Sopenharmony_ci * \param a A 424e5c31af7Sopenharmony_ci * \param b B 425e5c31af7Sopenharmony_ci * \return true if A and B point to same object, false otherwise. 426e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 427e5c31af7Sopenharmony_citemplate<class T, class U> 428e5c31af7Sopenharmony_ciinline bool operator== (const SharedPtr<T>& a, const SharedPtr<U>& b) throw() 429e5c31af7Sopenharmony_ci{ 430e5c31af7Sopenharmony_ci return a.get() == b.get(); 431e5c31af7Sopenharmony_ci} 432e5c31af7Sopenharmony_ci 433e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 434e5c31af7Sopenharmony_ci * \brief Compare pointers. 435e5c31af7Sopenharmony_ci * \param a A 436e5c31af7Sopenharmony_ci * \param b B 437e5c31af7Sopenharmony_ci * \return true if A and B point to different objects, false otherwise. 438e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 439e5c31af7Sopenharmony_citemplate<class T, class U> 440e5c31af7Sopenharmony_ciinline bool operator!= (const SharedPtr<T>& a, const SharedPtr<U>& b) throw() 441e5c31af7Sopenharmony_ci{ 442e5c31af7Sopenharmony_ci return a.get() != b.get(); 443e5c31af7Sopenharmony_ci} 444e5c31af7Sopenharmony_ci 445e5c31af7Sopenharmony_ci/** Swap pointer contents. */ 446e5c31af7Sopenharmony_citemplate<typename T> 447e5c31af7Sopenharmony_ciinline void SharedPtr<T>::swap (SharedPtr<T>& other) 448e5c31af7Sopenharmony_ci{ 449e5c31af7Sopenharmony_ci using std::swap; 450e5c31af7Sopenharmony_ci swap(m_ptr, other.m_ptr); 451e5c31af7Sopenharmony_ci swap(m_state, other.m_state); 452e5c31af7Sopenharmony_ci} 453e5c31af7Sopenharmony_ci 454e5c31af7Sopenharmony_ci/** Swap operator for SharedPtr's. */ 455e5c31af7Sopenharmony_citemplate<typename T> 456e5c31af7Sopenharmony_ciinline void swap (SharedPtr<T>& a, SharedPtr<T>& b) 457e5c31af7Sopenharmony_ci{ 458e5c31af7Sopenharmony_ci a.swap(b); 459e5c31af7Sopenharmony_ci} 460e5c31af7Sopenharmony_ci 461e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 462e5c31af7Sopenharmony_ci * \brief Set pointer to null. 463e5c31af7Sopenharmony_ci * 464e5c31af7Sopenharmony_ci * clear() removes current reference and sets pointer to null value. 465e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 466e5c31af7Sopenharmony_citemplate<typename T> 467e5c31af7Sopenharmony_ciinline void SharedPtr<T>::clear (void) 468e5c31af7Sopenharmony_ci{ 469e5c31af7Sopenharmony_ci release(); 470e5c31af7Sopenharmony_ci m_ptr = DE_NULL; 471e5c31af7Sopenharmony_ci m_state = DE_NULL; 472e5c31af7Sopenharmony_ci} 473e5c31af7Sopenharmony_ci 474e5c31af7Sopenharmony_citemplate<typename T> 475e5c31af7Sopenharmony_ciinline void SharedPtr<T>::acquireFromWeak (const WeakPtr<T>& weakRef) 476e5c31af7Sopenharmony_ci{ 477e5c31af7Sopenharmony_ci DE_ASSERT(!m_ptr && !m_state); 478e5c31af7Sopenharmony_ci 479e5c31af7Sopenharmony_ci SharedPtrStateBase* state = weakRef.m_state; 480e5c31af7Sopenharmony_ci 481e5c31af7Sopenharmony_ci if (!state) 482e5c31af7Sopenharmony_ci return; // Empty reference. 483e5c31af7Sopenharmony_ci 484e5c31af7Sopenharmony_ci { 485e5c31af7Sopenharmony_ci deInt32 oldCount, newCount; 486e5c31af7Sopenharmony_ci 487e5c31af7Sopenharmony_ci // Do atomic compare and increment. 488e5c31af7Sopenharmony_ci do 489e5c31af7Sopenharmony_ci { 490e5c31af7Sopenharmony_ci oldCount = state->strongRefCount; 491e5c31af7Sopenharmony_ci if (oldCount == 0) 492e5c31af7Sopenharmony_ci throw DeadReferenceException(); 493e5c31af7Sopenharmony_ci newCount = oldCount+1; 494e5c31af7Sopenharmony_ci } while (deAtomicCompareExchange32((deUint32 volatile*)&state->strongRefCount, (deUint32)oldCount, (deUint32)newCount) != (deUint32)oldCount); 495e5c31af7Sopenharmony_ci 496e5c31af7Sopenharmony_ci deAtomicIncrement32(&state->weakRefCount); 497e5c31af7Sopenharmony_ci } 498e5c31af7Sopenharmony_ci 499e5c31af7Sopenharmony_ci m_ptr = weakRef.m_ptr; 500e5c31af7Sopenharmony_ci m_state = state; 501e5c31af7Sopenharmony_ci} 502e5c31af7Sopenharmony_ci 503e5c31af7Sopenharmony_citemplate<typename T> 504e5c31af7Sopenharmony_ciinline void SharedPtr<T>::acquire (void) 505e5c31af7Sopenharmony_ci{ 506e5c31af7Sopenharmony_ci if (m_state) 507e5c31af7Sopenharmony_ci { 508e5c31af7Sopenharmony_ci deAtomicIncrement32(&m_state->strongRefCount); 509e5c31af7Sopenharmony_ci deAtomicIncrement32(&m_state->weakRefCount); 510e5c31af7Sopenharmony_ci } 511e5c31af7Sopenharmony_ci} 512e5c31af7Sopenharmony_ci 513e5c31af7Sopenharmony_citemplate<typename T> 514e5c31af7Sopenharmony_ciinline void SharedPtr<T>::release (void) 515e5c31af7Sopenharmony_ci{ 516e5c31af7Sopenharmony_ci if (m_state) 517e5c31af7Sopenharmony_ci { 518e5c31af7Sopenharmony_ci if (deAtomicDecrement32(&m_state->strongRefCount) == 0) 519e5c31af7Sopenharmony_ci { 520e5c31af7Sopenharmony_ci m_ptr = DE_NULL; 521e5c31af7Sopenharmony_ci m_state->deletePtr(); 522e5c31af7Sopenharmony_ci } 523e5c31af7Sopenharmony_ci 524e5c31af7Sopenharmony_ci if (deAtomicDecrement32(&m_state->weakRefCount) == 0) 525e5c31af7Sopenharmony_ci { 526e5c31af7Sopenharmony_ci delete m_state; 527e5c31af7Sopenharmony_ci m_state = DE_NULL; 528e5c31af7Sopenharmony_ci } 529e5c31af7Sopenharmony_ci } 530e5c31af7Sopenharmony_ci} 531e5c31af7Sopenharmony_ci 532e5c31af7Sopenharmony_ci// WeakPtr template implementation. 533e5c31af7Sopenharmony_ci 534e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 535e5c31af7Sopenharmony_ci * \brief Construct empty weak pointer. 536e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 537e5c31af7Sopenharmony_citemplate<typename T> 538e5c31af7Sopenharmony_ciinline WeakPtr<T>::WeakPtr (void) 539e5c31af7Sopenharmony_ci : m_ptr (DE_NULL) 540e5c31af7Sopenharmony_ci , m_state (DE_NULL) 541e5c31af7Sopenharmony_ci{ 542e5c31af7Sopenharmony_ci} 543e5c31af7Sopenharmony_ci 544e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 545e5c31af7Sopenharmony_ci * \brief Construct weak pointer from other weak reference. 546e5c31af7Sopenharmony_ci * \param other Weak reference. 547e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 548e5c31af7Sopenharmony_citemplate<typename T> 549e5c31af7Sopenharmony_ciinline WeakPtr<T>::WeakPtr (const WeakPtr<T>& other) 550e5c31af7Sopenharmony_ci : m_ptr (other.m_ptr) 551e5c31af7Sopenharmony_ci , m_state (other.m_state) 552e5c31af7Sopenharmony_ci{ 553e5c31af7Sopenharmony_ci acquire(); 554e5c31af7Sopenharmony_ci} 555e5c31af7Sopenharmony_ci 556e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 557e5c31af7Sopenharmony_ci * \brief Construct weak pointer from shared pointer. 558e5c31af7Sopenharmony_ci * \param other Shared pointer. 559e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 560e5c31af7Sopenharmony_citemplate<typename T> 561e5c31af7Sopenharmony_ciinline WeakPtr<T>::WeakPtr (const SharedPtr<T>& other) 562e5c31af7Sopenharmony_ci : m_ptr (other.m_ptr) 563e5c31af7Sopenharmony_ci , m_state (other.m_state) 564e5c31af7Sopenharmony_ci{ 565e5c31af7Sopenharmony_ci acquire(); 566e5c31af7Sopenharmony_ci} 567e5c31af7Sopenharmony_ci 568e5c31af7Sopenharmony_citemplate<typename T> 569e5c31af7Sopenharmony_ciinline WeakPtr<T>::~WeakPtr (void) 570e5c31af7Sopenharmony_ci{ 571e5c31af7Sopenharmony_ci release(); 572e5c31af7Sopenharmony_ci} 573e5c31af7Sopenharmony_ci 574e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 575e5c31af7Sopenharmony_ci * \brief Assign from another weak pointer. 576e5c31af7Sopenharmony_ci * \param other Weak reference. 577e5c31af7Sopenharmony_ci * \return Reference to this WeakPtr. 578e5c31af7Sopenharmony_ci * 579e5c31af7Sopenharmony_ci * The current weak reference is removed first and then a new weak reference 580e5c31af7Sopenharmony_ci * to the object pointed by other is taken. 581e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 582e5c31af7Sopenharmony_citemplate<typename T> 583e5c31af7Sopenharmony_ciinline WeakPtr<T>& WeakPtr<T>::operator= (const WeakPtr<T>& other) 584e5c31af7Sopenharmony_ci{ 585e5c31af7Sopenharmony_ci if (this == &other) 586e5c31af7Sopenharmony_ci return *this; 587e5c31af7Sopenharmony_ci 588e5c31af7Sopenharmony_ci release(); 589e5c31af7Sopenharmony_ci 590e5c31af7Sopenharmony_ci m_ptr = other.m_ptr; 591e5c31af7Sopenharmony_ci m_state = other.m_state; 592e5c31af7Sopenharmony_ci 593e5c31af7Sopenharmony_ci acquire(); 594e5c31af7Sopenharmony_ci 595e5c31af7Sopenharmony_ci return *this; 596e5c31af7Sopenharmony_ci} 597e5c31af7Sopenharmony_ci 598e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 599e5c31af7Sopenharmony_ci * \brief Assign from shared pointer. 600e5c31af7Sopenharmony_ci * \param other Shared pointer. 601e5c31af7Sopenharmony_ci * \return Reference to this WeakPtr. 602e5c31af7Sopenharmony_ci * 603e5c31af7Sopenharmony_ci * The current weak reference is removed first and then a new weak reference 604e5c31af7Sopenharmony_ci * to the object pointed by other is taken. 605e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 606e5c31af7Sopenharmony_citemplate<typename T> 607e5c31af7Sopenharmony_ciinline WeakPtr<T>& WeakPtr<T>::operator= (const SharedPtr<T>& other) 608e5c31af7Sopenharmony_ci{ 609e5c31af7Sopenharmony_ci release(); 610e5c31af7Sopenharmony_ci 611e5c31af7Sopenharmony_ci m_ptr = other.m_ptr; 612e5c31af7Sopenharmony_ci m_state = other.m_state; 613e5c31af7Sopenharmony_ci 614e5c31af7Sopenharmony_ci acquire(); 615e5c31af7Sopenharmony_ci 616e5c31af7Sopenharmony_ci return *this; 617e5c31af7Sopenharmony_ci} 618e5c31af7Sopenharmony_ci 619e5c31af7Sopenharmony_citemplate<typename T> 620e5c31af7Sopenharmony_ciinline void WeakPtr<T>::acquire (void) 621e5c31af7Sopenharmony_ci{ 622e5c31af7Sopenharmony_ci if (m_state) 623e5c31af7Sopenharmony_ci deAtomicIncrement32(&m_state->weakRefCount); 624e5c31af7Sopenharmony_ci} 625e5c31af7Sopenharmony_ci 626e5c31af7Sopenharmony_citemplate<typename T> 627e5c31af7Sopenharmony_ciinline void WeakPtr<T>::release (void) 628e5c31af7Sopenharmony_ci{ 629e5c31af7Sopenharmony_ci if (m_state) 630e5c31af7Sopenharmony_ci { 631e5c31af7Sopenharmony_ci if (deAtomicDecrement32(&m_state->weakRefCount) == 0) 632e5c31af7Sopenharmony_ci { 633e5c31af7Sopenharmony_ci delete m_state; 634e5c31af7Sopenharmony_ci m_state = DE_NULL; 635e5c31af7Sopenharmony_ci m_ptr = DE_NULL; 636e5c31af7Sopenharmony_ci } 637e5c31af7Sopenharmony_ci } 638e5c31af7Sopenharmony_ci} 639e5c31af7Sopenharmony_ci 640e5c31af7Sopenharmony_ci} // de 641e5c31af7Sopenharmony_ci 642e5c31af7Sopenharmony_ci#endif // _DESHAREDPTR_HPP 643