// Boost.Signals library

// Copyright Douglas Gregor 2001-2004. Use, modification and
// distribution is subject to 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)

// For more information, see http://www.boost.org

#ifndef BOOST_SIGNALS_TRACKABLE_HPP
#define BOOST_SIGNALS_TRACKABLE_HPP

#include <boost/type_traits.hpp>
#include <boost/signals/connection.hpp>
#include <boost/ref.hpp>
#include <boost/utility/addressof.hpp>
#include <list>
#include <vector>

#ifdef BOOST_HAS_ABI_HEADERS
#  include BOOST_ABI_PREFIX
#endif

namespace boost {

namespace BOOST_SIGNALS_NAMESPACE {
  // Base class for "trackable" objects that can be tracked when they are
  // bound in slot target functions. When a trackable object is destroyed,
  // the signal/slot connections are disconnected automatically.
  class BOOST_SIGNALS_DECL trackable {
  private:
    static void signal_disconnected(void* obj, void* data);

    friend class detail::signal_base_impl;
    friend class detail::slot_base;
    void signal_connected(connection, BOOST_SIGNALS_NAMESPACE::detail::bound_object&) const;

  protected:
    trackable() : connected_signals(), dying(false) {}
    trackable(const trackable&) : connected_signals(), dying(false) {}
    ~trackable();

    trackable& operator=(const trackable&)
    {
      dying = true;
      connected_signals.clear();
      dying = false;
      return *this;
    }

  private:
    typedef std::list<connection> connection_list;
    typedef connection_list::iterator connection_iterator;

    // List of connections that this object is part of
    mutable connection_list connected_signals;

    // True when the object is being destroyed
    mutable bool dying;
  };

  namespace detail {
    template<bool Cond> struct truth {};

    // A visitor that adds each trackable object to a vector
    class bound_objects_visitor {
    public:
      bound_objects_visitor(std::vector<const trackable*>& v) :
        bound_objects(v)
      {
      }

      template<typename T>
      void operator()(const T& t) const
      {
        decode(t, 0);
      }

    private:
      // decode() decides between a reference wrapper and anything else
      template<typename T>
      void decode(const reference_wrapper<T>& t, int) const
      {
        add_if_trackable(t.get_pointer());
      }

      template<typename T>
      void decode(const T& t, long) const
      {
        typedef truth<(is_pointer<T>::value)> is_a_pointer;
        maybe_get_pointer(t, is_a_pointer());
      }

      // maybe_get_pointer() decides between a pointer and a non-pointer
      template<typename T>
      void maybe_get_pointer(const T& t, truth<true>) const
      {
        add_if_trackable(t);
      }

      template<typename T>
      void maybe_get_pointer(const T& t, truth<false>) const
      {
        // Take the address of this object, because the object itself may be
        // trackable
        add_if_trackable(boost::addressof(t));
      }

      // add_if_trackable() adds trackable objects to the list of bound objects
      inline void add_if_trackable(const trackable* b) const
      {
        if (b) {
          bound_objects.push_back(b);
        }
      }

      inline void add_if_trackable(const void*) const { }

      template<typename R>
      inline void add_if_trackable(R (*)()) const { }

      template<typename R, typename T1>
      inline void add_if_trackable(R (*)(T1)) const { }

      template<typename R, typename T1, typename T2>
      inline void add_if_trackable(R (*)(T1, T2)) const { }

      template<typename R, typename T1, typename T2, typename T3>
      inline void add_if_trackable(R (*)(T1, T2, T3)) const { }

      template<typename R, typename T1, typename T2, typename T3, typename T4>
      inline void add_if_trackable(R (*)(T1, T2, T3, T4)) const { }

      template<typename R, typename T1, typename T2, typename T3, typename T4,
               typename T5>
      inline void add_if_trackable(R (*)(T1, T2, T3, T4, T5)) const { }

      template<typename R, typename T1, typename T2, typename T3, typename T4,
               typename T5, typename T6>
      inline void add_if_trackable(R (*)(T1, T2, T3, T4, T5, T6)) const { }

      template<typename R, typename T1, typename T2, typename T3, typename T4,
               typename T5, typename T6, typename T7>
      inline void add_if_trackable(R (*)(T1, T2, T3, T4, T5, T6, T7)) const { }

      template<typename R, typename T1, typename T2, typename T3, typename T4,
               typename T5, typename T6, typename T7, typename T8>
      inline void 
      add_if_trackable(R (*)(T1, T2, T3, T4, T5, T6, T7, T8)) const { }

      template<typename R, typename T1, typename T2, typename T3, typename T4,
               typename T5, typename T6, typename T7, typename T8, typename T9>
      inline void
      add_if_trackable(R (*)(T1, T2, T3, T4, T5, T6, T7, T8, T9)) const { }

      template<typename R, typename T1, typename T2, typename T3, typename T4,
               typename T5, typename T6, typename T7, typename T8, typename T9,
               typename T10>
      inline void
      add_if_trackable(R (*)(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)) const { }

      std::vector<const trackable*>& bound_objects;
    };
  } // end namespace detail
} // end namespace BOOST_SIGNALS_NAMESPACE

} // end namespace boost

#ifdef BOOST_HAS_ABI_HEADERS
#  include BOOST_ABI_SUFFIX
#endif

#endif // BOOST_SIGNALS_TRACKABLE_HPP
