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