Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-15 10:08:19

0001 #ifndef BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED
0002 #define BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED
0003 
0004 //
0005 //  intrusive_ptr.hpp
0006 //
0007 //  Copyright (c) 2001, 2002 Peter Dimov
0008 //
0009 //  Distributed under the Boost Software License, Version 1.0. (See
0010 //  accompanying file LICENSE_1_0.txt or copy at
0011 //  http://www.boost.org/LICENSE_1_0.txt)
0012 //
0013 //  See http://www.boost.org/libs/smart_ptr/ for documentation.
0014 //
0015 
0016 #include <boost/smart_ptr/detail/sp_convertible.hpp>
0017 #include <boost/smart_ptr/detail/sp_noexcept.hpp>
0018 #include <boost/assert.hpp>
0019 
0020 #include <functional>           // for std::less
0021 #include <iosfwd>               // for std::basic_ostream
0022 #include <cstddef>
0023 
0024 namespace boost
0025 {
0026 
0027 //
0028 //  intrusive_ptr
0029 //
0030 //  A smart pointer that uses intrusive reference counting.
0031 //
0032 //  Relies on unqualified calls to
0033 //  
0034 //      void intrusive_ptr_add_ref(T * p);
0035 //      void intrusive_ptr_release(T * p);
0036 //
0037 //          (p != 0)
0038 //
0039 //  The object is responsible for destroying itself.
0040 //
0041 
0042 template<class T> class intrusive_ptr
0043 {
0044 private:
0045 
0046     typedef intrusive_ptr this_type;
0047 
0048 public:
0049 
0050     typedef T element_type;
0051 
0052     constexpr intrusive_ptr() noexcept : px( 0 )
0053     {
0054     }
0055 
0056     intrusive_ptr( T * p, bool add_ref = true ): px( p )
0057     {
0058         if( px != 0 && add_ref ) intrusive_ptr_add_ref( px );
0059     }
0060 
0061     template<class U>
0062     intrusive_ptr( intrusive_ptr<U> const & rhs, typename boost::detail::sp_enable_if_convertible<U,T>::type = boost::detail::sp_empty() )
0063     : px( rhs.get() )
0064     {
0065         if( px != 0 ) intrusive_ptr_add_ref( px );
0066     }
0067 
0068     intrusive_ptr(intrusive_ptr const & rhs): px( rhs.px )
0069     {
0070         if( px != 0 ) intrusive_ptr_add_ref( px );
0071     }
0072 
0073     ~intrusive_ptr()
0074     {
0075         if( px != 0 ) intrusive_ptr_release( px );
0076     }
0077 
0078     template<class U> intrusive_ptr & operator=(intrusive_ptr<U> const & rhs)
0079     {
0080         this_type(rhs).swap(*this);
0081         return *this;
0082     }
0083 
0084 // Move support
0085 
0086     intrusive_ptr(intrusive_ptr && rhs) noexcept : px( rhs.px )
0087     {
0088         rhs.px = 0;
0089     }
0090 
0091     intrusive_ptr & operator=(intrusive_ptr && rhs) noexcept
0092     {
0093         this_type( static_cast< intrusive_ptr && >( rhs ) ).swap(*this);
0094         return *this;
0095     }
0096 
0097     template<class U> friend class intrusive_ptr;
0098 
0099     template<class U>
0100     intrusive_ptr(intrusive_ptr<U> && rhs, typename boost::detail::sp_enable_if_convertible<U,T>::type = boost::detail::sp_empty())
0101     : px( rhs.px )
0102     {
0103         rhs.px = 0;
0104     }
0105 
0106     template<class U>
0107     intrusive_ptr & operator=(intrusive_ptr<U> && rhs) noexcept
0108     {
0109         this_type( static_cast< intrusive_ptr<U> && >( rhs ) ).swap(*this);
0110         return *this;
0111     }
0112 
0113     intrusive_ptr & operator=(intrusive_ptr const & rhs)
0114     {
0115         this_type(rhs).swap(*this);
0116         return *this;
0117     }
0118 
0119     intrusive_ptr & operator=(T * rhs)
0120     {
0121         this_type(rhs).swap(*this);
0122         return *this;
0123     }
0124 
0125     void reset()
0126     {
0127         this_type().swap( *this );
0128     }
0129 
0130     void reset( T * rhs )
0131     {
0132         this_type( rhs ).swap( *this );
0133     }
0134 
0135     void reset( T * rhs, bool add_ref )
0136     {
0137         this_type( rhs, add_ref ).swap( *this );
0138     }
0139 
0140     T * get() const noexcept
0141     {
0142         return px;
0143     }
0144 
0145     T * detach() noexcept
0146     {
0147         T * ret = px;
0148         px = 0;
0149         return ret;
0150     }
0151 
0152     T & operator*() const BOOST_SP_NOEXCEPT_WITH_ASSERT
0153     {
0154         BOOST_ASSERT( px != 0 );
0155         return *px;
0156     }
0157 
0158     T * operator->() const BOOST_SP_NOEXCEPT_WITH_ASSERT
0159     {
0160         BOOST_ASSERT( px != 0 );
0161         return px;
0162     }
0163 
0164     explicit operator bool () const noexcept
0165     {
0166         return px != 0;
0167     }
0168 
0169     void swap(intrusive_ptr & rhs) noexcept
0170     {
0171         T * tmp = px;
0172         px = rhs.px;
0173         rhs.px = tmp;
0174     }
0175 
0176 private:
0177 
0178     T * px;
0179 };
0180 
0181 template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b) noexcept
0182 {
0183     return a.get() == b.get();
0184 }
0185 
0186 template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b) noexcept
0187 {
0188     return a.get() != b.get();
0189 }
0190 
0191 template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, U * b) noexcept
0192 {
0193     return a.get() == b;
0194 }
0195 
0196 template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, U * b) noexcept
0197 {
0198     return a.get() != b;
0199 }
0200 
0201 template<class T, class U> inline bool operator==(T * a, intrusive_ptr<U> const & b) noexcept
0202 {
0203     return a == b.get();
0204 }
0205 
0206 template<class T, class U> inline bool operator!=(T * a, intrusive_ptr<U> const & b) noexcept
0207 {
0208     return a != b.get();
0209 }
0210 
0211 template<class T> inline bool operator==( intrusive_ptr<T> const & p, std::nullptr_t ) noexcept
0212 {
0213     return p.get() == 0;
0214 }
0215 
0216 template<class T> inline bool operator==( std::nullptr_t, intrusive_ptr<T> const & p ) noexcept
0217 {
0218     return p.get() == 0;
0219 }
0220 
0221 template<class T> inline bool operator!=( intrusive_ptr<T> const & p, std::nullptr_t ) noexcept
0222 {
0223     return p.get() != 0;
0224 }
0225 
0226 template<class T> inline bool operator!=( std::nullptr_t, intrusive_ptr<T> const & p ) noexcept
0227 {
0228     return p.get() != 0;
0229 }
0230 
0231 template<class T> inline bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b) noexcept
0232 {
0233     return std::less<T *>()(a.get(), b.get());
0234 }
0235 
0236 template<class T> void swap(intrusive_ptr<T> & lhs, intrusive_ptr<T> & rhs) noexcept
0237 {
0238     lhs.swap(rhs);
0239 }
0240 
0241 // mem_fn support
0242 
0243 template<class T> T * get_pointer(intrusive_ptr<T> const & p) noexcept
0244 {
0245     return p.get();
0246 }
0247 
0248 // pointer casts
0249 
0250 template<class T, class U> intrusive_ptr<T> static_pointer_cast(intrusive_ptr<U> const & p)
0251 {
0252     return static_cast<T *>(p.get());
0253 }
0254 
0255 template<class T, class U> intrusive_ptr<T> const_pointer_cast(intrusive_ptr<U> const & p)
0256 {
0257     return const_cast<T *>(p.get());
0258 }
0259 
0260 template<class T, class U> intrusive_ptr<T> dynamic_pointer_cast(intrusive_ptr<U> const & p)
0261 {
0262     return dynamic_cast<T *>(p.get());
0263 }
0264 
0265 template<class T, class U> intrusive_ptr<T> static_pointer_cast( intrusive_ptr<U> && p ) noexcept
0266 {
0267     return intrusive_ptr<T>( static_cast<T*>( p.detach() ), false );
0268 }
0269 
0270 template<class T, class U> intrusive_ptr<T> const_pointer_cast( intrusive_ptr<U> && p ) noexcept
0271 {
0272     return intrusive_ptr<T>( const_cast<T*>( p.detach() ), false );
0273 }
0274 
0275 template<class T, class U> intrusive_ptr<T> dynamic_pointer_cast( intrusive_ptr<U> && p ) noexcept
0276 {
0277     T * p2 = dynamic_cast<T*>( p.get() );
0278 
0279     intrusive_ptr<T> r( p2, false );
0280 
0281     if( p2 ) p.detach();
0282 
0283     return r;
0284 }
0285 
0286 // operator<<
0287 
0288 template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, intrusive_ptr<Y> const & p)
0289 {
0290     os << p.get();
0291     return os;
0292 }
0293 
0294 // hash_value
0295 
0296 template< class T > struct hash;
0297 
0298 template< class T > std::size_t hash_value( boost::intrusive_ptr<T> const & p ) noexcept
0299 {
0300     return boost::hash< T* >()( p.get() );
0301 }
0302 
0303 } // namespace boost
0304 
0305 // std::hash
0306 
0307 namespace std
0308 {
0309 
0310 template<class T> struct hash< ::boost::intrusive_ptr<T> >
0311 {
0312     std::size_t operator()( ::boost::intrusive_ptr<T> const & p ) const noexcept
0313     {
0314         return std::hash< T* >()( p.get() );
0315     }
0316 };
0317 
0318 } // namespace std
0319 
0320 #endif  // #ifndef BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED