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