Erase elements in LinkedList::remove_if

Change-Id: I5119a78c73ffe780a81c53ab5ff0266d5c82d319
diff --git a/linker/linked_list.h b/linker/linked_list.h
index e51eb9c..14fe1e5 100644
--- a/linker/linked_list.h
+++ b/linker/linked_list.h
@@ -88,24 +88,50 @@
   template<typename F>
   void for_each(F&& action) {
     for (LinkedListEntry<T>* e = head_; e != nullptr; e = e->next) {
-      if (e->element != nullptr) {
-        action(e->element);
-      }
+      action(e->element);
     }
   }
 
   template<typename F>
-  void remove_if(F&& predicate) {
-    for (LinkedListEntry<T>* e = head_; e != nullptr; e = e->next) {
-      if (e->element != nullptr && predicate(e->element)) {
-        e->element = nullptr;
+  void remove_if(F predicate) {
+    for (LinkedListEntry<T>* e = head_, *p = nullptr; e != nullptr;) {
+      if (predicate(e->element)) {
+        LinkedListEntry<T>* next = e->next;
+        if (p == nullptr) {
+          head_ = next;
+        } else {
+          p->next = next;
+        }
+        Allocator::free(e);
+        e = next;
+      } else {
+        p = e;
+        e = e->next;
       }
     }
   }
 
-  bool contains(const T* el) {
+  size_t size() const {
+    size_t sz = 0;
     for (LinkedListEntry<T>* e = head_; e != nullptr; e = e->next) {
-      if (e->element != nullptr && e->element == el) {
+      ++sz;
+    }
+
+    return sz;
+  }
+
+  size_t copy_to_array(T* array[], size_t array_length) const {
+    size_t sz = 0;
+    for (LinkedListEntry<T>* e = head_; sz < array_length && e != nullptr; e = e->next) {
+      array[sz++] = e->element;
+    }
+
+    return sz;
+  }
+
+  bool contains(const T* el) const {
+    for (LinkedListEntry<T>* e = head_; e != nullptr; e = e->next) {
+      if (e->element == el) {
         return true;
       }
     }