//=======================================================================
// Copyright 2002 Indiana University.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#ifndef BOOST_LIST_BASE_HPP
#define BOOST_LIST_BASE_HPP

#include <boost/iterator_adaptors.hpp>

// Perhaps this should go through formal review, and move to <boost/>.

/*
  An alternate interface idea:
    Extend the std::list functionality by creating remove/insert
    functions that do not require the container object!
 */

namespace boost {
  namespace detail {

    //=========================================================================
    // Linked-List Generic Implementation Functions

    template <class Node, class Next>
    inline Node
    slist_insert_after(Node pos, Node x, 
                       Next next)
    {
      next(x) = next(pos);
      next(pos) = x;
      return x;
    }

    // return next(pos) or next(next(pos)) ?
    template <class Node, class Next>
    inline Node
    slist_remove_after(Node pos, 
                       Next next)
    {
      Node n = next(pos);
      next(pos) = next(n);
      return n;
    }

    template <class Node, class Next>
    inline Node
    slist_remove_range(Node before_first, Node last, 
                       Next next)
    {
      next(before_first) = last;
      return last;
    }

    template <class Node, class Next>
    inline Node
    slist_previous(Node head, Node x, Node nil, 
                   Next next)
    {
      while (head != nil && next(head) != x)
        head = next(head);
      return head;
    }

    template<class Node, class Next>
    inline void
    slist_splice_after(Node pos, Node before_first, Node before_last, 
                       Next next)
    {
      if (pos != before_first && pos != before_last) {
        Node first = next(before_first);
        Node after = next(pos);
        next(before_first) = next(before_last);
        next(pos) = first;
        next(before_last) = after;
      }
    }

    template <class Node, class Next>
    inline Node
    slist_reverse(Node node, Node nil, 
                  Next next)
    {
      Node result = node;
      node = next(node);
      next(result) = nil;
      while(node) {
        Node next = next(node);
        next(node) = result;
        result = node;
        node = next;
      }
      return result;
    }

    template <class Node, class Next>
    inline std::size_t
    slist_size(Node head, Node nil, 
               Next next)
    {
      std::size_t s = 0;
      for ( ; head != nil; head = next(head))
        ++s;
      return s;
    }

    template <class Next, class Data>
    class slist_iterator_policies
    {
    public:
      explicit slist_iterator_policies(const Next& n, const Data& d)
        : m_next(n), m_data(d) { }

      template <class Reference, class Node>
      Reference dereference(type<Reference>, const Node& x) const
        { return m_data(x); }

      template <class Node>
      void increment(Node& x) const
        { x = m_next(x); }

      template <class Node>
      bool equal(Node& x, Node& y) const
        { return x == y; }

    protected:
      Next m_next;
      Data m_data;
    };

  //===========================================================================
  // Doubly-Linked List Generic Implementation Functions

    template <class Node, class Next, class Prev>
    inline void
    dlist_insert_before(Node pos, Node x, 
                        Next next, Prev prev)
    {
      next(x) = pos;
      prev(x) = prev(pos);
      next(prev(pos)) = x;
      prev(pos) = x;
    }

    template <class Node, class Next, class Prev>
    void
    dlist_remove(Node pos, 
                 Next next, Prev prev)
    {
      Node next_node = next(pos);
      Node prev_node = prev(pos);
      next(prev_node) = next_node;
      prev(next_node) = prev_node;
    }

    // This deletes every node in the list except the
    // sentinel node.
    template <class Node, class Delete>
    inline void
    dlist_clear(Node sentinel, Delete del)
    {
      Node i, tmp;
      i = next(sentinel);
      while (i != sentinel) {
        tmp = i;
        i = next(i);
        del(tmp);
      }
    }
    
    template <class Node>
    inline bool
    dlist_empty(Node dummy)
    {
      return next(dummy) == dummy;
    }

    template <class Node, class Next, class Prev>  
    void
    dlist_transfer(Node pos, Node first, Node last, 
                   Next next, Prev prev)
    {
      if (pos != last) {
        // Remove [first,last) from its old position
        next(prev(last)) = pos;
        next(prev(first)) = last;
        next(prev(pos)) = first;

        // Splice [first,last) into its new position
        Node tmp = prev(pos);
        prev(pos) = prev(last);
        prev(last) = prev(first);
        prev(first) = tmp;
      }
    }  

    template <class Next, class Prev, class Data>
    class dlist_iterator_policies
      : public slist_iterator_policies<Next, Data>
    {
      typedef slist_iterator_policies<Next, Data> Base;
    public:
      template <class Node>
      void decrement(Node& x) const
        { x = m_prev(x); }

      dlist_iterator_policies(Next n, Prev p, Data d) 
        : Base(n,d), m_prev(p) { }
    protected:
      Prev m_prev;
    };

  } // namespace detail
} // namespace boost

#endif // BOOST_LIST_BASE_HPP
