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