1 // Boost.Signals library
3 // Copyright (C) 2001, 2002 Doug Gregor (gregod@cs.rpi.edu)
5 // Permission to copy, use, sell and distribute this software is granted
6 // provided this copyright notice appears in all copies.
7 // Permission to modify the code and to distribute modified code is granted
8 // provided this copyright notice appears in all copies, and a notice
9 // that the code was modified is included with the copyright notice.
11 // This software is provided "as is" without express or implied warranty,
12 // and with no claim as to its suitability for any purpose.
14 // For more information, see http://www.boost.org
16 #ifndef BOOST_SIGNALS_SIGNAL_BASE_HEADER
17 #define BOOST_SIGNALS_SIGNAL_BASE_HEADER
19 #ifdef BOOST_SIGNALS_IN_LIBRARY_SOURCE
20 # define BOOST_FUNCTION_SILENT_DEPRECATED
23 #include <boost/signals/detail/signals_common.hpp>
24 #include <boost/signals/connection.hpp>
25 #include <boost/signals/trackable.hpp>
26 #include <boost/smart_ptr.hpp>
27 #include <boost/any.hpp>
28 #include <boost/utility.hpp>
29 #include <boost/function/function2.hpp>
35 namespace BOOST_SIGNALS_NAMESPACE {
37 // Forward declaration for the mapping from slot names to connections
40 // This function object bridges from a pair of any objects that hold
41 // values of type Key to the underlying function object that compares
42 // values of type Key.
43 template<typename Compare, typename Key>
44 class any_bridge_compare {
46 typedef bool result_type;
47 typedef const any& first_argument_type;
48 typedef const any& second_argument_type;
50 any_bridge_compare(const Compare& c) : comp(c) {}
52 bool operator()(const any& k1, const any& k2) const
54 // if k1 is empty, then it precedes nothing
58 // if k2 is empty, then k1 must precede it
62 // Neither is empty, so compare their values to order them
63 // The strange */& is so that we will get a reference to the
64 // value stored in the any object instead of a copy
65 return comp(*any_cast<Key>(&k1), *any_cast<Key>(&k2));
72 // Must be constructed before calling the slots, because it safely
74 class BOOST_SIGNALS_DECL call_notification {
76 call_notification(const shared_ptr<signal_base_impl>&);
79 shared_ptr<signal_base_impl> impl;
82 // Implementation of base class for all signals. It handles the
83 // management of the underlying slot lists.
84 class BOOST_SIGNALS_DECL signal_base_impl {
86 friend class call_notification;
88 typedef function2<bool, any, any> compare_type;
90 // Make sure that an exception does not cause the "clearing" flag to
92 class temporarily_set_clearing {
94 temporarily_set_clearing(signal_base_impl* b) : base(b)
96 base->flags.clearing = true;
99 ~temporarily_set_clearing()
101 base->flags.clearing = false;
105 signal_base_impl* base;
108 friend class temporarily_set_clearing;
110 signal_base_impl(const compare_type&);
113 // Disconnect all slots connected to this signal
114 void disconnect_all_slots();
116 // Are there any connected slots?
119 // Disconnect all slots in the given group
120 void disconnect(const any&);
122 // We're being notified that a slot has disconnected
123 static void slot_disconnected(void* obj, void* data);
125 connection connect_slot(const any& slot,
127 const std::vector<const trackable*>&);
130 // Remove all of the slots that have been marked "disconnected"
131 void remove_disconnected_slots() const;
134 // Our call depth when invoking slots (> 1 when we have a loop)
135 mutable int call_depth;
138 // True if some slots have disconnected, but we were not able to
139 // remove them from the list of slots because there are valid
140 // iterators into the slot list
141 mutable bool delayed_disconnect:1;
143 // True if we are disconnecting all disconnected slots
148 typedef std::multimap<any, connection_slot_pair, compare_type>
150 typedef slot_container_type::iterator slot_iterator;
151 typedef slot_container_type::value_type stored_slot_type;
152 mutable slot_container_type slots_;
155 class BOOST_SIGNALS_DECL signal_base : public noncopyable {
157 typedef signal_base_impl::compare_type compare_type;
159 friend class call_notification;
161 signal_base(const compare_type& comp) : impl()
163 impl.reset(new signal_base_impl(comp));
169 // Disconnect all slots connected to this signal
170 void disconnect_all_slots() { impl->disconnect_all_slots(); }
172 // Are there any connected slots?
173 bool empty() const { return impl->empty(); }
176 connection connect_slot(const any& slot,
178 const std::vector<const trackable*>& bound)
180 return impl->connect_slot(slot, name, bound);
183 typedef signal_base_impl::slot_iterator slot_iterator;
184 typedef signal_base_impl::stored_slot_type stored_slot_type;
186 shared_ptr<signal_base_impl> impl;
188 } // end namespace detail
189 } // end namespace BOOST_SIGNALS_NAMESPACE
190 } // end namespace boost
192 #endif // BOOST_SIGNALS_SIGNAL_BASE_HEADER