//////////////////////////////////////////////////////////////////////////////
//
// This file is the adaptation for Interprocess of boost/shared_ptr.hpp
//
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
// (C) Copyright Peter Dimov 2001, 2002, 2003
// (C) Copyright Ion Gaztanaga 2006-2009.
// 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_SHARED_PTR_HPP_INCLUDED
#define BOOST_INTERPROCESS_SHARED_PTR_HPP_INCLUDED

#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>

#include <boost/interprocess/detail/utilities.hpp>
#include <boost/interprocess/detail/cast_tags.hpp>
#include <boost/assert.hpp>
#include <boost/interprocess/smart_ptr/detail/shared_count.hpp>
#include <boost/interprocess/detail/mpl.hpp>
#include <boost/interprocess/detail/move.hpp>
#include <boost/interprocess/detail/type_traits.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/smart_ptr/deleter.hpp>
#include <boost/static_assert.hpp>
#include <boost/pointer_to_other.hpp>

#include <algorithm>            // for std::swap
#include <functional>           // for std::less
#include <typeinfo>             // for std::bad_cast
#include <iosfwd>               // for std::basic_ostream

//!\file
//!Describes the smart pointer shared_ptr

namespace boost{
namespace interprocess{

template<class T, class VoidAllocator, class Deleter> class weak_ptr;
template<class T, class VoidAllocator, class Deleter> class enable_shared_from_this;

namespace detail{

template<class T, class VoidAllocator, class Deleter>
inline void sp_enable_shared_from_this
  (shared_count<T, VoidAllocator, Deleter> const & pn
  ,enable_shared_from_this<T, VoidAllocator, Deleter> *pe
  ,T *ptr)
   
{
   (void)ptr;
   if(pe != 0){
      pe->_internal_weak_this._internal_assign(pn);
   }
}

template<class T, class VoidAllocator, class Deleter>
inline void sp_enable_shared_from_this(shared_count<T, VoidAllocator, Deleter> const &, ...)
{}

} // namespace detail

//!shared_ptr stores a pointer to a dynamically allocated object. 
//!The object pointed to is guaranteed to be deleted when the last shared_ptr pointing to 
//!it is destroyed or reset.
//!
//!shared_ptr is parameterized on 
//!T (the type of the object pointed to), VoidAllocator (the void allocator to be used
//!to allocate the auxiliary data) and Deleter (the deleter whose 
//!operator() will be used to delete the object.
//!
//!The internal pointer will be of the same pointer type as typename 
//!VoidAllocator::pointer type (that is, if typename VoidAllocator::pointer is 
//!offset_ptr<void>, the internal pointer will be offset_ptr<T>).
//!
//!Because the implementation uses reference counting, cycles of shared_ptr
//!instances will not be reclaimed. For example, if main() holds a
//!shared_ptr to A, which directly or indirectly holds a shared_ptr back
//!to A, A's use count will be 2. Destruction of the original shared_ptr
//!will leave A dangling with a use count of 1.
//!Use weak_ptr to "break cycles."
template<class T, class VoidAllocator, class Deleter>
class shared_ptr
{
   /// @cond
   private:
   typedef shared_ptr<T, VoidAllocator, Deleter> this_type;
   /// @endcond

   public:

   typedef T                                                   element_type;
   typedef T                                                   value_type;
   typedef typename boost::pointer_to_other
      <typename VoidAllocator::pointer, T>::type               pointer;
   typedef typename detail::add_reference
                     <value_type>::type                        reference;
   typedef typename detail::add_reference
                     <const value_type>::type                  const_reference;
   typedef typename boost::pointer_to_other
            <typename VoidAllocator::pointer, const Deleter>::type         const_deleter_pointer;
   typedef typename boost::pointer_to_other
            <typename VoidAllocator::pointer, const VoidAllocator>::type   const_allocator_pointer;

   BOOST_INTERPROCESS_COPYABLE_AND_MOVABLE(shared_ptr)
   public:

   //!Constructs an empty shared_ptr.
   //!Use_count() == 0 && get()== 0.
   shared_ptr()
      :  m_pn() // never throws
   {}

   //!Constructs a shared_ptr that owns the pointer p. Auxiliary data will be allocated
   //!with a copy of a and the object will be deleted with a copy of d.
   //!Requirements: Deleter and A's copy constructor must not throw.
   explicit shared_ptr(const pointer&p, const VoidAllocator &a = VoidAllocator(), const Deleter &d = Deleter())
      :  m_pn(p, a, d)
   {  
      //Check that the pointer passed is of the same type that
      //the pointer the allocator defines or it's a raw pointer
      typedef typename boost::pointer_to_other<pointer, T>::type ParameterPointer;
      BOOST_STATIC_ASSERT((detail::is_same<pointer, ParameterPointer>::value) ||
                          (detail::is_pointer<pointer>::value));
      detail::sp_enable_shared_from_this<T, VoidAllocator, Deleter>( m_pn, detail::get_pointer(p), detail::get_pointer(p) ); 
   }


   //!Constructs a shared_ptr that shares ownership with r and stores p.
   //!Postconditions: get() == p && use_count() == r.use_count().
   //!Throws: nothing.
   shared_ptr(const shared_ptr &other, const pointer &p)
      :  m_pn(other.m_pn, p)
   {}

   //!If r is empty, constructs an empty shared_ptr. Otherwise, constructs 
   //!a shared_ptr that shares ownership with r. Never throws.
   template<class Y>
   shared_ptr(shared_ptr<Y, VoidAllocator, Deleter> const & r)
      :  m_pn(r.m_pn) // never throws
   {}

   //!Constructs a shared_ptr that shares ownership with r and stores 
   //!a copy of the pointer stored in r.
   template<class Y>
   explicit shared_ptr(weak_ptr<Y, VoidAllocator, Deleter> const & r)
      :  m_pn(r.m_pn) // may throw
   {}

   //!Move-Constructs a shared_ptr that takes ownership of other resource and
   //!other is put in default-constructed state.
   //!Throws: nothing.
   explicit shared_ptr(BOOST_INTERPROCESS_RV_REF(shared_ptr) other)
      :  m_pn()
   {  this->swap(other);   }

   /// @cond
   template<class Y>
   shared_ptr(shared_ptr<Y, VoidAllocator, Deleter> const & r, detail::static_cast_tag)
      :  m_pn( pointer(static_cast<T*>(detail::get_pointer(r.m_pn.get_pointer())))
             , r.m_pn) 
   {}

   template<class Y>
   shared_ptr(shared_ptr<Y, VoidAllocator, Deleter> const & r, detail::const_cast_tag)
      :  m_pn( pointer(const_cast<T*>(detail::get_pointer(r.m_pn.get_pointer())))
             , r.m_pn) 
   {}

   template<class Y>
   shared_ptr(shared_ptr<Y, VoidAllocator, Deleter> const & r, detail::dynamic_cast_tag)
      :  m_pn( pointer(dynamic_cast<T*>(detail::get_pointer(r.m_pn.get_pointer())))
             , r.m_pn) 
   {
      if(!m_pn.get_pointer()){ // need to allocate new counter -- the cast failed
         m_pn = detail::shared_count<T, VoidAllocator, Deleter>();
      }
   }
   /// @endcond

   //!Equivalent to shared_ptr(r).swap(*this).
   //!Never throws
   template<class Y>
   shared_ptr & operator=(shared_ptr<Y, VoidAllocator, Deleter> const & r)
   {
      m_pn = r.m_pn; // shared_count::op= doesn't throw
      return *this;
   }

   //!Equivalent to shared_ptr(r).swap(*this).
   //!Never throws
   shared_ptr & operator=(BOOST_INTERPROCESS_COPY_ASSIGN_REF(shared_ptr) r)
   {
      m_pn = r.m_pn; // shared_count::op= doesn't throw
      return *this;
   }

   //!Move-assignment. Equivalent to shared_ptr(other).swap(*this).
   //!Never throws
   shared_ptr & operator=(BOOST_INTERPROCESS_RV_REF(shared_ptr) other) // never throws
   {
      this_type(other).swap(*this);
      return *this;
   }

   //!This is equivalent to:
   //!this_type().swap(*this);
   void reset()
   {  
      this_type().swap(*this);   
   }

   //!This is equivalent to:
   //!this_type(p, a, d).swap(*this);
   template<class Pointer>
   void reset(const Pointer &p, const VoidAllocator &a = VoidAllocator(), const Deleter &d = Deleter())
   {  
      //Check that the pointer passed is of the same type that
      //the pointer the allocator defines or it's a raw pointer
      typedef typename boost::pointer_to_other<Pointer, T>::type ParameterPointer;
      BOOST_STATIC_ASSERT((detail::is_same<pointer, ParameterPointer>::value) ||
                          (detail::is_pointer<Pointer>::value));
      this_type(p, a, d).swap(*this);  
   }

   template<class Y>
   void reset(shared_ptr<Y, VoidAllocator, Deleter> const & r, const pointer &p)
   {
      this_type(r, p).swap(*this);
   }

   //!Returns a reference to the
   //!pointed type
   reference operator* () const // never throws
   {  BOOST_ASSERT(m_pn.get_pointer() != 0);  return *m_pn.get_pointer(); }

   //!Returns the pointer pointing 
   //!to the owned object
   pointer operator-> () const // never throws
   {  BOOST_ASSERT(m_pn.get_pointer() != 0);  return m_pn.get_pointer();  }

   //!Returns the pointer pointing 
   //!to the owned object
   pointer get() const  // never throws
   {  return m_pn.get_pointer();  }

   /// @cond
   // implicit conversion to "bool"
   void unspecified_bool_type_func() const {}
   typedef void (this_type::*unspecified_bool_type)() const;

   operator unspecified_bool_type() const // never throws
   {  return !m_pn.get_pointer() ? 0 : &this_type::unspecified_bool_type_func;  }
   /// @endcond

   //!Not operator.
   //!Returns true if this->get() != 0, false otherwise
   bool operator! () const // never throws
   {  return !m_pn.get_pointer();   }

   //!Returns use_count() == 1.
   //!unique() might be faster than use_count()
   bool unique() const // never throws
   {  return m_pn.unique();  }

   //!Returns the number of shared_ptr objects, *this included,
   //!that share ownership with *this, or an unspecified nonnegative
   //!value when *this is empty.
   //!use_count() is not necessarily efficient. Use only for
   //!debugging and testing purposes, not for production code.
   long use_count() const // never throws
   {  return m_pn.use_count();  }

   //!Exchanges the contents of the two
   //!smart pointers.
   void swap(shared_ptr<T, VoidAllocator, Deleter> & other) // never throws
   {  m_pn.swap(other.m_pn);   }

   /// @cond

   template<class T2, class A2, class Deleter2> 
   bool _internal_less(shared_ptr<T2, A2, Deleter2> const & rhs) const
   {  return m_pn < rhs.m_pn;  }

   const_deleter_pointer get_deleter() const
   {  return m_pn.get_deleter(); }

//   const_allocator_pointer get_allocator() const
//   {  return m_pn.get_allocator(); }

   private:

   template<class T2, class A2, class Deleter2> friend class shared_ptr;
   template<class T2, class A2, class Deleter2> friend class weak_ptr;

   detail::shared_count<T, VoidAllocator, Deleter>   m_pn;    // reference counter
   /// @endcond
};  // shared_ptr

template<class T, class VoidAllocator, class Deleter, class U, class VoidAllocator2, class Deleter2> inline 
bool operator==(shared_ptr<T, VoidAllocator, Deleter> const & a, shared_ptr<U, VoidAllocator2, Deleter2> const & b)
{  return a.get() == b.get(); }

template<class T, class VoidAllocator, class Deleter, class U, class VoidAllocator2, class Deleter2> inline 
bool operator!=(shared_ptr<T, VoidAllocator, Deleter> const & a, shared_ptr<U, VoidAllocator2, Deleter2> const & b)
{  return a.get() != b.get(); }

template<class T, class VoidAllocator, class Deleter, class U, class VoidAllocator2, class Deleter2> inline 
bool operator<(shared_ptr<T, VoidAllocator, Deleter> const & a, shared_ptr<U, VoidAllocator2, Deleter2> const & b)
{  return a._internal_less(b);   }

template<class T, class VoidAllocator, class Deleter> inline 
void swap(shared_ptr<T, VoidAllocator, Deleter> & a, shared_ptr<T, VoidAllocator, Deleter> & b)
{  a.swap(b);  }

template<class T, class VoidAllocator, class Deleter, class U> inline
shared_ptr<T, VoidAllocator, Deleter> static_pointer_cast(shared_ptr<U, VoidAllocator, Deleter> const & r)
{  return shared_ptr<T, VoidAllocator, Deleter>(r, detail::static_cast_tag());   }

template<class T, class VoidAllocator, class Deleter, class U> inline 
shared_ptr<T, VoidAllocator, Deleter> const_pointer_cast(shared_ptr<U, VoidAllocator, Deleter> const & r)
{  return shared_ptr<T, VoidAllocator, Deleter>(r, detail::const_cast_tag()); }

template<class T, class VoidAllocator, class Deleter, class U> inline 
shared_ptr<T, VoidAllocator, Deleter> dynamic_pointer_cast(shared_ptr<U, VoidAllocator, Deleter> const & r)
{  return shared_ptr<T, VoidAllocator, Deleter>(r, detail::dynamic_cast_tag());  }

// get_pointer() enables boost::mem_fn to recognize shared_ptr
template<class T, class VoidAllocator, class Deleter> inline
T * get_pointer(shared_ptr<T, VoidAllocator, Deleter> const & p)
{  return p.get();   }

// operator<<
template<class E, class T, class Y, class VoidAllocator, class Deleter> inline
std::basic_ostream<E, T> & operator<< 
   (std::basic_ostream<E, T> & os, shared_ptr<Y, VoidAllocator, Deleter> const & p)
{  os << p.get();   return os;   }

//!Returns the type of a shared pointer
//!of type T with the allocator boost::interprocess::allocator allocator
//!and boost::interprocess::deleter deleter
//!that can be constructed in the given managed segment type.
template<class T, class ManagedMemory>
struct managed_shared_ptr
{
   typedef typename ManagedMemory::template allocator<void>::type void_allocator;
   typedef typename ManagedMemory::template deleter<T>::type      deleter;
   typedef shared_ptr< T, void_allocator, deleter>                type;
};

//!Returns an instance of a shared pointer constructed
//!with the default allocator and deleter from a pointer
//!of type T that has been allocated in the passed managed segment
template<class T, class ManagedMemory>
inline typename managed_shared_ptr<T, ManagedMemory>::type
   make_managed_shared_ptr(T *constructed_object, ManagedMemory &managed_memory)
{
   return typename managed_shared_ptr<T, ManagedMemory>::type
   ( constructed_object
   , managed_memory.template get_allocator<void>()
   , managed_memory.template get_deleter<T>()
   );
}

} // namespace interprocess

/// @cond

#if defined(_MSC_VER) && (_MSC_VER < 1400)
// get_pointer() enables boost::mem_fn to recognize shared_ptr
template<class T, class VoidAllocator, class Deleter> inline
T * get_pointer(boost::interprocess::shared_ptr<T, VoidAllocator, Deleter> const & p)
{  return p.get();   }
#endif

/// @endcond

} // namespace boost

#include <boost/interprocess/detail/config_end.hpp>

#endif  // #ifndef BOOST_INTERPROCESS_SHARED_PTR_HPP_INCLUDED
