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 ){
19 self.next = self.prev = &self;
22 inline void list_swap( ListNodeBase& self, ListNodeBase& other ){
23 ListNodeBase tmp( self );
24 if ( other.next == &other ) {
25 list_initialise( self );
30 self.next->prev = self.prev->next = &self;
32 if ( tmp.next == &self ) {
33 list_initialise( other );
38 other.next->prev = other.prev->next = &other;
42 inline void node_link( ListNodeBase* node, ListNodeBase* next ){
44 node->prev = next->prev;
46 node->prev->next = node;
48 inline void node_unlink( ListNodeBase* node ){
49 node->prev->next = node->next;
50 node->next->prev = node->prev;
53 template<typename Value>
54 struct ListNode : public ListNodeBase
58 ListNode( const Value& value ) : value( value ){
60 ListNode* getNext() const {
61 return static_cast<ListNode*>( next );
63 ListNode* getPrev() const {
64 return static_cast<ListNode*>( prev );
68 template<typename Type>
72 typedef Type value_type;
73 typedef value_type* pointer;
74 typedef value_type& reference;
76 template<typename Other>
79 typedef NonConstTraits<Other> other;
83 template<typename Type>
87 typedef Type value_type;
88 typedef const value_type* pointer;
89 typedef const value_type& reference;
91 template<typename Other>
94 typedef ConstTraits<Other> other;
98 template<typename Traits>
102 typedef std::bidirectional_iterator_tag iterator_category;
103 typedef std::ptrdiff_t difference_type;
104 typedef difference_type distance_type;
105 typedef typename Traits::value_type value_type;
106 typedef typename Traits::pointer pointer;
107 typedef typename Traits::reference reference;
110 typedef ListNode<value_type> Node;
111 typedef typename Traits::template rebind<Node>::other NodeTraits;
112 typedef typename NodeTraits::pointer NodePointer;
113 typedef typename Traits::template rebind< Opaque<value_type> >::other OpaqueTraits;
114 typedef typename OpaqueTraits::pointer OpaquePointer;
118 m_node = m_node->getNext();
121 m_node = m_node->getPrev();
126 explicit ListIterator( NodePointer node ) : m_node( node ){
128 explicit ListIterator( OpaquePointer p ) : m_node( reinterpret_cast<NodePointer>( p ) ){
134 OpaquePointer opaque() const {
135 return reinterpret_cast<OpaquePointer>( m_node );
138 bool operator==( const ListIterator& other ) const {
139 return m_node == other.m_node;
141 bool operator!=( const ListIterator& other ) const {
142 return !operator==( other );
144 ListIterator& operator++(){
148 ListIterator operator++( int ){
149 ListIterator tmp = *this;
153 ListIterator& operator--(){
157 ListIterator operator--( int ){
158 ListIterator tmp = *this;
162 reference operator*() const {
163 return m_node->value;
165 pointer operator->() const {
166 return &( operator*() );
171 template<typename Value, typename Allocator = DefaultAllocator<Value> >
172 class List : private Allocator
174 typedef ListDetail::ListNode<Value> Node;
175 ListDetail::ListNodeBase list;
176 typedef typename Allocator::template rebind<Node>::other NodeAllocator;
178 Node* newNode( const Value& value ){
179 return new ( NodeAllocator( *this ).allocate( 1 ) )Node( value );
181 void deleteNode( Node* node ){
183 NodeAllocator( *this ).deallocate( node, 1 );
186 typedef Value value_type;
187 typedef ListDetail::ListIterator< ListDetail::NonConstTraits<Value> > iterator;
188 typedef ListDetail::ListIterator< ListDetail::ConstTraits<Value> > const_iterator;
191 list_initialise( list );
193 explicit List( const Allocator& allocator ) : Allocator( allocator ){
194 list_initialise( list );
197 for (; list.next != &list; )
199 Node* node = static_cast<Node*>( list.next );
200 list.next = list.next->next;
205 return iterator( static_cast<Node*>( list.next ) );
208 return iterator( static_cast<Node*>( &list ) );
210 const_iterator begin() const {
211 return const_iterator( static_cast<const Node*>( list.next ) );
213 const_iterator end() const {
214 return const_iterator( static_cast<const Node*>( &list ) );
216 void push_back( const Value& value ){
217 insert( end(), value );
219 void pop_back( const Value& value ){
220 erase( --end(), value );
222 void push_front( const Value& value ){
223 insert( begin(), value );
225 void pop_front( const Value& value ){
226 erase( begin(), value );
228 iterator insert( iterator pos, const Value& value ){
229 Node* node = newNode( value );
230 node_link( node, pos.node() );
231 return iterator( node );
233 iterator erase( iterator pos ){
234 Node* node = pos.node();
235 Node* next = node->getNext();
238 return iterator( next );
242 template<typename Functor>
245 typedef List<Functor> SignalList;
250 typedef Functor handler_type;
251 typedef Handle< Opaque<Functor> > handler_id_type;
252 typedef typename SignalList::iterator iterator;
253 typedef typename SignalList::const_iterator const_iterator;
255 return events.begin();
260 const_iterator begin() const {
261 return events.begin();
263 const_iterator end() const {
266 handler_id_type connectFirst( const Functor& event ){
267 events.push_front( event );
268 return handler_id_type( begin().opaque() );
270 handler_id_type connectLast( const Functor& event ){
271 events.push_back( event );
272 return handler_id_type( ( --end() ).opaque() );
274 bool isConnected( handler_id_type id ){
275 for ( iterator i = begin(); i != end(); ++i )
277 if ( id.get() == i.opaque() ) {
283 handler_id_type connectBefore( handler_id_type id, const Functor& event ){
284 ASSERT_MESSAGE( isConnected( id ), "SignalBase::connectBefore: invalid id" );
285 return events.insert( iterator( id.get() ), event ).opaque();
287 handler_id_type connectAfter( handler_id_type id, const Functor& event ){
288 ASSERT_MESSAGE( isConnected( id ), "SignalBase::connectAfter: invalid id" );
289 return events.insert( ++iterator( id.get() ), event ).opaque();
291 void disconnect( handler_id_type id ){
292 ASSERT_MESSAGE( isConnected( id ), "SignalBase::disconnect: invalid id" );
293 events.erase( iterator( id.get() ) );
298 // It is safe to disconnect the signal handler currently being invoked.
299 template<typename InputIterator, typename SignalHandlerInvoke>
300 inline void invokeSignalHandlers( InputIterator first, InputIterator last, SignalHandlerInvoke invoke ){
301 while ( first != last && invoke( *first++ ) != SIGNAL_STOP_EMISSION ) ;
304 class Signal0 : public SignalBase<SignalHandler>
307 void operator()() const {
308 invokeSignalHandlers( begin(), end(), FunctorInvoke<handler_type>() );
312 template<typename FirstArgument>
313 class Signal1 : public SignalBase< SignalHandler1<FirstArgument> >
315 typedef SignalBase< SignalHandler1<FirstArgument> > Base;
317 void operator()( FirstArgument a1 ) const {
318 invokeSignalHandlers( Base::begin(), Base::end(), FunctorInvoke<typename Base::handler_type>( a1 ) );
322 template<typename FirstArgument, typename SecondArgument>
323 class Signal2 : public SignalBase< SignalHandler2<FirstArgument, SecondArgument> >
325 typedef SignalBase< SignalHandler2<FirstArgument, SecondArgument> > Base;
327 void operator()( FirstArgument a1, SecondArgument a2 ) const {
328 invokeSignalHandlers( Base::begin(), Base::end(), FunctorInvoke<typename Base::handler_type>( a1, a2 ) );
332 template<typename FirstArgument, typename SecondArgument, typename ThirdArgument>
333 class Signal3 : public SignalBase< SignalHandler3<FirstArgument, SecondArgument, ThirdArgument> >
335 typedef SignalBase< SignalHandler3<FirstArgument, SecondArgument, ThirdArgument> > Base;
337 void operator()( FirstArgument a1, SecondArgument a2, ThirdArgument a3 ) const {
338 invokeSignalHandlers( Base::begin(), Base::end(), FunctorInvoke<typename Base::handler_type>( a1, a2, a3 ) );