343 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			343 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 
								 | 
							
								/////////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// (C) Copyright Olaf Krzikalla 2004-2006.
							 | 
						||
| 
								 | 
							
								// (C) Copyright Ion Gaztanaga  2006-2014
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// 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_LINEAR_SLIST_ALGORITHMS_HPP
							 | 
						||
| 
								 | 
							
								#define BOOST_INTRUSIVE_LINEAR_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/algo_type.hpp>
							 | 
						||
| 
								 | 
							
								#include <cstddef>
							 | 
						||
| 
								 | 
							
								#include <boost/intrusive/detail/minimal_pair_header.hpp>   //std::pair
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if defined(BOOST_HAS_PRAGMA_ONCE)
							 | 
						||
| 
								 | 
							
								#  pragma once
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace boost {
							 | 
						||
| 
								 | 
							
								namespace intrusive {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//! linear_slist_algorithms provides basic algorithms to manipulate nodes
							 | 
						||
| 
								 | 
							
								//! forming a linear singly linked list.
							 | 
						||
| 
								 | 
							
								//!
							 | 
						||
| 
								 | 
							
								//! linear_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 linear 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 linear_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) == node_ptr()</tt>
							 | 
						||
| 
								 | 
							
								   //!
							 | 
						||
| 
								 | 
							
								   //! <b>Complexity</b>: Constant
							 | 
						||
| 
								 | 
							
								   //!
							 | 
						||
| 
								 | 
							
								   //! <b>Throws</b>: Nothing.
							 | 
						||
| 
								 | 
							
								   static void init(const 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 node_ptr() == 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(const 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 linear list.
							 | 
						||
| 
								 | 
							
								   //!
							 | 
						||
| 
								 | 
							
								   //! <b>Complexity</b>: Constant
							 | 
						||
| 
								 | 
							
								   //!
							 | 
						||
| 
								 | 
							
								   //! <b>Throws</b>: Nothing.
							 | 
						||
| 
								 | 
							
								   static void unlink_after(const node_ptr & prev_node, const node_ptr & last_node);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   //! <b>Requires</b>: prev_node must be a node of a linear list.
							 | 
						||
| 
								 | 
							
								   //!
							 | 
						||
| 
								 | 
							
								   //! <b>Effects</b>: Links this_node after prev_node in the linear list.
							 | 
						||
| 
								 | 
							
								   //!
							 | 
						||
| 
								 | 
							
								   //! <b>Complexity</b>: Constant
							 | 
						||
| 
								 | 
							
								   //!
							 | 
						||
| 
								 | 
							
								   //! <b>Throws</b>: Nothing.
							 | 
						||
| 
								 | 
							
								   static void link_after(const node_ptr & prev_node, const node_ptr & this_node);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   //! <b>Requires</b>: b and e must be nodes of the same linear list or an empty range.
							 | 
						||
| 
								 | 
							
								   //!   and p must be a node of a different linear list.
							 | 
						||
| 
								 | 
							
								   //!
							 | 
						||
| 
								 | 
							
								   //! <b>Effects</b>: Removes the nodes from (b, e] range from their linear list and inserts
							 | 
						||
| 
								 | 
							
								   //!   them after p in p's linear list.
							 | 
						||
| 
								 | 
							
								   //!
							 | 
						||
| 
								 | 
							
								   //! <b>Complexity</b>: Constant
							 | 
						||
| 
								 | 
							
								   //!
							 | 
						||
| 
								 | 
							
								   //! <b>Throws</b>: Nothing.
							 | 
						||
| 
								 | 
							
								   static void transfer_after(const node_ptr & p, const node_ptr & b, const 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.
							 | 
						||
| 
								 | 
							
								   BOOST_INTRUSIVE_FORCEINLINE static void init_header(const node_ptr & this_node)
							 | 
						||
| 
								 | 
							
								   {  NodeTraits::set_next(this_node, node_ptr ());  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   //! <b>Requires</b>: this_node and prev_init_node must be in the same linear list.
							 | 
						||
| 
								 | 
							
								   //!
							 | 
						||
| 
								 | 
							
								   //! <b>Effects</b>: Returns the previous node of this_node in the linear 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.
							 | 
						||
| 
								 | 
							
								   BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_previous_node(const node_ptr & prev_init_node, const node_ptr & this_node)
							 | 
						||
| 
								 | 
							
								   {  return base_t::get_previous_node(prev_init_node, this_node);   }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   //! <b>Requires</b>: this_node must be in a linear list or be an empty linear list.
							 | 
						||
| 
								 | 
							
								   //!
							 | 
						||
| 
								 | 
							
								   //! <b>Effects</b>: Returns the number of nodes in a linear list. If the linear list
							 | 
						||
| 
								 | 
							
								   //!  is empty, returns 1.
							 | 
						||
| 
								 | 
							
								   //!
							 | 
						||
| 
								 | 
							
								   //! <b>Complexity</b>: Linear
							 | 
						||
| 
								 | 
							
								   //!
							 | 
						||
| 
								 | 
							
								   //! <b>Throws</b>: Nothing.
							 | 
						||
| 
								 | 
							
								   static std::size_t count(const 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);
							 | 
						||
| 
								 | 
							
								      return result;
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   //! <b>Requires</b>: this_node and other_node must be nodes inserted
							 | 
						||
| 
								 | 
							
								   //!  in linear lists or be empty linear lists.
							 | 
						||
| 
								 | 
							
								   //!
							 | 
						||
| 
								 | 
							
								   //! <b>Effects</b>: Moves all the nodes previously chained after this_node after other_node
							 | 
						||
| 
								 | 
							
								   //!   and vice-versa.
							 | 
						||
| 
								 | 
							
								   //!
							 | 
						||
| 
								 | 
							
								   //! <b>Complexity</b>: Constant
							 | 
						||
| 
								 | 
							
								   //!
							 | 
						||
| 
								 | 
							
								   //! <b>Throws</b>: Nothing.
							 | 
						||
| 
								 | 
							
								   static void swap_trailing_nodes(const node_ptr & this_node, const node_ptr & other_node)
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      node_ptr this_nxt    = NodeTraits::get_next(this_node);
							 | 
						||
| 
								 | 
							
								      node_ptr other_nxt   = NodeTraits::get_next(other_node);
							 | 
						||
| 
								 | 
							
								      NodeTraits::set_next(this_node, other_nxt);
							 | 
						||
| 
								 | 
							
								      NodeTraits::set_next(other_node, this_nxt);
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   //! <b>Effects</b>: Reverses the order of elements in the list.
							 | 
						||
| 
								 | 
							
								   //!
							 | 
						||
| 
								 | 
							
								   //! <b>Returns</b>: The new first node of the list.
							 | 
						||
| 
								 | 
							
								   //!
							 | 
						||
| 
								 | 
							
								   //! <b>Throws</b>: Nothing.
							 | 
						||
| 
								 | 
							
								   //!
							 | 
						||
| 
								 | 
							
								   //! <b>Complexity</b>: This function is linear to the contained elements.
							 | 
						||
| 
								 | 
							
								   static node_ptr reverse(const node_ptr & p)
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      if(!p) return node_ptr();
							 | 
						||
| 
								 | 
							
								      node_ptr i = NodeTraits::get_next(p);
							 | 
						||
| 
								 | 
							
								      node_ptr first(p);
							 | 
						||
| 
								 | 
							
								      while(i){
							 | 
						||
| 
								 | 
							
								         node_ptr nxti(NodeTraits::get_next(i));
							 | 
						||
| 
								 | 
							
								         base_t::unlink_after(p);
							 | 
						||
| 
								 | 
							
								         NodeTraits::set_next(i, first);
							 | 
						||
| 
								 | 
							
								         first = i;
							 | 
						||
| 
								 | 
							
								         i = nxti;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      return first;
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   //! <b>Effects</b>: Moves the first n nodes starting at p to the end of the list.
							 | 
						||
| 
								 | 
							
								   //!
							 | 
						||
| 
								 | 
							
								   //! <b>Returns</b>: A pair containing the new first and last node of the list or
							 | 
						||
| 
								 | 
							
								   //!   if there has been any movement, a null pair 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 std::pair<node_ptr, node_ptr> move_first_n_backwards(const node_ptr & p, std::size_t n)
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      std::pair<node_ptr, node_ptr> ret;
							 | 
						||
| 
								 | 
							
								      //Null shift, or count() == 0 or 1, nothing to do
							 | 
						||
| 
								 | 
							
								      if(!n || !p || !NodeTraits::get_next(p)){
							 | 
						||
| 
								 | 
							
								         return ret;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      node_ptr first = p;
							 | 
						||
| 
								 | 
							
								      bool end_found = false;
							 | 
						||
| 
								 | 
							
								      node_ptr new_last = node_ptr();
							 | 
						||
| 
								 | 
							
								      node_ptr old_last = node_ptr();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      //Now find the new last node according to the shift count.
							 | 
						||
| 
								 | 
							
								      //If we find 0 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 == node_ptr()){
							 | 
						||
| 
								 | 
							
								            //Shortcut the shift with the modulo of the size of the list
							 | 
						||
| 
								 | 
							
								            n %= i;
							 | 
						||
| 
								 | 
							
								            if(!n)   return ret;
							 | 
						||
| 
								 | 
							
								            old_last = new_last;
							 | 
						||
| 
								 | 
							
								            i = 0;
							 | 
						||
| 
								 | 
							
								            //Unlink p and continue the new first node search
							 | 
						||
| 
								 | 
							
								            first = p;
							 | 
						||
| 
								 | 
							
								            //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){
							 | 
						||
| 
								 | 
							
								         old_last = base_t::get_previous_node(first, node_ptr());
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      //Now link p after the new last node
							 | 
						||
| 
								 | 
							
								      NodeTraits::set_next(old_last, p);
							 | 
						||
| 
								 | 
							
								      NodeTraits::set_next(new_last, node_ptr());
							 | 
						||
| 
								 | 
							
								      ret.first   = first;
							 | 
						||
| 
								 | 
							
								      ret.second  = new_last;
							 | 
						||
| 
								 | 
							
								      return ret;
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   //! <b>Effects</b>: Moves the first n nodes starting at p to the beginning of the list.
							 | 
						||
| 
								 | 
							
								   //!
							 | 
						||
| 
								 | 
							
								   //! <b>Returns</b>: A pair containing the new first and last node of the list or
							 | 
						||
| 
								 | 
							
								   //!   if there has been any movement, a null pair 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 std::pair<node_ptr, node_ptr> move_first_n_forward(const node_ptr & p, std::size_t n)
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      std::pair<node_ptr, node_ptr> ret;
							 | 
						||
| 
								 | 
							
								      //Null shift, or count() == 0 or 1, nothing to do
							 | 
						||
| 
								 | 
							
								      if(!n || !p || !NodeTraits::get_next(p))
							 | 
						||
| 
								 | 
							
								         return ret;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      node_ptr first  = p;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      //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(!!(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 ret;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								         for( new_last = p
							 | 
						||
| 
								 | 
							
								            ; --new_before_last_pos
							 | 
						||
| 
								 | 
							
								            ; new_last = node_traits::get_next(new_last)){
							 | 
						||
| 
								 | 
							
								            //empty
							 | 
						||
| 
								 | 
							
								         }
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      //Get the first new node
							 | 
						||
| 
								 | 
							
								      node_ptr new_first(node_traits::get_next(new_last));
							 | 
						||
| 
								 | 
							
								      //Now put the old beginning after the old end
							 | 
						||
| 
								 | 
							
								      NodeTraits::set_next(old_last, p);
							 | 
						||
| 
								 | 
							
								      NodeTraits::set_next(new_last, node_ptr());
							 | 
						||
| 
								 | 
							
								      ret.first   = new_first;
							 | 
						||
| 
								 | 
							
								      ret.second  = new_last;
							 | 
						||
| 
								 | 
							
								      return ret;
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/// @cond
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template<class NodeTraits>
							 | 
						||
| 
								 | 
							
								struct get_algo<LinearSListAlgorithms, NodeTraits>
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								   typedef linear_slist_algorithms<NodeTraits> type;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/// @endcond
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								} //namespace intrusive
							 | 
						||
| 
								 | 
							
								} //namespace boost
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <boost/intrusive/detail/config_end.hpp>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif //BOOST_INTRUSIVE_LINEAR_SLIST_ALGORITHMS_HPP
							 |