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 // It is safe to disconnect the signal handler currently being invoked.
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

Generated by  doxygen 1.6.2