diff options
Diffstat (limited to 'boost/interprocess/smart_ptr/intrusive_ptr.hpp')
-rw-r--r-- | boost/interprocess/smart_ptr/intrusive_ptr.hpp | 296 |
1 files changed, 296 insertions, 0 deletions
diff --git a/boost/interprocess/smart_ptr/intrusive_ptr.hpp b/boost/interprocess/smart_ptr/intrusive_ptr.hpp new file mode 100644 index 0000000000..3f086f5360 --- /dev/null +++ b/boost/interprocess/smart_ptr/intrusive_ptr.hpp @@ -0,0 +1,296 @@ +////////////////////////////////////////////////////////////////////////////// +// +// This file is the adaptation for Interprocess of boost/intrusive_ptr.hpp +// +// (C) Copyright Peter Dimov 2001, 2002 +// (C) Copyright Ion Gaztanaga 2006. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTERPROCESS_INTRUSIVE_PTR_HPP_INCLUDED +#define BOOST_INTERPROCESS_INTRUSIVE_PTR_HPP_INCLUDED + +//!\file +//!Describes an intrusive ownership pointer. + +#include <boost/interprocess/detail/config_begin.hpp> +#include <boost/interprocess/detail/workaround.hpp> + +#include <boost/assert.hpp> +#include <boost/interprocess/detail/utilities.hpp> +#include <boost/intrusive/pointer_traits.hpp> + +#include <functional> // for std::less +#include <iosfwd> // for std::basic_ostream + + +namespace boost { +namespace interprocess { + +//!The intrusive_ptr class template stores a pointer to an object +//!with an embedded reference count. intrusive_ptr is parameterized on +//!T (the type of the object pointed to) and VoidPointer(a void pointer type +//!that defines the type of pointer that intrusive_ptr will store). +//!intrusive_ptr<T, void *> defines a class with a T* member whereas +//!intrusive_ptr<T, offset_ptr<void> > defines a class with a offset_ptr<T> member. +//!Relies on unqualified calls to: +//! +//! void intrusive_ptr_add_ref(T * p); +//! void intrusive_ptr_release(T * p); +//! +//! with (p != 0) +//! +//!The object is responsible for destroying itself. +template<class T, class VoidPointer> +class intrusive_ptr +{ + public: + //!Provides the type of the internal stored pointer. + typedef typename boost::intrusive:: + pointer_traits<VoidPointer>::template + rebind_pointer<T>::type pointer; + //!Provides the type of the stored pointer. + typedef T element_type; + + /// @cond + private: + typedef VoidPointer VP; + typedef intrusive_ptr this_type; + typedef pointer this_type::*unspecified_bool_type; + /// @endcond + + public: + //!Constructor. Initializes internal pointer to 0. + //!Does not throw + intrusive_ptr(): m_ptr(0) + {} + + //!Constructor. Copies pointer and if "p" is not zero and + //!"add_ref" is true calls intrusive_ptr_add_ref(to_raw_pointer(p)). + //!Does not throw + intrusive_ptr(const pointer &p, bool add_ref = true): m_ptr(p) + { + if(m_ptr != 0 && add_ref) intrusive_ptr_add_ref(ipcdetail::to_raw_pointer(m_ptr)); + } + + //!Copy constructor. Copies the internal pointer and if "p" is not + //!zero calls intrusive_ptr_add_ref(to_raw_pointer(p)). Does not throw + intrusive_ptr(intrusive_ptr const & rhs) + : m_ptr(rhs.m_ptr) + { + if(m_ptr != 0) intrusive_ptr_add_ref(ipcdetail::to_raw_pointer(m_ptr)); + } + + //!Constructor from related. Copies the internal pointer and if "p" is not + //!zero calls intrusive_ptr_add_ref(to_raw_pointer(p)). Does not throw + template<class U> intrusive_ptr + (intrusive_ptr<U, VP> const & rhs) + : m_ptr(rhs.get()) + { + if(m_ptr != 0) intrusive_ptr_add_ref(ipcdetail::to_raw_pointer(m_ptr)); + } + + //!Destructor. If internal pointer is not 0, calls + //!intrusive_ptr_release(to_raw_pointer(m_ptr)). Does not throw + ~intrusive_ptr() + { + if(m_ptr != 0) intrusive_ptr_release(ipcdetail::to_raw_pointer(m_ptr)); + } + + //!Assignment operator. Equivalent to intrusive_ptr(r).swap(*this). + //!Does not throw + intrusive_ptr & operator=(intrusive_ptr const & rhs) + { + this_type(rhs).swap(*this); + return *this; + } + + //!Assignment from related. Equivalent to intrusive_ptr(r).swap(*this). + //!Does not throw + template<class U> intrusive_ptr & operator= + (intrusive_ptr<U, VP> const & rhs) + { + this_type(rhs).swap(*this); + return *this; + } + + //!Assignment from pointer. Equivalent to intrusive_ptr(r).swap(*this). + //!Does not throw + intrusive_ptr & operator=(pointer rhs) + { + this_type(rhs).swap(*this); + return *this; + } + + //!Returns a reference to the internal pointer. + //!Does not throw + pointer &get() + { return m_ptr; } + + //!Returns a reference to the internal pointer. + //!Does not throw + const pointer &get() const + { return m_ptr; } + + //!Returns *get(). + //!Does not throw + T & operator*() const + { return *m_ptr; } + + //!Returns *get(). + //!Does not throw + const pointer &operator->() const + { return m_ptr; } + + //!Returns get(). + //!Does not throw + pointer &operator->() + { return m_ptr; } + + //!Conversion to boolean. + //!Does not throw + operator unspecified_bool_type () const + { return m_ptr == 0? 0: &this_type::m_ptr; } + + //!Not operator. + //!Does not throw + bool operator! () const + { return m_ptr == 0; } + + //!Exchanges the contents of the two smart pointers. + //!Does not throw + void swap(intrusive_ptr & rhs) + { ipcdetail::do_swap(m_ptr, rhs.m_ptr); } + + /// @cond + private: + pointer m_ptr; + /// @endcond +}; + +//!Returns a.get() == b.get(). +//!Does not throw +template<class T, class U, class VP> inline +bool operator==(intrusive_ptr<T, VP> const & a, + intrusive_ptr<U, VP> const & b) +{ return a.get() == b.get(); } + +//!Returns a.get() != b.get(). +//!Does not throw +template<class T, class U, class VP> inline +bool operator!=(intrusive_ptr<T, VP> const & a, + intrusive_ptr<U, VP> const & b) +{ return a.get() != b.get(); } + +//!Returns a.get() == b. +//!Does not throw +template<class T, class VP> inline +bool operator==(intrusive_ptr<T, VP> const & a, + const typename intrusive_ptr<T, VP>::pointer &b) +{ return a.get() == b; } + +//!Returns a.get() != b. +//!Does not throw +template<class T, class VP> inline +bool operator!=(intrusive_ptr<T, VP> const & a, + const typename intrusive_ptr<T, VP>::pointer &b) +{ return a.get() != b; } + +//!Returns a == b.get(). +//!Does not throw +template<class T, class VP> inline +bool operator==(const typename intrusive_ptr<T, VP>::pointer &a, + intrusive_ptr<T, VP> const & b) +{ return a == b.get(); } + +//!Returns a != b.get(). +//!Does not throw +template<class T, class VP> inline +bool operator!=(const typename intrusive_ptr<T, VP>::pointer &a, + intrusive_ptr<T, VP> const & b) +{ return a != b.get(); } + +//!Returns a.get() < b.get(). +//!Does not throw +template<class T, class VP> inline +bool operator<(intrusive_ptr<T, VP> const & a, + intrusive_ptr<T, VP> const & b) +{ + return std::less<typename intrusive_ptr<T, VP>::pointer>() + (a.get(), b.get()); +} + +//!Exchanges the contents of the two intrusive_ptrs. +//!Does not throw +template<class T, class VP> inline +void swap(intrusive_ptr<T, VP> & lhs, + intrusive_ptr<T, VP> & rhs) +{ lhs.swap(rhs); } + +// operator<< +template<class E, class T, class Y, class VP> +inline std::basic_ostream<E, T> & operator<< + (std::basic_ostream<E, T> & os, intrusive_ptr<Y, VP> const & p) +{ os << p.get(); return os; } + +//!Returns p.get(). +//!Does not throw +template<class T, class VP> +inline typename boost::interprocess::intrusive_ptr<T, VP>::pointer + to_raw_pointer(intrusive_ptr<T, VP> p) +{ return p.get(); } + +/*Emulates static cast operator. Does not throw*/ +/* +template<class T, class U, class VP> +inline boost::interprocess::intrusive_ptr<T, VP> static_pointer_cast + (boost::interprocess::intrusive_ptr<U, VP> const & p) +{ return do_static_cast<U>(p.get()); } +*/ +/*Emulates const cast operator. Does not throw*/ +/* +template<class T, class U, class VP> +inline boost::interprocess::intrusive_ptr<T, VP> const_pointer_cast + (boost::interprocess::intrusive_ptr<U, VP> const & p) +{ return do_const_cast<U>(p.get()); } +*/ + +/*Emulates dynamic cast operator. Does not throw*/ +/* +template<class T, class U, class VP> +inline boost::interprocess::intrusive_ptr<T, VP> dynamic_pointer_cast + (boost::interprocess::intrusive_ptr<U, VP> const & p) +{ return do_dynamic_cast<U>(p.get()); } +*/ + +/*Emulates reinterpret cast operator. Does not throw*/ +/* +template<class T, class U, class VP> +inline boost::interprocess::intrusive_ptr<T, VP>reinterpret_pointer_cast + (boost::interprocess::intrusive_ptr<U, VP> const & p) +{ return do_reinterpret_cast<U>(p.get()); } +*/ + +} // namespace interprocess + +/// @cond + +#if defined(_MSC_VER) && (_MSC_VER < 1400) +//!Returns p.get(). +//!Does not throw +template<class T, class VP> +inline T *to_raw_pointer(boost::interprocess::intrusive_ptr<T, VP> p) +{ return p.get(); } +#endif + +/// @endcond + +} // namespace boost + +#include <boost/interprocess/detail/config_end.hpp> + +#endif // #ifndef BOOST_INTERPROCESS_INTRUSIVE_PTR_HPP_INCLUDED |