Chris@16: ////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // This file is the adaptation for Interprocess of boost/intrusive_ptr.hpp Chris@16: // Chris@16: // (C) Copyright Peter Dimov 2001, 2002 Chris@16: // (C) Copyright Ion Gaztanaga 2006-2012. Distributed under the Boost Chris@16: // Software License, Version 1.0. (See accompanying file Chris@16: // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: // See http://www.boost.org/libs/interprocess for documentation. Chris@16: // Chris@16: ////////////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: #ifndef BOOST_INTERPROCESS_INTRUSIVE_PTR_HPP_INCLUDED Chris@16: #define BOOST_INTERPROCESS_INTRUSIVE_PTR_HPP_INCLUDED Chris@16: Chris@101: #ifndef BOOST_CONFIG_HPP Chris@101: # include Chris@101: #endif Chris@101: # Chris@101: #if defined(BOOST_HAS_PRAGMA_ONCE) Chris@101: # pragma once Chris@101: #endif Chris@101: Chris@16: //!\file Chris@16: //!Describes an intrusive ownership pointer. Chris@16: Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@101: #include Chris@16: Chris@16: #include // for std::basic_ostream Chris@16: Chris@101: #include //std::less Chris@16: Chris@16: namespace boost { Chris@16: namespace interprocess { Chris@16: Chris@16: //!The intrusive_ptr class template stores a pointer to an object Chris@16: //!with an embedded reference count. intrusive_ptr is parameterized on Chris@16: //!T (the type of the object pointed to) and VoidPointer(a void pointer type Chris@16: //!that defines the type of pointer that intrusive_ptr will store). Chris@16: //!intrusive_ptr defines a class with a T* member whereas Chris@16: //!intrusive_ptr > defines a class with a offset_ptr member. Chris@16: //!Relies on unqualified calls to: Chris@16: //! Chris@16: //! void intrusive_ptr_add_ref(T * p); Chris@16: //! void intrusive_ptr_release(T * p); Chris@16: //! Chris@16: //! with (p != 0) Chris@16: //! Chris@16: //!The object is responsible for destroying itself. Chris@16: template Chris@16: class intrusive_ptr Chris@16: { Chris@16: public: Chris@16: //!Provides the type of the internal stored pointer. Chris@16: typedef typename boost::intrusive:: Chris@16: pointer_traits::template Chris@16: rebind_pointer::type pointer; Chris@16: //!Provides the type of the stored pointer. Chris@16: typedef T element_type; Chris@16: Chris@101: #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) Chris@16: private: Chris@16: typedef VoidPointer VP; Chris@16: typedef intrusive_ptr this_type; Chris@16: typedef pointer this_type::*unspecified_bool_type; Chris@101: #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED Chris@16: Chris@16: public: Chris@16: //!Constructor. Initializes internal pointer to 0. Chris@16: //!Does not throw Chris@16: intrusive_ptr(): m_ptr(0) Chris@16: {} Chris@16: Chris@16: //!Constructor. Copies pointer and if "p" is not zero and Chris@16: //!"add_ref" is true calls intrusive_ptr_add_ref(to_raw_pointer(p)). Chris@16: //!Does not throw Chris@16: intrusive_ptr(const pointer &p, bool add_ref = true): m_ptr(p) Chris@16: { Chris@16: if(m_ptr != 0 && add_ref) intrusive_ptr_add_ref(ipcdetail::to_raw_pointer(m_ptr)); Chris@16: } Chris@16: Chris@16: //!Copy constructor. Copies the internal pointer and if "p" is not Chris@16: //!zero calls intrusive_ptr_add_ref(to_raw_pointer(p)). Does not throw Chris@16: intrusive_ptr(intrusive_ptr const & rhs) Chris@16: : m_ptr(rhs.m_ptr) Chris@16: { Chris@16: if(m_ptr != 0) intrusive_ptr_add_ref(ipcdetail::to_raw_pointer(m_ptr)); Chris@16: } Chris@16: Chris@16: //!Constructor from related. Copies the internal pointer and if "p" is not Chris@16: //!zero calls intrusive_ptr_add_ref(to_raw_pointer(p)). Does not throw Chris@16: template intrusive_ptr Chris@16: (intrusive_ptr const & rhs) Chris@16: : m_ptr(rhs.get()) Chris@16: { Chris@16: if(m_ptr != 0) intrusive_ptr_add_ref(ipcdetail::to_raw_pointer(m_ptr)); Chris@16: } Chris@16: Chris@16: //!Destructor. If internal pointer is not 0, calls Chris@16: //!intrusive_ptr_release(to_raw_pointer(m_ptr)). Does not throw Chris@16: ~intrusive_ptr() Chris@16: { Chris@16: if(m_ptr != 0) intrusive_ptr_release(ipcdetail::to_raw_pointer(m_ptr)); Chris@16: } Chris@16: Chris@16: //!Assignment operator. Equivalent to intrusive_ptr(r).swap(*this). Chris@16: //!Does not throw Chris@16: intrusive_ptr & operator=(intrusive_ptr const & rhs) Chris@16: { Chris@16: this_type(rhs).swap(*this); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: //!Assignment from related. Equivalent to intrusive_ptr(r).swap(*this). Chris@16: //!Does not throw Chris@16: template intrusive_ptr & operator= Chris@16: (intrusive_ptr const & rhs) Chris@16: { Chris@16: this_type(rhs).swap(*this); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: //!Assignment from pointer. Equivalent to intrusive_ptr(r).swap(*this). Chris@16: //!Does not throw Chris@16: intrusive_ptr & operator=(pointer rhs) Chris@16: { Chris@16: this_type(rhs).swap(*this); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: //!Returns a reference to the internal pointer. Chris@16: //!Does not throw Chris@16: pointer &get() Chris@16: { return m_ptr; } Chris@16: Chris@16: //!Returns a reference to the internal pointer. Chris@16: //!Does not throw Chris@16: const pointer &get() const Chris@16: { return m_ptr; } Chris@16: Chris@16: //!Returns *get(). Chris@16: //!Does not throw Chris@16: T & operator*() const Chris@16: { return *m_ptr; } Chris@16: Chris@16: //!Returns *get(). Chris@16: //!Does not throw Chris@16: const pointer &operator->() const Chris@16: { return m_ptr; } Chris@16: Chris@16: //!Returns get(). Chris@16: //!Does not throw Chris@16: pointer &operator->() Chris@16: { return m_ptr; } Chris@16: Chris@16: //!Conversion to boolean. Chris@16: //!Does not throw Chris@16: operator unspecified_bool_type () const Chris@16: { return m_ptr == 0? 0: &this_type::m_ptr; } Chris@16: Chris@16: //!Not operator. Chris@16: //!Does not throw Chris@16: bool operator! () const Chris@16: { return m_ptr == 0; } Chris@16: Chris@16: //!Exchanges the contents of the two smart pointers. Chris@16: //!Does not throw Chris@16: void swap(intrusive_ptr & rhs) Chris@101: { ::boost::adl_move_swap(m_ptr, rhs.m_ptr); } Chris@16: Chris@101: #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) Chris@16: private: Chris@16: pointer m_ptr; Chris@101: #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED Chris@16: }; Chris@16: Chris@16: //!Returns a.get() == b.get(). Chris@16: //!Does not throw Chris@16: template inline Chris@16: bool operator==(intrusive_ptr const & a, Chris@16: intrusive_ptr const & b) Chris@16: { return a.get() == b.get(); } Chris@16: Chris@16: //!Returns a.get() != b.get(). Chris@16: //!Does not throw Chris@16: template inline Chris@16: bool operator!=(intrusive_ptr const & a, Chris@16: intrusive_ptr const & b) Chris@16: { return a.get() != b.get(); } Chris@16: Chris@16: //!Returns a.get() == b. Chris@16: //!Does not throw Chris@16: template inline Chris@16: bool operator==(intrusive_ptr const & a, Chris@16: const typename intrusive_ptr::pointer &b) Chris@16: { return a.get() == b; } Chris@16: Chris@16: //!Returns a.get() != b. Chris@16: //!Does not throw Chris@16: template inline Chris@16: bool operator!=(intrusive_ptr const & a, Chris@16: const typename intrusive_ptr::pointer &b) Chris@16: { return a.get() != b; } Chris@16: Chris@16: //!Returns a == b.get(). Chris@16: //!Does not throw Chris@16: template inline Chris@16: bool operator==(const typename intrusive_ptr::pointer &a, Chris@16: intrusive_ptr const & b) Chris@16: { return a == b.get(); } Chris@16: Chris@16: //!Returns a != b.get(). Chris@16: //!Does not throw Chris@16: template inline Chris@16: bool operator!=(const typename intrusive_ptr::pointer &a, Chris@16: intrusive_ptr const & b) Chris@16: { return a != b.get(); } Chris@16: Chris@16: //!Returns a.get() < b.get(). Chris@16: //!Does not throw Chris@16: template inline Chris@16: bool operator<(intrusive_ptr const & a, Chris@16: intrusive_ptr const & b) Chris@16: { Chris@16: return std::less::pointer>() Chris@16: (a.get(), b.get()); Chris@16: } Chris@16: Chris@16: //!Exchanges the contents of the two intrusive_ptrs. Chris@16: //!Does not throw Chris@16: template inline Chris@16: void swap(intrusive_ptr & lhs, Chris@16: intrusive_ptr & rhs) Chris@16: { lhs.swap(rhs); } Chris@16: Chris@16: // operator<< Chris@16: template Chris@16: inline std::basic_ostream & operator<< Chris@16: (std::basic_ostream & os, intrusive_ptr const & p) Chris@16: { os << p.get(); return os; } Chris@16: Chris@16: //!Returns p.get(). Chris@16: //!Does not throw Chris@16: template Chris@16: inline typename boost::interprocess::intrusive_ptr::pointer Chris@16: to_raw_pointer(intrusive_ptr p) Chris@16: { return p.get(); } Chris@16: Chris@16: /*Emulates static cast operator. Does not throw*/ Chris@16: /* Chris@16: template Chris@16: inline boost::interprocess::intrusive_ptr static_pointer_cast Chris@16: (boost::interprocess::intrusive_ptr const & p) Chris@16: { return do_static_cast(p.get()); } Chris@16: */ Chris@16: /*Emulates const cast operator. Does not throw*/ Chris@16: /* Chris@16: template Chris@16: inline boost::interprocess::intrusive_ptr const_pointer_cast Chris@16: (boost::interprocess::intrusive_ptr const & p) Chris@16: { return do_const_cast(p.get()); } Chris@16: */ Chris@16: Chris@16: /*Emulates dynamic cast operator. Does not throw*/ Chris@16: /* Chris@16: template Chris@16: inline boost::interprocess::intrusive_ptr dynamic_pointer_cast Chris@16: (boost::interprocess::intrusive_ptr const & p) Chris@16: { return do_dynamic_cast(p.get()); } Chris@16: */ Chris@16: Chris@16: /*Emulates reinterpret cast operator. Does not throw*/ Chris@16: /* Chris@16: template Chris@16: inline boost::interprocess::intrusive_ptrreinterpret_pointer_cast Chris@16: (boost::interprocess::intrusive_ptr const & p) Chris@16: { return do_reinterpret_cast(p.get()); } Chris@16: */ Chris@16: Chris@16: } // namespace interprocess Chris@16: Chris@101: #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) Chris@16: Chris@16: #if defined(_MSC_VER) && (_MSC_VER < 1400) Chris@16: //!Returns p.get(). Chris@16: //!Does not throw Chris@16: template Chris@16: inline T *to_raw_pointer(boost::interprocess::intrusive_ptr p) Chris@16: { return p.get(); } Chris@16: #endif Chris@16: Chris@101: #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED Chris@16: Chris@16: } // namespace boost Chris@16: Chris@16: #include Chris@16: Chris@16: #endif // #ifndef BOOST_INTERPROCESS_INTRUSIVE_PTR_HPP_INCLUDED