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::bidirectional_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*());
194 template<typename Value, typename Allocator = DefaultAllocator<Value> >
195 class List : private Allocator
197 typedef ListDetail::ListNode<Value> Node;
198 ListDetail::ListNodeBase list;
199 typedef typename Allocator::template rebind<Node>::other NodeAllocator;
201 Node* newNode(const Value& value)
203 return new (NodeAllocator(*this).allocate(1)) Node(value);
205 void deleteNode(Node* node)
208 NodeAllocator(*this).deallocate(node, 1);
211 typedef Value value_type;
212 typedef ListDetail::ListIterator< ListDetail::NonConstTraits<Value> > iterator;
213 typedef ListDetail::ListIterator< ListDetail::ConstTraits<Value> > const_iterator;
217 list_initialise(list);
219 explicit List(const Allocator& allocator) : Allocator(allocator)
221 list_initialise(list);
225 for(; list.next != &list;)
227 Node* node = static_cast<Node*>(list.next);
228 list.next = list.next->next;
234 return iterator(static_cast<Node*>(list.next));
238 return iterator(static_cast<Node*>(&list));
240 const_iterator begin() const
242 return const_iterator(static_cast<const Node*>(list.next));
244 const_iterator end() const
246 return const_iterator(static_cast<const Node*>(&list));
248 void push_back(const Value& value)
250 insert(end(), value);
252 void pop_back(const Value& value)
254 erase(--end(), value);
256 void push_front(const Value& value)
258 insert(begin(), value);
260 void pop_front(const Value& value)
262 erase(begin(), value);
264 iterator insert(iterator pos, const Value& value)
266 Node* node = newNode(value);
267 node_link(node, pos.node());
268 return iterator(node);
270 iterator erase(iterator pos)
272 Node* node = pos.node();
273 Node* next = node->getNext();
276 return iterator(next);
280 template<typename Functor>
283 typedef List<Functor> SignalList;
288 typedef Functor handler_type;
289 typedef Handle< Opaque<Functor> > handler_id_type;
290 typedef typename SignalList::iterator iterator;
291 typedef typename SignalList::const_iterator const_iterator;
294 return events.begin();
300 const_iterator begin() const
302 return events.begin();
304 const_iterator end() const
308 handler_id_type connectFirst(const Functor& event)
310 events.push_front(event);
311 return handler_id_type(begin().opaque());
313 handler_id_type connectLast(const Functor& event)
315 events.push_back(event);
316 return handler_id_type((--end()).opaque());
318 bool isConnected(handler_id_type id)
320 for(iterator i = begin(); i != end(); ++i)
322 if(id.get() == i.opaque())
329 handler_id_type connectBefore(handler_id_type id, const Functor& event)
331 ASSERT_MESSAGE(isConnected(id), "SignalBase::connectBefore: invalid id");
332 return events.insert(iterator(id.get()), event).opaque();
334 handler_id_type connectAfter(handler_id_type id, const Functor& event)
336 ASSERT_MESSAGE(isConnected(id), "SignalBase::connectAfter: invalid id");
337 return events.insert(++iterator(id.get()), event).opaque();
339 void disconnect(handler_id_type id)
341 ASSERT_MESSAGE(isConnected(id), "SignalBase::disconnect: invalid id");
342 events.erase(iterator(id.get()));
347 // It is safe to disconnect the signal handler currently being invoked.
348 template<typename InputIterator, typename SignalHandlerInvoke>
349 inline void invokeSignalHandlers(InputIterator first, InputIterator last, SignalHandlerInvoke invoke)
351 while(first != last && invoke(*first++) != SIGNAL_STOP_EMISSION);
354 class Signal0 : public SignalBase<SignalHandler>
357 void operator()() const
359 invokeSignalHandlers(begin(), end(), FunctorInvoke<handler_type>());
363 template<typename FirstArgument>
364 class Signal1 : public SignalBase< SignalHandler1<FirstArgument> >
366 typedef SignalBase< SignalHandler1<FirstArgument> > Base;
368 void operator()(FirstArgument a1) const
370 invokeSignalHandlers(Base::begin(), Base::end(), Functor1Invoke<typename Base::handler_type>(a1));
374 template<typename FirstArgument, typename SecondArgument>
375 class Signal2 : public SignalBase< SignalHandler2<FirstArgument, SecondArgument> >
377 typedef SignalBase< SignalHandler2<FirstArgument, SecondArgument> > Base;
379 void operator()(FirstArgument a1, SecondArgument a2) const
381 invokeSignalHandlers(Base::begin(), Base::end(), Functor2Invoke<typename Base::handler_type>(a1, a2));
385 template<typename FirstArgument, typename SecondArgument, typename ThirdArgument>
386 class Signal3 : public SignalBase< SignalHandler3<FirstArgument, SecondArgument, ThirdArgument> >
388 typedef SignalBase< SignalHandler3<FirstArgument, SecondArgument, ThirdArgument> > Base;
390 void operator()(FirstArgument a1, SecondArgument a2, ThirdArgument a3) const
392 invokeSignalHandlers(Base::begin(), Base::end(), Functor3Invoke<typename Base::handler_type>(a1, a2, a3));