LCOV - code coverage report
Current view: top level - usr/include/boost/smart_ptr - intrusive_ptr.hpp (source / functions) Hit Total Coverage
Test: ROSE Lines: 0 23 0.0 %
Date: 2022-12-08 13:48:47 Functions: 0 1 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : #ifndef BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED
       2             : #define BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED
       3             : 
       4             : //
       5             : //  intrusive_ptr.hpp
       6             : //
       7             : //  Copyright (c) 2001, 2002 Peter Dimov
       8             : //
       9             : //  Distributed under the Boost Software License, Version 1.0. (See
      10             : //  accompanying file LICENSE_1_0.txt or copy at
      11             : //  http://www.boost.org/LICENSE_1_0.txt)
      12             : //
      13             : //  See http://www.boost.org/libs/smart_ptr/ for documentation.
      14             : //
      15             : 
      16             : #include <boost/config.hpp>
      17             : 
      18             : #include <boost/assert.hpp>
      19             : #include <boost/detail/workaround.hpp>
      20             : #include <boost/smart_ptr/detail/sp_convertible.hpp>
      21             : #include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
      22             : #include <boost/smart_ptr/detail/sp_noexcept.hpp>
      23             : 
      24             : #include <boost/config/no_tr1/functional.hpp>           // for std::less
      25             : 
      26             : #if !defined(BOOST_NO_IOSTREAM)
      27             : #if !defined(BOOST_NO_IOSFWD)
      28             : #include <iosfwd>               // for std::basic_ostream
      29             : #else
      30             : #include <ostream>
      31             : #endif
      32             : #endif
      33             : 
      34             : 
      35             : namespace boost
      36             : {
      37             : 
      38             : //
      39             : //  intrusive_ptr
      40             : //
      41             : //  A smart pointer that uses intrusive reference counting.
      42             : //
      43             : //  Relies on unqualified calls to
      44             : //  
      45             : //      void intrusive_ptr_add_ref(T * p);
      46             : //      void intrusive_ptr_release(T * p);
      47             : //
      48             : //          (p != 0)
      49             : //
      50             : //  The object is responsible for destroying itself.
      51             : //
      52             : 
      53             : template<class T> class intrusive_ptr
      54             : {
      55             : private:
      56             : 
      57             :     typedef intrusive_ptr this_type;
      58             : 
      59             : public:
      60             : 
      61             :     typedef T element_type;
      62             : 
      63           0 :     BOOST_CONSTEXPR intrusive_ptr() BOOST_SP_NOEXCEPT : px( 0 )
      64             :     {
      65             :     }
      66             : 
      67           0 :     intrusive_ptr( T * p, bool add_ref = true ): px( p )
      68             :     {
      69           0 :         if( px != 0 && add_ref ) intrusive_ptr_add_ref( px );
      70             :     }
      71             : 
      72             : #if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES)
      73             : 
      74             :     template<class U>
      75             : #if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
      76             : 
      77             :     intrusive_ptr( intrusive_ptr<U> const & rhs, typename boost::detail::sp_enable_if_convertible<U,T>::type = boost::detail::sp_empty() )
      78             : 
      79             : #else
      80             : 
      81             :     intrusive_ptr( intrusive_ptr<U> const & rhs )
      82             : 
      83             : #endif
      84             :     : px( rhs.get() )
      85             :     {
      86             :         if( px != 0 ) intrusive_ptr_add_ref( px );
      87             :     }
      88             : 
      89             : #endif
      90             : 
      91             :     intrusive_ptr(intrusive_ptr const & rhs): px( rhs.px )
      92             :     {
      93             :         if( px != 0 ) intrusive_ptr_add_ref( px );
      94             :     }
      95             : 
      96           0 :     ~intrusive_ptr()
      97             :     {
      98           0 :         if( px != 0 ) intrusive_ptr_release( px );
      99           0 :     }
     100             : 
     101             : #if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES)
     102             : 
     103             :     template<class U> intrusive_ptr & operator=(intrusive_ptr<U> const & rhs)
     104             :     {
     105             :         this_type(rhs).swap(*this);
     106             :         return *this;
     107             :     }
     108             : 
     109             : #endif
     110             : 
     111             : // Move support
     112             : 
     113             : #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
     114             : 
     115           0 :     intrusive_ptr(intrusive_ptr && rhs) BOOST_SP_NOEXCEPT : px( rhs.px )
     116             :     {
     117           0 :         rhs.px = 0;
     118             :     }
     119             : 
     120             :     intrusive_ptr & operator=(intrusive_ptr && rhs) BOOST_SP_NOEXCEPT
     121             :     {
     122             :         this_type( static_cast< intrusive_ptr && >( rhs ) ).swap(*this);
     123             :         return *this;
     124             :     }
     125             : 
     126             :     template<class U> friend class intrusive_ptr;
     127             : 
     128             :     template<class U>
     129             : #if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
     130             : 
     131             :     intrusive_ptr(intrusive_ptr<U> && rhs, typename boost::detail::sp_enable_if_convertible<U,T>::type = boost::detail::sp_empty())
     132             : 
     133             : #else
     134             : 
     135             :     intrusive_ptr(intrusive_ptr<U> && rhs)
     136             : 
     137             : #endif        
     138             :     : px( rhs.px )
     139             :     {
     140             :         rhs.px = 0;
     141             :     }
     142             : 
     143             :     template<class U>
     144             :     intrusive_ptr & operator=(intrusive_ptr<U> && rhs) BOOST_SP_NOEXCEPT
     145             :     {
     146             :         this_type( static_cast< intrusive_ptr<U> && >( rhs ) ).swap(*this);
     147             :         return *this;
     148             :     }
     149             : 
     150             : #endif
     151             : 
     152             :     intrusive_ptr & operator=(intrusive_ptr const & rhs)
     153             :     {
     154             :         this_type(rhs).swap(*this);
     155             :         return *this;
     156             :     }
     157             : 
     158             :     intrusive_ptr & operator=(T * rhs)
     159             :     {
     160             :         this_type(rhs).swap(*this);
     161             :         return *this;
     162             :     }
     163             : 
     164           0 :     void reset()
     165             :     {
     166           0 :         this_type().swap( *this );
     167           0 :     }
     168             : 
     169           0 :     void reset( T * rhs )
     170             :     {
     171           0 :         this_type( rhs ).swap( *this );
     172           0 :     }
     173             : 
     174             :     void reset( T * rhs, bool add_ref )
     175             :     {
     176             :         this_type( rhs, add_ref ).swap( *this );
     177             :     }
     178             : 
     179           0 :     T * get() const BOOST_SP_NOEXCEPT
     180             :     {
     181             :         return px;
     182             :     }
     183             : 
     184             :     T * detach() BOOST_SP_NOEXCEPT
     185             :     {
     186             :         T * ret = px;
     187             :         px = 0;
     188             :         return ret;
     189             :     }
     190             : 
     191             :     T & operator*() const BOOST_SP_NOEXCEPT_WITH_ASSERT
     192             :     {
     193             :         BOOST_ASSERT( px != 0 );
     194             :         return *px;
     195             :     }
     196             : 
     197           0 :     T * operator->() const BOOST_SP_NOEXCEPT_WITH_ASSERT
     198             :     {
     199           0 :         BOOST_ASSERT( px != 0 );
     200             :         return px;
     201             :     }
     202             : 
     203             : // implicit conversion to "bool"
     204             : #include <boost/smart_ptr/detail/operator_bool.hpp>
     205             : 
     206           0 :     void swap(intrusive_ptr & rhs) BOOST_SP_NOEXCEPT
     207             :     {
     208           0 :         T * tmp = px;
     209           0 :         px = rhs.px;
     210           0 :         rhs.px = tmp;
     211             :     }
     212             : 
     213             : private:
     214             : 
     215             :     T * px;
     216             : };
     217             : 
     218           0 : template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b) BOOST_SP_NOEXCEPT
     219             : {
     220           0 :     return a.get() == b.get();
     221             : }
     222             : 
     223             : template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b) BOOST_SP_NOEXCEPT
     224             : {
     225             :     return a.get() != b.get();
     226             : }
     227             : 
     228             : template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, U * b) BOOST_SP_NOEXCEPT
     229             : {
     230             :     return a.get() == b;
     231             : }
     232             : 
     233             : template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, U * b) BOOST_SP_NOEXCEPT
     234             : {
     235             :     return a.get() != b;
     236             : }
     237             : 
     238             : template<class T, class U> inline bool operator==(T * a, intrusive_ptr<U> const & b) BOOST_SP_NOEXCEPT
     239             : {
     240             :     return a == b.get();
     241             : }
     242             : 
     243             : template<class T, class U> inline bool operator!=(T * a, intrusive_ptr<U> const & b) BOOST_SP_NOEXCEPT
     244             : {
     245             :     return a != b.get();
     246             : }
     247             : 
     248             : #if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
     249             : 
     250             : // Resolve the ambiguity between our op!= and the one in rel_ops
     251             : 
     252             : template<class T> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b) BOOST_SP_NOEXCEPT
     253             : {
     254             :     return a.get() != b.get();
     255             : }
     256             : 
     257             : #endif
     258             : 
     259             : #if !defined( BOOST_NO_CXX11_NULLPTR )
     260             : 
     261             : template<class T> inline bool operator==( intrusive_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT
     262             : {
     263             :     return p.get() == 0;
     264             : }
     265             : 
     266             : template<class T> inline bool operator==( boost::detail::sp_nullptr_t, intrusive_ptr<T> const & p ) BOOST_SP_NOEXCEPT
     267             : {
     268             :     return p.get() == 0;
     269             : }
     270             : 
     271             : template<class T> inline bool operator!=( intrusive_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT
     272             : {
     273             :     return p.get() != 0;
     274             : }
     275             : 
     276             : template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, intrusive_ptr<T> const & p ) BOOST_SP_NOEXCEPT
     277             : {
     278             :     return p.get() != 0;
     279             : }
     280             : 
     281             : #endif
     282             : 
     283             : template<class T> inline bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b) BOOST_SP_NOEXCEPT
     284             : {
     285             :     return std::less<T *>()(a.get(), b.get());
     286             : }
     287             : 
     288             : template<class T> void swap(intrusive_ptr<T> & lhs, intrusive_ptr<T> & rhs) BOOST_SP_NOEXCEPT
     289             : {
     290             :     lhs.swap(rhs);
     291             : }
     292             : 
     293             : // mem_fn support
     294             : 
     295             : template<class T> T * get_pointer(intrusive_ptr<T> const & p) BOOST_SP_NOEXCEPT
     296             : {
     297             :     return p.get();
     298             : }
     299             : 
     300             : // pointer casts
     301             : 
     302             : template<class T, class U> intrusive_ptr<T> static_pointer_cast(intrusive_ptr<U> const & p)
     303             : {
     304             :     return static_cast<T *>(p.get());
     305             : }
     306             : 
     307             : template<class T, class U> intrusive_ptr<T> const_pointer_cast(intrusive_ptr<U> const & p)
     308             : {
     309             :     return const_cast<T *>(p.get());
     310             : }
     311             : 
     312             : template<class T, class U> intrusive_ptr<T> dynamic_pointer_cast(intrusive_ptr<U> const & p)
     313             : {
     314             :     return dynamic_cast<T *>(p.get());
     315             : }
     316             : 
     317             : #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
     318             : 
     319             : template<class T, class U> intrusive_ptr<T> static_pointer_cast( intrusive_ptr<U> && p ) BOOST_SP_NOEXCEPT
     320             : {
     321             :     return intrusive_ptr<T>( static_cast<T*>( p.detach() ), false );
     322             : }
     323             : 
     324             : template<class T, class U> intrusive_ptr<T> const_pointer_cast( intrusive_ptr<U> && p ) BOOST_SP_NOEXCEPT
     325             : {
     326             :     return intrusive_ptr<T>( const_cast<T*>( p.detach() ), false );
     327             : }
     328             : 
     329             : template<class T, class U> intrusive_ptr<T> dynamic_pointer_cast( intrusive_ptr<U> && p ) BOOST_SP_NOEXCEPT
     330             : {
     331             :     T * p2 = dynamic_cast<T*>( p.get() );
     332             : 
     333             :     intrusive_ptr<T> r( p2, false );
     334             : 
     335             :     if( p2 ) p.detach();
     336             : 
     337             :     return r;
     338             : }
     339             : 
     340             : #endif // defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
     341             : 
     342             : // operator<<
     343             : 
     344             : #if !defined(BOOST_NO_IOSTREAM)
     345             : 
     346             : #if defined(BOOST_NO_TEMPLATED_IOSTREAMS) || ( defined(__GNUC__) &&  (__GNUC__ < 3) )
     347             : 
     348             : template<class Y> std::ostream & operator<< (std::ostream & os, intrusive_ptr<Y> const & p)
     349             : {
     350             :     os << p.get();
     351             :     return os;
     352             : }
     353             : 
     354             : #else
     355             : 
     356             : // in STLport's no-iostreams mode no iostream symbols can be used
     357             : #ifndef _STLP_NO_IOSTREAMS
     358             : 
     359             : # if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, < 1300 && __SGI_STL_PORT)
     360             : // MSVC6 has problems finding std::basic_ostream through the using declaration in namespace _STL
     361             : using std::basic_ostream;
     362             : template<class E, class T, class Y> basic_ostream<E, T> & operator<< (basic_ostream<E, T> & os, intrusive_ptr<Y> const & p)
     363             : # else
     364             : template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, intrusive_ptr<Y> const & p)
     365             : # endif 
     366             : {
     367             :     os << p.get();
     368             :     return os;
     369             : }
     370             : 
     371             : #endif // _STLP_NO_IOSTREAMS
     372             : 
     373             : #endif // __GNUC__ < 3
     374             : 
     375             : #endif // !defined(BOOST_NO_IOSTREAM)
     376             : 
     377             : // hash_value
     378             : 
     379             : template< class T > struct hash;
     380             : 
     381             : template< class T > std::size_t hash_value( boost::intrusive_ptr<T> const & p ) BOOST_SP_NOEXCEPT
     382             : {
     383             :     return boost::hash< T* >()( p.get() );
     384             : }
     385             : 
     386             : } // namespace boost
     387             : 
     388             : #endif  // #ifndef BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED

Generated by: LCOV version 1.14