2 #if !defined(INCLUDED_SIGNAL_H)
3 #define INCLUDED_SIGNAL_H
6 #include "memory/allocator.h"
7 #include "debugging/debugging.h"
18 inline void list_initialise(ListNodeBase& self)
20 self.next = self.prev = &self;
23 inline void list_swap(ListNodeBase& self, ListNodeBase& other)
25 ListNodeBase tmp(self);
26 if(other.next == &other)
28 list_initialise(self);
33 self.next->prev = self.prev->next = &self;
37 list_initialise(other);
42 other.next->prev = other.prev->next = &other;
46 inline void node_link(ListNodeBase* node, ListNodeBase* next)
49 node->prev = next->prev;
51 node->prev->next = node;
53 inline void node_unlink(ListNodeBase* node)
55 node->prev->next = node->next;
56 node->next->prev = node->prev;
59 template<typename Value>
60 struct ListNode : public ListNodeBase
64 ListNode(const Value& value) : value(value)
67 ListNode* getNext() const
69 return static_cast<ListNode*>(next);
71 ListNode* getPrev() const
73 return static_cast<ListNode*>(prev);
77 template<typename Type>
81 typedef Type value_type;
82 typedef value_type* pointer;
83 typedef value_type& reference;
85 template<typename Other>
88 typedef NonConstTraits<Other> other;
92 template<typename Type>
96 typedef Type value_type;
97 typedef const value_type* pointer;
98 typedef const value_type& reference;
100 template<typename Other>
103 typedef ConstTraits<Other> other;
107 template<typename Traits>
111 typedef std::forward_iterator_tag iterator_category;
112 typedef std::ptrdiff_t difference_type;
113 typedef difference_type distance_type;
114 typedef typename Traits::value_type value_type;
115 typedef typename Traits::pointer pointer;
116 typedef typename Traits::reference reference;
119 typedef ListNode<value_type> Node;
120 typedef typename Traits::template rebind<Node>::other NodeTraits;
121 typedef typename NodeTraits::pointer NodePointer;
122 typedef typename Traits::template rebind< Opaque<value_type> >::other OpaqueTraits;
123 typedef typename OpaqueTraits::pointer OpaquePointer;
128 m_node = m_node->getNext();
132 m_node = m_node->getPrev();
137 explicit ListIterator(NodePointer node) : m_node(node)
140 explicit ListIterator(OpaquePointer p) : m_node(reinterpret_cast<NodePointer>(p))
148 OpaquePointer opaque() const
150 return reinterpret_cast<OpaquePointer>(m_node);
153 bool operator==(const ListIterator& other) const
155 return m_node == other.m_node;
157 bool operator!=(const ListIterator& other) const
159 return !operator==(other);
161 ListIterator& operator++()
166 ListIterator operator++(int)
168 ListIterator tmp = *this;
172 ListIterator& operator--()
177 ListIterator operator--(int)
179 ListIterator tmp = *this;
183 reference operator*() const
185 return m_node->value;
187 pointer operator->() const
189 return &(operator*());
196 template<typename Value, typename Allocator = DefaultAllocator<Value> >
197 class List : private Allocator
199 typedef ListDetail::ListNode<Value> Node;
200 ListDetail::ListNodeBase list;
201 typedef typename Allocator::template rebind<Node>::other NodeAllocator;
203 typedef Value value_type;
204 typedef ListDetail::ListIterator< ListDetail::NonConstTraits<Value> > iterator;
205 typedef ListDetail::ListIterator< ListDetail::ConstTraits<Value> > const_iterator;
209 list_initialise(list);
211 explicit List(const Allocator& allocator) : Allocator(allocator)
213 list_initialise(list);
217 return iterator(static_cast<Node*>(list.next));
221 return iterator(static_cast<Node*>(&list));
223 const_iterator begin() const
225 return const_iterator(static_cast<const Node*>(list.next));
227 const_iterator end() const
229 return const_iterator(static_cast<const Node*>(&list));
231 void push_back(const Value& value)
233 insert(end(), value);
235 void pop_back(const Value& value)
237 erase(--end(), value);
239 void push_front(const Value& value)
241 insert(begin(), value);
243 void pop_front(const Value& value)
245 erase(begin(), value);
247 iterator insert(iterator pos, const Value& x)
249 Node* node = new (NodeAllocator(*this).allocate(1)) Node(x);
250 node_link(node, pos.node());
251 return iterator(node);
253 iterator erase(iterator pos)
255 Node* node = pos.node();
256 Node* next = node->getNext();
259 NodeAllocator(*this).deallocate(node, 1);
260 return iterator(next);
264 template<typename Functor>
267 typedef List<Functor> SignalList;
272 typedef Functor handler_type;
273 typedef Handle< Opaque<Functor> > handler_id_type;
274 typedef typename SignalList::iterator iterator;
275 typedef typename SignalList::const_iterator const_iterator;
278 return events.begin();
284 const_iterator begin() const
286 return events.begin();
288 const_iterator end() const
292 handler_id_type connectFirst(const Functor& event)
294 events.push_front(event);
295 return handler_id_type(begin().opaque());
297 handler_id_type connectLast(const Functor& event)
299 events.push_back(event);
300 return handler_id_type((--end()).opaque());
302 bool isConnected(handler_id_type id)
304 for(iterator i = begin(); i != end(); ++i)
306 if(id.get() == i.opaque())
313 handler_id_type connectBefore(handler_id_type id, const Functor& event)
315 ASSERT_MESSAGE(isConnected(id), "SignalBase::connectBefore: invalid id");
316 return events.insert(iterator(id.get()), event).opaque();
318 handler_id_type connectAfter(handler_id_type id, const Functor& event)
320 ASSERT_MESSAGE(isConnected(id), "SignalBase::connectAfter: invalid id");
321 return events.insert(++iterator(id.get()), event).opaque();
323 void disconnect(handler_id_type id)
325 ASSERT_MESSAGE(isConnected(id), "SignalBase::disconnect: invalid id");
326 events.erase(iterator(id.get()));
331 // It is safe to disconnect the signal handler currently being invoked.
332 template<typename InputIterator, typename SignalHandlerInvoke>
333 inline void invokeSignalHandlers(InputIterator first, InputIterator last, SignalHandlerInvoke invoke)
335 while(first != last && invoke(*first++) != SIGNAL_STOP_EMISSION);
338 class Signal0 : public SignalBase<SignalHandler>
341 void operator()() const
343 invokeSignalHandlers(begin(), end(), FunctorInvoke<typename handler_type>());
347 template<typename FirstArgument>
348 class Signal1 : public SignalBase< SignalHandler1<FirstArgument> >
351 void operator()(FirstArgument a1) const
353 invokeSignalHandlers(begin(), end(), Functor1Invoke<typename handler_type>(a1));
357 template<typename FirstArgument, typename SecondArgument>
358 class Signal2 : public SignalBase< SignalHandler2<FirstArgument, SecondArgument> >
361 void operator()(FirstArgument a1, SecondArgument a2) const
363 invokeSignalHandlers(begin(), end(), Functor2Invoke<typename handler_type>(a1, a2));
367 template<typename FirstArgument, typename SecondArgument, typename ThirdArgument>
368 class Signal3 : public SignalBase< SignalHandler3<FirstArgument, SecondArgument, ThirdArgument> >
371 void operator()(FirstArgument a1, SecondArgument a2, ThirdArgument a3) const
373 invokeSignalHandlers(begin(), end(), Functor3Invoke<typename handler_type>(a1, a2, a3));