Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:53:29

0001 //////////////////////////////////////////////////////////////////////////////
0002 //
0003 // This file is the adaptation for Interprocess of boost/intrusive_ptr.hpp
0004 //
0005 // (C) Copyright Peter Dimov 2001, 2002
0006 // (C) Copyright Ion Gaztanaga 2006-2012. Distributed under the Boost
0007 // Software License, Version 1.0. (See accompanying file
0008 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0009 //
0010 // See http://www.boost.org/libs/interprocess for documentation.
0011 //
0012 //////////////////////////////////////////////////////////////////////////////
0013 
0014 #ifndef BOOST_INTERPROCESS_INTRUSIVE_PTR_HPP_INCLUDED
0015 #define BOOST_INTERPROCESS_INTRUSIVE_PTR_HPP_INCLUDED
0016 
0017 #ifndef BOOST_CONFIG_HPP
0018 #  include <boost/config.hpp>
0019 #endif
0020 #
0021 #if defined(BOOST_HAS_PRAGMA_ONCE)
0022 #  pragma once
0023 #endif
0024 
0025 //!\file
0026 //!Describes an intrusive ownership pointer.
0027 
0028 #include <boost/interprocess/detail/config_begin.hpp>
0029 #include <boost/interprocess/detail/workaround.hpp>
0030 
0031 #include <boost/assert.hpp>
0032 #include <boost/interprocess/detail/utilities.hpp>
0033 #include <boost/intrusive/pointer_traits.hpp>
0034 #include <boost/move/adl_move_swap.hpp>
0035 #include <boost/move/core.hpp>
0036 
0037 #include <iosfwd>               // for std::basic_ostream
0038 
0039 #include <boost/intrusive/detail/minimal_less_equal_header.hpp>   //std::less
0040 
0041 namespace boost {
0042 namespace interprocess {
0043 
0044 //!The intrusive_ptr class template stores a pointer to an object
0045 //!with an embedded reference count. intrusive_ptr is parameterized on
0046 //!T (the type of the object pointed to) and VoidPointer(a void pointer type
0047 //!that defines the type of pointer that intrusive_ptr will store).
0048 //!intrusive_ptr<T, void *> defines a class with a T* member whereas
0049 //!intrusive_ptr<T, offset_ptr<void> > defines a class with a offset_ptr<T> member.
0050 //!Relies on unqualified calls to:
0051 //!
0052 //!  void intrusive_ptr_add_ref(T * p) BOOST_NOEXCEPT;
0053 //!  void intrusive_ptr_release(T * p) BOOST_NOEXCEPT;
0054 //!
0055 //!  with (p != 0)
0056 //!
0057 //!The object is responsible for destroying itself.
0058 template<class T, class VoidPointer>
0059 class intrusive_ptr
0060 {
0061    public:
0062    //!Provides the type of the internal stored pointer.
0063    typedef typename boost::intrusive::
0064       pointer_traits<VoidPointer>::template
0065          rebind_pointer<T>::type                pointer;
0066    //!Provides the type of the stored pointer.
0067    typedef T element_type;
0068 
0069    #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0070    private:
0071    typedef VoidPointer VP;
0072    typedef intrusive_ptr this_type;
0073    typedef pointer this_type::*unspecified_bool_type;
0074    #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
0075 
0076    BOOST_COPYABLE_AND_MOVABLE(intrusive_ptr)
0077 
0078    public:
0079    //!Constructor. Initializes internal pointer to 0.
0080    //!Does not throw
0081    intrusive_ptr() BOOST_NOEXCEPT
0082        : m_ptr(0)
0083    {}
0084 
0085    //!Constructor. Copies pointer and if "p" is not zero and
0086    //!"add_ref" is true calls intrusive_ptr_add_ref(to_raw_pointer(p)).
0087    //!Does not throw
0088    intrusive_ptr(const pointer &p, bool add_ref = true) BOOST_NOEXCEPT
0089        : m_ptr(p)
0090    {
0091       if(m_ptr != 0 && add_ref) intrusive_ptr_add_ref(ipcdetail::to_raw_pointer(m_ptr));
0092    }
0093 
0094    //!Copy constructor. Copies the internal pointer and if "p" is not
0095    //!zero calls intrusive_ptr_add_ref(to_raw_pointer(p)). Does not throw
0096    intrusive_ptr(intrusive_ptr const & rhs) BOOST_NOEXCEPT
0097       :  m_ptr(rhs.m_ptr)
0098    {
0099       if(m_ptr != 0) intrusive_ptr_add_ref(ipcdetail::to_raw_pointer(m_ptr));
0100    }
0101 
0102    //!Move constructor. Moves the internal pointer. Does not throw
0103    intrusive_ptr(BOOST_RV_REF(intrusive_ptr) rhs) BOOST_NOEXCEPT
0104        : m_ptr(rhs.m_ptr) 
0105    {
0106        rhs.m_ptr = 0;
0107    }
0108 
0109    //!Constructor from related. Copies the internal pointer and if "p" is not
0110    //!zero calls intrusive_ptr_add_ref(to_raw_pointer(p)). Does not throw
0111    template<class U> intrusive_ptr(intrusive_ptr<U, VP> const & rhs) BOOST_NOEXCEPT
0112       :  m_ptr(rhs.get())
0113    {
0114       if(m_ptr != 0) intrusive_ptr_add_ref(ipcdetail::to_raw_pointer(m_ptr));
0115    }
0116 
0117    //!Destructor. Calls reset(). Does not throw
0118    ~intrusive_ptr()
0119    {
0120       reset();
0121    }
0122 
0123    //!Assignment operator. Equivalent to intrusive_ptr(r).swap(*this).
0124    //!Does not throw
0125    intrusive_ptr & operator=(BOOST_COPY_ASSIGN_REF(intrusive_ptr) rhs) BOOST_NOEXCEPT
0126    {
0127       this_type(rhs).swap(*this);
0128       return *this;
0129    }
0130 
0131    //!Move Assignment operator
0132    //!Does not throw
0133    intrusive_ptr & operator=(BOOST_RV_REF(intrusive_ptr) rhs) BOOST_NOEXCEPT 
0134    {
0135        rhs.swap(*this);
0136        rhs.reset();
0137        return *this;
0138    }
0139 
0140    //!Assignment from related. Equivalent to intrusive_ptr(r).swap(*this).
0141    //!Does not throw
0142    template<class U> intrusive_ptr & operator=(intrusive_ptr<U, VP> const & rhs) BOOST_NOEXCEPT
0143    {
0144       this_type(rhs).swap(*this);
0145       return *this;
0146    }
0147 
0148    //!Assignment from pointer. Equivalent to intrusive_ptr(r).swap(*this).
0149    //!Does not throw
0150    intrusive_ptr & operator=(pointer rhs) BOOST_NOEXCEPT
0151    {
0152       this_type(rhs).swap(*this);
0153       return *this;
0154    }
0155 
0156    //!Release internal pointer and set it to 0. If internal pointer is not 0, calls
0157    //!intrusive_ptr_release(to_raw_pointer(m_ptr)). Does not throw
0158    void reset() BOOST_NOEXCEPT {
0159       if(m_ptr != 0) {
0160         pointer ptr = m_ptr;
0161         m_ptr = 0;
0162         intrusive_ptr_release(ipcdetail::to_raw_pointer(ptr));
0163       }
0164    }
0165 
0166    //!Returns a reference to the internal pointer.
0167    //!Does not throw
0168    pointer &get() BOOST_NOEXCEPT
0169    {  return m_ptr;  }
0170 
0171    //!Returns a reference to the internal pointer.
0172    //!Does not throw
0173    const pointer &get() const BOOST_NOEXCEPT
0174    {  return m_ptr;  }
0175 
0176    //!Returns *get().
0177    //!Does not throw
0178    T & operator*() const BOOST_NOEXCEPT
0179    {  return *m_ptr; }
0180 
0181    //!Returns *get().
0182    //!Does not throw
0183    const pointer &operator->() const BOOST_NOEXCEPT
0184    {  return m_ptr;  }
0185 
0186    //!Returns get().
0187    //!Does not throw
0188    pointer &operator->() BOOST_NOEXCEPT
0189    {  return m_ptr;  }
0190 
0191    //!Conversion to boolean.
0192    //!Does not throw
0193    operator unspecified_bool_type () const BOOST_NOEXCEPT
0194    {  return m_ptr == 0? 0: &this_type::m_ptr;  }
0195 
0196    //!Not operator.
0197    //!Does not throw
0198    bool operator! () const BOOST_NOEXCEPT
0199    {  return m_ptr == 0;   }
0200 
0201    //!Exchanges the contents of the two smart pointers.
0202    //!Does not throw
0203    void swap(intrusive_ptr & rhs) BOOST_NOEXCEPT
0204    {  ::boost::adl_move_swap(m_ptr, rhs.m_ptr);  }
0205 
0206    #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0207    private:
0208    pointer m_ptr;
0209    #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
0210 };
0211 
0212 //!Returns a.get() == b.get().
0213 //!Does not throw
0214 template<class T, class U, class VP> inline
0215 bool operator==(intrusive_ptr<T, VP> const & a,
0216                 intrusive_ptr<U, VP> const & b) BOOST_NOEXCEPT
0217 {  return a.get() == b.get(); }
0218 
0219 //!Returns a.get() != b.get().
0220 //!Does not throw
0221 template<class T, class U, class VP> inline
0222 bool operator!=(intrusive_ptr<T, VP> const & a,
0223                 intrusive_ptr<U, VP> const & b) BOOST_NOEXCEPT
0224 {  return a.get() != b.get(); }
0225 
0226 //!Returns a.get() == b.
0227 //!Does not throw
0228 template<class T, class VP> inline
0229 bool operator==(intrusive_ptr<T, VP> const & a,
0230                        const typename intrusive_ptr<T, VP>::pointer &b) BOOST_NOEXCEPT
0231 {  return a.get() == b; }
0232 
0233 //!Returns a.get() != b.
0234 //!Does not throw
0235 template<class T, class VP> inline
0236 bool operator!=(intrusive_ptr<T, VP> const & a,
0237                 const typename intrusive_ptr<T, VP>::pointer &b) BOOST_NOEXCEPT
0238 {  return a.get() != b; }
0239 
0240 //!Returns a == b.get().
0241 //!Does not throw
0242 template<class T, class VP> inline
0243 bool operator==(const typename intrusive_ptr<T, VP>::pointer &a,
0244                 intrusive_ptr<T, VP> const & b) BOOST_NOEXCEPT
0245 {  return a == b.get(); }
0246 
0247 //!Returns a != b.get().
0248 //!Does not throw
0249 template<class T, class VP> inline
0250 bool operator!=(const typename intrusive_ptr<T, VP>::pointer &a,
0251                        intrusive_ptr<T, VP> const & b) BOOST_NOEXCEPT
0252 {  return a != b.get(); }
0253 
0254 //!Returns a.get() < b.get().
0255 //!Does not throw
0256 template<class T, class VP> inline
0257 bool operator<(intrusive_ptr<T, VP> const & a,
0258                intrusive_ptr<T, VP> const & b) BOOST_NOEXCEPT
0259 {
0260    return std::less<typename intrusive_ptr<T, VP>::pointer>()
0261       (a.get(), b.get());
0262 }
0263 
0264 //!Exchanges the contents of the two intrusive_ptrs.
0265 //!Does not throw
0266 template<class T, class VP> inline
0267 void swap(intrusive_ptr<T, VP> & lhs,
0268           intrusive_ptr<T, VP> & rhs) BOOST_NOEXCEPT
0269 {  lhs.swap(rhs); }
0270 
0271 // operator<<
0272 template<class E, class T, class Y, class VP>
0273 inline std::basic_ostream<E, T> & operator<<
0274    (std::basic_ostream<E, T> & os, intrusive_ptr<Y, VP> const & p) BOOST_NOEXCEPT
0275 {  os << p.get(); return os;  }
0276 
0277 //!Returns p.get().
0278 //!Does not throw
0279 template<class T, class VP>
0280 inline typename boost::interprocess::intrusive_ptr<T, VP>::pointer
0281    to_raw_pointer(intrusive_ptr<T, VP> p) BOOST_NOEXCEPT
0282 {  return p.get();   }
0283 
0284 /*Emulates static cast operator. Does not throw*/
0285 /*
0286 template<class T, class U, class VP>
0287 inline boost::interprocess::intrusive_ptr<T, VP> static_pointer_cast
0288    (boost::interprocess::intrusive_ptr<U, VP> const & p) BOOST_NOEXCEPT
0289 {  return do_static_cast<U>(p.get());  }
0290 */
0291 /*Emulates const cast operator. Does not throw*/
0292 /*
0293 template<class T, class U, class VP>
0294 inline boost::interprocess::intrusive_ptr<T, VP> const_pointer_cast
0295    (boost::interprocess::intrusive_ptr<U, VP> const & p) BOOST_NOEXCEPT
0296 {  return do_const_cast<U>(p.get());   }
0297 */
0298 
0299 /*Emulates dynamic cast operator. Does not throw*/
0300 /*
0301 template<class T, class U, class VP>
0302 inline boost::interprocess::intrusive_ptr<T, VP> dynamic_pointer_cast
0303    (boost::interprocess::intrusive_ptr<U, VP> const & p) BOOST_NOEXCEPT
0304 {  return do_dynamic_cast<U>(p.get()); }
0305 */
0306 
0307 /*Emulates reinterpret cast operator. Does not throw*/
0308 /*
0309 template<class T, class U, class VP>
0310 inline boost::interprocess::intrusive_ptr<T, VP>reinterpret_pointer_cast
0311    (boost::interprocess::intrusive_ptr<U, VP> const & p) BOOST_NOEXCEPT
0312 {  return do_reinterpret_cast<U>(p.get());   }
0313 */
0314 
0315 } // namespace interprocess
0316 
0317 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0318 
0319 #if defined(_MSC_VER) && (_MSC_VER < 1400)
0320 //!Returns p.get().
0321 //!Does not throw
0322 template<class T, class VP>
0323 inline T *to_raw_pointer(boost::interprocess::intrusive_ptr<T, VP> p) BOOST_NOEXCEPT
0324 {  return p.get();   }
0325 #endif
0326 
0327 #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
0328 
0329 } // namespace boost
0330 
0331 #include <boost/interprocess/detail/config_end.hpp>
0332 
0333 #endif  // #ifndef BOOST_INTERPROCESS_INTRUSIVE_PTR_HPP_INCLUDED