os/ossrv/ossrv_pub/boost_apis/boost/signals/trackable.hpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Boost.Signals library
sl@0
     2
sl@0
     3
// Copyright Douglas Gregor 2001-2004. Use, modification and
sl@0
     4
// distribution is subject to the Boost Software License, Version
sl@0
     5
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
sl@0
     6
// http://www.boost.org/LICENSE_1_0.txt)
sl@0
     7
sl@0
     8
// For more information, see http://www.boost.org
sl@0
     9
sl@0
    10
#ifndef BOOST_SIGNALS_TRACKABLE_HPP
sl@0
    11
#define BOOST_SIGNALS_TRACKABLE_HPP
sl@0
    12
sl@0
    13
#include <boost/type_traits.hpp>
sl@0
    14
#include <boost/signals/connection.hpp>
sl@0
    15
#include <boost/pending/ct_if.hpp>
sl@0
    16
#include <boost/ref.hpp>
sl@0
    17
#include <boost/utility/addressof.hpp>
sl@0
    18
#include <list>
sl@0
    19
#include <vector>
sl@0
    20
sl@0
    21
#ifdef BOOST_HAS_ABI_HEADERS
sl@0
    22
#  include BOOST_ABI_PREFIX
sl@0
    23
#endif
sl@0
    24
sl@0
    25
namespace boost {
sl@0
    26
sl@0
    27
namespace BOOST_SIGNALS_NAMESPACE {
sl@0
    28
  // Base class for "trackable" objects that can be tracked when they are
sl@0
    29
  // bound in slot target functions. When a trackable object is destroyed,
sl@0
    30
  // the signal/slot connections are disconnected automatically.
sl@0
    31
  class BOOST_SIGNALS_DECL trackable {
sl@0
    32
  private:
sl@0
    33
    static void signal_disconnected(void* obj, void* data);
sl@0
    34
sl@0
    35
    friend class detail::signal_base_impl;
sl@0
    36
    friend class detail::slot_base;
sl@0
    37
    void signal_connected(connection, BOOST_SIGNALS_NAMESPACE::detail::bound_object&) const;
sl@0
    38
sl@0
    39
  protected:
sl@0
    40
    trackable() : connected_signals(), dying(false) {}
sl@0
    41
    trackable(const trackable&) : connected_signals(), dying(false) {}
sl@0
    42
    ~trackable();
sl@0
    43
sl@0
    44
    trackable& operator=(const trackable&)
sl@0
    45
    {
sl@0
    46
      connected_signals.clear();
sl@0
    47
      return *this;
sl@0
    48
    }
sl@0
    49
sl@0
    50
  private:
sl@0
    51
    typedef std::list<connection> connection_list;
sl@0
    52
    typedef connection_list::iterator connection_iterator;
sl@0
    53
sl@0
    54
    // List of connections that this object is part of
sl@0
    55
    mutable connection_list connected_signals;
sl@0
    56
sl@0
    57
    // True when the object is being destroyed
sl@0
    58
    mutable bool dying;
sl@0
    59
  };
sl@0
    60
sl@0
    61
  namespace detail {
sl@0
    62
    template<bool Cond> struct truth {};
sl@0
    63
sl@0
    64
    // A visitor that adds each trackable object to a vector
sl@0
    65
    class bound_objects_visitor {
sl@0
    66
    public:
sl@0
    67
      bound_objects_visitor(std::vector<const trackable*>& v) :
sl@0
    68
        bound_objects(v)
sl@0
    69
      {
sl@0
    70
      }
sl@0
    71
sl@0
    72
      template<typename T>
sl@0
    73
      void operator()(const T& t) const
sl@0
    74
      {
sl@0
    75
        decode(t, 0);
sl@0
    76
      }
sl@0
    77
sl@0
    78
    private:
sl@0
    79
      // decode() decides between a reference wrapper and anything else
sl@0
    80
      template<typename T>
sl@0
    81
      void decode(const reference_wrapper<T>& t, int) const
sl@0
    82
      {
sl@0
    83
        add_if_trackable(t.get_pointer());
sl@0
    84
      }
sl@0
    85
sl@0
    86
      template<typename T>
sl@0
    87
      void decode(const T& t, long) const
sl@0
    88
      {
sl@0
    89
        typedef truth<(is_pointer<T>::value)> is_a_pointer;
sl@0
    90
        maybe_get_pointer(t, is_a_pointer());
sl@0
    91
      }
sl@0
    92
sl@0
    93
      // maybe_get_pointer() decides between a pointer and a non-pointer
sl@0
    94
      template<typename T>
sl@0
    95
      void maybe_get_pointer(const T& t, truth<true>) const
sl@0
    96
      {
sl@0
    97
        add_if_trackable(t);
sl@0
    98
      }
sl@0
    99
sl@0
   100
      template<typename T>
sl@0
   101
      void maybe_get_pointer(const T& t, truth<false>) const
sl@0
   102
      {
sl@0
   103
        // Take the address of this object, because the object itself may be
sl@0
   104
        // trackable
sl@0
   105
        add_if_trackable(boost::addressof(t));
sl@0
   106
      }
sl@0
   107
sl@0
   108
      // add_if_trackable() adds trackable objects to the list of bound objects
sl@0
   109
      inline void add_if_trackable(const trackable* b) const
sl@0
   110
      {
sl@0
   111
        if (b) {
sl@0
   112
          bound_objects.push_back(b);
sl@0
   113
        }
sl@0
   114
      }
sl@0
   115
sl@0
   116
      inline void add_if_trackable(const void*) const
sl@0
   117
      {
sl@0
   118
      }
sl@0
   119
sl@0
   120
      template<typename R>
sl@0
   121
      inline void add_if_trackable(R (*)()) const
sl@0
   122
      {
sl@0
   123
      }
sl@0
   124
sl@0
   125
      template<typename R, typename T1>
sl@0
   126
      inline void add_if_trackable(R (*)(T1)) const
sl@0
   127
      {
sl@0
   128
      }
sl@0
   129
sl@0
   130
      template<typename R, typename T1, typename T2>
sl@0
   131
      inline void add_if_trackable(R (*)(T1, T2)) const
sl@0
   132
      {
sl@0
   133
      }
sl@0
   134
sl@0
   135
      template<typename R, typename T1, typename T2, typename T3>
sl@0
   136
      inline void add_if_trackable(R (*)(T1, T2, T3)) const
sl@0
   137
      {
sl@0
   138
      }
sl@0
   139
sl@0
   140
      template<typename R, typename T1, typename T2, typename T3, typename T4>
sl@0
   141
      inline void add_if_trackable(R (*)(T1, T2, T3, T4)) const
sl@0
   142
      {
sl@0
   143
      }
sl@0
   144
sl@0
   145
      template<typename R, typename T1, typename T2, typename T3, typename T4,
sl@0
   146
               typename T5>
sl@0
   147
      inline void add_if_trackable(R (*)(T1, T2, T3, T4, T5)) const
sl@0
   148
      {
sl@0
   149
      }
sl@0
   150
sl@0
   151
      template<typename R, typename T1, typename T2, typename T3, typename T4,
sl@0
   152
               typename T5, typename T6>
sl@0
   153
      inline void add_if_trackable(R (*)(T1, T2, T3, T4, T5, T6)) const
sl@0
   154
      {
sl@0
   155
      }
sl@0
   156
sl@0
   157
      template<typename R, typename T1, typename T2, typename T3, typename T4,
sl@0
   158
               typename T5, typename T6, typename T7>
sl@0
   159
      inline void add_if_trackable(R (*)(T1, T2, T3, T4, T5, T6, T7)) const
sl@0
   160
      {
sl@0
   161
      }
sl@0
   162
sl@0
   163
      template<typename R, typename T1, typename T2, typename T3, typename T4,
sl@0
   164
               typename T5, typename T6, typename T7, typename T8>
sl@0
   165
      inline void add_if_trackable(R (*)(T1, T2, T3, T4, T5, T6, T7, T8)) const
sl@0
   166
      {
sl@0
   167
      }
sl@0
   168
sl@0
   169
      template<typename R, typename T1, typename T2, typename T3, typename T4,
sl@0
   170
               typename T5, typename T6, typename T7, typename T8, typename T9>
sl@0
   171
      inline void
sl@0
   172
      add_if_trackable(R (*)(T1, T2, T3, T4, T5, T6, T7, T8, T9)) const
sl@0
   173
      {
sl@0
   174
      }
sl@0
   175
sl@0
   176
      template<typename R, typename T1, typename T2, typename T3, typename T4,
sl@0
   177
               typename T5, typename T6, typename T7, typename T8, typename T9,
sl@0
   178
               typename T10>
sl@0
   179
      inline void
sl@0
   180
      add_if_trackable(R (*)(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)) const
sl@0
   181
      {
sl@0
   182
      }
sl@0
   183
sl@0
   184
      std::vector<const trackable*>& bound_objects;
sl@0
   185
    };
sl@0
   186
  } // end namespace detail
sl@0
   187
} // end namespace BOOST_SIGNALS_NAMESPACE
sl@0
   188
sl@0
   189
} // end namespace boost
sl@0
   190
sl@0
   191
#ifdef BOOST_HAS_ABI_HEADERS
sl@0
   192
#  include BOOST_ABI_SUFFIX
sl@0
   193
#endif
sl@0
   194
sl@0
   195
#endif // BOOST_SIGNALS_TRACKABLE_HPP