// Splay tree utilities                                             -*- C++ -*-
// Copyright (C) 2020-2023 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
// GCC 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, or (at your option) any later
// version.
//
// GCC 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 GCC; see the file COPYING3.  If not see
// <http://www.gnu.org/licenses/>.

// INDEX is either 0 or 1.  If it is 0, return NODE's left child,
// otherwise return NODE's right child.
template<typename Accessors>
inline typename base_splay_tree<Accessors>::node_type
base_splay_tree<Accessors>::get_child (node_type node, unsigned int index)
{
  return Accessors::child (node, index);
}

// INDEX is either 0 or 1.  If it is 0, change NODE's left child to CHILD,
// otherwise change NODE's right child to CHILD.  If CHILD has a parent
// field, record that its parent is now NODE.
template<typename Accessors>
inline void
base_splay_tree<Accessors>::set_child (node_type node, unsigned int index,
				       node_type child)
{
  Accessors::child (node, index) = child;
  if (child)
    set_parent (child, node);
}

// Rotate the tree to promote child number INDEX of NODE, so that that
// child becomes a parent of NODE.  Return the promoted node.
//
// The caller has the responsibility of assigning a correct parent
// to the returned node.
template<typename Accessors>
inline typename base_splay_tree<Accessors>::node_type
base_splay_tree<Accessors>::promote_child (node_type node, unsigned int index)
{
  node_type promoted = get_child (node, index);
  set_child (node, index, get_child (promoted, 1 - index));
  set_child (promoted, 1 - index, node);
  return promoted;
}

// Treat child number INDEX of NODE as being CHILD and rotate the tree
// so that CHILD becomes a parent of NODE.
//
// The caller has the responsibility of assigning a correct parent to CHILD.
template<typename Accessors>
inline void
base_splay_tree<Accessors>::promote_child (node_type node, unsigned int index,
					   node_type child)
{
  set_child (node, index, get_child (child, 1 - index));
  set_child (child, 1 - index, node);
}

// Print NODE to PP, using PRINTER (PP, N) to print the contents of node N.
// Prefix each new line with INDENT_STRING.  CODE is 'T' if NODE is the root
// node, 'L' if NODE is the left child of its parent, or 'R' if NODE is the
// right child of its parent.
template<typename Accessors>
template<typename Printer>
void
base_splay_tree<Accessors>::print (pretty_printer *pp, node_type node,
				   Printer printer, char code,
				   vec<char> &indent_string)
{
  // In the comments below, PREFIX refers to the incoming contents
  // of INDENT_STRING.
  node_type left = get_child (node, 0);
  node_type right = get_child (node, 1);

  auto orig_indent_len = indent_string.length ();
  indent_string.safe_grow (orig_indent_len + 3);
  char *extra_indent = indent_string.address () + orig_indent_len;

  // Print [T], [L], or [R].
  extra_indent[0] = '[';
  extra_indent[1] = code;
  extra_indent[2] = ']';
  pp_append_text (pp, extra_indent, indent_string.end ());
  pp_space (pp);

  // Print the node itself, using PREFIX + " | " or PREFIX + "   " to indent
  // new lines under the "[_]" that we just printed.
  extra_indent[0] = ' ';
  extra_indent[1] = (left || right ? '|' : ' ');
  extra_indent[2] = ' ';
  {
    pretty_printer sub_pp;
    printer (&sub_pp, node);
    const char *text = pp_formatted_text (&sub_pp);
    while (const char *end = strchr (text, '\n'))
      {
	pp_append_text (pp, text, end);
	pp_newline_and_indent (pp, 0);
	pp_append_text (pp, indent_string.begin (), indent_string.end ());
	text = end + 1;
      }
    pp_string (pp, text);
  }

  if (left)
    {
      // Print PREFIX + " +-" for the first line of the left subtree,
      // to be followed by "[L]".
      extra_indent[1] = '+';
      extra_indent[2] = '-';
      pp_newline_and_indent (pp, 0);
      pp_append_text (pp, indent_string.begin (), indent_string.end ());

      // Print the left subtree, using PREFIX + " | " or PREFIX + "   "
      // to indent under the PREFIX + " +-" that we just printed.
      extra_indent[1] = right ? '|' : ' ';
      extra_indent[2] = ' ';
      print (pp, left, printer, 'L', indent_string);
      extra_indent = indent_string.address () + orig_indent_len;

      // If LEFT is not a leaf and we also have a right subtree, use a
      // PREFIX + " |" line to separate them.
      if (right && (get_child (left, 0) || get_child (left, 1)))
	{
	  pp_newline_and_indent (pp, 0);
	  pp_append_text (pp, indent_string.begin (), &extra_indent[2]);
	}
    }
  if (right)
    {
      // Print PREFIX + " +-" for the first line of the right subtree,
      // to be followed by "[R]".
      extra_indent[1] = '+';
      extra_indent[2] = '-';
      pp_newline_and_indent (pp, 0);
      pp_append_text (pp, indent_string.begin (), indent_string.end ());

      // Print the right subtree, using PREFIX + "   " to indent under the
      // PREFIX + " +-" that we just printed.
      extra_indent[1] = ' ';
      extra_indent[2] = ' ';
      print (pp, right, printer, 'R', indent_string);
    }
  indent_string.truncate (orig_indent_len);
}

// See the comment above the declaration.
template<typename Accessors>
template<typename Printer>
void
base_splay_tree<Accessors>::print (pretty_printer *pp, node_type node,
				   Printer printer)
{
  if (!node)
    {
      pp_string (pp, "null");
      return;
    }
  auto_vec<char, 64> indent_string;
  print (pp, node, printer, 'T', indent_string);
}

// If N is 1, splay the last (rightmost) node reachable from START
// to the position that START current holds and return the splayed node.
// START is not itself the last node.
//
// If N is 0, splay the first (leftmost) node reachable from START
// to the position that START current holds and return the splayed node.
// START is not itself the first node.
//
// The caller has the responsibility of updating the parent of the
// returned node.
template<typename Accessors>
template<unsigned int N>
typename base_splay_tree<Accessors>::node_type
base_splay_tree<Accessors>::splay_limit (node_type start)
{
  // This essentially follows the simpilfied top-down method described
  // in Sleator and Tarjan's "Self-adjusting Binary Search Trees", but
  // specialized for the case in which the comparison result is fixed.
  // The first iteration is peeled to avoid the need for stack temporaries.
  //
  // The comments and names reflect the behavior for N == 1, but the
  // N == 0 case behaves analogously.

  // Rotate the tree to promote the right child of START to the root.
  node_type node = promote_child (start, N);
  if (node_type right = get_child (node, N))
    {
      // Perform the link left step, which for this first iteration
      // means making NODE the root of the left tree.
      //
      // NODE will become left child of the final node.  For a right
      // spine starting at NODE of the form:
      //
      //  1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> ... -> N
      //  |    |    |    |    |    |    |           |
      //  V    V    V    V    V    V    V           V
      //  A    B    C    D    E    F    G           NL
      //
      // the next step is to create a subtree of N whose right spine contains
      // the odd-numbered nodes, as follows:
      //
      //  N
      //  |
      //  V
      //  1 ------> 3 ------> 5 ------> 7 -> .... -> NL
      //  |         |         |         |
      //  V         V         V         V
      //  A         2 -> C    4 -> E    6 -> G
      //            |         |         |
      //            V         V         V
      //            B         D         F
      //
      // First record 1 as the left child of the final root (N) and move
      // on to node 2.
      node_type final_child = node;
      node_type new_spine_end = node;
      node = right;
      while (node_type right = get_child (node, N))
	{
	  // Perform another rotate left step.
	  //
	  // We've built the tree rooted at 1 in the diagram above up to,
	  // but not including, an even-numbered node NODE on the original
	  // right spine.  Rotate the tree at NODE to promote the following
	  // odd-numbered node.
	  promote_child (node, N, right);
	  node = right;
	  if (node_type right = get_child (node, N))
	    {
	      // Perform another link left step.
	      //
	      // Add the promoted odd-numbered node to the right spine of the
	      // tree rooted at 1 and move on to the next even-numbered node.
	      set_child (new_spine_end, N, node);
	      new_spine_end = node;
	      node = right;
	    }
	}
      // Perform the assembly step.
      //
      // Add NL to the new spine and make N the new root.
      set_child (new_spine_end, N, get_child (node, 1 - N));
      set_child (node, 1 - N, final_child);
    }
  return node;
}

// Remove NODE from its position in the splay tree.  If NODE has at least
// one child node, return the node that should now hold NODE's position in
// the splay tree.  If NODE has no children, return null.
//
// The caller has the responsibility of updating the parent of the
// returned node.
template<typename Accessors>
inline typename base_splay_tree<Accessors>::node_type
base_splay_tree<Accessors>::remove_node_internal (node_type node)
{
  node_type left = get_child (node, 0);
  node_type right = get_child (node, 1);
  if (!left)
    return right;

  if (!right)
    return left;

  if (get_child (left, 1))
    {
      left = splay_limit<1> (left);
      gcc_checking_assert (!get_child (left, 1));
    }
  set_child (left, 1, right);
  return left;
}

// See the comment above the declaration.
template<typename Accessors>
inline void
base_splay_tree<Accessors>::insert_child (node_type node, unsigned int index,
					  node_type child)
{
  gcc_checking_assert (!get_child (child, 0) && !get_child (child, 1));
  set_child (child, index, get_child (node, index));
  set_child (node, index, child);
}

// Implement splay_next_node if N == 1 and splay_prev_node if N == 0.
template<typename Accessors>
template<unsigned int N>
bool
rooted_splay_tree<Accessors>::splay_neighbor ()
{
  node_type node = m_root;
  node_type new_root = get_child (node, N);
  if (!new_root)
    return false;

  if (get_child (new_root, 1 - N))
    {
      // NEW_ROOT is not itself the required node, so splay the required
      // node into its place.
      new_root = parent::template splay_limit<1 - N> (new_root);
      gcc_checking_assert (!get_child (new_root, 1 - N));
      set_child (node, N, node_type ());
      set_child (new_root, 1 - N, node);
    }
  else
    promote_child (node, N, new_root);
  set_parent (new_root, node_type ());
  m_root = new_root;
  return true;
}

// See the comment above the declaration.
template<typename Accessors>
template<typename Comparator>
bool
rooted_splay_tree<Accessors>::insert (node_type new_node, Comparator compare)
{
  gcc_checking_assert (!get_child (new_node, 0) && !get_child (new_node, 1));
  if (!m_root)
    {
      m_root = new_node;
      return true;
    }

  int comparison = lookup (compare);
  if (comparison == 0)
    return false;

  // Insert NEW_NODE before M_ROOT if COMPARISON < 0 and after M_ROOT
  // otherwise.
  set_child (new_node, comparison < 0, m_root);
  set_child (new_node, comparison > 0, get_child (m_root, comparison > 0));
  set_child (m_root, comparison > 0, nullptr);
  m_root = new_node;
  return true;
}

// See the comment above the declaration.
template<typename Accessors>
inline void
rooted_splay_tree<Accessors>::insert_max_node (node_type new_node)
{
  gcc_checking_assert (!get_child (new_node, 0) && !get_child (new_node, 1));
  set_child (new_node, 0, m_root);
  m_root = new_node;
}

// See the comment above the declaration.
template<typename Accessors>
inline void
rooted_splay_tree<Accessors>::splice_next_tree (rooted_splay_tree next_tree)
{
  splay_max_node ();
  set_child (m_root, 1, next_tree.m_root);
}

// See the comment above the declaration.
template<typename Accessors>
inline void
rooted_splay_tree<Accessors>::replace_max_node_at_root (node_type new_node)
{
  node_type old_node = m_root;
  gcc_checking_assert (!get_child (new_node, 0)
		       && !get_child (new_node, 1)
		       && !get_child (old_node, 1));
  set_child (new_node, 0, get_child (old_node, 0));
  // Clear the links from OLD_NODE.  Its parent and right child are
  // already node_type ().
  set_child (old_node, 0, node_type ());
  m_root = new_node;
}

// See the comment above the declaration.
template<typename Accessors>
inline void
rooted_splay_tree<Accessors>::remove_root ()
{
  node_type node = m_root;
  m_root = parent::remove_node_internal (node);
  if (m_root)
    set_parent (m_root, node_type ());
  // Clear the links from NODE.  Its parent is already node_type ().
  set_child (node, 0, node_type ());
  set_child (node, 1, node_type ());
}

// See the comment above the declaration.
template<typename Accessors>
inline rooted_splay_tree<Accessors>
rooted_splay_tree<Accessors>::split_before_root ()
{
  node_type new_root = get_child (m_root, 0);
  set_child (m_root, 0, node_type ());
  set_parent (new_root, node_type ());
  return new_root;
}

// See the comment above the declaration.
template<typename Accessors>
inline rooted_splay_tree<Accessors>
rooted_splay_tree<Accessors>::split_after_root ()
{
  node_type new_root = get_child (m_root, 1);
  set_child (m_root, 1, node_type ());
  set_parent (new_root, node_type ());
  return new_root;
}

// See the comment above the declaration.
template<typename Accessors>
inline bool
rooted_splay_tree<Accessors>::splay_prev_node ()
{
  return splay_neighbor<0> ();
}

// See the comment above the declaration.
template<typename Accessors>
inline bool
rooted_splay_tree<Accessors>::splay_next_node ()
{
  return splay_neighbor<1> ();
}

// See the comment above the declaration.
template<typename Accessors>
inline void
rooted_splay_tree<Accessors>::splay_min_node ()
{
  if (m_root && get_child (m_root, 0))
    {
      m_root = parent::template splay_limit<0> (m_root);
      set_parent (m_root, node_type ());
    }
}

// See the comment above the declaration.
template<typename Accessors>
inline void
rooted_splay_tree<Accessors>::splay_max_node ()
{
  if (m_root && get_child (m_root, 1))
    {
      m_root = parent::template splay_limit<1> (m_root);
      set_parent (m_root, node_type ());
    }
}

// See the comment above the declaration.
template<typename Accessors>
inline typename rooted_splay_tree<Accessors>::node_type
rooted_splay_tree<Accessors>::min_node ()
{
  splay_min_node ();
  return m_root;
}

// See the comment above the declaration.
template<typename Accessors>
inline typename rooted_splay_tree<Accessors>::node_type
rooted_splay_tree<Accessors>::max_node ()
{
  splay_max_node ();
  return m_root;
}

// See the comment above the declaration.
template<typename Accessors>
template<typename Comparator>
auto
rooted_splay_tree<Accessors>::lookup (Comparator compare)
  -> decltype (compare (m_root))
{
  // This essentially follows the simpilfied top-down method described
  // in Sleator and Tarjan's "Self-adjusting Binary Search Trees", but
  // with the complication that the comparisons are done only once.
  using result_type = decltype (compare (m_root));

  // The roots of the left and right trees.
  node_type link_left_root = node_type ();
  node_type link_right_root = node_type ();

  // Where to add new nodes to the left and right trees.
  node_type *link_left_ptr = &link_left_root;
  node_type *link_right_ptr = &link_right_root;

  // The nodes that contain *LINK_LEFT_PTR and *LINK_RIGHT_PTR,
  // once they no longer point to the roots above.
  node_type link_left_parent = node_type ();
  node_type link_right_parent = node_type ();

  auto link_left = [&](node_type node)
    {
      *link_left_ptr = node;
      link_left_ptr = &Accessors::child (node, 1);
      set_parent (node, link_left_parent);
      link_left_parent = node;
    };

  auto link_right = [&](node_type node)
    {
      *link_right_ptr = node;
      link_right_ptr = &Accessors::child (node, 0);
      set_parent (node, link_right_parent);
      link_right_parent = node;
    };

  node_type node = m_root;
  node_type parent = node_type ();
  result_type result;
  result_type old_result = 0;
  while (1)
    {
      // OLD_RESULT is 0 if NODE is the root of the middle tree.
      // Otherwise, PARENT is the root of the middle tree and OLD_RESULT
      // is how it compared.
      //
      // Results are:
      // < 0 if we want something smaller.
      // = 0 if we found the right node.
      // > 0 if we want something bigger.
      result = compare (node);
      if (old_result < 0)
	{
	  if (result < 0)
	    {
	      // SEARCH < NODE < PARENT
	      //
	      // Promote NODE (rotate right).
	      promote_child (parent, 0, node);
	      node_type next = get_child (node, 0);
	      if (!next)
		break;

	      link_right (node);

	      // NEXT is now the root of the middle tree.
	      node = next;
	      old_result = 0;
	      continue;
	    }

	  // SEARCH >= NODE, NODE < PARENT
	  link_right (parent);
	}
      else if (old_result > 0)
	{
	  if (result > 0)
	    {
	      // SEARCH > NODE > PARENT
	      //
	      // Promote NODE (rotate left).
	      promote_child (parent, 1, node);
	      node_type next = get_child (node, 1);
	      if (!next)
		break;

	      link_left (node);

	      // NEXT is now the root of the middle tree.
	      node = next;
	      old_result = 0;
	      continue;
	    }

	  // SEARCH <= NODE, NODE > PARENT
	  link_left (parent);
	}

      // Microoptimization to allow NODE to be read even if RESULT == 0.
      node_type next = get_child (node, result >= 0);
      if (result == 0 || !next)
	break;

      // NODE is now the root of the tree.
      parent = node;
      node = next;
      old_result = result;
    }

  node_type new_left = link_left_root;
  node_type new_right = link_right_root;

  if (new_left)
    {
      node_type old_left = get_child (node, 0);
      *link_left_ptr = old_left;
      if (old_left)
	set_parent (old_left, link_left_parent);
      set_child (node, 0, new_left);
    }

  if (new_right)
    {
      node_type old_right = get_child (node, 1);
      *link_right_ptr = old_right;
      if (old_right)
	set_parent (old_right, link_right_parent);
      set_child (node, 1, new_right);
    }

  set_parent (node, node_type ());
  m_root = node;
  return result;
}

// See the comment above the declaration.
template<typename Accessors>
template<typename LeftPredicate, typename RightPredicate>
int
rooted_splay_tree<Accessors>::lookup (LeftPredicate want_something_smaller,
				      RightPredicate want_something_bigger)
{
  // This essentially follows the simpilfied top-down method described
  // in Sleator and Tarjan's "Self-adjusting Binary Search Trees"
  // (and follows it more closely than the single-comparator version above).

  // The roots of the left and right trees.
  node_type link_left_root = node_type ();
  node_type link_right_root = node_type ();

  // Where to add new nodes to the left and right trees.
  node_type *link_left_ptr = &link_left_root;
  node_type *link_right_ptr = &link_right_root;

  // The nodes that contain *LINK_LEFT_PTR and *LINK_RIGHT_PTR,
  // once they no longer point to the roots above.
  node_type link_left_parent = node_type ();
  node_type link_right_parent = node_type ();

  node_type node = m_root;
  int result;
  for (;;)
    {
      // NODE is the root of the middle tree.
      if (want_something_smaller (node))
	{
	  result = -1;
	  node_type next = get_child (node, 0);
	  if (!next)
	    break;

	  if (want_something_smaller (next))
	    {
	      // Promote NODE (rotate right).
	      promote_child (node, 0, next);
	      node = next;
	      next = get_child (node, 0);
	      if (!next)
		break;
	    }

	  // Add NODE to the right tree (link right).
	  *link_right_ptr = node;
	  link_right_ptr = &Accessors::child (node, 0);
	  set_parent (node, link_right_parent);
	  link_right_parent = node;

	  node = next;
	}
      else if (want_something_bigger (node))
	{
	  result = 1;
	  node_type next = get_child (node, 1);
	  if (!next)
	    break;

	  if (want_something_bigger (next))
	    {
	      // Promote NODE (rotate left).
	      promote_child (node, 1, next);
	      node = next;
	      next = get_child (node, 1);
	      if (!next)
		break;
	    }

	  // Add NODE to the left tree (link left).
	  *link_left_ptr = node;
	  link_left_ptr = &Accessors::child (node, 1);
	  set_parent (node, link_left_parent);
	  link_left_parent = node;

	  node = next;
	}
      else
	{
	  result = 0;
	  break;
	}
    }

  node_type new_left = link_left_root;
  node_type new_right = link_right_root;

  if (new_left)
    {
      node_type old_left = get_child (node, 0);
      *link_left_ptr = old_left;
      if (old_left)
	set_parent (old_left, link_left_parent);
      set_child (node, 0, new_left);
    }

  if (new_right)
    {
      node_type old_right = get_child (node, 1);
      *link_right_ptr = old_right;
      if (old_right)
	set_parent (old_right, link_right_parent);
      set_child (node, 1, new_right);
    }

  set_parent (node, node_type ());
  m_root = node;
  return result;
}

// See the comment above the declaration.
template<typename Accessors>
template<typename Printer>
inline void
rooted_splay_tree<Accessors>::print (pretty_printer *pp, Printer printer) const
{
  print (pp, m_root, printer);
}

// Return NODE's current parent.
template<typename Accessors>
inline typename rootless_splay_tree<Accessors>::node_type
rootless_splay_tree<Accessors>::get_parent (node_type node)
{
  return Accessors::parent (node);
}

// CHILD is known to be a child of PARENT.  Return which index it has.
template<typename Accessors>
inline unsigned int
rootless_splay_tree<Accessors>::child_index (node_type parent, node_type child)
{
  return get_child (parent, 1) == child;
}

// If N == 1, implement splay_known_max_node, otherwise implement
// splay_known_min_node.
template<typename Accessors>
template<unsigned int N>
inline void
rootless_splay_tree<Accessors>::splay_known_limit (node_type node)
{
  node_type child = node;
  node_type parent = get_parent (child);
  if (!parent)
    return;

  do
    // At this point, NODE conceptually replaces CHILD as a child of
    // PARENT, but we haven't yet updated PARENT accordingly.
    if (node_type grandparent = get_parent (parent))
      {
	node_type greatgrandparent = get_parent (grandparent);
	promote_child (grandparent, N, parent);
	promote_child (parent, N, node);
	child = grandparent;
	parent = greatgrandparent;
      }
    else
      {
	promote_child (parent, N, node);
	break;
      }
  while (parent);
  set_parent (node, node_type ());
}

// See the comment above the declaration.
template<typename Accessors>
typename rootless_splay_tree<Accessors>::node_type
rootless_splay_tree<Accessors>::remove_node (node_type node)
{
  node_type replacement = parent::remove_node_internal (node);
  if (node_type parent = get_parent (node))
    set_child (parent, child_index (parent, node), replacement);
  else if (replacement)
    set_parent (replacement, node_type ());
  // Clear the links from NODE.
  set_parent (node, node_type ());
  set_child (node, 0, node_type ());
  set_child (node, 1, node_type ());
  return replacement;
}

// See the comment above the declaration.
template<typename Accessors>
void
rootless_splay_tree<Accessors>::splay (node_type node)
{
  node_type child = node;
  node_type parent = get_parent (child);
  if (!parent)
    return;

  do
    {
      // At this point, NODE conceptually replaces CHILD as a child of
      // PARENT, but we haven't yet updated PARENT accordingly.
      unsigned int index = child_index (parent, child);
      if (node_type grandparent = get_parent (parent))
	{
	  node_type greatgrandparent = get_parent (grandparent);
	  unsigned int parent_index = child_index (grandparent, parent);
	  if (index == parent_index)
	    {
	      promote_child (grandparent, parent_index, parent);
	      promote_child (parent, index, node);
	    }
	  else
	    {
	      promote_child (parent, index, node);
	      promote_child (grandparent, parent_index, node);
	    }
	  child = grandparent;
	  parent = greatgrandparent;
	}
      else
	{
	  promote_child (parent, index, node);
	  break;
	}
    }
  while (parent);
  set_parent (node, node_type ());
}

// See the comment above the declaration.
template<typename Accessors>
inline void
rootless_splay_tree<Accessors>::splay_known_min_node (node_type node)
{
  splay_known_limit<0> (node);
}

// See the comment above the declaration.
template<typename Accessors>
inline void
rootless_splay_tree<Accessors>::splay_known_max_node (node_type node)
{
  splay_known_limit<1> (node);
}

// See the comment above the declaration.
template<typename Accessors>
template<typename DefaultResult, typename Predicate>
auto
rootless_splay_tree<Accessors>::
splay_and_search (node_type node, DefaultResult default_result,
		  Predicate predicate)
  -> decltype (predicate (node, 0))
{
  using Result = decltype (predicate (node, 0));

  node_type child = node;
  node_type parent = get_parent (child);
  if (!parent)
    return default_result;

  do
    {
      // At this point, NODE conceptually replaces CHILD as a child of
      // PARENT, but we haven't yet updated PARENT accordingly.
      unsigned int index = child_index (parent, child);
      if (Result result = predicate (parent, index))
	{
	  set_child (parent, index, node);
	  return result;
	}
      if (node_type grandparent = get_parent (parent))
	{
	  node_type greatgrandparent = get_parent (grandparent);
	  unsigned int parent_index = child_index (grandparent, parent);
	  if (Result result = predicate (grandparent, parent_index))
	    {
	      set_child (parent, index, node);
	      return result;
	    }
	  if (index == parent_index)
	    {
	      promote_child (grandparent, parent_index, parent);
	      promote_child (parent, index, node);
	    }
	  else
	    {
	      promote_child (parent, index, node);
	      promote_child (grandparent, parent_index, node);
	    }
	  child = grandparent;
	  parent = greatgrandparent;
	}
      else
	{
	  promote_child (parent, index, node);
	  break;
	}
    }
  while (parent);
  set_parent (node, node_type ());
  return default_result;
}

// Splay NODE1 looking to see if one of its ancestors is NODE2.  If it is,
// return -1 if NODE1 comes before NODE2 or 1 if NODE1 comes after NODE2.
// Return 0 if NODE2 is not an ancestor of NODE1.
template<typename Accessors>
int
rootless_splay_tree<Accessors>::compare_nodes_one_way (node_type node1,
						       node_type node2)
{
  auto compare = [&](node_type parent, unsigned int index) -> int
    {
      if (parent == node2)
	return index ? 1 : -1;
      return 0;
    };
  return splay_and_search (node1, 0, compare);
}

// See the comment above the declaration.
template<typename Accessors>
int
rootless_splay_tree<Accessors>::compare_nodes (node_type node1,
					       node_type node2)
{
  if (node1 == node2)
    return 0;

  // Splay NODE1 looking for NODE2.
  int cmp = compare_nodes_one_way (node1, node2);
  if (cmp)
    return cmp;

  // That failed, but NODE1 is now the root of the tree.  Splay NODE2
  // to see on which side of NODE1 it falls.
  cmp = compare_nodes_one_way (node2, node1);
  gcc_checking_assert (cmp);
  return -cmp;
}
