]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - libs/signal/signal.h
fixed memleak
[xonotic/netradiant.git] / libs / signal / signal.h
index dc187e96c41da7f8a22bb1e0839462f9471bb906..a4fecd9d39de3093978bb0120b93d77b6d0d3cb0 100644 (file)
@@ -108,7 +108,7 @@ namespace ListDetail
   class ListIterator
   {
   public:
-    typedef std::forward_iterator_tag iterator_category;
+    typedef std::bidirectional_iterator_tag iterator_category;
     typedef std::ptrdiff_t difference_type;
     typedef difference_type distance_type;
     typedef typename Traits::value_type value_type;
@@ -191,14 +191,22 @@ namespace ListDetail
   };
 }
 
-class Opaque;
-
 template<typename Value, typename Allocator = DefaultAllocator<Value> >
 class List : private Allocator
 {
   typedef ListDetail::ListNode<Value> Node;
   ListDetail::ListNodeBase list;
   typedef typename Allocator::template rebind<Node>::other NodeAllocator;
+
+  Node* newNode(const Value& value)
+  {
+    return new (NodeAllocator(*this).allocate(1)) Node(value);
+  }
+  void deleteNode(Node* node)
+  {
+    node->~Node();
+    NodeAllocator(*this).deallocate(node, 1);
+  }
 public:
   typedef Value value_type;
   typedef ListDetail::ListIterator< ListDetail::NonConstTraits<Value> > iterator;
@@ -212,6 +220,15 @@ public:
   {
     list_initialise(list);
   }
+  ~List()
+  {
+    for(; list.next != &list;)
+    {
+      Node* node = static_cast<Node*>(list.next);
+      list.next = list.next->next;
+      deleteNode(node);
+    }
+  }
   iterator begin()
   {
     return iterator(static_cast<Node*>(list.next));
@@ -244,9 +261,9 @@ public:
   {
     erase(begin(), value);
   }
-  iterator insert(iterator pos, const Value& x)
+  iterator insert(iterator pos, const Value& value)
   {
-    Node* node = new (NodeAllocator(*this).allocate(1)) Node(x);
+    Node* node = newNode(value);
     node_link(node, pos.node());
     return iterator(node);
   }
@@ -255,8 +272,7 @@ public:
     Node* node = pos.node();
     Node* next = node->getNext();
     node_unlink(node);
-    node->~Node();
-    NodeAllocator(*this).deallocate(node, 1);
+    deleteNode(node);
     return iterator(next);
   }
 };
@@ -340,37 +356,40 @@ class Signal0 : public SignalBase<SignalHandler>
 public:
   void operator()() const
   {
-    invokeSignalHandlers(begin(), end(), FunctorInvoke<typename handler_type>());
+    invokeSignalHandlers(begin(), end(), FunctorInvoke<handler_type>());
   }
 };
 
 template<typename FirstArgument>
 class Signal1 : public SignalBase< SignalHandler1<FirstArgument> >
 {
+  typedef SignalBase< SignalHandler1<FirstArgument> > Base;
 public:
   void operator()(FirstArgument a1) const
   {
-    invokeSignalHandlers(begin(), end(), Functor1Invoke<typename handler_type>(a1));
+    invokeSignalHandlers(Base::begin(), Base::end(), Functor1Invoke<typename Base::handler_type>(a1));
   }
 };
 
 template<typename FirstArgument, typename SecondArgument>
 class Signal2 : public SignalBase< SignalHandler2<FirstArgument, SecondArgument> >
 {
+  typedef SignalBase< SignalHandler2<FirstArgument, SecondArgument> > Base;
 public:
   void operator()(FirstArgument a1, SecondArgument a2) const
   {
-    invokeSignalHandlers(begin(), end(), Functor2Invoke<typename handler_type>(a1, a2));
+    invokeSignalHandlers(Base::begin(), Base::end(), Functor2Invoke<typename Base::handler_type>(a1, a2));
   }
 };
 
 template<typename FirstArgument, typename SecondArgument, typename ThirdArgument>
 class Signal3 : public SignalBase< SignalHandler3<FirstArgument, SecondArgument, ThirdArgument> >
 {
+  typedef SignalBase< SignalHandler3<FirstArgument, SecondArgument, ThirdArgument> > Base;
 public:
   void operator()(FirstArgument a1, SecondArgument a2, ThirdArgument a3) const
   {
-    invokeSignalHandlers(begin(), end(), Functor3Invoke<typename handler_type>(a1, a2, a3));
+    invokeSignalHandlers(Base::begin(), Base::end(), Functor3Invoke<typename Base::handler_type>(a1, a2, a3));
   }
 };