📄 boost_shared_ptr.h
字号:
// <tr1/boost_shared_ptr.h> -*- C++ -*-// Copyright (C) 2005 Free Software Foundation, Inc.//// This file is part of the GNU ISO C++ Library. This library is free// software; you can redistribute it and/or modify it under the// terms of the GNU General Public License as published by the// Free Software Foundation; either version 2, or (at your option)// any later version.// This library is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.// You should have received a copy of the GNU General Public License along// with this library; see the file COPYING. If not, write to the Free// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,// USA.// As a special exception, you may use this file as part of a free software// library without restriction. Specifically, if other files instantiate// templates or use macros or inline functions from this file, or you compile// this file and link it with other files to produce an executable, this// file does not by itself cause the resulting executable to be covered by// the GNU General Public License. This exception does not however// invalidate any other reasons why the executable file might be covered by// the GNU General Public License.// shared_count.hpp// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.// shared_ptr.hpp// Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes.// Copyright (C) 2001, 2002, 2003 Peter Dimov// weak_ptr.hpp// Copyright (C) 2001, 2002, 2003 Peter Dimov// enable_shared_from_this.hpp// Copyright (C) 2002 Peter Dimov// Distributed under the Boost Software License, Version 1.0. (See// accompanying file LICENSE_1_0.txt or copy at// http://www.boost.org/LICENSE_1_0.txt)// GCC Note: based on version 1.32.0 of the Boost library./** @file boost_memory.h * This is an internal header file, included by other library headers. * You should not attempt to use it directly. */#ifndef _BOOST_SHARED_PTR_H#define _BOOST_SHARED_PTR_H 1// namespace std::tr1namespace std{namespace tr1{class bad_weak_ptr : public std::exception{public: virtual char const* what() const throw() { return "tr1::bad_weak_ptr"; }};// Helper for exception objects in <tr1/memory>// TODO this should be defined in a different file.inline void__throw_bad_weak_ptr(){#if __EXCEPTIONS throw bad_weak_ptr();#else std::abort();#endif}template<typename _Tp> struct _Sp_deleter { typedef void result_type; typedef _Tp* argument_type; void operator()(_Tp* p) const { delete p; } };class _Sp_counted_base{public: _Sp_counted_base() : _M_use_count(1), _M_weak_count(1) { // For the case of __GTHREAD_MUTEX_INIT we haven't initialised // the mutex yet, so do it now.#if defined(__GTHREADS) && defined(__GTHREAD_MUTEX_INIT) __gthread_mutex_t __tmp = __GTHREAD_MUTEX_INIT; _M_mutex = __tmp;#endif } virtual ~_Sp_counted_base() // nothrow { } // dispose() is called when _M_use_count drops to zero, to release // the resources managed by *this. virtual void dispose() = 0; // nothrow // destroy() is called when _M_weak_count drops to zero. virtual void destroy() // nothrow { delete this; } virtual void* get_deleter(const std::type_info&) = 0; void add_ref_copy() { __gnu_cxx::__atomic_add(&_M_use_count, 1); } void add_ref_lock() { __gnu_cxx::lock lock(_M_mutex); if (__gnu_cxx::__exchange_and_add(&_M_use_count, 1) == 0) { _M_use_count = 0; __throw_bad_weak_ptr(); } } void release() // nothrow { if (__gnu_cxx::__exchange_and_add(&_M_use_count, -1) == 1) { dispose();#ifdef __GTHREADS _GLIBCXX_READ_MEM_BARRIER; _GLIBCXX_WRITE_MEM_BARRIER;#endif if (__gnu_cxx::__exchange_and_add(&_M_weak_count, -1) == 1) destroy(); } } void weak_add_ref() // nothrow { __gnu_cxx::__atomic_add(&_M_weak_count, 1); } void weak_release() // nothrow { if (__gnu_cxx::__exchange_and_add(&_M_weak_count, -1) == 1) {#ifdef __GTHREADS _GLIBCXX_READ_MEM_BARRIER; _GLIBCXX_WRITE_MEM_BARRIER;#endif destroy(); } } long use_count() const // nothrow { return _M_use_count; // XXX is this MT safe? }private: _Sp_counted_base(_Sp_counted_base const&); _Sp_counted_base& operator=(_Sp_counted_base const&); _Atomic_word _M_use_count; // #shared _Atomic_word _M_weak_count; // #weak + (#shared != 0) __gnu_cxx::mutex_type _M_mutex;};template<typename _Ptr, typename _Deleter> class _Sp_counted_base_impl : public _Sp_counted_base { public: /** * @brief * @pre d(p) must not throw. */ _Sp_counted_base_impl(_Ptr __p, _Deleter __d) : _M_ptr(__p), _M_del(__d) { } virtual void dispose() // nothrow { _M_del(_M_ptr); } virtual void* get_deleter(const std::type_info& __ti) { return __ti == typeid(_Deleter) ? &_M_del : 0; } private: _Sp_counted_base_impl(const _Sp_counted_base_impl&); _Sp_counted_base_impl& operator=(const _Sp_counted_base_impl&); _Ptr _M_ptr; // copy constructor must not throw _Deleter _M_del; // copy constructor must not throw };class weak_count;class shared_count{private: _Sp_counted_base* _M_pi; friend class weak_count;public: shared_count() : _M_pi(0) // nothrow { } template<typename _Ptr, typename _Deleter> shared_count(_Ptr __p, _Deleter __d) : _M_pi(0) { try { _M_pi = new _Sp_counted_base_impl<_Ptr, _Deleter>(__p, __d); } catch(...) { __d(__p); // delete __p __throw_exception_again; } } // auto_ptr<_Tp> is special cased to provide the strong guarantee template<typename _Tp> explicit shared_count(std::auto_ptr<_Tp>& __r) : _M_pi(new _Sp_counted_base_impl<_Tp*, _Sp_deleter<_Tp> >(__r.get(), _Sp_deleter<_Tp>())) { __r.release(); } // throws bad_weak_ptr when __r.use_count() == 0 explicit shared_count(const weak_count& __r); ~shared_count() // nothrow { if (_M_pi != 0) _M_pi->release(); } shared_count(const shared_count& __r) : _M_pi(__r._M_pi) // nothrow { if (_M_pi != 0) _M_pi->add_ref_copy(); } shared_count& operator=(const shared_count& __r) // nothrow { _Sp_counted_base* __tmp = __r._M_pi; if(__tmp != _M_pi) { if(__tmp != 0) __tmp->add_ref_copy(); if(_M_pi != 0) _M_pi->release(); _M_pi = __tmp; } return *this; } void swap(shared_count& __r) // nothrow { _Sp_counted_base* __tmp = __r._M_pi; __r._M_pi = _M_pi; _M_pi = __tmp; } long use_count() const // nothrow { return _M_pi != 0 ? _M_pi->use_count() : 0; } bool unique() const // nothrow { return this->use_count() == 1; } friend inline bool operator==(const shared_count& __a, const shared_count& __b) { return __a._M_pi == __b._M_pi; } friend inline bool operator<(const shared_count& __a, const shared_count& __b) { return std::less<_Sp_counted_base*>()(__a._M_pi, __b._M_pi); } void* get_deleter(const std::type_info& __ti) const { return _M_pi ? _M_pi->get_deleter(__ti) : 0; }};class weak_count{private: _Sp_counted_base* _M_pi; friend class shared_count;public: weak_count() : _M_pi(0) // nothrow { } weak_count(const shared_count& __r) : _M_pi(__r._M_pi) // nothrow { if (_M_pi != 0) _M_pi->weak_add_ref(); } weak_count(const weak_count& __r) : _M_pi(__r._M_pi) // nothrow { if (_M_pi != 0) _M_pi->weak_add_ref(); } ~weak_count() // nothrow { if (_M_pi != 0) _M_pi->weak_release(); } weak_count& operator=(const shared_count& __r) // nothrow { _Sp_counted_base* __tmp = __r._M_pi; if (__tmp != 0) __tmp->weak_add_ref(); if (_M_pi != 0) _M_pi->weak_release(); _M_pi = __tmp; return *this; } weak_count& operator=(const weak_count& __r) // nothrow { _Sp_counted_base * __tmp = __r._M_pi; if (__tmp != 0) __tmp->weak_add_ref(); if (_M_pi != 0) _M_pi->weak_release(); _M_pi = __tmp; return *this; } void swap(weak_count& __r) // nothrow { _Sp_counted_base * __tmp = __r._M_pi; __r._M_pi = _M_pi; _M_pi = __tmp; } long use_count() const // nothrow { return _M_pi != 0 ? _M_pi->use_count() : 0; } friend inline bool operator==(const weak_count& __a, const weak_count& __b) { return __a._M_pi == __b._M_pi; } friend inline bool operator<(const weak_count& __a, const weak_count& __b) { return std::less<_Sp_counted_base*>()(__a._M_pi, __b._M_pi); }};inlineshared_count::shared_count(const weak_count& __r): _M_pi(__r._M_pi){ if (_M_pi != 0) _M_pi->add_ref_lock(); else __throw_bad_weak_ptr();}// fwd declstemplate<typename _Tp> class shared_ptr;template<typename _Tp> class weak_ptr;template<typename _Tp> class enable_shared_from_this;struct __static_cast_tag {};struct __const_cast_tag {};struct __dynamic_cast_tag {};struct __polymorphic_cast_tag {};template<class _Tp> struct shared_ptr_traits { typedef _Tp& reference; };template<> struct shared_ptr_traits<void> { typedef void reference; };template<> struct shared_ptr_traits<void const> { typedef void reference; };template<> struct shared_ptr_traits<void volatile> { typedef void reference; };template<> struct shared_ptr_traits<void const volatile> { typedef void reference; };// enable_shared_from_this support// friend of enable_shared_from_thistemplate<typename _Tp1, typename _Tp2> void __enable_shared_from_this(const shared_count& __pn, const enable_shared_from_this<_Tp1>* __pe, const _Tp2* __px );inline void__enable_shared_from_this(const shared_count&, ...){ }// get_deleter must be declared before friend declaration by shared_ptr.template<typename _Del, typename _Tp> _Del* get_deleter(const shared_ptr<_Tp>&);/** * @class shared_ptr <tr1/memory> * * A smart pointer with reference-counted copy semantics. * The object pointed to is deleted when the last shared_ptr pointing to it * is destroyed or reset. */template<typename _Tp> class shared_ptr { typedef typename shared_ptr_traits<_Tp>::reference _Reference; public: typedef _Tp element_type;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -