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