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*());
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 typedef Value value_type;
202 typedef ListDetail::ListIterator< ListDetail::NonConstTraits<Value> > iterator;
203 typedef ListDetail::ListIterator< ListDetail::ConstTraits<Value> > const_iterator;
207 list_initialise(list);
209 explicit List(const Allocator& allocator) : Allocator(allocator)
211 list_initialise(list);
215 return iterator(static_cast<Node*>(list.next));
219 return iterator(static_cast<Node*>(&list));
221 const_iterator begin() const
223 return const_iterator(static_cast<const Node*>(list.next));
225 const_iterator end() const
227 return const_iterator(static_cast<const Node*>(&list));
229 void push_back(const Value& value)
231 insert(end(), value);
233 void pop_back(const Value& value)
235 erase(--end(), value);
237 void push_front(const Value& value)
239 insert(begin(), value);
241 void pop_front(const Value& value)
243 erase(begin(), value);
245 iterator insert(iterator pos, const Value& x)
247 Node* node = new (NodeAllocator(*this).allocate(1)) Node(x);
248 node_link(node, pos.node());
249 return iterator(node);
251 iterator erase(iterator pos)
253 Node* node = pos.node();
254 Node* next = node->getNext();
257 NodeAllocator(*this).deallocate(node, 1);
258 return iterator(next);
262 template<typename Functor>
265 typedef List<Functor> SignalList;
270 typedef Functor handler_type;
271 typedef Handle< Opaque<Functor> > handler_id_type;
272 typedef typename SignalList::iterator iterator;
273 typedef typename SignalList::const_iterator const_iterator;
276 return events.begin();
282 const_iterator begin() const
284 return events.begin();
286 const_iterator end() const
290 handler_id_type connectFirst(const Functor& event)
292 events.push_front(event);
293 return handler_id_type(begin().opaque());
295 handler_id_type connectLast(const Functor& event)
297 events.push_back(event);
298 return handler_id_type((--end()).opaque());
300 bool isConnected(handler_id_type id)
302 for(iterator i = begin(); i != end(); ++i)
304 if(id.get() == i.opaque())
311 handler_id_type connectBefore(handler_id_type id, const Functor& event)
313 ASSERT_MESSAGE(isConnected(id), "SignalBase::connectBefore: invalid id");
314 return events.insert(iterator(id.get()), event).opaque();
316 handler_id_type connectAfter(handler_id_type id, const Functor& event)
318 ASSERT_MESSAGE(isConnected(id), "SignalBase::connectAfter: invalid id");
319 return events.insert(++iterator(id.get()), event).opaque();
321 void disconnect(handler_id_type id)
323 ASSERT_MESSAGE(isConnected(id), "SignalBase::disconnect: invalid id");
324 events.erase(iterator(id.get()));
329 // It is safe to disconnect the signal handler currently being invoked.
330 template<typename InputIterator, typename SignalHandlerInvoke>
331 inline void invokeSignalHandlers(InputIterator first, InputIterator last, SignalHandlerInvoke invoke)
333 while(first != last && invoke(*first++) != SIGNAL_STOP_EMISSION);
336 class Signal0 : public SignalBase<SignalHandler>
339 void operator()() const
341 invokeSignalHandlers(begin(), end(), FunctorInvoke<handler_type>());
345 template<typename FirstArgument>
346 class Signal1 : public SignalBase< SignalHandler1<FirstArgument> >
348 typedef SignalBase< SignalHandler1<FirstArgument> > Base;
350 void operator()(FirstArgument a1) const
352 invokeSignalHandlers(Base::begin(), Base::end(), Functor1Invoke<typename Base::handler_type>(a1));
356 template<typename FirstArgument, typename SecondArgument>
357 class Signal2 : public SignalBase< SignalHandler2<FirstArgument, SecondArgument> >
359 typedef SignalBase< SignalHandler2<FirstArgument, SecondArgument> > Base;
361 void operator()(FirstArgument a1, SecondArgument a2) const
363 invokeSignalHandlers(Base::begin(), Base::end(), Functor2Invoke<typename Base::handler_type>(a1, a2));
367 template<typename FirstArgument, typename SecondArgument, typename ThirdArgument>
368 class Signal3 : public SignalBase< SignalHandler3<FirstArgument, SecondArgument, ThirdArgument> >
370 typedef SignalBase< SignalHandler3<FirstArgument, SecondArgument, ThirdArgument> > Base;
372 void operator()(FirstArgument a1, SecondArgument a2, ThirdArgument a3) const
374 invokeSignalHandlers(Base::begin(), Base::end(), Functor3Invoke<typename Base::handler_type>(a1, a2, a3));