signal.h
Go to the documentation of this file.00001
00002 #if !defined(INCLUDED_SIGNAL_H)
00003 #define INCLUDED_SIGNAL_H
00004
00005 #include "isignal.h"
00006 #include "memory/allocator.h"
00007 #include "debugging/debugging.h"
00008 #include <iterator>
00009
00010 namespace ListDetail {
00011 struct ListNodeBase {
00012 ListNodeBase* next;
00013 ListNodeBase* prev;
00014 };
00015
00016 inline void list_initialise(ListNodeBase& self) {
00017 self.next = self.prev = &self;
00018 }
00019
00020 inline void list_swap(ListNodeBase& self, ListNodeBase& other) {
00021 ListNodeBase tmp(self);
00022 if (other.next == &other) {
00023 list_initialise(self);
00024 } else {
00025 self = other;
00026 self.next->prev = self.prev->next = &self;
00027 }
00028 if (tmp.next == &self) {
00029 list_initialise(other);
00030 } else {
00031 other = tmp;
00032 other.next->prev = other.prev->next = &other;
00033 }
00034 }
00035
00036 inline void node_link(ListNodeBase* node, ListNodeBase* next) {
00037 node->next = next;
00038 node->prev = next->prev;
00039 next->prev = node;
00040 node->prev->next = node;
00041 }
00042 inline void node_unlink(ListNodeBase* node) {
00043 node->prev->next = node->next;
00044 node->next->prev = node->prev;
00045 }
00046
00047 template<typename Value>
00048 struct ListNode : public ListNodeBase {
00049 Value value;
00050
00051 ListNode(const Value& value) : value(value) {
00052 }
00053 ListNode* getNext() const {
00054 return static_cast<ListNode*>(next);
00055 }
00056 ListNode* getPrev() const {
00057 return static_cast<ListNode*>(prev);
00058 }
00059 };
00060
00061 template<typename Type>
00062 class NonConstTraits {
00063 public:
00064 typedef Type value_type;
00065 typedef value_type* pointer;
00066 typedef value_type& reference;
00067
00068 template<typename Other>
00069 struct rebind {
00070 typedef NonConstTraits<Other> other;
00071 };
00072 };
00073
00074 template<typename Type>
00075 class ConstTraits {
00076 public:
00077 typedef Type value_type;
00078 typedef const value_type* pointer;
00079 typedef const value_type& reference;
00080
00081 template<typename Other>
00082 struct rebind {
00083 typedef ConstTraits<Other> other;
00084 };
00085 };
00086
00087 template<typename Traits>
00088 class ListIterator {
00089 public:
00090 typedef std::bidirectional_iterator_tag iterator_category;
00091 typedef std::ptrdiff_t difference_type;
00092 typedef difference_type distance_type;
00093 typedef typename Traits::value_type value_type;
00094 typedef typename Traits::pointer pointer;
00095 typedef typename Traits::reference reference;
00096
00097 private:
00098 typedef ListNode<value_type> Node;
00099 typedef typename Traits::template rebind<Node>::other NodeTraits;
00100 typedef typename NodeTraits::pointer NodePointer;
00101 typedef typename Traits::template rebind< Opaque<value_type> >::other OpaqueTraits;
00102 typedef typename OpaqueTraits::pointer OpaquePointer;
00103 NodePointer m_node;
00104
00105 void increment() {
00106 m_node = m_node->getNext();
00107 }
00108 void decrement() {
00109 m_node = m_node->getPrev();
00110 }
00111
00112
00113 public:
00114 explicit ListIterator(NodePointer node) : m_node(node) {
00115 }
00116 explicit ListIterator(OpaquePointer p) : m_node(reinterpret_cast<NodePointer>(p)) {
00117 }
00118
00119 NodePointer node() {
00120 return m_node;
00121 }
00122 OpaquePointer opaque() const {
00123 return reinterpret_cast<OpaquePointer>(m_node);
00124 }
00125
00126 bool operator==(const ListIterator& other) const {
00127 return m_node == other.m_node;
00128 }
00129 bool operator!=(const ListIterator& other) const {
00130 return !operator==(other);
00131 }
00132 ListIterator& operator++() {
00133 increment();
00134 return *this;
00135 }
00136 ListIterator operator++(int) {
00137 ListIterator tmp = *this;
00138 increment();
00139 return tmp;
00140 }
00141 ListIterator& operator--() {
00142 decrement();
00143 return *this;
00144 }
00145 ListIterator operator--(int) {
00146 ListIterator tmp = *this;
00147 decrement();
00148 return tmp;
00149 }
00150 reference operator*() const {
00151 return m_node->value;
00152 }
00153 pointer operator->() const {
00154 return &(operator*());
00155 }
00156 };
00157 }
00158
00159 template < typename Value, typename Allocator = DefaultAllocator<Value> >
00160 class List : private Allocator {
00161 typedef ListDetail::ListNode<Value> Node;
00162 ListDetail::ListNodeBase list;
00163 typedef typename Allocator::template rebind<Node>::other NodeAllocator;
00164
00165 Node* newNode(const Value& value) {
00166 return new (NodeAllocator(*this).allocate(1)) Node(value);
00167 }
00168 void deleteNode(Node* node) {
00169 node->~Node();
00170 NodeAllocator(*this).deallocate(node, 1);
00171 }
00172 public:
00173 typedef Value value_type;
00174 typedef ListDetail::ListIterator< ListDetail::NonConstTraits<Value> > iterator;
00175 typedef ListDetail::ListIterator< ListDetail::ConstTraits<Value> > const_iterator;
00176
00177 List() {
00178 list_initialise(list);
00179 }
00180 explicit List(const Allocator& allocator) : Allocator(allocator) {
00181 list_initialise(list);
00182 }
00183 ~List() {
00184 for (; list.next != &list;) {
00185 Node* node = static_cast<Node*>(list.next);
00186 list.next = list.next->next;
00187 deleteNode(node);
00188 }
00189 }
00190 iterator begin() {
00191 return iterator(static_cast<Node*>(list.next));
00192 }
00193 iterator end() {
00194 return iterator(static_cast<Node*>(&list));
00195 }
00196 const_iterator begin() const {
00197 return const_iterator(static_cast<const Node*>(list.next));
00198 }
00199 const_iterator end() const {
00200 return const_iterator(static_cast<const Node*>(&list));
00201 }
00202 void push_back(const Value& value) {
00203 insert(end(), value);
00204 }
00205 void pop_back(const Value& value) {
00206 erase(--end(), value);
00207 }
00208 void push_front(const Value& value) {
00209 insert(begin(), value);
00210 }
00211 void pop_front(const Value& value) {
00212 erase(begin(), value);
00213 }
00214 iterator insert(iterator pos, const Value& value) {
00215 Node* node = newNode(value);
00216 node_link(node, pos.node());
00217 return iterator(node);
00218 }
00219 iterator erase(iterator pos) {
00220 Node* node = pos.node();
00221 Node* next = node->getNext();
00222 node_unlink(node);
00223 deleteNode(node);
00224 return iterator(next);
00225 }
00226 };
00227
00228 template<typename Functor>
00229 class SignalBase {
00230 typedef List<Functor> SignalList;
00231 SignalList events;
00232
00233 public:
00234
00235 typedef Functor handler_type;
00236 typedef Handle< Opaque<Functor> > handler_id_type;
00237 typedef typename SignalList::iterator iterator;
00238 typedef typename SignalList::const_iterator const_iterator;
00239 iterator begin() {
00240 return events.begin();
00241 }
00242 iterator end() {
00243 return events.end();
00244 }
00245 const_iterator begin() const {
00246 return events.begin();
00247 }
00248 const_iterator end() const {
00249 return events.end();
00250 }
00251 handler_id_type connectFirst(const Functor& event) {
00252 events.push_front(event);
00253 return handler_id_type(begin().opaque());
00254 }
00255 handler_id_type connectLast(const Functor& event) {
00256 events.push_back(event);
00257 return handler_id_type((--end()).opaque());
00258 }
00259 bool isConnected(handler_id_type id) {
00260 for (iterator i = begin(); i != end(); ++i) {
00261 if (id.get() == i.opaque()) {
00262 return true;
00263 }
00264 }
00265 return false;
00266 }
00267 handler_id_type connectBefore(handler_id_type id, const Functor& event) {
00268 ASSERT_MESSAGE(isConnected(id), "SignalBase::connectBefore: invalid id");
00269 return events.insert(iterator(id.get()), event).opaque();
00270 }
00271 handler_id_type connectAfter(handler_id_type id, const Functor& event) {
00272 ASSERT_MESSAGE(isConnected(id), "SignalBase::connectAfter: invalid id");
00273 return events.insert(++iterator(id.get()), event).opaque();
00274 }
00275 void disconnect(handler_id_type id) {
00276 ASSERT_MESSAGE(isConnected(id), "SignalBase::disconnect: invalid id");
00277 events.erase(iterator(id.get()));
00278 }
00279 };
00280
00282
00283 template<typename InputIterator, typename SignalHandlerInvoke>
00284 inline void invokeSignalHandlers(InputIterator first, InputIterator last, SignalHandlerInvoke invoke) {
00285 while (first != last && invoke(*first++) != SIGNAL_STOP_EMISSION);
00286 }
00287
00288 class Signal0 : public SignalBase<SignalHandler> {
00289 public:
00290 void operator()() const {
00291 invokeSignalHandlers(begin(), end(), FunctorInvoke<handler_type>());
00292 }
00293 };
00294
00295 template<typename FirstArgument>
00296 class Signal1 : public SignalBase< SignalHandler1<FirstArgument> > {
00297 typedef SignalBase< SignalHandler1<FirstArgument> > Base;
00298 public:
00299 void operator()(FirstArgument a1) const {
00300 invokeSignalHandlers(Base::begin(), Base::end(), Functor1Invoke<typename Base::handler_type>(a1));
00301 }
00302 };
00303
00304 template<typename FirstArgument, typename SecondArgument>
00305 class Signal2 : public SignalBase< SignalHandler2<FirstArgument, SecondArgument> > {
00306 typedef SignalBase< SignalHandler2<FirstArgument, SecondArgument> > Base;
00307 public:
00308 void operator()(FirstArgument a1, SecondArgument a2) const {
00309 invokeSignalHandlers(Base::begin(), Base::end(), Functor2Invoke<typename Base::handler_type>(a1, a2));
00310 }
00311 };
00312
00313 template<typename FirstArgument, typename SecondArgument, typename ThirdArgument>
00314 class Signal3 : public SignalBase< SignalHandler3<FirstArgument, SecondArgument, ThirdArgument> > {
00315 typedef SignalBase< SignalHandler3<FirstArgument, SecondArgument, ThirdArgument> > Base;
00316 public:
00317 void operator()(FirstArgument a1, SecondArgument a2, ThirdArgument a3) const {
00318 invokeSignalHandlers(Base::begin(), Base::end(), Functor3Invoke<typename Base::handler_type>(a1, a2, a3));
00319 }
00320 };
00321
00322 #endif