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 }

Generated on Fri Jan 23 20:12:10 2009 for libstdc++ by  doxygen 1.5.6