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: 416801c0680107ff001b065db07b125d622926f311Mika Isojärvi DeadReferenceException (void) throw() 426801c0680107ff001b065db07b125d622926f311Mika Isojärvi : std::exception() 436801c0680107ff001b065db07b125d622926f311Mika Isojärvi { 446801c0680107ff001b065db07b125d622926f311Mika Isojärvi } 453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 466801c0680107ff001b065db07b125d622926f311Mika Isojärvi const char* what (void) const throw() 476801c0680107ff001b065db07b125d622926f311Mika Isojärvi { 486801c0680107ff001b065db07b125d622926f311Mika Isojärvi return "DeadReferenceException"; 496801c0680107ff001b065db07b125d622926f311Mika Isojärvi } 506801c0680107ff001b065db07b125d622926f311Mika Isojärvi}; 513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 526801c0680107ff001b065db07b125d622926f311Mika Isojärvistruct SharedPtrStateBase 533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 546801c0680107ff001b065db07b125d622926f311Mika Isojärvi SharedPtrStateBase (void) 553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : strongRefCount (0) 563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , weakRefCount (0) 573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 606801c0680107ff001b065db07b125d622926f311Mika Isojärvi virtual ~SharedPtrStateBase (void) throw() {} 616801c0680107ff001b065db07b125d622926f311Mika Isojärvi virtual void deletePtr (void) throw() = 0; 626801c0680107ff001b065db07b125d622926f311Mika Isojärvi 636801c0680107ff001b065db07b125d622926f311Mika Isojärvi volatile deInt32 strongRefCount; 646801c0680107ff001b065db07b125d622926f311Mika Isojärvi volatile deInt32 weakRefCount; //!< WeakPtr references + StrongPtr references. 653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 676801c0680107ff001b065db07b125d622926f311Mika Isojärvitemplate<typename Type, typename Deleter> 686801c0680107ff001b065db07b125d622926f311Mika Isojärvistruct SharedPtrState : public SharedPtrStateBase 693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 706801c0680107ff001b065db07b125d622926f311Mika Isojärvi SharedPtrState (Type* ptr, Deleter deleter) 716801c0680107ff001b065db07b125d622926f311Mika Isojärvi : m_ptr (ptr) 726801c0680107ff001b065db07b125d622926f311Mika Isojärvi , m_deleter (deleter) 736801c0680107ff001b065db07b125d622926f311Mika Isojärvi { 746801c0680107ff001b065db07b125d622926f311Mika Isojärvi } 753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 766801c0680107ff001b065db07b125d622926f311Mika Isojärvi virtual ~SharedPtrState (void) throw() 776801c0680107ff001b065db07b125d622926f311Mika Isojärvi { 786801c0680107ff001b065db07b125d622926f311Mika Isojärvi DE_ASSERT(!m_ptr); 796801c0680107ff001b065db07b125d622926f311Mika Isojärvi } 806801c0680107ff001b065db07b125d622926f311Mika Isojärvi 816801c0680107ff001b065db07b125d622926f311Mika Isojärvi virtual void deletePtr (void) throw() 826801c0680107ff001b065db07b125d622926f311Mika Isojärvi { 836801c0680107ff001b065db07b125d622926f311Mika Isojärvi m_deleter(m_ptr); 846801c0680107ff001b065db07b125d622926f311Mika Isojärvi m_ptr = DE_NULL; 856801c0680107ff001b065db07b125d622926f311Mika Isojärvi } 866801c0680107ff001b065db07b125d622926f311Mika Isojärvi 876801c0680107ff001b065db07b125d622926f311Mika Isojärviprivate: 886801c0680107ff001b065db07b125d622926f311Mika Isojärvi Type* m_ptr; 896801c0680107ff001b065db07b125d622926f311Mika Isojärvi Deleter m_deleter; 906801c0680107ff001b065db07b125d622926f311Mika Isojärvi}; 916801c0680107ff001b065db07b125d622926f311Mika Isojärvi 926801c0680107ff001b065db07b125d622926f311Mika Isojärvitemplate<typename T> 933c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass SharedPtr; 943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 956801c0680107ff001b065db07b125d622926f311Mika Isojärvitemplate<typename T> 963c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass WeakPtr; 973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Shared pointer 1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * SharedPtr is smart pointer for managing shared ownership to a pointer. 1026801c0680107ff001b065db07b125d622926f311Mika Isojärvi * Multiple SharedPtrs can maintain ownership to the pointer and it is 1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * destructed when last SharedPtr is destroyed. 1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 1056801c0680107ff001b065db07b125d622926f311Mika Isojärvi * SharedPtr can also be NULL. 1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 1076801c0680107ff001b065db07b125d622926f311Mika Isojärvitemplate<typename T> 1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass SharedPtr 1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SharedPtr (void); 1126801c0680107ff001b065db07b125d622926f311Mika Isojärvi SharedPtr (const SharedPtr<T>& other); 1136801c0680107ff001b065db07b125d622926f311Mika Isojärvi explicit SharedPtr (T* ptr); 1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1156801c0680107ff001b065db07b125d622926f311Mika Isojärvi template<typename Deleter> 1166801c0680107ff001b065db07b125d622926f311Mika Isojärvi SharedPtr (T* ptr, Deleter deleter); 1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1186801c0680107ff001b065db07b125d622926f311Mika Isojärvi template<typename Y> 1196801c0680107ff001b065db07b125d622926f311Mika Isojärvi explicit SharedPtr (const SharedPtr<Y>& other); 1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1216801c0680107ff001b065db07b125d622926f311Mika Isojärvi template<typename Y> 1226801c0680107ff001b065db07b125d622926f311Mika Isojärvi explicit SharedPtr (const WeakPtr<Y>& other); 1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ~SharedPtr (void); 1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1266801c0680107ff001b065db07b125d622926f311Mika Isojärvi template<typename Y> 1276801c0680107ff001b065db07b125d622926f311Mika Isojärvi SharedPtr& operator= (const SharedPtr<Y>& other); 1286801c0680107ff001b065db07b125d622926f311Mika Isojärvi SharedPtr& operator= (const SharedPtr<T>& other); 1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1306801c0680107ff001b065db07b125d622926f311Mika Isojärvi template<typename Y> 1316801c0680107ff001b065db07b125d622926f311Mika Isojärvi SharedPtr& operator= (const WeakPtr<Y>& other); 1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry T* get (void) const throw() { return m_ptr; } //!< Get stored pointer. 1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry T* operator-> (void) const throw() { return m_ptr; } //!< Get stored pointer. 1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry T& operator* (void) const throw() { return *m_ptr; } //!< De-reference pointer. 1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry operator bool (void) const throw() { return !!m_ptr; } 1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1396801c0680107ff001b065db07b125d622926f311Mika Isojärvi void swap (SharedPtr<T>& other); 1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void clear (void); 1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1436801c0680107ff001b065db07b125d622926f311Mika Isojärvi template<typename Y> 1446801c0680107ff001b065db07b125d622926f311Mika Isojärvi operator SharedPtr<Y> (void) const; 1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void acquire (void); 1486801c0680107ff001b065db07b125d622926f311Mika Isojärvi void acquireFromWeak (const WeakPtr<T>& other); 1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void release (void); 1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1516801c0680107ff001b065db07b125d622926f311Mika Isojärvi T* m_ptr; 1526801c0680107ff001b065db07b125d622926f311Mika Isojärvi SharedPtrStateBase* m_state; 1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1546801c0680107ff001b065db07b125d622926f311Mika Isojärvi friend class WeakPtr<T>; 1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1566801c0680107ff001b065db07b125d622926f311Mika Isojärvi template<typename U> 1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry friend class SharedPtr; 1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Weak pointer 1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WeakPtr manages weak references to objects owned by SharedPtr. Shared 1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * pointer can be converted to weak pointer and vice versa. Weak pointer 1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * differs from SharedPtr by not affecting the lifetime of the managed 1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * object. 1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WeakPtr can be converted back to SharedPtr but that operation can fail 1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * if the object is no longer live. In such case DeadReferenceException 1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * will be thrown. 1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 1726801c0680107ff001b065db07b125d622926f311Mika Isojärvitemplate<typename T> 1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass WeakPtr 1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 1766801c0680107ff001b065db07b125d622926f311Mika Isojärvi WeakPtr (void); 1776801c0680107ff001b065db07b125d622926f311Mika Isojärvi WeakPtr (const WeakPtr<T>& other); 1786801c0680107ff001b065db07b125d622926f311Mika Isojärvi 1796801c0680107ff001b065db07b125d622926f311Mika Isojärvi explicit WeakPtr (const SharedPtr<T>& other); 1806801c0680107ff001b065db07b125d622926f311Mika Isojärvi ~WeakPtr (void); 1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1826801c0680107ff001b065db07b125d622926f311Mika Isojärvi WeakPtr& operator= (const WeakPtr<T>& other); 1836801c0680107ff001b065db07b125d622926f311Mika Isojärvi WeakPtr& operator= (const SharedPtr<T>& other); 1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1856801c0680107ff001b065db07b125d622926f311Mika Isojärvi SharedPtr<T> lock (void); 1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 1886801c0680107ff001b065db07b125d622926f311Mika Isojärvi void acquire (void); 1896801c0680107ff001b065db07b125d622926f311Mika Isojärvi void release (void); 1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1916801c0680107ff001b065db07b125d622926f311Mika Isojärvi T* m_ptr; 1926801c0680107ff001b065db07b125d622926f311Mika Isojärvi SharedPtrStateBase* m_state; 1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1946801c0680107ff001b065db07b125d622926f311Mika Isojärvi friend class SharedPtr<T>; 1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// SharedPtr template implementation. 1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Construct empty shared pointer. 2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 2026801c0680107ff001b065db07b125d622926f311Mika Isojärvitemplate<typename T> 2036801c0680107ff001b065db07b125d622926f311Mika Isojärviinline SharedPtr<T>::SharedPtr (void) 2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_ptr (DE_NULL) 2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_state (DE_NULL) 2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Construct shared pointer from pointer. 2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param ptr Pointer to be managed. 2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Ownership of the pointer will be transferred to SharedPtr and future 2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * SharedPtr's initialized or assigned from this SharedPtr. 2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 2166801c0680107ff001b065db07b125d622926f311Mika Isojärvi * If allocation of shared state fails. The "ptr" argument will not be 2176801c0680107ff001b065db07b125d622926f311Mika Isojärvi * released. 2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 2196801c0680107ff001b065db07b125d622926f311Mika Isojärvitemplate<typename T> 2206801c0680107ff001b065db07b125d622926f311Mika Isojärviinline SharedPtr<T>::SharedPtr (T* ptr) 2216801c0680107ff001b065db07b125d622926f311Mika Isojärvi : m_ptr (DE_NULL) 2226801c0680107ff001b065db07b125d622926f311Mika Isojärvi , m_state (DE_NULL) 2236801c0680107ff001b065db07b125d622926f311Mika Isojärvi{ 2246801c0680107ff001b065db07b125d622926f311Mika Isojärvi try 2256801c0680107ff001b065db07b125d622926f311Mika Isojärvi { 2266801c0680107ff001b065db07b125d622926f311Mika Isojärvi m_ptr = ptr; 2276801c0680107ff001b065db07b125d622926f311Mika Isojärvi m_state = new SharedPtrState<T, DefaultDeleter<T> >(ptr, DefaultDeleter<T>()); 2286801c0680107ff001b065db07b125d622926f311Mika Isojärvi m_state->strongRefCount = 1; 2296801c0680107ff001b065db07b125d622926f311Mika Isojärvi m_state->weakRefCount = 1; 2306801c0680107ff001b065db07b125d622926f311Mika Isojärvi } 2316801c0680107ff001b065db07b125d622926f311Mika Isojärvi catch (...) 2326801c0680107ff001b065db07b125d622926f311Mika Isojärvi { 2336801c0680107ff001b065db07b125d622926f311Mika Isojärvi // \note ptr is not released. 2346801c0680107ff001b065db07b125d622926f311Mika Isojärvi delete m_state; 2356801c0680107ff001b065db07b125d622926f311Mika Isojärvi throw; 2366801c0680107ff001b065db07b125d622926f311Mika Isojärvi } 2376801c0680107ff001b065db07b125d622926f311Mika Isojärvi} 2386801c0680107ff001b065db07b125d622926f311Mika Isojärvi 2396801c0680107ff001b065db07b125d622926f311Mika Isojärvi/*--------------------------------------------------------------------*//*! 2406801c0680107ff001b065db07b125d622926f311Mika Isojärvi * \brief Construct shared pointer from pointer. 2416801c0680107ff001b065db07b125d622926f311Mika Isojärvi * \param ptr Pointer to be managed. 2426801c0680107ff001b065db07b125d622926f311Mika Isojärvi * 2436801c0680107ff001b065db07b125d622926f311Mika Isojärvi * Ownership of the pointer will be transferred to SharedPtr and future 2446801c0680107ff001b065db07b125d622926f311Mika Isojärvi * SharedPtr's initialized or assigned from this SharedPtr. 2456801c0680107ff001b065db07b125d622926f311Mika Isojärvi * 2466801c0680107ff001b065db07b125d622926f311Mika Isojärvi * Deleter must be callable type and deleter is called with the pointer 2476801c0680107ff001b065db07b125d622926f311Mika Isojärvi * argument when the reference count becomes 0. 2486801c0680107ff001b065db07b125d622926f311Mika Isojärvi * 2496801c0680107ff001b065db07b125d622926f311Mika Isojärvi * If allocation of shared state fails. The "ptr" argument will not be 2506801c0680107ff001b065db07b125d622926f311Mika Isojärvi * released. 2516801c0680107ff001b065db07b125d622926f311Mika Isojärvi * 2526801c0680107ff001b065db07b125d622926f311Mika Isojärvi * Calling deleter or calling destructor for deleter should never throw. 2536801c0680107ff001b065db07b125d622926f311Mika Isojärvi *//*--------------------------------------------------------------------*/ 2546801c0680107ff001b065db07b125d622926f311Mika Isojärvitemplate<typename T> 2556801c0680107ff001b065db07b125d622926f311Mika Isojärvitemplate<typename Deleter> 2566801c0680107ff001b065db07b125d622926f311Mika Isojärviinline SharedPtr<T>::SharedPtr (T* ptr, Deleter deleter) 2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_ptr (DE_NULL) 2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_state (DE_NULL) 2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry try 2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_ptr = ptr; 2636801c0680107ff001b065db07b125d622926f311Mika Isojärvi m_state = new SharedPtrState<T, Deleter>(ptr, deleter); 2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state->strongRefCount = 1; 2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state->weakRefCount = 1; 2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry catch (...) 2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2696801c0680107ff001b065db07b125d622926f311Mika Isojärvi // \note ptr is not released. 2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry delete m_state; 2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw; 2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Initialize shared pointer from another SharedPtr. 2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param other Pointer to be shared. 2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 2796801c0680107ff001b065db07b125d622926f311Mika Isojärvitemplate<typename T> 2806801c0680107ff001b065db07b125d622926f311Mika Isojärviinline SharedPtr<T>::SharedPtr (const SharedPtr<T>& other) 2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_ptr (other.m_ptr) 2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_state (other.m_state) 2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry acquire(); 2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Initialize shared pointer from another SharedPtr. 2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param other Pointer to be shared. 2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Y* must be convertible to T*. 2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 2936801c0680107ff001b065db07b125d622926f311Mika Isojärvitemplate<typename T> 2946801c0680107ff001b065db07b125d622926f311Mika Isojärvitemplate<typename Y> 2956801c0680107ff001b065db07b125d622926f311Mika Isojärviinline SharedPtr<T>::SharedPtr (const SharedPtr<Y>& other) 2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_ptr (other.m_ptr) 2976801c0680107ff001b065db07b125d622926f311Mika Isojärvi , m_state (other.m_state) 2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry acquire(); 3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Initialize shared pointer from weak reference. 3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param other Pointer to be shared. 3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Y* must be convertible to T*. 3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 3086801c0680107ff001b065db07b125d622926f311Mika Isojärvitemplate<typename T> 3096801c0680107ff001b065db07b125d622926f311Mika Isojärvitemplate<typename Y> 3106801c0680107ff001b065db07b125d622926f311Mika Isojärviinline SharedPtr<T>::SharedPtr (const WeakPtr<Y>& other) 3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_ptr (DE_NULL) 3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_state (DE_NULL) 3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry acquireFromWeak(other); 3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3176801c0680107ff001b065db07b125d622926f311Mika Isojärvitemplate<typename T> 3186801c0680107ff001b065db07b125d622926f311Mika Isojärviinline SharedPtr<T>::~SharedPtr (void) 3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry release(); 3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Assign from other shared pointer. 3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param other Pointer to be shared. 3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \return Reference to this SharedPtr. 3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 3286801c0680107ff001b065db07b125d622926f311Mika Isojärvi * Reference to current pointer is released and reference to new pointer is 3296801c0680107ff001b065db07b125d622926f311Mika Isojärvi * acquired. 3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Y* must be convertible to T*. 3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 3336801c0680107ff001b065db07b125d622926f311Mika Isojärvitemplate<typename T> 3346801c0680107ff001b065db07b125d622926f311Mika Isojärvitemplate<typename Y> 3356801c0680107ff001b065db07b125d622926f311Mika Isojärviinline SharedPtr<T>& SharedPtr<T>::operator= (const SharedPtr<Y>& other) 3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3376801c0680107ff001b065db07b125d622926f311Mika Isojärvi if (m_state == other.m_state) 3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return *this; 3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Release current reference. 3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry release(); 3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Copy from other and acquire reference. 3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_ptr = other.m_ptr; 3456801c0680107ff001b065db07b125d622926f311Mika Isojärvi m_state = other.m_state; 3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry acquire(); 3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return *this; 3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Assign from other shared pointer. 3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param other Pointer to be shared. 3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \return Reference to this SharedPtr. 3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 3576801c0680107ff001b065db07b125d622926f311Mika Isojärvi * Reference to current pointer is released and reference to new pointer is 3586801c0680107ff001b065db07b125d622926f311Mika Isojärvi * acquired. 3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 3606801c0680107ff001b065db07b125d622926f311Mika Isojärvitemplate<typename T> 3616801c0680107ff001b065db07b125d622926f311Mika Isojärviinline SharedPtr<T>& SharedPtr<T>::operator= (const SharedPtr<T>& other) 3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3636801c0680107ff001b065db07b125d622926f311Mika Isojärvi if (m_state == other.m_state) 3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return *this; 3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Release current reference. 3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry release(); 3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Copy from other and acquire reference. 3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_ptr = other.m_ptr; 3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = other.m_state; 3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry acquire(); 3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return *this; 3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Assign from weak pointer. 3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param other Weak reference. 3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \return Reference to this SharedPtr. 3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 3836801c0680107ff001b065db07b125d622926f311Mika Isojärvi * Tries to acquire reference to WeakPtr, releases current reference and 3846801c0680107ff001b065db07b125d622926f311Mika Isojärvi * holds reference to new pointer. 3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 3866801c0680107ff001b065db07b125d622926f311Mika Isojärvi * If WeakPtr can't be acquired, throws DeadReferenceException and doesn't 3876801c0680107ff001b065db07b125d622926f311Mika Isojärvi * release the current reference. 3886801c0680107ff001b065db07b125d622926f311Mika Isojärvi * 3896801c0680107ff001b065db07b125d622926f311Mika Isojärvi * If WeakPtr references same pointer as SharedPtr this call will always 3906801c0680107ff001b065db07b125d622926f311Mika Isojärvi * succeed. 3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Y* must be convertible to T*. 3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 3946801c0680107ff001b065db07b125d622926f311Mika Isojärvitemplate<typename T> 3956801c0680107ff001b065db07b125d622926f311Mika Isojärvitemplate<typename Y> 3966801c0680107ff001b065db07b125d622926f311Mika Isojärviinline SharedPtr<T>& SharedPtr<T>::operator= (const WeakPtr<Y>& other) 3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3986801c0680107ff001b065db07b125d622926f311Mika Isojärvi if (m_state == other.m_state) 3996801c0680107ff001b065db07b125d622926f311Mika Isojärvi return *this; 4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4016801c0680107ff001b065db07b125d622926f311Mika Isojärvi { 4026801c0680107ff001b065db07b125d622926f311Mika Isojärvi SharedPtr<T> sharedOther(other); 4036801c0680107ff001b065db07b125d622926f311Mika Isojärvi *this = other; 4046801c0680107ff001b065db07b125d622926f311Mika Isojärvi } 4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return *this; 4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Type conversion operator. 4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 4126801c0680107ff001b065db07b125d622926f311Mika Isojärvi * T* must be convertible to Y*. 4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 4146801c0680107ff001b065db07b125d622926f311Mika Isojärvitemplate<class T> 4156801c0680107ff001b065db07b125d622926f311Mika Isojärvitemplate<typename Y> 4166801c0680107ff001b065db07b125d622926f311Mika Isojärviinline SharedPtr<T>::operator SharedPtr<Y> (void) const 4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4186801c0680107ff001b065db07b125d622926f311Mika Isojärvi return SharedPtr<Y>(*this); 4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Compare pointers. 4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param a A 4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param b B 4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \return true if A and B point to same object, false otherwise. 4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 4276801c0680107ff001b065db07b125d622926f311Mika Isojärvitemplate<class T, class U> 4286801c0680107ff001b065db07b125d622926f311Mika Isojärviinline bool operator== (const SharedPtr<T>& a, const SharedPtr<U>& b) throw() 4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return a.get() == b.get(); 4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Compare pointers. 4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param a A 4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param b B 4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \return true if A and B point to different objects, false otherwise. 4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 4396801c0680107ff001b065db07b125d622926f311Mika Isojärvitemplate<class T, class U> 4406801c0680107ff001b065db07b125d622926f311Mika Isojärviinline bool operator!= (const SharedPtr<T>& a, const SharedPtr<U>& b) throw() 4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return a.get() != b.get(); 4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/** Swap pointer contents. */ 4466801c0680107ff001b065db07b125d622926f311Mika Isojärvitemplate<typename T> 4476801c0680107ff001b065db07b125d622926f311Mika Isojärviinline void SharedPtr<T>::swap (SharedPtr<T>& other) 4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry using std::swap; 4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry swap(m_ptr, other.m_ptr); 4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry swap(m_state, other.m_state); 4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/** Swap operator for SharedPtr's. */ 4556801c0680107ff001b065db07b125d622926f311Mika Isojärvitemplate<typename T> 4566801c0680107ff001b065db07b125d622926f311Mika Isojärviinline void swap (SharedPtr<T>& a, SharedPtr<T>& b) 4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry a.swap(b); 4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Set pointer to null. 4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * clear() removes current reference and sets pointer to null value. 4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 4666801c0680107ff001b065db07b125d622926f311Mika Isojärvitemplate<typename T> 4676801c0680107ff001b065db07b125d622926f311Mika Isojärviinline void SharedPtr<T>::clear (void) 4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry release(); 4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_ptr = DE_NULL; 4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = DE_NULL; 4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4746801c0680107ff001b065db07b125d622926f311Mika Isojärvitemplate<typename T> 4756801c0680107ff001b065db07b125d622926f311Mika Isojärviinline void SharedPtr<T>::acquireFromWeak (const WeakPtr<T>& weakRef) 4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(!m_ptr && !m_state); 4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4796801c0680107ff001b065db07b125d622926f311Mika Isojärvi SharedPtrStateBase* state = weakRef.m_state; 4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!state) 4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; // Empty reference. 4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4856801c0680107ff001b065db07b125d622926f311Mika Isojärvi deInt32 oldCount, newCount; 4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Do atomic compare and increment. 4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry do 4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry oldCount = state->strongRefCount; 4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (oldCount == 0) 4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw DeadReferenceException(); 4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry newCount = oldCount+1; 4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } while (deAtomicCompareExchange32((deUint32 volatile*)&state->strongRefCount, (deUint32)oldCount, (deUint32)newCount) != (deUint32)oldCount); 4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deAtomicIncrement32(&state->weakRefCount); 4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_ptr = weakRef.m_ptr; 5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = state; 5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5036801c0680107ff001b065db07b125d622926f311Mika Isojärvitemplate<typename T> 5046801c0680107ff001b065db07b125d622926f311Mika Isojärviinline void SharedPtr<T>::acquire (void) 5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_state) 5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5086801c0680107ff001b065db07b125d622926f311Mika Isojärvi deAtomicIncrement32(&m_state->strongRefCount); 5096801c0680107ff001b065db07b125d622926f311Mika Isojärvi deAtomicIncrement32(&m_state->weakRefCount); 5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5136801c0680107ff001b065db07b125d622926f311Mika Isojärvitemplate<typename T> 5146801c0680107ff001b065db07b125d622926f311Mika Isojärviinline void SharedPtr<T>::release (void) 5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_state) 5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5186801c0680107ff001b065db07b125d622926f311Mika Isojärvi if (deAtomicDecrement32(&m_state->strongRefCount) == 0) 5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5206801c0680107ff001b065db07b125d622926f311Mika Isojärvi m_ptr = DE_NULL; 5216801c0680107ff001b065db07b125d622926f311Mika Isojärvi m_state->deletePtr(); 5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5236801c0680107ff001b065db07b125d622926f311Mika Isojärvi 5246801c0680107ff001b065db07b125d622926f311Mika Isojärvi if (deAtomicDecrement32(&m_state->weakRefCount) == 0) 5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5266801c0680107ff001b065db07b125d622926f311Mika Isojärvi delete m_state; 5276801c0680107ff001b065db07b125d622926f311Mika Isojärvi m_state = DE_NULL; 5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// WeakPtr template implementation. 5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Construct empty weak pointer. 5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 5376801c0680107ff001b065db07b125d622926f311Mika Isojärvitemplate<typename T> 5386801c0680107ff001b065db07b125d622926f311Mika Isojärviinline WeakPtr<T>::WeakPtr (void) 5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_ptr (DE_NULL) 5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_state (DE_NULL) 5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Construct weak pointer from other weak reference. 5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param other Weak reference. 5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 5486801c0680107ff001b065db07b125d622926f311Mika Isojärvitemplate<typename T> 5496801c0680107ff001b065db07b125d622926f311Mika Isojärviinline WeakPtr<T>::WeakPtr (const WeakPtr<T>& other) 5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_ptr (other.m_ptr) 5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_state (other.m_state) 5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry acquire(); 5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Construct weak pointer from shared pointer. 5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param other Shared pointer. 5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 5606801c0680107ff001b065db07b125d622926f311Mika Isojärvitemplate<typename T> 5616801c0680107ff001b065db07b125d622926f311Mika Isojärviinline WeakPtr<T>::WeakPtr (const SharedPtr<T>& other) 5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_ptr (other.m_ptr) 5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_state (other.m_state) 5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry acquire(); 5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5686801c0680107ff001b065db07b125d622926f311Mika Isojärvitemplate<typename T> 5696801c0680107ff001b065db07b125d622926f311Mika Isojärviinline WeakPtr<T>::~WeakPtr (void) 5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry release(); 5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Assign from another weak pointer. 5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param other Weak reference. 5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \return Reference to this WeakPtr. 5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * The current weak reference is removed first and then a new weak reference 5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * to the object pointed by other is taken. 5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 5826801c0680107ff001b065db07b125d622926f311Mika Isojärvitemplate<typename T> 5836801c0680107ff001b065db07b125d622926f311Mika Isojärviinline WeakPtr<T>& WeakPtr<T>::operator= (const WeakPtr<T>& other) 5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (this == &other) 5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return *this; 5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry release(); 5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_ptr = other.m_ptr; 5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = other.m_state; 5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry acquire(); 5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return *this; 5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Assign from shared pointer. 6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param other Shared pointer. 6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \return Reference to this WeakPtr. 6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * The current weak reference is removed first and then a new weak reference 6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * to the object pointed by other is taken. 6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 6066801c0680107ff001b065db07b125d622926f311Mika Isojärvitemplate<typename T> 6076801c0680107ff001b065db07b125d622926f311Mika Isojärviinline WeakPtr<T>& WeakPtr<T>::operator= (const SharedPtr<T>& other) 6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry release(); 6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_ptr = other.m_ptr; 6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_state = other.m_state; 6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry acquire(); 6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return *this; 6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6196801c0680107ff001b065db07b125d622926f311Mika Isojärvitemplate<typename T> 6206801c0680107ff001b065db07b125d622926f311Mika Isojärviinline void WeakPtr<T>::acquire (void) 6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_state) 6236801c0680107ff001b065db07b125d622926f311Mika Isojärvi deAtomicIncrement32(&m_state->weakRefCount); 6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6266801c0680107ff001b065db07b125d622926f311Mika Isojärvitemplate<typename T> 6276801c0680107ff001b065db07b125d622926f311Mika Isojärviinline void WeakPtr<T>::release (void) 6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_state) 6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6316801c0680107ff001b065db07b125d622926f311Mika Isojärvi if (deAtomicDecrement32(&m_state->weakRefCount) == 0) 6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6336801c0680107ff001b065db07b125d622926f311Mika Isojärvi delete m_state; 6346801c0680107ff001b065db07b125d622926f311Mika Isojärvi m_state = DE_NULL; 6356801c0680107ff001b065db07b125d622926f311Mika Isojärvi m_ptr = DE_NULL; 6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // de 6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif // _DESHAREDPTR_HPP 643