/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
// (C) Copyright Ion Gaztanaga  2006-2009
//
// 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)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////

#ifndef BOOST_INTRUSIVE_CIRCULAR_SLIST_ALGORITHMS_HPP
#define BOOST_INTRUSIVE_CIRCULAR_SLIST_ALGORITHMS_HPP

#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/intrusive_fwd.hpp>
#include <boost/intrusive/detail/common_slist_algorithms.hpp>
#include <boost/intrusive/detail/assert.hpp>
#include <cstddef>

namespace boost {
namespace intrusive {

//! circular_slist_algorithms provides basic algorithms to manipulate nodes
//! forming a circular singly linked list. An empty circular list is formed by a node
//! whose pointer to the next node points to itself.
//!
//! circular_slist_algorithms is configured with a NodeTraits class, which encapsulates the
//! information about the node to be manipulated. NodeTraits must support the
//! following interface:
//!
//! <b>Typedefs</b>:
//!
//! <tt>node</tt>: The type of the node that forms the circular list
//!
//! <tt>node_ptr</tt>: A pointer to a node
//!
//! <tt>const_node_ptr</tt>: A pointer to a const node
//!
//! <b>Static functions</b>:
//!
//! <tt>static node_ptr get_next(const_node_ptr n);</tt>
//! 
//! <tt>static void set_next(node_ptr n, node_ptr next);</tt>
template<class NodeTraits>
class circular_slist_algorithms
   /// @cond
   : public detail::common_slist_algorithms<NodeTraits>
   /// @endcond
{
   /// @cond
   typedef detail::common_slist_algorithms<NodeTraits> base_t;
   /// @endcond
   public:
   typedef typename NodeTraits::node            node;
   typedef typename NodeTraits::node_ptr        node_ptr;
   typedef typename NodeTraits::const_node_ptr  const_node_ptr;
   typedef NodeTraits                           node_traits;

   #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)

   //! <b>Effects</b>: Constructs an non-used list element, putting the next
   //!   pointer to null:
   //!  <tt>NodeTraits::get_next(this_node) == 0</tt>
   //! 
   //! <b>Complexity</b>: Constant 
   //! 
   //! <b>Throws</b>: Nothing.
   static void init(node_ptr this_node);

   //! <b>Requires</b>: this_node must be in a circular list or be an empty circular list.
   //! 
   //! <b>Effects</b>: Returns true is "this_node" is the only node of a circular list:
   //!  or it's a not inserted node:
   //!  <tt>return !NodeTraits::get_next(this_node) || NodeTraits::get_next(this_node) == this_node</tt>
   //! 
   //! <b>Complexity</b>: Constant 
   //! 
   //! <b>Throws</b>: Nothing.
   static bool unique(const_node_ptr this_node);

   //! <b>Effects</b>: Returns true is "this_node" has the same state as
   //!  if it was inited using "init(node_ptr)"
   //! 
   //! <b>Complexity</b>: Constant 
   //! 
   //! <b>Throws</b>: Nothing.
   static bool inited(const_node_ptr this_node);

   //! <b>Requires</b>: prev_node must be in a circular list or be an empty circular list.
   //! 
   //! <b>Effects</b>: Unlinks the next node of prev_node from the circular list.
   //! 
   //! <b>Complexity</b>: Constant 
   //! 
   //! <b>Throws</b>: Nothing.
   static void unlink_after(node_ptr prev_node);

   //! <b>Requires</b>: prev_node and last_node must be in a circular list
   //!  or be an empty circular list.
   //!
   //! <b>Effects</b>: Unlinks the range (prev_node, last_node) from the circular list.
   //!
   //! <b>Complexity</b>: Constant 
   //!
   //! <b>Throws</b>: Nothing.
   static void unlink_after(node_ptr prev_node, node_ptr last_node);

   //! <b>Requires</b>: prev_node must be a node of a circular list.
   //! 
   //! <b>Effects</b>: Links this_node after prev_node in the circular list.
   //! 
   //! <b>Complexity</b>: Constant 
   //! 
   //! <b>Throws</b>: Nothing.
   static void link_after(node_ptr prev_node, node_ptr this_node);

   //! <b>Requires</b>: b and e must be nodes of the same circular list or an empty range.
   //!   and p must be a node of a different circular list.
   //! 
   //! <b>Effects</b>: Removes the nodes from (b, e] range from their circular list and inserts
   //!   them after p in p's circular list.
   //! 
   //! <b>Complexity</b>: Constant 
   //! 
   //! <b>Throws</b>: Nothing.
   static void transfer_after(node_ptr p, node_ptr b, node_ptr e);

   #endif   //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)

   //! <b>Effects</b>: Constructs an empty list, making this_node the only
   //!   node of the circular list:
   //!  <tt>NodeTraits::get_next(this_node) == this_node</tt>.
   //! 
   //! <b>Complexity</b>: Constant 
   //! 
   //! <b>Throws</b>: Nothing.
   static void init_header(node_ptr this_node)
   {  NodeTraits::set_next(this_node, this_node);  } 

   //! <b>Requires</b>: this_node and prev_init_node must be in the same circular list.
   //! 
   //! <b>Effects</b>: Returns the previous node of this_node in the circular list starting.
   //!   the search from prev_init_node. The first node checked for equality
   //!   is NodeTraits::get_next(prev_init_node).
   //! 
   //! <b>Complexity</b>: Linear to the number of elements between prev_init_node and this_node.
   //! 
   //! <b>Throws</b>: Nothing.
   static node_ptr get_previous_node(node_ptr prev_init_node, node_ptr this_node)
   {  return base_t::get_previous_node(prev_init_node, this_node);   }

   //! <b>Requires</b>: this_node must be in a circular list or be an empty circular list.
   //! 
   //! <b>Effects</b>: Returns the previous node of this_node in the circular list.
   //! 
   //! <b>Complexity</b>: Linear to the number of elements in the circular list.
   //! 
   //! <b>Throws</b>: Nothing.
   static node_ptr get_previous_node(node_ptr this_node)
   {  return base_t::get_previous_node(this_node, this_node); }

   //! <b>Requires</b>: this_node must be in a circular list or be an empty circular list.
   //! 
   //! <b>Effects</b>: Returns the previous node of the previous node of this_node in the circular list.
   //! 
   //! <b>Complexity</b>: Linear to the number of elements in the circular list.
   //! 
   //! <b>Throws</b>: Nothing.
   static node_ptr get_previous_previous_node(node_ptr this_node)
   {  return get_previous_previous_node(this_node, this_node); }

   //! <b>Requires</b>: this_node and prev_prev_init_node must be in the same circular list.
   //! 
   //! <b>Effects</b>: Returns the previous node of the previous node of this_node in the
   //!   circular list starting. the search from prev_init_node. The first node checked
   //!   for equality is NodeTraits::get_next((NodeTraits::get_next(prev_prev_init_node)).
   //! 
   //! <b>Complexity</b>: Linear to the number of elements in the circular list.
   //! 
   //! <b>Throws</b>: Nothing.
   static node_ptr get_previous_previous_node(node_ptr prev_prev_init_node, node_ptr this_node)
   {
      node_ptr p = prev_prev_init_node;
      node_ptr p_next = NodeTraits::get_next(p);
      node_ptr p_next_next = NodeTraits::get_next(p_next);
      while (this_node != p_next_next){
         p = p_next;
         p_next = p_next_next;
         p_next_next = NodeTraits::get_next(p_next);
      }
      return p;
   }

   //! <b>Requires</b>: this_node must be in a circular list or be an empty circular list.
   //! 
   //! <b>Effects</b>: Returns the number of nodes in a circular list. If the circular list
   //!  is empty, returns 1.
   //! 
   //! <b>Complexity</b>: Linear 
   //! 
   //! <b>Throws</b>: Nothing.
   static std::size_t count(const_node_ptr this_node) 
   {
      std::size_t result = 0;
      const_node_ptr p = this_node;
      do{
         p = NodeTraits::get_next(p);
         ++result;
      } while (p != this_node);
      return result;
   }

   //! <b>Requires</b>: this_node must be in a circular list, be an empty circular list or be inited.
   //! 
   //! <b>Effects</b>: Unlinks the node from the circular list.
   //! 
   //! <b>Complexity</b>: Linear to the number of elements in the circular list 
   //! 
   //! <b>Throws</b>: Nothing.
   static void unlink(node_ptr this_node)
   {
      if(NodeTraits::get_next(this_node))
         base_t::unlink_after(get_previous_node(this_node));
   }

   //! <b>Requires</b>: nxt_node must be a node of a circular list.
   //! 
   //! <b>Effects</b>: Links this_node before nxt_node in the circular list.
   //! 
   //! <b>Complexity</b>: Linear to the number of elements in the circular list. 
   //! 
   //! <b>Throws</b>: Nothing.
   static void link_before (node_ptr nxt_node, node_ptr this_node)
   {  base_t::link_after(get_previous_node(nxt_node), this_node);   }

   //! <b>Requires</b>: this_node and other_node must be nodes inserted
   //!  in circular lists or be empty circular lists.
   //! 
   //! <b>Effects</b>: Swaps the position of the nodes: this_node is inserted in
   //!   other_nodes position in the second circular list and the other_node is inserted
   //!   in this_node's position in the first circular list.
   //! 
   //! <b>Complexity</b>: Linear to number of elements of both lists 
   //! 
   //! <b>Throws</b>: Nothing.
   static void swap_nodes(node_ptr this_node, node_ptr other_node)
   {
      if (other_node == this_node)
         return;
      bool this_inited  = base_t::inited(this_node);
      bool other_inited = base_t::inited(other_node);
      if(this_inited){
         base_t::init_header(this_node);
      }
      if(other_inited){
         base_t::init_header(other_node);
      }

      bool empty1 = base_t::unique(this_node);
      bool empty2 = base_t::unique(other_node);
      node_ptr prev_this (get_previous_node(this_node));
      node_ptr prev_other(get_previous_node(other_node));

      node_ptr this_next (NodeTraits::get_next(this_node));
      node_ptr other_next(NodeTraits::get_next(other_node));
      NodeTraits::set_next(this_node, other_next);
      NodeTraits::set_next(other_node, this_next);
      NodeTraits::set_next(empty1 ? other_node : prev_this, other_node);
      NodeTraits::set_next(empty2 ? this_node  : prev_other, this_node);

      if(this_inited){
         base_t::init(other_node);
      }
      if(other_inited){
         base_t::init(this_node);
      }
   }

   //! <b>Effects</b>: Reverses the order of elements in the list. 
   //! 
   //! <b>Throws</b>: Nothing.
   //! 
   //! <b>Complexity</b>: This function is linear to the contained elements.
   static void reverse(node_ptr p)
   {
      node_ptr i = NodeTraits::get_next(p), e(p); 
      for (;;) {
         node_ptr nxt(NodeTraits::get_next(i));
         if (nxt == e)
            break;
         base_t::transfer_after(e, i, nxt);
      }
   }

   //! <b>Effects</b>: Moves the node p n positions towards the end of the list.
   //!
   //! <b>Returns</b>: The previous node of p after the function if there has been any movement,
   //!   Null if n leads to no movement.
   //!
   //! <b>Throws</b>: Nothing.
   //! 
   //! <b>Complexity</b>: Linear to the number of elements plus the number moved positions.
   static node_ptr move_backwards(node_ptr p, std::size_t n)
   {
      //Null shift, nothing to do
      if(!n) return node_ptr(0);
      node_ptr first  = NodeTraits::get_next(p);

      //count() == 1 or 2, nothing to do
      if(NodeTraits::get_next(first) == p)
         return node_ptr(0);

      bool end_found = false;
      node_ptr new_last(0);

      //Now find the new last node according to the shift count.
      //If we find p before finding the new last node
      //unlink p, shortcut the search now that we know the size of the list
      //and continue.
      for(std::size_t i = 1; i <= n; ++i){
         new_last = first;
         first = NodeTraits::get_next(first);
         if(first == p){
            //Shortcut the shift with the modulo of the size of the list
            n %= i;
            if(!n)
               return node_ptr(0);
            i = 0;
            //Unlink p and continue the new first node search
            first = NodeTraits::get_next(p);
            base_t::unlink_after(new_last);
            end_found = true;
         }
      }

      //If the p has not been found in the previous loop, find it
      //starting in the new first node and unlink it
      if(!end_found){
         base_t::unlink_after(base_t::get_previous_node(first, p));
      }

      //Now link p after the new last node
      base_t::link_after(new_last, p);
      return new_last;
   }

   //! <b>Effects</b>: Moves the node p n positions towards the beginning of the list.
   //! 
   //! <b>Returns</b>: The previous node of p after the function if there has been any movement,
   //!   Null if n leads equals to no movement.
   //! 
   //! <b>Throws</b>: Nothing.
   //! 
   //! <b>Complexity</b>: Linear to the number of elements plus the number moved positions.
   static node_ptr move_forward(node_ptr p, std::size_t n)
   {
      //Null shift, nothing to do
      if(!n) return node_ptr(0);
      node_ptr first  = node_traits::get_next(p);

      //count() == 1 or 2, nothing to do
      if(node_traits::get_next(first) == p) return node_ptr(0);

      //Iterate until p is found to know where the current last node is.
      //If the shift count is less than the size of the list, we can also obtain
      //the position of the new last node after the shift.
      node_ptr old_last(first), next_to_it, new_last(p);
      std::size_t distance = 1;
      while(p != (next_to_it = node_traits::get_next(old_last))){
         if(++distance > n)
            new_last = node_traits::get_next(new_last);
         old_last = next_to_it;
      }
      //If the shift was bigger or equal than the size, obtain the equivalent
      //forward shifts and find the new last node.
      if(distance <= n){
         //Now find the equivalent forward shifts.
         //Shortcut the shift with the modulo of the size of the list
         std::size_t new_before_last_pos = (distance - (n % distance))% distance;
         //If the shift is a multiple of the size there is nothing to do
         if(!new_before_last_pos)   return node_ptr(0);
         
         for( new_last = p
            ; new_before_last_pos--
            ; new_last = node_traits::get_next(new_last)){
            //empty
         }
      }

      //Now unlink p and link it after the new last node
      base_t::unlink_after(old_last);
      base_t::link_after(new_last, p);
      return new_last;
   }
};

} //namespace intrusive 
} //namespace boost 

#include <boost/intrusive/detail/config_end.hpp>

#endif //BOOST_INTRUSIVE_CIRCULAR_SLIST_ALGORITHMS_HPP
