/* Intrusive double linked list for GDB, the GNU debugger.
   Copyright (C) 2021-2022 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#ifndef GDBSUPPORT_INTRUSIVE_LIST_H
#define GDBSUPPORT_INTRUSIVE_LIST_H

#define INTRUSIVE_LIST_UNLINKED_VALUE ((T *) -1)

/* A list node.  The elements put in an intrusive_list either inherit
   from this, or have a field of this type.  */
template<typename T>
class intrusive_list_node
{
public:
  bool is_linked () const
  {
    return next != INTRUSIVE_LIST_UNLINKED_VALUE;
  }

private:
  T *next = INTRUSIVE_LIST_UNLINKED_VALUE;
  T *prev = INTRUSIVE_LIST_UNLINKED_VALUE;

  template<typename T2, typename AsNode>
  friend struct intrusive_list_iterator;

  template<typename T2, typename AsNode>
  friend struct intrusive_list_reverse_iterator;

  template<typename T2, typename AsNode>
  friend struct intrusive_list;
};

/* Follows a couple types used by intrusive_list as template parameter to find
   the intrusive_list_node for a given element.  One for lists where the
   elements inherit intrusive_list_node, and another for elements that keep the
   node as member field.  */

/* For element types that inherit from intrusive_list_node.  */

template<typename T>
struct intrusive_base_node
{
  static intrusive_list_node<T> *as_node (T *elem)
  { return elem; }
};

/* For element types that keep the node as member field.  */

template<typename T, intrusive_list_node<T> T::*MemberNode>
struct intrusive_member_node
{
  static intrusive_list_node<T> *as_node (T *elem)
  { return &(elem->*MemberNode); }
};

/* Common code for forward and reverse iterators.  */

template<typename T, typename AsNode, typename SelfType>
struct intrusive_list_base_iterator
{
  using self_type = SelfType;
  using iterator_category = std::bidirectional_iterator_tag;
  using value_type = T;
  using pointer = T *;
  using const_pointer = const T *;
  using reference = T &;
  using const_reference = const T &;
  using difference_type = ptrdiff_t;
  using size_type = size_t;
  using node_type = intrusive_list_node<T>;

  /* Create an iterator pointing to ELEM.  */
  explicit intrusive_list_base_iterator (T *elem)
    : m_elem (elem)
  {}

  /* Create a past-the-end iterator.  */
  intrusive_list_base_iterator ()
    : m_elem (nullptr)
  {}

  reference operator* () const
  { return *m_elem; }

  pointer operator-> () const
  { return m_elem; }

  bool operator== (const self_type &other) const
  { return m_elem == other.m_elem; }

  bool operator!= (const self_type &other) const
  { return m_elem != other.m_elem; }

protected:
  static node_type *as_node (T *elem)
  { return AsNode::as_node (elem); }

  /* A past-end-the iterator points to the list's head.  */
  pointer m_elem;
};

/* Forward iterator for an intrusive_list.  */

template<typename T, typename AsNode = intrusive_base_node<T>>
struct intrusive_list_iterator
  : public intrusive_list_base_iterator
	     <T, AsNode, intrusive_list_iterator<T, AsNode>>
{
  using base = intrusive_list_base_iterator
		 <T, AsNode, intrusive_list_iterator<T, AsNode>>;
  using self_type = typename base::self_type;
  using node_type = typename base::node_type;

  /* Inherit constructor and M_NODE visibility from base.  */
  using base::base;
  using base::m_elem;

  self_type &operator++ ()
  {
    node_type *node = this->as_node (m_elem);
    m_elem = node->next;
    return *this;
  }

  self_type operator++ (int)
  {
    self_type temp = *this;
    node_type *node = this->as_node (m_elem);
    m_elem = node->next;
    return temp;
  }

  self_type &operator-- ()
  {
    node_type *node = this->as_node (m_elem);
    m_elem = node->prev;
    return *this;
  }

  self_type operator-- (int)
  {
    self_type temp = *this;
    node_type *node = this->as_node (m_elem);
    m_elem = node->prev;
    return temp;
  }
};

/* Reverse iterator for an intrusive_list.  */

template<typename T, typename AsNode = intrusive_base_node<T>>
struct intrusive_list_reverse_iterator
  : public intrusive_list_base_iterator
	     <T, AsNode, intrusive_list_reverse_iterator<T, AsNode>>
{
  using base = intrusive_list_base_iterator
		 <T, AsNode, intrusive_list_reverse_iterator<T, AsNode>>;
  using self_type = typename base::self_type;

  /* Inherit constructor and M_NODE visibility from base.  */
  using base::base;
  using base::m_elem;
  using node_type = typename base::node_type;

  self_type &operator++ ()
  {
    node_type *node = this->as_node (m_elem);
    m_elem = node->prev;
    return *this;
  }

  self_type operator++ (int)
  {
    self_type temp = *this;
    node_type *node = this->as_node (m_elem);
    m_elem = node->prev;
    return temp;
  }

  self_type &operator-- ()
  {
    node_type *node = this->as_node (m_elem);
    m_elem = node->next;
    return *this;
  }

  self_type operator-- (int)
  {
    self_type temp = *this;
    node_type *node = this->as_node (m_elem);
    m_elem = node->next;
    return temp;
  }
};

/* An intrusive double-linked list.

   T is the type of the elements to link.  The type T must either:

    - inherit from intrusive_list_node<T>
    - have an intrusive_list_node<T> member

   AsNode is a type with an as_node static method used to get a node from an
   element.  If elements inherit from intrusive_list_node<T>, use the default
   intrusive_base_node<T>.  If elements have an intrusive_list_node<T> member,
   use:

     intrusive_member_node<T, &T::member>

   where `member` is the name of the member.  */

template <typename T, typename AsNode = intrusive_base_node<T>>
class intrusive_list
{
public:
  using value_type = T;
  using pointer = T *;
  using const_pointer = const T *;
  using reference = T &;
  using const_reference = const T &;
  using difference_type = ptrdiff_t;
  using size_type = size_t;
  using iterator = intrusive_list_iterator<T, AsNode>;
  using reverse_iterator = intrusive_list_reverse_iterator<T, AsNode>;
  using const_iterator = const intrusive_list_iterator<T, AsNode>;
  using const_reverse_iterator
    = const intrusive_list_reverse_iterator<T, AsNode>;
  using node_type = intrusive_list_node<T>;

  intrusive_list () = default;

  ~intrusive_list ()
  {
    clear ();
  }

  intrusive_list (intrusive_list &&other)
    : m_front (other.m_front),
      m_back (other.m_back)
  {
    other.m_front = nullptr;
    other.m_back = nullptr;
  }

  intrusive_list &operator= (intrusive_list &&other)
  {
    m_front = other.m_front;
    m_back = other.m_back;
    other.m_front = nullptr;
    other.m_back = nullptr;

    return *this;
  }

  void swap (intrusive_list &other)
  {
    std::swap (m_front, other.m_front);
    std::swap (m_back, other.m_back);
  }

  iterator iterator_to (reference value)
  {
    return iterator (&value);
  }

  const_iterator iterator_to (const_reference value)
  {
    return const_iterator (&value);
  }

  reference front ()
  {
    gdb_assert (!this->empty ());
    return *m_front;
  }

  const_reference front () const
  {
    gdb_assert (!this->empty ());
    return *m_front;
  }

  reference back ()
  {
    gdb_assert (!this->empty ());
    return *m_back;
  }

  const_reference back () const
  {
    gdb_assert (!this->empty ());
    return *m_back;
  }

  void push_front (reference elem)
  {
    intrusive_list_node<T> *elem_node = as_node (&elem);

    gdb_assert (elem_node->next == INTRUSIVE_LIST_UNLINKED_VALUE);
    gdb_assert (elem_node->prev == INTRUSIVE_LIST_UNLINKED_VALUE);

    if (this->empty ())
      this->push_empty (elem);
    else
      this->push_front_non_empty (elem);
  }

  void push_back (reference elem)
  {
    intrusive_list_node<T> *elem_node = as_node (&elem);

    gdb_assert (elem_node->next == INTRUSIVE_LIST_UNLINKED_VALUE);
    gdb_assert (elem_node->prev == INTRUSIVE_LIST_UNLINKED_VALUE);

    if (this->empty ())
      this->push_empty (elem);
    else
      this->push_back_non_empty (elem);
  }

  /* Inserts ELEM before POS.  */
  void insert (const_iterator pos, reference elem)
  {
    if (this->empty ())
      return this->push_empty (elem);

    if (pos == this->begin ())
      return this->push_front_non_empty (elem);

    if (pos == this->end ())
      return this->push_back_non_empty (elem);

    intrusive_list_node<T> *elem_node = as_node (&elem);
    T *pos_elem = &*pos;
    intrusive_list_node<T> *pos_node = as_node (pos_elem);
    T *prev_elem = pos_node->prev;
    intrusive_list_node<T> *prev_node = as_node (prev_elem);

    gdb_assert (elem_node->next == INTRUSIVE_LIST_UNLINKED_VALUE);
    gdb_assert (elem_node->prev == INTRUSIVE_LIST_UNLINKED_VALUE);

    elem_node->prev = prev_elem;
    prev_node->next = &elem;
    elem_node->next = pos_elem;
    pos_node->prev = &elem;
  }

  /* Move elements from LIST at the end of the current list.  */
  void splice (intrusive_list &&other)
  {
    if (other.empty ())
      return;

    if (this->empty ())
      {
	*this = std::move (other);
	return;
      }

    /* [A ... B] + [C ... D] */
    T *b_elem = m_back;
    node_type *b_node = as_node (b_elem);
    T *c_elem = other.m_front;
    node_type *c_node = as_node (c_elem);
    T *d_elem = other.m_back;

    b_node->next = c_elem;
    c_node->prev = b_elem;
    m_back = d_elem;

    other.m_front = nullptr;
    other.m_back = nullptr;
  }

  void pop_front ()
  {
    gdb_assert (!this->empty ());
    erase_element (*m_front);
  }

  void pop_back ()
  {
    gdb_assert (!this->empty ());
    erase_element (*m_back);
  }

private:
  /* Push ELEM in the list, knowing the list is empty.  */
  void push_empty (T &elem)
  {
    gdb_assert (this->empty ());

    intrusive_list_node<T> *elem_node = as_node (&elem);

    gdb_assert (elem_node->next == INTRUSIVE_LIST_UNLINKED_VALUE);
    gdb_assert (elem_node->prev == INTRUSIVE_LIST_UNLINKED_VALUE);

    m_front = &elem;
    m_back = &elem;
    elem_node->prev = nullptr;
    elem_node->next = nullptr;
  }

  /* Push ELEM at the front of the list, knowing the list is not empty.  */
  void push_front_non_empty (T &elem)
  {
    gdb_assert (!this->empty ());

    intrusive_list_node<T> *elem_node = as_node (&elem);
    intrusive_list_node<T> *front_node = as_node (m_front);

    gdb_assert (elem_node->next == INTRUSIVE_LIST_UNLINKED_VALUE);
    gdb_assert (elem_node->prev == INTRUSIVE_LIST_UNLINKED_VALUE);

    elem_node->next = m_front;
    front_node->prev = &elem;
    elem_node->prev = nullptr;
    m_front = &elem;
  }

  /* Push ELEM at the back of the list, knowing the list is not empty.  */
  void push_back_non_empty (T &elem)
  {
    gdb_assert (!this->empty ());

    intrusive_list_node<T> *elem_node = as_node (&elem);
    intrusive_list_node<T> *back_node = as_node (m_back);

    gdb_assert (elem_node->next == INTRUSIVE_LIST_UNLINKED_VALUE);
    gdb_assert (elem_node->prev == INTRUSIVE_LIST_UNLINKED_VALUE);

    elem_node->prev = m_back;
    back_node->next = &elem;
    elem_node->next = nullptr;
    m_back = &elem;
  }

  void erase_element (T &elem)
  {
    intrusive_list_node<T> *elem_node = as_node (&elem);

    gdb_assert (elem_node->prev != INTRUSIVE_LIST_UNLINKED_VALUE);
    gdb_assert (elem_node->next != INTRUSIVE_LIST_UNLINKED_VALUE);

    if (m_front == &elem)
      {
	gdb_assert (elem_node->prev == nullptr);
	m_front = elem_node->next;
      }
    else
      {
	gdb_assert (elem_node->prev != nullptr);
	intrusive_list_node<T> *prev_node = as_node (elem_node->prev);
	prev_node->next = elem_node->next;
      }

    if (m_back == &elem)
      {
	gdb_assert (elem_node->next == nullptr);
	m_back = elem_node->prev;
      }
    else
      {
	gdb_assert (elem_node->next != nullptr);
	intrusive_list_node<T> *next_node = as_node (elem_node->next);
	next_node->prev = elem_node->prev;
      }

    elem_node->next = INTRUSIVE_LIST_UNLINKED_VALUE;
    elem_node->prev = INTRUSIVE_LIST_UNLINKED_VALUE;
  }

public:
  /* Remove the element pointed by I from the list.  The element
     pointed by I is not destroyed.  */
  iterator erase (const_iterator i)
  {
    iterator ret = i;
    ++ret;

    erase_element (*i);

    return ret;
  }

  /* Erase all the elements.  The elements are not destroyed.  */
  void clear ()
  {
    while (!this->empty ())
      pop_front ();
  }

  /* Erase all the elements.  Disposer::operator()(pointer) is called
     for each of the removed elements.  */
  template<typename Disposer>
  void clear_and_dispose (Disposer disposer)
  {
    while (!this->empty ())
      {
	pointer p = &front ();
	pop_front ();
	disposer (p);
      }
  }

  bool empty () const
  {
    return m_front == nullptr;
  }

  iterator begin () noexcept
  {
    return iterator (m_front);
  }

  const_iterator begin () const noexcept
  {
    return const_iterator (m_front);
  }

  const_iterator cbegin () const noexcept
  {
    return const_iterator (m_front);
  }

  iterator end () noexcept
  {
    return {};
  }

  const_iterator end () const noexcept
  {
    return {};
  }

  const_iterator cend () const noexcept
  {
    return {};
  }

  reverse_iterator rbegin () noexcept
  {
    return reverse_iterator (m_back);
  }

  const_reverse_iterator rbegin () const noexcept
  {
    return const_reverse_iterator (m_back);
  }

  const_reverse_iterator crbegin () const noexcept
  {
    return const_reverse_iterator (m_back);
  }

  reverse_iterator rend () noexcept
  {
    return {};
  }

  const_reverse_iterator rend () const noexcept
  {
    return {};
  }

  const_reverse_iterator crend () const noexcept
  {
    return {};
  }

private:
  static node_type *as_node (T *elem)
  {
    return AsNode::as_node (elem);
  }

  T *m_front = nullptr;
  T *m_back = nullptr;
};

#endif /* GDBSUPPORT_INTRUSIVE_LIST_H */
