deSharedPtr.hpp revision 3c827367444ee418f129b2c238299f49d3264554
13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#ifndef _DESHAREDPTR_HPP 23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define _DESHAREDPTR_HPP 33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*------------------------------------------------------------------------- 43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements C++ Base Library 53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * ----------------------------- 63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project 83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License"); 103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License. 113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at 123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * http://www.apache.org/licenses/LICENSE-2.0 143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software 163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS, 173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and 193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License. 203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*! 223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file 233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Shared pointer. 243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deDefs.hpp" 273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deAtomic.h" 283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <exception> 303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <algorithm> 313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 323c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace de 333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! Shared pointer self-test. 363c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid SharedPtr_selfTest (void); 373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 383c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass DeadReferenceException : public std::exception 393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 403c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DeadReferenceException (void) throw() : std::exception() {} 423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* what (void) const throw() { return "DeadReferenceException"; } 433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 453c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<bool threadSafe> 463c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct ReferenceCount; 473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 483c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<> struct ReferenceCount<true> { typedef volatile int Type; }; 493c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<> struct ReferenceCount<false> { typedef int Type; }; 503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 513c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<class Deleter, bool threadSafe> 523c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct SharedPtrState 533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SharedPtrState (Deleter deleter_) 553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : strongRefCount (0) 563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , weakRefCount (0) 573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , deleter (deleter_) 583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typename ReferenceCount<threadSafe>::Type strongRefCount; 623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typename ReferenceCount<threadSafe>::Type weakRefCount; //!< WeakPtr references + StrongPtr references. 633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Deleter deleter; 643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 663c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename DstDeleterType, typename SrcDeleterType, bool threadSafe> 673c827367444ee418f129b2c238299f49d3264554Jarkko PoyrySharedPtrState<DstDeleterType, threadSafe>* sharedPtrStateCast (SharedPtrState<SrcDeleterType, threadSafe>* state) 683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return reinterpret_cast<SharedPtrState<DstDeleterType, threadSafe>*>(state); 703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 723c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename T, class Deleter, bool threadSafe> 733c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass SharedPtr; 743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 753c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename T, class Deleter, bool threadSafe> 763c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass WeakPtr; 773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Shared pointer 803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * SharedPtr is smart pointer for managing shared ownership to a pointer. 823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Multiple SharedPtr's can maintain ownership to the pointer and it is 833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * destructed when last SharedPtr is destroyed. 843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Shared pointers can be assigned (or initialized using copy constructor) 863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * and in such case the previous reference is first freed and then a new 873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * reference to the new pointer is acquired. 883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * SharedPtr can also be empty. 903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * If threadSafe template parameter is set to true, it is safe to share 923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * data using SharedPtr across threads. SharedPtr object itself is not 933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * thread safe and should not be mutated from multiple threads simultaneously. 943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \todo [2012-10-26 pyry] Add custom deleter. 963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 973c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename T, class Deleter = DefaultDeleter<T>, bool threadSafe = true> 983c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass SharedPtr 993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SharedPtr (void); 1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SharedPtr (const SharedPtr<T, Deleter, threadSafe>& other); 1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry template<typename Y> 1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry explicit SharedPtr (Y* ptr, Deleter deleter = Deleter()); 1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry template<typename Y, class DeleterY> 1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry explicit SharedPtr (const SharedPtr<Y, DeleterY, threadSafe>& other); 1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry template<typename Y, class DeleterY> 1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry explicit SharedPtr (const WeakPtr<Y, DeleterY, threadSafe>& other); 1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ~SharedPtr (void); 1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry template<typename Y, class DeleterY> 1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SharedPtr& operator= (const SharedPtr<Y, DeleterY, threadSafe>& other); 1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SharedPtr& operator= (const SharedPtr<T, Deleter, threadSafe>& other); 1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry template<typename Y, class DeleterY> 1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SharedPtr& operator= (const WeakPtr<Y, DeleterY, threadSafe>& other); 1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry T* get (void) const throw() { return m_ptr; } //!< Get stored pointer. 1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry T* operator-> (void) const throw() { return m_ptr; } //!< Get stored pointer. 1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry T& operator* (void) const throw() { return *m_ptr; } //!< De-reference pointer. 1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry operator bool (void) const throw() { return !!m_ptr; } 1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void swap (SharedPtr<T, Deleter, threadSafe>& other); 1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void clear (void); 1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry template<typename Y, class DeleterY> 1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry operator SharedPtr<Y, DeleterY, threadSafe> (void) const; 1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void acquire (void); 1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void acquireFromWeak (const WeakPtr<T, Deleter, threadSafe>& other); 1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void release (void); 1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry T* m_ptr; 1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SharedPtrState<Deleter, threadSafe>* m_state; 1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry friend class WeakPtr<T, Deleter, threadSafe>; 1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry template<typename U, class DeleterU, bool threadSafeU> 1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry friend class SharedPtr; 1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Weak pointer 1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WeakPtr manages weak references to objects owned by SharedPtr. Shared 1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * pointer can be converted to weak pointer and vice versa. Weak pointer 1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * differs from SharedPtr by not affecting the lifetime of the managed 1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * object. 1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WeakPtr can be converted back to SharedPtr but that operation can fail 1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * if the object is no longer live. In such case DeadReferenceException 1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * will be thrown. 1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \todo [2012-10-26 pyry] Add custom deleter. 1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename T, class Deleter = DefaultDeleter<T>, bool threadSafe = true> 1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass WeakPtr 1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry WeakPtr (void); 1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry WeakPtr (const WeakPtr<T, Deleter, threadSafe>& other); 1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry explicit WeakPtr (const SharedPtr<T, Deleter, threadSafe>& other); 1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ~WeakPtr (void); 1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry WeakPtr& operator= (const WeakPtr<T, Deleter, threadSafe>& other); 1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry WeakPtr& operator= (const SharedPtr<T, Deleter, threadSafe>& other); 1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SharedPtr<T, Deleter, threadSafe> lock (void); 1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void acquire (void); 1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void release (void); 1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry T* m_ptr; 1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SharedPtrState<Deleter, threadSafe>* m_state; 1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry friend class SharedPtr<T, Deleter, threadSafe>; 1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// SharedPtr template implementation. 1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Construct empty shared pointer. 1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename T, class Deleter, bool threadSafe> 1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline SharedPtr<T, Deleter, threadSafe>::SharedPtr (void) 1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_ptr (DE_NULL) 1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_state (DE_NULL) 1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Construct shared pointer from pointer. 2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param ptr Pointer to be managed. 2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Ownership of the pointer will be transferred to SharedPtr and future 2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * SharedPtr's initialized or assigned from this SharedPtr. 2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Y* must be convertible to T*. 2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename T, class Deleter, bool threadSafe> 2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename Y> 2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline SharedPtr<T, Deleter, threadSafe>::SharedPtr (Y* ptr, Deleter deleter) 2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_ptr (DE_NULL) 2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_state (DE_NULL) 2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry try 2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_ptr = ptr; 2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = new SharedPtrState<Deleter, threadSafe>(deleter); 2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state->strongRefCount = 1; 2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state->weakRefCount = 1; 2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry catch (...) 2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry delete m_ptr; 2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry delete m_state; 2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw; 2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Initialize shared pointer from another SharedPtr. 2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param other Pointer to be shared. 2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename T, class Deleter, bool threadSafe> 2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline SharedPtr<T, Deleter, threadSafe>::SharedPtr (const SharedPtr<T, Deleter, threadSafe>& other) 2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_ptr (other.m_ptr) 2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_state (other.m_state) 2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry acquire(); 2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Initialize shared pointer from another SharedPtr. 2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param other Pointer to be shared. 2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Y* must be convertible to T*. 2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename T, class Deleter, bool threadSafe> 2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename Y, class DeleterY> 2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline SharedPtr<T, Deleter, threadSafe>::SharedPtr (const SharedPtr<Y, DeleterY, threadSafe>& other) 2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_ptr (other.m_ptr) 2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_state (sharedPtrStateCast<Deleter>(other.m_state)) 2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry acquire(); 2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Initialize shared pointer from weak reference. 2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param other Pointer to be shared. 2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Y* must be convertible to T*. 2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename T, class Deleter, bool threadSafe> 2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename Y, class DeleterY> 2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline SharedPtr<T, Deleter, threadSafe>::SharedPtr (const WeakPtr<Y, DeleterY, threadSafe>& other) 2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_ptr (DE_NULL) 2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_state (DE_NULL) 2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry acquireFromWeak(other); 2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename T, class Deleter, bool threadSafe> 2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline SharedPtr<T, Deleter, threadSafe>::~SharedPtr (void) 2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry release(); 2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Assign from other shared pointer. 2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param other Pointer to be shared. 2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \return Reference to this SharedPtr. 2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Reference to current pointer (if any) will be released first. Then a new 2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * reference to the pointer managed by other will be acquired. 2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Y* must be convertible to T*. 2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename T, class Deleter, bool threadSafe> 2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename Y, class DeleterY> 2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline SharedPtr<T, Deleter, threadSafe>& SharedPtr<T, Deleter, threadSafe>::operator= (const SharedPtr<Y, DeleterY, threadSafe>& other) 2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (*this == other) 2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return *this; 2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Release current reference. 2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry release(); 2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Copy from other and acquire reference. 2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_ptr = other.m_ptr; 2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = sharedPtrStateCast<Deleter>(other.m_state); 3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry acquire(); 3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return *this; 3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Assign from other shared pointer. 3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param other Pointer to be shared. 3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \return Reference to this SharedPtr. 3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Reference to current pointer (if any) will be released first. Then a new 3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * reference to the pointer managed by other will be acquired. 3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename T, class Deleter, bool threadSafe> 3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline SharedPtr<T, Deleter, threadSafe>& SharedPtr<T, Deleter, threadSafe>::operator= (const SharedPtr<T, Deleter, threadSafe>& other) 3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (*this == other) 3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return *this; 3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Release current reference. 3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry release(); 3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Copy from other and acquire reference. 3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_ptr = other.m_ptr; 3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = other.m_state; 3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry acquire(); 3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return *this; 3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Assign from weak pointer. 3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param other Weak reference. 3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \return Reference to this SharedPtr. 3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Reference to current pointer (if any) will be released first. Then a 3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * reference to pointer managed by WeakPtr is acquired if the pointer 3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * is still live (eg. there's at least one strong reference). 3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * If pointer is no longer live, DeadReferenceException is thrown. 3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Y* must be convertible to T*. 3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename T, class Deleter, bool threadSafe> 3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename Y, class DeleterY> 3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline SharedPtr<T, Deleter, threadSafe>& SharedPtr<T, Deleter, threadSafe>::operator= (const WeakPtr<Y, DeleterY, threadSafe>& other) 3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Release current reference. 3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry release(); 3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_ptr = DE_NULL; 3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = DE_NULL; 3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry acquireFromWeak(other); 3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return *this; 3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Type conversion operator. 3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * T* must be convertible to Y*. Since resulting SharedPtr will share the 3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * ownership destroying Y* must be equal to destroying T*. 3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<class T, class Deleter, bool threadSafe> 3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename Y, class DeleterY> 3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline SharedPtr<T, Deleter, threadSafe>::operator SharedPtr<Y, DeleterY, threadSafe> (void) const 3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return SharedPtr<Y, DeleterY, threadSafe>(*this); 3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Compare pointers. 3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param a A 3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param b B 3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \return true if A and B point to same object, false otherwise. 3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<class T, class DeleterT, bool threadSafeT, class U, class DeleterU, bool threadSafeU> 3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline bool operator== (const SharedPtr<T, DeleterT, threadSafeT>& a, const SharedPtr<U, DeleterU, threadSafeU>& b) throw() 3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return a.get() == b.get(); 3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Compare pointers. 3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param a A 3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param b B 3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \return true if A and B point to different objects, false otherwise. 3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<class T, class DeleterT, bool threadSafeT, class U, class DeleterU, bool threadSafeU> 3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline bool operator!= (const SharedPtr<T, DeleterT, threadSafeT>& a, const SharedPtr<U, DeleterU, threadSafeU>& b) throw() 3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return a.get() != b.get(); 3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/** Swap pointer contents. */ 3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename T, class Deleter, bool threadSafe> 3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline void SharedPtr<T, Deleter, threadSafe>::swap (SharedPtr<T, Deleter, threadSafe>& other) 4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry using std::swap; 4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry swap(m_ptr, other.m_ptr); 4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry swap(m_state, other.m_state); 4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/** Swap operator for SharedPtr's. */ 4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename T, class Deleter, bool threadSafe> 4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline void swap (SharedPtr<T, Deleter, threadSafe>& a, SharedPtr<T, Deleter, threadSafe>& b) 4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry a.swap(b); 4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Set pointer to null. 4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * clear() removes current reference and sets pointer to null value. 4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename T, class Deleter, bool threadSafe> 4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline void SharedPtr<T, Deleter, threadSafe>::clear (void) 4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry release(); 4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_ptr = DE_NULL; 4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = DE_NULL; 4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename T, class Deleter, bool threadSafe> 4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline void SharedPtr<T, Deleter, threadSafe>::acquireFromWeak (const WeakPtr<T, Deleter, threadSafe>& weakRef) 4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(!m_ptr && !m_state); 4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SharedPtrState<Deleter, threadSafe>* state = weakRef.m_state; 4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!state) 4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; // Empty reference. 4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (threadSafe) 4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int oldCount, newCount; 4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Do atomic compare and increment. 4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry do 4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry oldCount = state->strongRefCount; 4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (oldCount == 0) 4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw DeadReferenceException(); 4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry newCount = oldCount+1; 4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } while (deAtomicCompareExchange32((deUint32 volatile*)&state->strongRefCount, (deUint32)oldCount, (deUint32)newCount) != (deUint32)oldCount); 4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deAtomicIncrement32(&state->weakRefCount); 4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (state->strongRefCount == 0) 4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw DeadReferenceException(); 4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry state->strongRefCount += 1; 4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry state->weakRefCount += 1; 4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_ptr = weakRef.m_ptr; 4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = state; 4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename T, class Deleter, bool threadSafe> 4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline void SharedPtr<T, Deleter, threadSafe>::acquire (void) 4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_state) 4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (threadSafe) 4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deAtomicIncrement32((deInt32 volatile*)&m_state->strongRefCount); 4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deAtomicIncrement32((deInt32 volatile*)&m_state->weakRefCount); 4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state->strongRefCount += 1; 4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state->weakRefCount += 1; 4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename T, class Deleter, bool threadSafe> 4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline void SharedPtr<T, Deleter, threadSafe>::release (void) 4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_state) 4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (threadSafe) 4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (deAtomicDecrement32(&m_state->strongRefCount) == 0) 4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state->deleter(m_ptr); 4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_ptr = DE_NULL; 4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (deAtomicDecrement32(&m_state->weakRefCount) == 0) 4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry delete m_state; 4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = DE_NULL; 4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state->strongRefCount -= 1; 5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state->weakRefCount -= 1; 5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(m_state->strongRefCount >= 0 && m_state->weakRefCount >= 0); 5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_state->strongRefCount == 0) 5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state->deleter(m_ptr); 5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_ptr = DE_NULL; 5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_state->weakRefCount == 0) 5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry delete m_state; 5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = DE_NULL; 5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// WeakPtr template implementation. 5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Construct empty weak pointer. 5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename T, class Deleter, bool threadSafe> 5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline WeakPtr<T, Deleter, threadSafe>::WeakPtr (void) 5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_ptr (DE_NULL) 5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_state (DE_NULL) 5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Construct weak pointer from other weak reference. 5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param other Weak reference. 5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename T, class Deleter, bool threadSafe> 5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline WeakPtr<T, Deleter, threadSafe>::WeakPtr (const WeakPtr<T, Deleter, threadSafe>& other) 5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_ptr (other.m_ptr) 5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_state (other.m_state) 5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry acquire(); 5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Construct weak pointer from shared pointer. 5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param other Shared pointer. 5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename T, class Deleter, bool threadSafe> 5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline WeakPtr<T, Deleter, threadSafe>::WeakPtr (const SharedPtr<T, Deleter, threadSafe>& other) 5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_ptr (other.m_ptr) 5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_state (other.m_state) 5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry acquire(); 5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename T, class Deleter, bool threadSafe> 5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline WeakPtr<T, Deleter, threadSafe>::~WeakPtr (void) 5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry release(); 5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Assign from another weak pointer. 5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param other Weak reference. 5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \return Reference to this WeakPtr. 5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * The current weak reference is removed first and then a new weak reference 5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * to the object pointed by other is taken. 5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename T, class Deleter, bool threadSafe> 5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline WeakPtr<T, Deleter, threadSafe>& WeakPtr<T, Deleter, threadSafe>::operator= (const WeakPtr<T, Deleter, threadSafe>& other) 5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (this == &other) 5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return *this; 5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry release(); 5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_ptr = other.m_ptr; 5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = other.m_state; 5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry acquire(); 5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return *this; 5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Assign from shared pointer. 5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param other Shared pointer. 5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \return Reference to this WeakPtr. 5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * The current weak reference is removed first and then a new weak reference 5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * to the object pointed by other is taken. 5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename T, class Deleter, bool threadSafe> 5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline WeakPtr<T, Deleter, threadSafe>& WeakPtr<T, Deleter, threadSafe>::operator= (const SharedPtr<T, Deleter, threadSafe>& other) 5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry release(); 6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_ptr = other.m_ptr; 6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = other.m_state; 6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry acquire(); 6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return *this; 6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename T, class Deleter, bool threadSafe> 6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline void WeakPtr<T, Deleter, threadSafe>::acquire (void) 6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_state) 6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (threadSafe) 6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deAtomicIncrement32(&m_state->weakRefCount); 6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state->weakRefCount += 1; 6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename T, class Deleter, bool threadSafe> 6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline void WeakPtr<T, Deleter, threadSafe>::release (void) 6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_state) 6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (threadSafe) 6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (deAtomicDecrement32(&m_state->weakRefCount) == 0) 6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry delete m_state; 6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = DE_NULL; 6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_ptr = DE_NULL; 6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state->weakRefCount -= 1; 6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(m_state->weakRefCount >= 0); 6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_state->weakRefCount == 0) 6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry delete m_state; 6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = DE_NULL; 6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_ptr = DE_NULL; 6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // de 6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif // _DESHAREDPTR_HPP 653