
//  helper code for dealing with tracking non-boost shared_ptr/weak_ptr

// Copyright Frank Mori Hess 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/signals2 for library home page.

#ifndef BOOST_SIGNALS2_FOREIGN_PTR_HPP
#define BOOST_SIGNALS2_FOREIGN_PTR_HPP

#include <algorithm>
#include <boost/assert.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/smart_ptr/bad_weak_ptr.hpp>
#include <boost/utility/swap.hpp>

namespace std
{
  template<typename T> class shared_ptr;
  template<typename T> class weak_ptr;
}

namespace boost
{
  template<typename T> class shared_ptr;
  template<typename T> class weak_ptr;

  namespace signals2
  {
    template<typename WeakPtr> struct weak_ptr_traits
    {};
    template<typename T> struct weak_ptr_traits<boost::weak_ptr<T> >
    {
      typedef boost::shared_ptr<T> shared_type;
    };
    template<typename T> struct weak_ptr_traits<std::weak_ptr<T> >
    {
      typedef std::shared_ptr<T> shared_type;
    };

    template<typename SharedPtr> struct shared_ptr_traits
    {};

    template<typename T> struct shared_ptr_traits<boost::shared_ptr<T> >
    {
      typedef boost::weak_ptr<T> weak_type;
    };
    template<typename T> struct shared_ptr_traits<std::shared_ptr<T> >
    {
      typedef std::weak_ptr<T> weak_type;
    };

    namespace detail
    {
      struct foreign_shared_ptr_impl_base
      {
        virtual ~foreign_shared_ptr_impl_base() {}
        virtual void* get() const = 0;
        virtual foreign_shared_ptr_impl_base * clone() const = 0;
      };

      template<typename FSP>
      class foreign_shared_ptr_impl: public foreign_shared_ptr_impl_base
      {
      public:
        foreign_shared_ptr_impl(const FSP &p): _p(p)
        {}
        virtual void * get() const
        {
          return _p.get();
        }
        virtual foreign_shared_ptr_impl * clone() const
        {
          return new foreign_shared_ptr_impl(*this);
        }
      private:
        FSP _p;
      };

      class foreign_void_shared_ptr
      {
      public:
        foreign_void_shared_ptr():
          _p(0)
        {}
        foreign_void_shared_ptr(const foreign_void_shared_ptr &other):
          _p(other._p->clone())
        {}
        template<typename FSP>
        explicit foreign_void_shared_ptr(const FSP &fsp):
          _p(new foreign_shared_ptr_impl<FSP>(fsp))
        {}
        ~foreign_void_shared_ptr()
        {
          delete _p;
        }
        foreign_void_shared_ptr & operator=(const foreign_void_shared_ptr &other)
        {
          if(&other == this) return *this;
          foreign_void_shared_ptr(other).swap(*this);
          return *this;
        }
        void swap(foreign_void_shared_ptr &other)
        {
          boost::swap(_p, other._p);
        }
      private:
        foreign_shared_ptr_impl_base *_p;
      };

      struct foreign_weak_ptr_impl_base
      {
        virtual ~foreign_weak_ptr_impl_base() {}
        virtual foreign_void_shared_ptr lock() const = 0;
        virtual bool expired() const = 0;
        virtual foreign_weak_ptr_impl_base * clone() const = 0;
      };

      template<typename FWP>
      class foreign_weak_ptr_impl: public foreign_weak_ptr_impl_base
      {
      public:
        foreign_weak_ptr_impl(const FWP &p): _p(p)
        {}
        virtual foreign_void_shared_ptr lock() const
        {
          return foreign_void_shared_ptr(_p.lock());
        }
        virtual bool expired() const
        {
          return _p.expired();
        }
        virtual foreign_weak_ptr_impl * clone() const
        {
          return new foreign_weak_ptr_impl(*this);
        }
      private:
        FWP _p;
      };

      class foreign_void_weak_ptr
      {
      public:
        foreign_void_weak_ptr()
        {}
        foreign_void_weak_ptr(const foreign_void_weak_ptr &other):
          _p(other._p->clone())
        {}
        template<typename FWP>
        explicit foreign_void_weak_ptr(const FWP &fwp):
          _p(new foreign_weak_ptr_impl<FWP>(fwp))
        {}
        foreign_void_weak_ptr & operator=(const foreign_void_weak_ptr &other)
        {
          if(&other == this) return *this;
          foreign_void_weak_ptr(other).swap(*this);
          return *this;
        }
        void swap(foreign_void_weak_ptr &other)
        {
          boost::swap(_p, other._p);
        }
        foreign_void_shared_ptr lock() const
        {
          return _p->lock();
        }
        bool expired() const
        {
          return _p->expired();
        }
      private:
        boost::scoped_ptr<foreign_weak_ptr_impl_base> _p;
      };
    } // namespace detail

  } // namespace signals2
} // namespace boost

#endif  // BOOST_SIGNALS2_FOREIGN_PTR_HPP
