1
2 #if !defined( INCLUDED_SIGNAL_H )
3 #define INCLUDED_SIGNAL_H
4
5 #include "isignal.h"
6 #include "memory/allocator.h"
7 #include "debugging/debugging.h"
8 #include <iterator>
9
10 namespace ListDetail
11 {
12 struct ListNodeBase
13 {
14 ListNodeBase* next;
15 ListNodeBase* prev;
16 };
17
list_initialise(ListNodeBase & self)18 inline void list_initialise( ListNodeBase& self ){
19 self.next = self.prev = &self;
20 }
21
list_swap(ListNodeBase & self,ListNodeBase & other)22 inline void list_swap( ListNodeBase& self, ListNodeBase& other ){
23 ListNodeBase tmp( self );
24 if ( other.next == &other ) {
25 list_initialise( self );
26 }
27 else
28 {
29 self = other;
30 self.next->prev = self.prev->next = &self;
31 }
32 if ( tmp.next == &self ) {
33 list_initialise( other );
34 }
35 else
36 {
37 other = tmp;
38 other.next->prev = other.prev->next = &other;
39 }
40 }
41
node_link(ListNodeBase * node,ListNodeBase * next)42 inline void node_link( ListNodeBase* node, ListNodeBase* next ){
43 node->next = next;
44 node->prev = next->prev;
45 next->prev = node;
46 node->prev->next = node;
47 }
node_unlink(ListNodeBase * node)48 inline void node_unlink( ListNodeBase* node ){
49 node->prev->next = node->next;
50 node->next->prev = node->prev;
51 }
52
53 template<typename Value>
54 struct ListNode : public ListNodeBase
55 {
56 Value value;
57
ListNodeListNode58 ListNode( const Value& value ) : value( value ){
59 }
getNextListNode60 ListNode* getNext() const {
61 return static_cast<ListNode*>( next );
62 }
getPrevListNode63 ListNode* getPrev() const {
64 return static_cast<ListNode*>( prev );
65 }
66 };
67
68 template<typename Type>
69 class NonConstTraits
70 {
71 public:
72 typedef Type value_type;
73 typedef value_type* pointer;
74 typedef value_type& reference;
75
76 template<typename Other>
77 struct rebind
78 {
79 typedef NonConstTraits<Other> other;
80 };
81 };
82
83 template<typename Type>
84 class ConstTraits
85 {
86 public:
87 typedef Type value_type;
88 typedef const value_type* pointer;
89 typedef const value_type& reference;
90
91 template<typename Other>
92 struct rebind
93 {
94 typedef ConstTraits<Other> other;
95 };
96 };
97
98 template<typename Traits>
99 class ListIterator
100 {
101 public:
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;
108
109 private:
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;
115 NodePointer m_node;
116
increment()117 void increment(){
118 m_node = m_node->getNext();
119 }
decrement()120 void decrement(){
121 m_node = m_node->getPrev();
122 }
123
124
125 public:
ListIterator(NodePointer node)126 explicit ListIterator( NodePointer node ) : m_node( node ){
127 }
ListIterator(OpaquePointer p)128 explicit ListIterator( OpaquePointer p ) : m_node( reinterpret_cast<NodePointer>( p ) ){
129 }
130
node()131 NodePointer node(){
132 return m_node;
133 }
opaque()134 OpaquePointer opaque() const {
135 return reinterpret_cast<OpaquePointer>( m_node );
136 }
137
138 bool operator==( const ListIterator& other ) const {
139 return m_node == other.m_node;
140 }
141 bool operator!=( const ListIterator& other ) const {
142 return !operator==( other );
143 }
144 ListIterator& operator++(){
145 increment();
146 return *this;
147 }
148 ListIterator operator++( int ){
149 ListIterator tmp = *this;
150 increment();
151 return tmp;
152 }
153 ListIterator& operator--(){
154 decrement();
155 return *this;
156 }
157 ListIterator operator--( int ){
158 ListIterator tmp = *this;
159 decrement();
160 return tmp;
161 }
162 reference operator*() const {
163 return m_node->value;
164 }
165 pointer operator->() const {
166 return &( operator*() );
167 }
168 };
169 }
170
171 template<typename Value, typename Allocator = DefaultAllocator<Value> >
172 class List : private Allocator
173 {
174 typedef ListDetail::ListNode<Value> Node;
175 ListDetail::ListNodeBase list;
176 typedef typename Allocator::template rebind<Node>::other NodeAllocator;
177
newNode(const Value & value)178 Node* newNode( const Value& value ){
179 return new ( NodeAllocator( *this ).allocate( 1 ) )Node( value );
180 }
deleteNode(Node * node)181 void deleteNode( Node* node ){
182 node->~Node();
183 NodeAllocator( *this ).deallocate( node, 1 );
184 }
185 public:
186 typedef Value value_type;
187 typedef ListDetail::ListIterator< ListDetail::NonConstTraits<Value> > iterator;
188 typedef ListDetail::ListIterator< ListDetail::ConstTraits<Value> > const_iterator;
189
List()190 List(){
191 list_initialise( list );
192 }
List(const Allocator & allocator)193 explicit List( const Allocator& allocator ) : Allocator( allocator ){
194 list_initialise( list );
195 }
~List()196 ~List(){
197 for (; list.next != &list; )
198 {
199 Node* node = static_cast<Node*>( list.next );
200 list.next = list.next->next;
201 deleteNode( node );
202 }
203 }
begin()204 iterator begin(){
205 return iterator( static_cast<Node*>( list.next ) );
206 }
end()207 iterator end(){
208 return iterator( static_cast<Node*>( &list ) );
209 }
begin()210 const_iterator begin() const {
211 return const_iterator( static_cast<const Node*>( list.next ) );
212 }
end()213 const_iterator end() const {
214 return const_iterator( static_cast<const Node*>( &list ) );
215 }
push_back(const Value & value)216 void push_back( const Value& value ){
217 insert( end(), value );
218 }
pop_back(const Value & value)219 void pop_back( const Value& value ){
220 erase( --end(), value );
221 }
push_front(const Value & value)222 void push_front( const Value& value ){
223 insert( begin(), value );
224 }
pop_front(const Value & value)225 void pop_front( const Value& value ){
226 erase( begin(), value );
227 }
insert(iterator pos,const Value & value)228 iterator insert( iterator pos, const Value& value ){
229 Node* node = newNode( value );
230 node_link( node, pos.node() );
231 return iterator( node );
232 }
erase(iterator pos)233 iterator erase( iterator pos ){
234 Node* node = pos.node();
235 Node* next = node->getNext();
236 node_unlink( node );
237 deleteNode( node );
238 return iterator( next );
239 }
240 };
241
242 template<typename Functor>
243 class SignalBase
244 {
245 typedef List<Functor> SignalList;
246 SignalList events;
247
248 public:
249
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;
begin()254 iterator begin(){
255 return events.begin();
256 }
end()257 iterator end(){
258 return events.end();
259 }
begin()260 const_iterator begin() const {
261 return events.begin();
262 }
end()263 const_iterator end() const {
264 return events.end();
265 }
connectFirst(const Functor & event)266 handler_id_type connectFirst( const Functor& event ){
267 events.push_front( event );
268 return handler_id_type( begin().opaque() );
269 }
connectLast(const Functor & event)270 handler_id_type connectLast( const Functor& event ){
271 events.push_back( event );
272 return handler_id_type( ( --end() ).opaque() );
273 }
isConnected(handler_id_type id)274 bool isConnected( handler_id_type id ){
275 for ( iterator i = begin(); i != end(); ++i )
276 {
277 if ( id.get() == i.opaque() ) {
278 return true;
279 }
280 }
281 return false;
282 }
connectBefore(handler_id_type id,const Functor & event)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();
286 }
connectAfter(handler_id_type id,const Functor & event)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();
290 }
disconnect(handler_id_type id)291 void disconnect( handler_id_type id ){
292 ASSERT_MESSAGE( isConnected( id ), "SignalBase::disconnect: invalid id" );
293 events.erase( iterator( id.get() ) );
294 }
295 };
296
297 ///\brief
298 // It is safe to disconnect the signal handler currently being invoked.
299 template<typename InputIterator, typename SignalHandlerInvoke>
invokeSignalHandlers(InputIterator first,InputIterator last,SignalHandlerInvoke invoke)300 inline void invokeSignalHandlers( InputIterator first, InputIterator last, SignalHandlerInvoke invoke ){
301 while ( first != last && invoke( *first++ ) != SIGNAL_STOP_EMISSION ) ;
302 }
303
304 class Signal0 : public SignalBase<SignalHandler>
305 {
306 public:
operator()307 void operator()() const {
308 invokeSignalHandlers( begin(), end(), FunctorInvoke<handler_type>() );
309 }
310 };
311
312 template<typename FirstArgument>
313 class Signal1 : public SignalBase< SignalHandler1<FirstArgument> >
314 {
315 typedef SignalBase< SignalHandler1<FirstArgument> > Base;
316 public:
operator()317 void operator()( FirstArgument a1 ) const {
318 invokeSignalHandlers( Base::begin(), Base::end(), Functor1Invoke<typename Base::handler_type>( a1 ) );
319 }
320 };
321
322 template<typename FirstArgument, typename SecondArgument>
323 class Signal2 : public SignalBase< SignalHandler2<FirstArgument, SecondArgument> >
324 {
325 typedef SignalBase< SignalHandler2<FirstArgument, SecondArgument> > Base;
326 public:
operator()327 void operator()( FirstArgument a1, SecondArgument a2 ) const {
328 invokeSignalHandlers( Base::begin(), Base::end(), Functor2Invoke<typename Base::handler_type>( a1, a2 ) );
329 }
330 };
331
332 template<typename FirstArgument, typename SecondArgument, typename ThirdArgument>
333 class Signal3 : public SignalBase< SignalHandler3<FirstArgument, SecondArgument, ThirdArgument> >
334 {
335 typedef SignalBase< SignalHandler3<FirstArgument, SecondArgument, ThirdArgument> > Base;
336 public:
operator()337 void operator()( FirstArgument a1, SecondArgument a2, ThirdArgument a3 ) const {
338 invokeSignalHandlers( Base::begin(), Base::end(), Functor3Invoke<typename Base::handler_type>( a1, a2, a3 ) );
339 }
340 };
341
342 #endif
343