void on_clear()

in src/ds/dllist.h [17:210]


    void on_clear(Ptr<T>) = ignore<T, Ptr>>
  class DLList final
  {
  private:
    static_assert(
      std::is_same<decltype(T::prev), Ptr<T>>::value,
      "T->prev must be a Ptr<T>");
    static_assert(
      std::is_same<decltype(T::next), Ptr<T>>::value,
      "T->next must be a Ptr<T>");

    Ptr<T> head = Terminator();
    Ptr<T> tail = Terminator();

  public:
    ~DLList()
    {
      clear();
    }

    DLList() = default;

    DLList(DLList&& o) noexcept
    {
      head = o.head;
      tail = o.tail;

      o.head = nullptr;
      o.tail = nullptr;
    }

    DLList& operator=(DLList&& o) noexcept
    {
      head = o.head;
      tail = o.tail;

      o.head = nullptr;
      o.tail = nullptr;
      return *this;
    }

    SNMALLOC_FAST_PATH bool is_empty()
    {
      return head == Terminator();
    }

    SNMALLOC_FAST_PATH Ptr<T> get_head()
    {
      return head;
    }

    Ptr<T> get_tail()
    {
      return tail;
    }

    SNMALLOC_FAST_PATH Ptr<T> pop()
    {
      Ptr<T> item = head;

      if (item != Terminator())
        remove(item);

      return item;
    }

    Ptr<T> pop_tail()
    {
      Ptr<T> item = tail;

      if (item != Terminator())
        remove(item);

      return item;
    }

    void insert(Ptr<T> item)
    {
#ifndef NDEBUG
      debug_check_not_contains(item);
#endif

      item->next = head;
      item->prev = Terminator();

      if (head != Terminator())
        head->prev = item;
      else
        tail = item;

      head = item;
#ifndef NDEBUG
      debug_check();
#endif
    }

    void insert_back(Ptr<T> item)
    {
#ifndef NDEBUG
      debug_check_not_contains(item);
#endif

      item->prev = tail;
      item->next = Terminator();

      if (tail != Terminator())
        tail->next = item;
      else
        head = item;

      tail = item;
#ifndef NDEBUG
      debug_check();
#endif
    }

    SNMALLOC_FAST_PATH void remove(Ptr<T> item)
    {
#ifndef NDEBUG
      debug_check_contains(item);
#endif

      if (item->next != Terminator())
        item->next->prev = item->prev;
      else
        tail = item->prev;

      if (item->prev != Terminator())
        item->prev->next = item->next;
      else
        head = item->next;

#ifndef NDEBUG
      debug_check();
#endif
    }

    void clear()
    {
      while (head != nullptr)
      {
        auto c = head;
        remove(c);
        on_clear(c);
      }
    }

    void debug_check_contains(Ptr<T> item)
    {
#ifndef NDEBUG
      debug_check();
      Ptr<T> curr = head;

      while (curr != item)
      {
        SNMALLOC_ASSERT(curr != Terminator());
        curr = curr->next;
      }
#else
      UNUSED(item);
#endif
    }

    void debug_check_not_contains(Ptr<T> item)
    {
#ifndef NDEBUG
      debug_check();
      Ptr<T> curr = head;

      while (curr != Terminator())
      {
        SNMALLOC_ASSERT(curr != item);
        curr = curr->next;
      }
#else
      UNUSED(item);
#endif
    }

    void debug_check()
    {
#ifndef NDEBUG
      Ptr<T> item = head;
      Ptr<T> prev = Terminator();

      while (item != Terminator())
      {
        SNMALLOC_ASSERT(item->prev == prev);
        prev = item;
        item = item->next;
      }
#endif
    }
  };