# tr1/boost_sp_shared_count.h

Go to the documentation of this file.

    00001 // <tr1/boost_sp_shared_count.h> -*- C++ -*-
    00002
    00003 // Copyright (C) 2007 Free Software Foundation, Inc.
    00004 //
    00005 // This file is part of the GNU ISO C++ Library.  This library is free
    00006 // software; you can redistribute it and/or modify it under the
    00007 // terms of the GNU General Public License as published by the
    00008 // Free Software Foundation; either version 2, or (at your option)
    00009 // any later version.
    00010
    00011 // This library is distributed in the hope that it will be useful,
    00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
    00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    00014 // GNU General Public License for more details.
    00015
    00016 // You should have received a copy of the GNU General Public License along
    00017 // with this library; see the file COPYING.  If not, write to the Free
    00018 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
    00019 // USA.
    00020
    00021 // As a special exception, you may use this file as part of a free software
    00022 // library without restriction.  Specifically, if other files instantiate
    00023 // templates or use macros or inline functions from this file, or you compile
    00024 // this file and link it with other files to produce an executable, this
    00025 // file does not by itself cause the resulting executable to be covered by
    00026 // the GNU General Public License.  This exception does not however
    00027 // invalidate any other reasons why the executable file might be covered by
    00028 // the GNU General Public License.
    00029
    00030 //  shared_count.hpp
    00031 //  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
    00032
    00033 //  shared_ptr.hpp
    00034 //  Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes.
    00035 //  Copyright (C) 2001, 2002, 2003 Peter Dimov
    00036
    00037 //  weak_ptr.hpp
    00038 //  Copyright (C) 2001, 2002, 2003 Peter Dimov
    00039
    00040 //  enable_shared_from_this.hpp
    00041 //  Copyright (C) 2002 Peter Dimov
    00042
    00043 // Distributed under the Boost Software License, Version 1.0. (See
    00044 // accompanying file LICENSE_1_0.txt or copy at
    00045 // http://www.boost.org/LICENSE_1_0.txt)
    00046
    00047 // GCC Note:  based on version 1.32.0 of the Boost library.
    00048
    00049 /** @file tr1/boost_sp_shared_count.h
    00050  *  This is an internal header file, included by other library headers.
    00051  *  You should not attempt to use it directly.
    00052  */
    00053
    00054 #if defined(_GLIBCXX_INCLUDE_AS_CXX0X)
    00055 #  error TR1 header cannot be included from C++0x header
    00056 #endif
    00057
    00058 namespace std
    00059 {
    00060 namespace tr1
    00061 {
    00062
    00063   template<typename _Ptr, typename _Deleter, _Lock_policy _Lp>
    00064     class _Sp_counted_base_impl
    00065     : public _Sp_counted_base<_Lp>
    00066     {
    00067     public:
    00068       /**
    00069        *  @brief
    00070        *  @pre     __d(__p) must not throw.
    00071        */
    00072       _Sp_counted_base_impl(_Ptr __p, _Deleter __d)
    00073       : _M_ptr(__p), _M_del(__d) { }
    00074
    00075       virtual void
    00076       _M_dispose() // nothrow
    00077       { _M_del(_M_ptr); }
    00078
    00079       virtual void*
    00080       _M_get_deleter(const std::type_info& __ti)
    00081       { return __ti == typeid(_Deleter) ? &_M_del : 0; }
    00082
    00083     private:
    00084       _Sp_counted_base_impl(const _Sp_counted_base_impl&);
    00085       _Sp_counted_base_impl& operator=(const _Sp_counted_base_impl&);
    00086
    00087       _Ptr      _M_ptr;  // copy constructor must not throw
    00088       _Deleter  _M_del;  // copy constructor must not throw
    00089     };
    00090
    00091   template<_Lock_policy _Lp = __default_lock_policy>
    00092     class __weak_count;
    00093
    00094   template<typename _Tp>
    00095     struct _Sp_deleter
    00096     {
    00097       typedef void result_type;
    00098       typedef _Tp* argument_type;
    00099       void operator()(_Tp* __p) const { delete __p; }
    00100     };
    00101
    00102   template<_Lock_policy _Lp = __default_lock_policy>
    00103     class __shared_count
    00104     {
    00105     public:
    00106       __shared_count()
    00107       : _M_pi(0) // nothrow
    00108       { }
    00109
    00110       template<typename _Ptr>
    00111         __shared_count(_Ptr __p) : _M_pi(0)
    00112         {
    00113       try
    00114         {
    00115           typedef typename std::tr1::remove_pointer<_Ptr>::type _Tp;
    00116           _M_pi = new _Sp_counted_base_impl<_Ptr, _Sp_deleter<_Tp>, _Lp>(
    00117               __p, _Sp_deleter<_Tp>());
    00118         }
    00119       catch(...)
    00120         {
    00121           delete __p;
    00122           __throw_exception_again;
    00123         }
    00124     }
    00125
    00126       template<typename _Ptr, typename _Deleter>
    00127         __shared_count(_Ptr __p, _Deleter __d) : _M_pi(0)
    00128         {
    00129       try
    00130         {
    00131           _M_pi = new _Sp_counted_base_impl<_Ptr, _Deleter, _Lp>(__p, __d);
    00132         }
    00133       catch(...)
    00134         {
    00135           __d(__p); // Call _Deleter on __p.
    00136           __throw_exception_again;
    00137         }
    00138     }
    00139
    00140       // Special case for auto_ptr<_Tp> to provide the strong guarantee.
    00141       template<typename _Tp>
    00142         explicit
    00143         __shared_count(std::auto_ptr<_Tp>& __r)
    00144     : _M_pi(new _Sp_counted_base_impl<_Tp*,
    00145         _Sp_deleter<_Tp>, _Lp >(__r.get(), _Sp_deleter<_Tp>()))
    00146         { __r.release(); }
    00147
    00148       // Throw bad_weak_ptr when __r._M_get_use_count() == 0.
    00149       explicit
    00150       __shared_count(const __weak_count<_Lp>& __r);
    00151
    00152       ~__shared_count() // nothrow
    00153       {
    00154     if (_M_pi != 0)
    00155       _M_pi->_M_release();
    00156       }
    00157
    00158       __shared_count(const __shared_count& __r)
    00159       : _M_pi(__r._M_pi) // nothrow
    00160       {
    00161     if (_M_pi != 0)
    00162       _M_pi->_M_add_ref_copy();
    00163       }
    00164
    00165       __shared_count&
    00166       operator=(const __shared_count& __r) // nothrow
    00167       {
    00168     _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
    00169     if (__tmp != _M_pi)
    00170       {
    00171         if (__tmp != 0)
    00172           __tmp->_M_add_ref_copy();
    00173         if (_M_pi != 0)
    00174           _M_pi->_M_release();
    00175         _M_pi = __tmp;
    00176       }
    00177     return *this;
    00178       }
    00179
    00180       void
    00181       _M_swap(__shared_count& __r) // nothrow
    00182       {
    00183     _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
    00184     __r._M_pi = _M_pi;
    00185     _M_pi = __tmp;
    00186       }
    00187
    00188       long
    00189       _M_get_use_count() const // nothrow
    00190       { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
    00191
    00192       bool
    00193       _M_unique() const // nothrow
    00194       { return this->_M_get_use_count() == 1; }
    00195
    00196       friend inline bool
    00197       operator==(const __shared_count& __a, const __shared_count& __b)
    00198       { return __a._M_pi == __b._M_pi; }
    00199
    00200       friend inline bool
    00201       operator<(const __shared_count& __a, const __shared_count& __b)
    00202       { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
    00203
    00204       void*
    00205       _M_get_deleter(const std::type_info& __ti) const
    00206       { return _M_pi ? _M_pi->_M_get_deleter(__ti) : 0; }
    00207
    00208     private:
    00209       friend class __weak_count<_Lp>;
    00210
    00211       _Sp_counted_base<_Lp>*  _M_pi;
    00212     };
    00213 }
    00214 }