code:
// -*- C++ -*-

// Copyright (C) 2005, 2006 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library 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 2, or (at your option) any later
// version.

// This library 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 library; see the file COPYING.  If not, write to
// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
// MA 02111-1307, USA.

// As a special exception, you may use this file as part of a free
// software library without restriction.  Specifically, if other files
// instantiate templates or use macros or inline functions from this
// file, or you compile this file and link it with other files to
// produce an executable, this file does not by itself cause the
// resulting executable to be covered by the GNU General Public
// License.  This exception does not however invalidate any other
// reasons why the executable file might be covered by the GNU General
// Public License.

// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.

// Permission to use, copy, modify, sell, and distribute this software
// is hereby granted without fee, provided that the above copyright
// notice appears in all copies, and that both that copyright notice
// and this permission notice appear in supporting documentation. None
// of the above authors, nor IBM Haifa Research Laboratories, make any
// representation about the suitability of this software for any
// purpose. It is provided "as is" without express or implied
// warranty.

/**
 * @file pat_trie_.hpp
 * Contains an implementation class for a patricia tree.
 */

/**
 * This implementation loosely borrows ideas from:
 * 1) "Fast Mergeable Integer Maps", Okasaki, Gill 1998
 * 2) "Ptset: Sets of integers implemented as Patricia trees",
 *    Jean-Christophe Filliatr, 2000
 **/

#include <ext/pb_ds/detail/pat_trie_/synth_e_access_traits.hpp>
#include <ext/pb_ds/detail/pat_trie_/node_base.hpp>
#include <ext/pb_ds/exception.hpp>
#include <ext/pb_ds/tag_and_trait.hpp>
#include <ext/pb_ds/detail/eq_fn/eq_by_less.hpp>
#include <ext/pb_ds/detail/types_traits.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/detail/cond_dealtor.hpp>
#include <ext/pb_ds/detail/type_utils.hpp>
#include <iterator>
#include <utility>
#include <algorithm>
#include <functional>
#include <assert.h>
#include <list>
#ifdef _GLIBCXX_DEBUG
#include <ext/pb_ds/detail/map_debug_base.hpp>
#endif
#include <debug/debug.h>

namespace pb_ds
{
  namespace detail
  {
#define PB_DS_CLASS_T_DEC \
    template<typename Key, typename Mapped, typename Node_And_It_Traits, \
	     typename Allocator>

#ifdef PB_DS_DATA_TRUE_INDICATOR
#define PB_DS_CLASS_NAME pat_trie_data_
#endif

#ifdef PB_DS_DATA_FALSE_INDICATOR
#define PB_DS_CLASS_NAME pat_trie_no_data_
#endif

#define PB_DS_CLASS_C_DEC \
    PB_DS_CLASS_NAME<Key, Mapped, Node_And_It_Traits, Allocator>

#define PB_DS_TYPES_TRAITS_C_DEC \
    types_traits<Key, Mapped, Allocator, false>

#ifdef _GLIBCXX_DEBUG
#define PB_DS_MAP_DEBUG_BASE_C_DEC \
    map_debug_base<Key,	eq_by_less<Key, \
			std::less<Key> >, typename Allocator::template rebind<Key>::other::const_reference>
#endif

#ifdef PB_DS_DATA_TRUE_INDICATOR
#define PB_DS_V2F(X) (X).first
#define PB_DS_V2S(X) (X).second
#define PB_DS_EP2VP(X)& ((X)->m_value)
#endif

#ifdef PB_DS_DATA_FALSE_INDICATOR
#define PB_DS_V2F(X) (X)
#define PB_DS_V2S(X) Mapped_Data()
#define PB_DS_EP2VP(X)& ((X)->m_value.first)
#endif

#define PB_DS_STATIC_ASSERT(UNIQUE, E)	\
    typedef static_assert_dumclass<sizeof(static_assert<(bool)(E)>)> \
    UNIQUE##static_assert_type

    /**
     * class description = PATRICIA trie implementation.">
     **/
    template<typename Key,
	     typename Mapped,
	     typename Node_And_It_Traits,
	     typename Allocator>
    class PB_DS_CLASS_NAME :
#ifdef _GLIBCXX_DEBUG
      public PB_DS_MAP_DEBUG_BASE_C_DEC,
#endif
      public Node_And_It_Traits::synth_e_access_traits,
      public Node_And_It_Traits::node_update,
      public PB_DS_TYPES_TRAITS_C_DEC
    {
    private:
      typedef PB_DS_TYPES_TRAITS_C_DEC traits_base;

      typedef typename Node_And_It_Traits::synth_e_access_traits synth_e_access_traits;
      typedef typename Allocator::template rebind<synth_e_access_traits>::other::const_pointer const_e_access_traits_pointer;
      typedef typename synth_e_access_traits::const_iterator const_e_iterator;

      typedef typename Node_And_It_Traits::node node;
      typedef typename Allocator::template rebind<node>::other::const_pointer const_node_pointer;

      typedef typename Allocator::template rebind<node>::other::pointer node_pointer;

      typedef typename Node_And_It_Traits::head head;
      typedef typename Allocator::template rebind<head>::other head_allocator;
      typedef typename head_allocator::pointer head_pointer;

      typedef typename Node_And_It_Traits::leaf leaf;
      typedef typename Allocator::template rebind<leaf>::other leaf_allocator;
      typedef typename leaf_allocator::const_pointer const_leaf_pointer;
      typedef typename leaf_allocator::pointer leaf_pointer;

      typedef typename Node_And_It_Traits::internal_node internal_node;
      typedef typename Allocator::template rebind<internal_node>::other internal_node_allocator;
      typedef typename internal_node_allocator::const_pointer const_internal_node_pointer;
      typedef typename internal_node_allocator::pointer internal_node_pointer;

#include <ext/pb_ds/detail/pat_trie_/cond_dtor_entry_dealtor.hpp>

#ifdef _GLIBCXX_DEBUG
      typedef PB_DS_MAP_DEBUG_BASE_C_DEC map_debug_base;
#endif

#include <ext/pb_ds/detail/pat_trie_/split_join_branch_bag.hpp>

      typedef typename Node_And_It_Traits::null_node_update_pointer null_node_update_pointer;

    public:
      typedef pat_trie_tag container_category;
      typedef Allocator allocator;
      typedef typename Allocator::size_type size_type;
      typedef typename Allocator::difference_type difference_type;

      typedef typename traits_base::key_type key_type;
      typedef typename traits_base::key_pointer key_pointer;
      typedef typename traits_base::const_key_pointer const_key_pointer;
      typedef typename traits_base::key_reference key_reference;
      typedef typename traits_base::const_key_reference const_key_reference;
      typedef typename traits_base::mapped_type mapped_type;
      typedef typename traits_base::mapped_pointer mapped_pointer;
      typedef typename traits_base::const_mapped_pointer const_mapped_pointer;
      typedef typename traits_base::mapped_reference mapped_reference;
      typedef typename traits_base::const_mapped_reference const_mapped_reference;
      typedef typename traits_base::value_type value_type;
      typedef typename traits_base::pointer pointer;
      typedef typename traits_base::const_pointer const_pointer;
      typedef typename traits_base::reference reference;
      typedef typename traits_base::const_reference const_reference;

      typedef typename Node_And_It_Traits::const_iterator const_point_iterator;
      typedef typename Node_And_It_Traits::iterator point_iterator;
      typedef const_point_iterator const_iterator;
      typedef point_iterator iterator;

      typedef typename Node_And_It_Traits::const_reverse_iterator const_reverse_iterator;
      typedef typename Node_And_It_Traits::reverse_iterator reverse_iterator;
      typedef typename Node_And_It_Traits::const_node_iterator const_node_iterator;
      typedef typename Node_And_It_Traits::node_iterator node_iterator;
      typedef typename Node_And_It_Traits::e_access_traits e_access_traits;
      typedef typename Node_And_It_Traits::node_update node_update;

      PB_DS_CLASS_NAME();

      PB_DS_CLASS_NAME(const e_access_traits&);

      PB_DS_CLASS_NAME(const PB_DS_CLASS_C_DEC&);

      void
      swap(PB_DS_CLASS_C_DEC&);

      ~PB_DS_CLASS_NAME();

      inline bool
      empty() const;

      inline size_type
      size() const;

      inline size_type
      max_size() const;

      e_access_traits&
      get_e_access_traits();

      const e_access_traits&
      get_e_access_traits() const;

      node_update&
      get_node_update();

      const node_update&
      get_node_update() const;

      inline std::pair<point_iterator, bool>
      insert(const_reference);

      inline mapped_reference
      operator[](const_key_reference r_key)
      {
#ifdef PB_DS_DATA_TRUE_INDICATOR
	return insert(std::make_pair(r_key, mapped_type())).first->second;
#else
	insert(r_key);
	return traits_base::s_null_mapped;
#endif
      }

      inline point_iterator
      find(const_key_reference);

      inline const_point_iterator
      find(const_key_reference) const;

      inline point_iterator
      lower_bound(const_key_reference);

      inline const_point_iterator
      lower_bound(const_key_reference) const;

      inline point_iterator
      upper_bound(const_key_reference);

      inline const_point_iterator
      upper_bound(const_key_reference) const;

      void
      clear();

      inline bool
      erase(const_key_reference);

      inline const_iterator
      erase(const_iterator);

#ifdef PB_DS_DATA_TRUE_INDICATOR
      inline iterator
      erase(iterator);
#endif

      inline const_reverse_iterator
      erase(const_reverse_iterator);

#ifdef PB_DS_DATA_TRUE_INDICATOR
      inline reverse_iterator
      erase(reverse_iterator);
#endif

      template<typename Pred>
      inline size_type
      erase_if(Pred);

      void
      join(PB_DS_CLASS_C_DEC&);

      void
      split(const_key_reference, PB_DS_CLASS_C_DEC&);

      inline iterator
      begin();

      inline const_iterator
      begin() const;

      inline iterator
      end();

      inline const_iterator
      end() const;

      inline reverse_iterator
      rbegin();

      inline const_reverse_iterator
      rbegin() const;

      inline reverse_iterator
      rend();

      inline const_reverse_iterator
      rend() const;

      inline const_node_iterator
      node_begin() const;

      inline node_iterator
      node_begin();

      inline const_node_iterator
      node_end() const;

      inline node_iterator
      node_end();

#ifdef PB_DS_PAT_TRIE_TRACE_
      void
      trace() const;
#endif

    protected:

      template<typename It>
      void
      copy_from_range(It, It);

      void
      value_swap(PB_DS_CLASS_C_DEC&);

      node_pointer
      recursive_copy_node(const_node_pointer);

    private:

      void
      initialize();

      inline void
      apply_update(node_pointer, null_node_update_pointer);

      template<typename Node_Update_>
      inline void
      apply_update(node_pointer, Node_Update_*);

      bool
      join_prep(PB_DS_CLASS_C_DEC&, split_join_branch_bag&);

      void
      rec_join_prep(const_node_pointer, const_node_pointer,
		    split_join_branch_bag&);

      void
      rec_join_prep(const_leaf_pointer, const_leaf_pointer,
		    split_join_branch_bag&);

      void
      rec_join_prep(const_leaf_pointer, const_internal_node_pointer,
		    split_join_branch_bag&);

      void
      rec_join_prep(const_internal_node_pointer, const_leaf_pointer,
		    split_join_branch_bag&);

      void
      rec_join_prep(const_internal_node_pointer, const_internal_node_pointer,
		    split_join_branch_bag&);

      node_pointer
      rec_join(node_pointer, node_pointer, size_type, split_join_branch_bag&);

      node_pointer
      rec_join(leaf_pointer, leaf_pointer, split_join_branch_bag&);

      node_pointer
      rec_join(leaf_pointer, internal_node_pointer, size_type,
	       split_join_branch_bag&);

      node_pointer
      rec_join(internal_node_pointer, leaf_pointer, size_type,
	       split_join_branch_bag&);

      node_pointer
      rec_join(internal_node_pointer, internal_node_pointer,
	       split_join_branch_bag&);

      size_type
      keys_diff_ind(typename e_access_traits::const_iterator, typename e_access_traits::const_iterator, typename e_access_traits::const_iterator, typename e_access_traits::const_iterator);

      internal_node_pointer
      insert_branch(node_pointer, node_pointer, split_join_branch_bag&);

      void
      update_min_max_for_inserted_leaf(leaf_pointer);

      void
      erase_leaf(leaf_pointer);

      inline void
      actual_erase_leaf(leaf_pointer);

      void
      clear_imp(node_pointer);

      void
      erase_fixup(internal_node_pointer);

      void
      update_min_max_for_erased_leaf(leaf_pointer);

      static inline const_e_iterator
      pref_begin(const_node_pointer);

      static inline const_e_iterator
      pref_end(const_node_pointer);

      inline node_pointer
      find_imp(const_key_reference);

      inline node_pointer
      lower_bound_imp(const_key_reference);

      inline node_pointer
      upper_bound_imp(const_key_reference);

      inline static const_leaf_pointer
      leftmost_descendant(const_node_pointer);

      inline static leaf_pointer
      leftmost_descendant(node_pointer);

      inline static const_leaf_pointer
      rightmost_descendant(const_node_pointer);

      inline static leaf_pointer
      rightmost_descendant(node_pointer);

#ifdef _GLIBCXX_DEBUG
      void
      assert_valid() const;

      void
      assert_iterators() const;

      void
      assert_reverse_iterators() const;

      static size_type
      recursive_count_leafs(const_node_pointer);
#endif

#ifdef PB_DS_PAT_TRIE_TRACE_
      static void
      trace_node(const_node_pointer, size_type);

      template<typename Metadata_>
      static void
      trace_node_metadata(const_node_pointer, type_to_type<Metadata_>);

      static void
      trace_node_metadata(const_node_pointer, type_to_type<null_node_metadata>);
#endif

      leaf_pointer
      split_prep(const_key_reference, PB_DS_CLASS_C_DEC&,
		 split_join_branch_bag&);

      node_pointer
      rec_split(node_pointer, const_e_iterator, const_e_iterator,
		PB_DS_CLASS_C_DEC&, split_join_branch_bag&);

      void
      split_insert_branch(size_type, const_e_iterator,
			  typename internal_node::iterator,
			  size_type, split_join_branch_bag&);

      static head_allocator s_head_allocator;
      static internal_node_allocator s_internal_node_allocator;
      static leaf_allocator s_leaf_allocator;

      head_pointer m_p_head;
      size_type m_size;
    };

#include <ext/pb_ds/detail/pat_trie_/constructors_destructor_fn_imps.hpp>
#include <ext/pb_ds/detail/pat_trie_/iterators_fn_imps.hpp>
#include <ext/pb_ds/detail/pat_trie_/insert_join_fn_imps.hpp>
#include <ext/pb_ds/detail/pat_trie_/erase_fn_imps.hpp>
#include <ext/pb_ds/detail/pat_trie_/find_fn_imps.hpp>
#include <ext/pb_ds/detail/pat_trie_/info_fn_imps.hpp>
#include <ext/pb_ds/detail/pat_trie_/policy_access_fn_imps.hpp>
#include <ext/pb_ds/detail/pat_trie_/split_fn_imps.hpp>
#include <ext/pb_ds/detail/pat_trie_/debug_fn_imps.hpp>
#include <ext/pb_ds/detail/pat_trie_/trace_fn_imps.hpp>
#include <ext/pb_ds/detail/pat_trie_/update_fn_imps.hpp>

#undef PB_DS_CLASS_C_DEC
#undef PB_DS_CLASS_T_DEC
#undef PB_DS_CLASS_NAME
#undef PB_DS_TYPES_TRAITS_C_DEC
#undef PB_DS_MAP_DEBUG_BASE_C_DEC
#undef PB_DS_V2F
#undef PB_DS_EP2VP
#undef PB_DS_V2S
#undef PB_DS_STATIC_ASSERT

  } // namespace detail
} // namespace pb_ds


code:
// -*- C++ -*-

// Copyright (C) 2005, 2006 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library 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 2, or (at your option) any later
// version.

// This library 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 library; see the file COPYING.  If not, write to
// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
// MA 02111-1307, USA.

// As a special exception, you may use this file as part of a free
// software library without restriction.  Specifically, if other files
// instantiate templates or use macros or inline functions from this
// file, or you compile this file and link it with other files to
// produce an executable, this file does not by itself cause the
// resulting executable to be covered by the GNU General Public
// License.  This exception does not however invalidate any other
// reasons why the executable file might be covered by the GNU General
// Public License.

// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.

// Permission to use, copy, modify, sell, and distribute this software
// is hereby granted without fee, provided that the above copyright
// notice appears in all copies, and that both that copyright notice
// and this permission notice appear in supporting documentation. None
// of the above authors, nor IBM Haifa Research Laboratories, make any
// representation about the suitability of this software for any
// purpose. It is provided "as is" without express or implied
// warranty.

/**
 * @file point_iterators.hpp
 * Contains an implementation class for bin_search_tree_.
 */

#ifndef PB_DS_PAT_TRIE_FIND_ITERATORS_HPP
#define PB_DS_PAT_TRIE_FIND_ITERATORS_HPP

#include <debug/debug.h>

namespace pb_ds
{
  namespace detail
  {

#define PB_DS_CONST_IT_C_DEC					\
    pat_trie_const_it_<						\
					Type_Traits,		\
					Node,			\
					Leaf,			\
					Head,			\
					Internal_Node,		\
					Is_Forward_Iterator,	\
					Allocator>

#define PB_DS_CONST_ODIR_IT_C_DEC				\
    pat_trie_const_it_<						\
					Type_Traits,		\
					Node,			\
					Leaf,			\
					Head,			\
					Internal_Node,		\
					!Is_Forward_Iterator,	\
					Allocator>

#define PB_DS_IT_C_DEC							\
    pat_trie_it_<							\
						Type_Traits,		\
						Node,			\
						Leaf,			\
						Head,			\
						Internal_Node,		\
						Is_Forward_Iterator,	\
						Allocator>

#define PB_DS_ODIR_IT_C_DEC						\
    pat_trie_it_<							\
						Type_Traits,		\
						Node,			\
						Leaf,			\
						Head,			\
						Internal_Node,		\
						!Is_Forward_Iterator,	\
						Allocator>

    // Const iterator.
    template<typename Type_Traits,
	     class Node,
	     class Leaf,
	     class Head,
	     class Internal_Node,
	     bool Is_Forward_Iterator,
	     class Allocator>
    class pat_trie_const_it_
    {

    private:
      typedef
      typename Allocator::template rebind<
      Node>::other::pointer
      node_pointer;

      typedef
      typename Allocator::template rebind<
	Leaf>::other::const_pointer
      const_leaf_pointer;

      typedef
      typename Allocator::template rebind<
	Leaf>::other::pointer
      leaf_pointer;

      typedef
      typename Allocator::template rebind<
	Head>::other::pointer
      head_pointer;

      typedef
      typename Allocator::template rebind<
	Internal_Node>::other::pointer
      internal_node_pointer;

    public:

      typedef std::bidirectional_iterator_tag iterator_category;

      typedef typename Allocator::difference_type difference_type;

      typedef typename Type_Traits::value_type value_type;

      typedef typename Type_Traits::pointer pointer;

      typedef typename Type_Traits::const_pointer const_pointer;

      typedef typename Type_Traits::reference reference;

      typedef typename Type_Traits::const_reference const_reference;

    public:

      inline
      pat_trie_const_it_(node_pointer p_nd = NULL) : m_p_nd(p_nd)
      { }

      inline
      pat_trie_const_it_(const PB_DS_CONST_ODIR_IT_C_DEC& other)
      : m_p_nd(other.m_p_nd)
      { }

      inline
      PB_DS_CONST_IT_C_DEC&
      operator=(const PB_DS_CONST_IT_C_DEC& other)
      {
	m_p_nd = other.m_p_nd;
	return *this;
      }

      inline
      PB_DS_CONST_IT_C_DEC&
      operator=(const PB_DS_CONST_ODIR_IT_C_DEC& other)
      {
	m_p_nd = other.m_p_nd;
	return *this;
      }

      inline const_pointer
      operator->() const
      {
	_GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == pat_trie_leaf_node_type);
	return &static_cast<leaf_pointer>(m_p_nd)->value();
      }

      inline const_reference
      operator*() const
      {
	_GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == pat_trie_leaf_node_type);
	return static_cast<leaf_pointer>(m_p_nd)->value();
      }

      inline bool
      operator==(const PB_DS_CONST_IT_C_DEC& other) const
      { return (m_p_nd == other.m_p_nd); }

      inline bool
      operator==(const PB_DS_CONST_ODIR_IT_C_DEC& other) const
      { return (m_p_nd == other.m_p_nd); }

      inline bool
      operator!=(const PB_DS_CONST_IT_C_DEC& other) const
      { return (m_p_nd != other.m_p_nd); }

      inline bool
      operator!=(const PB_DS_CONST_ODIR_IT_C_DEC& other) const
      { return (m_p_nd != other.m_p_nd); }

      inline PB_DS_CONST_IT_C_DEC&
      operator++()
      {
	inc(integral_constant<int,Is_Forward_Iterator>());
	return *this;
      }

      inline PB_DS_CONST_IT_C_DEC
      operator++(int)
      {
	PB_DS_CONST_IT_C_DEC ret_it(m_p_nd);
	operator++();
	return ret_it;
      }

      inline PB_DS_CONST_IT_C_DEC&
      operator--()
      {
	dec(integral_constant<int,Is_Forward_Iterator>());
	return *this;
      }

      inline PB_DS_CONST_IT_C_DEC
      operator--(int)
      {
	PB_DS_CONST_IT_C_DEC ret_it(m_p_nd);
	operator--();
	return ret_it;
      }

    protected:
      inline void
      inc(false_type)
      { dec(true_type()); }

      void
      inc(true_type)
      {
	if (m_p_nd->m_type == pat_trie_head_node_type)
	  {
	    m_p_nd = static_cast<head_pointer>(m_p_nd)->m_p_min;
	    return;
	  }

	node_pointer p_y = m_p_nd->m_p_parent;
	while (p_y->m_type != pat_trie_head_node_type &&
	       get_larger_sibling(m_p_nd) == NULL)
	  {
	    m_p_nd = p_y;
	    p_y = p_y->m_p_parent;
	  }

	if (p_y->m_type == pat_trie_head_node_type)
	  {
	    m_p_nd = p_y;
	    return;
	  }
	m_p_nd = leftmost_descendant(get_larger_sibling(m_p_nd));
      }

      inline void
      dec(false_type)
      { inc(true_type()); }

      void
      dec(true_type)
      {
	if (m_p_nd->m_type == pat_trie_head_node_type)
	  {
	    m_p_nd = static_cast<head_pointer>(m_p_nd)->m_p_max;
	    return;
	  }

	node_pointer p_y = m_p_nd->m_p_parent;
	while (p_y->m_type != pat_trie_head_node_type &&
	       get_smaller_sibling(m_p_nd) == NULL)
	  {
	    m_p_nd = p_y;
	    p_y = p_y->m_p_parent;
	  }

	if (p_y->m_type == pat_trie_head_node_type)
	  {
	    m_p_nd = p_y;
	    return;
	  }
	m_p_nd = rightmost_descendant(get_smaller_sibling(m_p_nd));
      }

      inline static node_pointer
      get_larger_sibling(node_pointer p_nd)
      {
	internal_node_pointer p_parent =
	  static_cast<internal_node_pointer>(p_nd->m_p_parent);

	typename Internal_Node::iterator it = p_parent->begin();
	while (*it != p_nd)
	  ++it;

	typename Internal_Node::iterator next_it = it;
	++next_it;
	return ((next_it == p_parent->end())? NULL :* next_it);
      }

      inline static node_pointer
      get_smaller_sibling(node_pointer p_nd)
      {
	internal_node_pointer p_parent =
	  static_cast<internal_node_pointer>(p_nd->m_p_parent);

	typename Internal_Node::iterator it = p_parent->begin();

	if (*it == p_nd)
	  return (NULL);
	typename Internal_Node::iterator prev_it;
	do
	  {
	    prev_it = it;
	    ++it;
	    if (*it == p_nd)
	      return (*prev_it);
	  }
	while (true);

	_GLIBCXX_DEBUG_ASSERT(false);
	return (NULL);
      }

      inline static leaf_pointer
      leftmost_descendant(node_pointer p_nd)
      {
	if (p_nd->m_type == pat_trie_leaf_node_type)
	  return static_cast<leaf_pointer>(p_nd);
	return static_cast<internal_node_pointer>(p_nd)->leftmost_descendant();
      }

      inline static leaf_pointer
      rightmost_descendant(node_pointer p_nd)
      {
	if (p_nd->m_type == pat_trie_leaf_node_type)
	  return static_cast<leaf_pointer>(p_nd);
	return static_cast<internal_node_pointer>(p_nd)->rightmost_descendant();
      }

    public:
      node_pointer m_p_nd;
    };

    // Iterator.
    template<typename Type_Traits,
	     class Node,
	     class Leaf,
	     class Head,
	     class Internal_Node,
	     bool Is_Forward_Iterator,
	     class Allocator>
    class pat_trie_it_ :
      public PB_DS_CONST_IT_C_DEC

    {
    private:
      typedef
      typename Allocator::template rebind<
      Node>::other::pointer
      node_pointer;

      typedef
      typename Allocator::template rebind<
	Leaf>::other::const_pointer
      const_leaf_pointer;

      typedef
      typename Allocator::template rebind<
	Leaf>::other::pointer
      leaf_pointer;

      typedef
      typename Allocator::template rebind<
	Head>::other::pointer
      head_pointer;

      typedef
      typename Allocator::template rebind<
	Internal_Node>::other::pointer
      internal_node_pointer;

    public:
      typedef typename Type_Traits::value_type value_type;

      typedef typename Type_Traits::const_pointer const_pointer;

      typedef typename Type_Traits::pointer pointer;

      typedef typename Type_Traits::const_reference const_reference;

      typedef typename Type_Traits::reference reference;

      inline
      pat_trie_it_(node_pointer p_nd = NULL) : PB_DS_CONST_IT_C_DEC((node_pointer)p_nd)
      { }

      inline
      pat_trie_it_(const PB_DS_ODIR_IT_C_DEC& other) : PB_DS_CONST_IT_C_DEC(other.m_p_nd)
      { }

      inline
      PB_DS_IT_C_DEC&
      operator=(const PB_DS_IT_C_DEC& other)
      {
	base_it_type::m_p_nd = other.m_p_nd;
	return *this;
      }

      inline
      PB_DS_IT_C_DEC&
      operator=(const PB_DS_ODIR_IT_C_DEC& other)
      {
	base_it_type::m_p_nd = other.m_p_nd;
	return *this;
      }

      inline pointer
      operator->() const
      {
	_GLIBCXX_DEBUG_ASSERT(base_it_type::m_p_nd->m_type == pat_trie_leaf_node_type);

	return &static_cast<leaf_pointer>(base_it_type::m_p_nd)->value();
      }

      inline reference
      operator*() const
      {
	_GLIBCXX_DEBUG_ASSERT(base_it_type::m_p_nd->m_type == pat_trie_leaf_node_type);
	return static_cast<leaf_pointer>(base_it_type::m_p_nd)->value();
      }

      inline PB_DS_IT_C_DEC&
      operator++()
      {
	PB_DS_CONST_IT_C_DEC::
	  operator++();
	return *this;
      }

      inline PB_DS_IT_C_DEC
      operator++(int)
      {
	PB_DS_IT_C_DEC ret_it(base_it_type::m_p_nd);
	operator++();
	return ret_it;
      }

      inline PB_DS_IT_C_DEC&
      operator--()
      {
	PB_DS_CONST_IT_C_DEC::operator--();
	return *this;
      }

      inline PB_DS_IT_C_DEC
      operator--(int)
      {
	PB_DS_IT_C_DEC ret_it(base_it_type::m_p_nd);
	operator--();
	return ret_it;
      }

    protected:
      typedef PB_DS_CONST_IT_C_DEC base_it_type;

      friend class PB_DS_CLASS_C_DEC;
    };

#undef PB_DS_CONST_IT_C_DEC
#undef PB_DS_CONST_ODIR_IT_C_DEC
#undef PB_DS_IT_C_DEC
#undef PB_DS_ODIR_IT_C_DEC

  } // namespace detail
} // namespace pb_ds

#endif

repo_name: veiledmerc/mira

license: mit


code:
// -*- C++ -*-

// Copyright (C) 2005, 2006 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library 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 2, or (at your option) any later
// version.

// This library 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 library; see the file COPYING.  If not, write to
// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
// MA 02111-1307, USA.

// As a special exception, you may use this file as part of a free
// software library without restriction.  Specifically, if other files
// instantiate templates or use macros or inline functions from this
// file, or you compile this file and link it with other files to
// produce an executable, this file does not by itself cause the
// resulting executable to be covered by the GNU General Public
// License.  This exception does not however invalidate any other
// reasons why the executable file might be covered by the GNU General
// Public License.

// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.

// Permission to use, copy, modify, sell, and distribute this software
// is hereby granted without fee, provided that the above copyright
// notice appears in all copies, and that both that copyright notice
// and this permission notice appear in supporting documentation. None
// of the above authors, nor IBM Haifa Research Laboratories, make any
// representation about the suitability of this software for any
// purpose. It is provided "as is" without express or implied
// warranty.

/**
 * @file policy_access_fn_imps.hpp
 * Contains an implementation class for bin_search_tree_.
 */

PB_DS_CLASS_T_DEC
typename PB_DS_CLASS_C_DEC::e_access_traits&
PB_DS_CLASS_C_DEC::
get_e_access_traits()
{ return *this; }

PB_DS_CLASS_T_DEC
const typename PB_DS_CLASS_C_DEC::e_access_traits&
PB_DS_CLASS_C_DEC::
get_e_access_traits() const
{ return *this; }

PB_DS_CLASS_T_DEC
typename PB_DS_CLASS_C_DEC::node_update&
PB_DS_CLASS_C_DEC::
get_node_update()
{ return *this; }

PB_DS_CLASS_T_DEC
const typename PB_DS_CLASS_C_DEC::node_update&
PB_DS_CLASS_C_DEC::
get_node_update() const
{ return *this; }


code:
// -*- C++ -*-

// Copyright (C) 2005, 2006 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library 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 2, or (at your option) any later
// version.

// This library 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 library; see the file COPYING.  If not, write to
// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
// MA 02111-1307, USA.

// As a special exception, you may use this file as part of a free
// software library without restriction.  Specifically, if other files
// instantiate templates or use macros or inline functions from this
// file, or you compile this file and link it with other files to
// produce an executable, this file does not by itself cause the
// resulting executable to be covered by the GNU General Public
// License.  This exception does not however invalidate any other
// reasons why the executable file might be covered by the GNU General
// Public License.

// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.

// Permission to use, copy, modify, sell, and distribute this software
// is hereby granted without fee, provided that the above copyright
// notice appears in all copies, and that both that copyright notice
// and this permission notice appear in supporting documentation. None
// of the above authors, nor IBM Haifa Research Laboratories, make any
// representation about the suitability of this software for any
// purpose. It is provided "as is" without express or implied
// warranty.

/**
 * @file r_erase_fn_imps.hpp
 * Contains an implementation class for bin_search_tree_.
 */

PB_DS_CLASS_T_DEC
inline void
PB_DS_CLASS_C_DEC::
actual_erase_node(node_pointer p_z)
{
  _GLIBCXX_DEBUG_ASSERT(m_size > 0);
  --m_size;
  _GLIBCXX_DEBUG_ONLY(erase_existing(PB_DS_V2F(p_z->m_value)));
  p_z->~node();
  s_node_allocator.deallocate(p_z, 1);
}

PB_DS_CLASS_T_DEC
inline void
PB_DS_CLASS_C_DEC::
update_min_max_for_erased_node(node_pointer p_z)
{
  if (m_size == 1)
    {
      m_p_head->m_p_left = m_p_head->m_p_right = m_p_head;
      return;
    }

  if (m_p_head->m_p_left == p_z)
    {
      iterator it(p_z);
      ++it;
      m_p_head->m_p_left = it.m_p_nd;
    }
  else if (m_p_head->m_p_right == p_z)
    {
      iterator it(p_z);
      --it;
      m_p_head->m_p_right = it.m_p_nd;
    }
}

PB_DS_CLASS_T_DEC
void
PB_DS_CLASS_C_DEC::
clear()
{
  _GLIBCXX_DEBUG_ONLY(assert_valid(true, true);)
  clear_imp(m_p_head->m_p_parent);
  m_size = 0;
  initialize();
  _GLIBCXX_DEBUG_ONLY(map_debug_base::clear();)
  _GLIBCXX_DEBUG_ONLY(assert_valid(true, true);)
}

PB_DS_CLASS_T_DEC
void
PB_DS_CLASS_C_DEC::
clear_imp(node_pointer p_nd)
{
  if (p_nd == NULL)
    return;
  clear_imp(p_nd->m_p_left);
  clear_imp(p_nd->m_p_right);
  p_nd->~Node();
  s_node_allocator.deallocate(p_nd, 1);
}


code:
// -*- C++ -*-

// Copyright (C) 2005, 2006 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library 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 2, or (at your option) any later
// version.

// This library 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 library; see the file COPYING.  If not, write to
// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
// MA 02111-1307, USA.

// As a special exception, you may use this file as part of a free
// software library without restriction.  Specifically, if other files
// instantiate templates or use macros or inline functions from this
// file, or you compile this file and link it with other files to
// produce an executable, this file does not by itself cause the
// resulting executable to be covered by the GNU General Public
// License.  This exception does not however invalidate any other
// reasons why the executable file might be covered by the GNU General
// Public License.

// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.

// Permission to use, copy, modify, sell, and distribute this software
// is hereby granted without fee, provided that the above copyright
// notice appears in all copies, and that both that copyright notice
// and this permission notice appear in supporting documentation. None
// of the above authors, nor IBM Haifa Research Laboratories, make any
// representation about the suitability of this software for any
// purpose. It is provided "as is" without express or implied
// warranty.

/**
 * @file rotate_fn_imps.hpp
 * Contains imps for rotating nodes.
 */

PB_DS_CLASS_T_DEC
inline void
PB_DS_CLASS_C_DEC::
rotate_left(node_pointer p_x)
{
  node_pointer p_y = p_x->m_p_right;
  p_x->m_p_right = p_y->m_p_left;

  if (p_y->m_p_left != NULL)
    p_y->m_p_left->m_p_parent = p_x;

  p_y->m_p_parent = p_x->m_p_parent;
  if (p_x == m_p_head->m_p_parent)
    m_p_head->m_p_parent = p_y;
  else if (p_x == p_x->m_p_parent->m_p_left)
    p_x->m_p_parent->m_p_left = p_y;
  else
    p_x->m_p_parent->m_p_right = p_y;

  p_y->m_p_left = p_x;
  p_x->m_p_parent = p_y;

  _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_x);)
  _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_y);)

  apply_update(p_x, (Node_Update* )this);
  apply_update(p_x->m_p_parent, (Node_Update* )this);
}

PB_DS_CLASS_T_DEC
inline void
PB_DS_CLASS_C_DEC::
rotate_right(node_pointer p_x)
{
  node_pointer p_y = p_x->m_p_left;
  p_x->m_p_left = p_y->m_p_right;

  if (p_y->m_p_right != NULL)
    p_y->m_p_right->m_p_parent = p_x;

  p_y->m_p_parent = p_x->m_p_parent;
  if (p_x == m_p_head->m_p_parent)
    m_p_head->m_p_parent = p_y;
  else if (p_x == p_x->m_p_parent->m_p_right)
    p_x->m_p_parent->m_p_right = p_y;
  else
    p_x->m_p_parent->m_p_left = p_y;

  p_y->m_p_right = p_x;
  p_x->m_p_parent = p_y;

  _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_x);)
  _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_y);)

  apply_update(p_x, (Node_Update* )this);
  apply_update(p_x->m_p_parent, (Node_Update* )this);
}

PB_DS_CLASS_T_DEC
inline void
PB_DS_CLASS_C_DEC::
rotate_parent(node_pointer p_nd)
{
  node_pointer p_parent = p_nd->m_p_parent;
  if (p_nd == p_parent->m_p_left)
    rotate_right(p_parent);
  else
    rotate_left(p_parent);
  _GLIBCXX_DEBUG_ASSERT(p_parent->m_p_parent = p_nd);
  _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_left == p_parent || p_nd->m_p_right == p_parent);
}

PB_DS_CLASS_T_DEC
inline void
PB_DS_CLASS_C_DEC::
apply_update(node_pointer /*p_nd*/, pb_ds::null_node_update*  /*p_update*/)
{ }

PB_DS_CLASS_T_DEC
template<typename Node_Update_>
inline void
PB_DS_CLASS_C_DEC::
apply_update(node_pointer p_nd, Node_Update_* p_update)
{
  p_update->operator()(& PB_DS_V2F(p_nd->m_value),(p_nd->m_p_left == NULL) ?
			NULL :
			& PB_DS_V2F(p_nd->m_p_left->m_value),(p_nd->m_p_right == NULL) ?
			NULL :
			& PB_DS_V2F(p_nd->m_p_right->m_value));
}

PB_DS_CLASS_T_DEC
template<typename Node_Update_>
inline void
PB_DS_CLASS_C_DEC::
update_to_top(node_pointer p_nd, Node_Update_* p_update)
{
  while (p_nd != m_p_head)
    {
      apply_update(p_nd, p_update);
      p_nd = p_nd->m_p_parent;
    }
}

PB_DS_CLASS_T_DEC
inline void
PB_DS_CLASS_C_DEC::
update_to_top(node_pointer /*p_nd*/, pb_ds::null_node_update*  /*p_update*/)
{ }


code:
// -*- C++ -*-

// Copyright (C) 2005, 2006 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library 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 2, or (at your option) any later
// version.

// This library 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 library; see the file COPYING.  If not, write to
// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
// MA 02111-1307, USA.

// As a special exception, you may use this file as part of a free
// software library without restriction.  Specifically, if other files
// instantiate templates or use macros or inline functions from this
// file, or you compile this file and link it with other files to
// produce an executable, this file does not by itself cause the
// resulting executable to be covered by the GNU General Public
// License.  This exception does not however invalidate any other
// reasons why the executable file might be covered by the GNU General
// Public License.

// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.

// Permission to use, copy, modify, sell, and distribute this software
// is hereby granted without fee, provided that the above copyright
// notice appears in all copies, and that both that copyright notice
// and this permission notice appear in supporting documentation. None
// of the above authors, nor IBM Haifa Research Laboratories, make any
// representation about the suitability of this software for any
// purpose. It is provided "as is" without express or implied
// warranty.

/**
 * @file split_fn_imps.hpp
 * Contains an implementation class for bin_search_tree_.
 */

PB_DS_CLASS_T_DEC
void
PB_DS_CLASS_C_DEC::
split(const_key_reference r_key, PB_DS_CLASS_C_DEC& other)
{
  _GLIBCXX_DEBUG_ONLY(assert_valid(););
  _GLIBCXX_DEBUG_ONLY(other.assert_valid(););
  split_join_branch_bag bag;
  leaf_pointer p_split_lf = split_prep(r_key, other, bag);
  if (p_split_lf == NULL)
    {
      _GLIBCXX_DEBUG_ASSERT(bag.empty());
      _GLIBCXX_DEBUG_ONLY(assert_valid();)
      _GLIBCXX_DEBUG_ONLY(other.assert_valid();)
      return;
    }

  _GLIBCXX_DEBUG_ASSERT(!bag.empty());
  other.clear();
  m_p_head->m_p_parent = rec_split(m_p_head->m_p_parent,
				   pref_begin(p_split_lf),
				   pref_end(p_split_lf),
				   other,
				   bag);

  m_p_head->m_p_parent->m_p_parent = m_p_head;

  other.m_p_head->m_p_max = m_p_head->m_p_max;
  m_p_head->m_p_max = rightmost_descendant(m_p_head->m_p_parent);
  other.m_p_head->m_p_min =
    other.leftmost_descendant(other.m_p_head->m_p_parent);

  other.m_size = std::distance(other.PB_DS_CLASS_C_DEC::begin(),
			       other.PB_DS_CLASS_C_DEC::end());
  m_size -= other.m_size;
  _GLIBCXX_DEBUG_ONLY(assert_valid(););
  _GLIBCXX_DEBUG_ONLY(other.assert_valid(););
}

PB_DS_CLASS_T_DEC
typename PB_DS_CLASS_C_DEC::leaf_pointer
PB_DS_CLASS_C_DEC::
split_prep(const_key_reference r_key, PB_DS_CLASS_C_DEC& other, split_join_branch_bag& r_bag)
{
  _GLIBCXX_DEBUG_ASSERT(r_bag.empty());
  if (m_size == 0)
    {
      other.clear();
      _GLIBCXX_DEBUG_ONLY(assert_valid(););
      _GLIBCXX_DEBUG_ONLY(other.assert_valid(););
      return (NULL);
    }

  if (synth_e_access_traits::cmp_keys(r_key,
				      PB_DS_V2F(static_cast<const_leaf_pointer>(m_p_head->m_p_min)->value())))
    {
      other.clear();
      value_swap(other);
      _GLIBCXX_DEBUG_ONLY(assert_valid(););
      _GLIBCXX_DEBUG_ONLY(other.assert_valid(););
      return (NULL);
    }

  if (!synth_e_access_traits::cmp_keys(r_key,
				       PB_DS_V2F(static_cast<const_leaf_pointer>(m_p_head->m_p_max)->value())))
    {
      _GLIBCXX_DEBUG_ONLY(assert_valid(););
      _GLIBCXX_DEBUG_ONLY(other.assert_valid(););
      return (NULL);
    }

  iterator it = lower_bound(r_key);

  if (!synth_e_access_traits::equal_keys(PB_DS_V2F(*it), r_key))
    --it;

  node_pointer p_nd = it.m_p_nd;
  _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == pat_trie_leaf_node_type);
  leaf_pointer p_ret_l = static_cast<leaf_pointer>(p_nd);
  while (p_nd->m_type != pat_trie_head_node_type)
    {
      r_bag.add_branch();
      p_nd = p_nd->m_p_parent;
    }
  _GLIBCXX_DEBUG_ONLY(map_debug_base::split(r_key,(synth_e_access_traits& )(*this), other);)

  return (p_ret_l);
}

PB_DS_CLASS_T_DEC
typename PB_DS_CLASS_C_DEC::node_pointer
PB_DS_CLASS_C_DEC::
rec_split(node_pointer p_nd, const_e_iterator b_it, const_e_iterator e_it, PB_DS_CLASS_C_DEC& other, split_join_branch_bag& r_bag)
{
  if (p_nd->m_type == pat_trie_leaf_node_type)
    {
      _GLIBCXX_DEBUG_ASSERT(other.m_p_head->m_p_parent == NULL);
      return (p_nd);
    }

  _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == pat_trie_internal_node_type);
  internal_node_pointer p_internal_nd = static_cast<internal_node_pointer>(p_nd);

  node_pointer p_child_ret = rec_split(p_internal_nd->get_child_node(b_it, e_it, this), b_it, e_it, other, r_bag);

  _GLIBCXX_DEBUG_ONLY(p_child_ret->assert_valid(this);)
  p_internal_nd->replace_child(p_child_ret, b_it, e_it, this);
  apply_update(p_internal_nd, (node_update* )this);

  typename internal_node::iterator child_it  =
    p_internal_nd->get_child_it(b_it, e_it, this);

  const size_type lhs_num_children =
    std::distance(p_internal_nd->begin(), child_it) + 1;

  _GLIBCXX_DEBUG_ASSERT(lhs_num_children > 0);

  size_type rhs_num_children =
    std::distance(p_internal_nd->begin(), p_internal_nd->end()) -
    lhs_num_children;

  if (rhs_num_children == 0)
    {
      apply_update(p_internal_nd, (node_update* )this);
      return (p_internal_nd);
    }

  ++child_it;
  other.split_insert_branch(p_internal_nd->get_e_ind(),
			    b_it, child_it, rhs_num_children, r_bag);

  child_it = p_internal_nd->get_child_it(b_it, e_it, this);
  ++child_it;
  while (rhs_num_children != 0)
    {
      child_it = p_internal_nd->remove_child(child_it);
      --rhs_num_children;
    }

  apply_update(p_internal_nd, (node_update* )this);
  _GLIBCXX_DEBUG_ASSERT(std::distance(p_internal_nd->begin(),
				      p_internal_nd->end()) >= 1);

  if (std::distance(p_internal_nd->begin(), p_internal_nd->end()) > 1)
    {
      p_internal_nd->update_prefixes(this);
      _GLIBCXX_DEBUG_ONLY(p_internal_nd->assert_valid(this);)
      apply_update(p_internal_nd, (node_update* )this);
      return (p_internal_nd);
    }

  node_pointer p_ret =* p_internal_nd->begin();
  p_internal_nd->~internal_node();
  s_internal_node_allocator.deallocate(p_internal_nd, 1);
  apply_update(p_ret, (node_update* )this);
  return (p_ret);
}

PB_DS_CLASS_T_DEC
void
PB_DS_CLASS_C_DEC::
split_insert_branch(size_type e_ind, const_e_iterator b_it, typename internal_node::iterator child_b_it, size_type num_children, split_join_branch_bag& r_bag)
{
#ifdef _GLIBCXX_DEBUG
  if (m_p_head->m_p_parent != NULL)
    m_p_head->m_p_parent->assert_valid(this);
#endif

  const size_type total_num_children =((m_p_head->m_p_parent == NULL)? 0 : 1) + num_children;

  if (total_num_children == 0)
    {
      _GLIBCXX_DEBUG_ASSERT(m_p_head->m_p_parent == NULL);
      return;
    }

  if (total_num_children == 1)
    {
      if (m_p_head->m_p_parent != NULL)
        {
	  _GLIBCXX_DEBUG_ONLY(m_p_head->m_p_parent->assert_valid(this);)
          return;
        }

      _GLIBCXX_DEBUG_ASSERT(m_p_head->m_p_parent == NULL);
      m_p_head->m_p_parent =* child_b_it;
      m_p_head->m_p_parent->m_p_parent = m_p_head;
      apply_update(m_p_head->m_p_parent, (node_update* )this);
      _GLIBCXX_DEBUG_ONLY(m_p_head->m_p_parent->assert_valid(this);)
      return;
    }

  _GLIBCXX_DEBUG_ASSERT(total_num_children > 1);
  internal_node_pointer p_new_root = r_bag.get_branch();
  new (p_new_root) internal_node(e_ind, b_it);
  size_type num_inserted = 0;
  while (num_inserted++ < num_children)
    {
      _GLIBCXX_DEBUG_ONLY((*child_b_it)->assert_valid(this);)
        p_new_root->add_child(*child_b_it, pref_begin(*child_b_it),
			      pref_end(*child_b_it), this);
      ++child_b_it;
    }

  if (m_p_head->m_p_parent != NULL)
    p_new_root->add_child(m_p_head->m_p_parent,
			  pref_begin(m_p_head->m_p_parent),
			  pref_end(m_p_head->m_p_parent), this);

  m_p_head->m_p_parent = p_new_root;
  p_new_root->m_p_parent = m_p_head;
  apply_update(m_p_head->m_p_parent, (node_update* )this);
  _GLIBCXX_DEBUG_ONLY(m_p_head->m_p_parent->assert_valid(this);)
}


code:
// -*- C++ -*-

// Copyright (C) 2005, 2006 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library 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 2, or (at your option) any later
// version.

// This library 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 library; see the file COPYING.  If not, write to
// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
// MA 02111-1307, USA.

// As a special exception, you may use this file as part of a free
// software library without restriction.  Specifically, if other files
// instantiate templates or use macros or inline functions from this
// file, or you compile this file and link it with other files to
// produce an executable, this file does not by itself cause the
// resulting executable to be covered by the GNU General Public
// License.  This exception does not however invalidate any other
// reasons why the executable file might be covered by the GNU General
// Public License.

// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.

// Permission to use, copy, modify, sell, and distribute this software
// is hereby granted without fee, provided that the above copyright
// notice appears in all copies, and that both that copyright notice
// and this permission notice appear in supporting documentation. None
// of the above authors, nor IBM Haifa Research Laboratories, make any
// representation about the suitability of this software for any
// purpose. It is provided "as is" without express or implied
// warranty.

/**
 * @file split_join_branch_bag.hpp
 * Contains an implementation class for pat_trie_.
 */

class split_join_branch_bag
{
private:
  typedef
  std::list<
  internal_node_pointer,
  typename Allocator::template rebind<
  internal_node_pointer>::other>
  bag_t;

public:

  void
  add_branch()
  {
    internal_node_pointer p_nd = s_internal_node_allocator.allocate(1);
    try
      {
	m_bag.push_back(p_nd);
      }
    catch(...)
      {
	s_internal_node_allocator.deallocate(p_nd, 1);
	__throw_exception_again;
      }
  }

  internal_node_pointer
  get_branch()
  {
    _GLIBCXX_DEBUG_ASSERT(!m_bag.empty());
    internal_node_pointer p_nd =* m_bag.begin();
    m_bag.pop_front();
    return p_nd;
  }

  ~split_join_branch_bag()
  {
    while (!m_bag.empty())
      {
	internal_node_pointer p_nd =* m_bag.begin();
	s_internal_node_allocator.deallocate(p_nd, 1);
	m_bag.pop_front();
      }
  }

  inline bool
  empty() const
  { return m_bag.empty(); }

private:
  bag_t m_bag;
};


code:
// -*- C++ -*-

// Copyright (C) 2005, 2006 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library 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 2, or (at your option) any later
// version.

// This library 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 library; see the file COPYING.  If not, write to
// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
// MA 02111-1307, USA.

// As a special exception, you may use this file as part of a free
// software library without restriction.  Specifically, if other files
// instantiate templates or use macros or inline functions from this
// file, or you compile this file and link it with other files to
// produce an executable, this file does not by itself cause the
// resulting executable to be covered by the GNU General Public
// License.  This exception does not however invalidate any other
// reasons why the executable file might be covered by the GNU General
// Public License.

// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.

// Permission to use, copy, modify, sell, and distribute this software
// is hereby granted without fee, provided that the above copyright
// notice appears in all copies, and that both that copyright notice
// and this permission notice appear in supporting documentation. None
// of the above authors, nor IBM Haifa Research Laboratories, make any
// representation about the suitability of this software for any
// purpose. It is provided "as is" without express or implied
// warranty.

/**
 * @file synth_e_access_traits.hpp
 * Contains an implementation class for a patricia tree.
 */

#ifndef PB_DS_SYNTH_E_ACCESS_TRAITS_HPP
#define PB_DS_SYNTH_E_ACCESS_TRAITS_HPP

#include <ext/pb_ds/detail/type_utils.hpp>

namespace pb_ds
{
  namespace detail
  {

#define PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC				\
    template<typename Type_Traits, bool Set, class E_Access_Traits>

#define PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC				\
    synth_e_access_traits<						\
						Type_Traits,		\
						Set,			\
						E_Access_Traits>

    template<typename Type_Traits, bool Set, class E_Access_Traits>
    struct synth_e_access_traits : public E_Access_Traits
    {

    private:
      typedef E_Access_Traits base_type;

      typedef Type_Traits type_traits;

      typedef typename type_traits::const_key_reference const_key_reference;

      typedef typename type_traits::const_reference const_reference;

    public:
      synth_e_access_traits();

      synth_e_access_traits(const E_Access_Traits& r_traits);

      inline bool
      equal_prefixes(typename base_type::const_iterator b_l, typename base_type::const_iterator e_l, typename base_type::const_iterator b_r, typename base_type::const_iterator e_r, bool compare_after = true) const;

      bool
      equal_keys(const_key_reference r_lhs_key, const_key_reference r_rhs_key) const;

      bool
      cmp_prefixes(typename base_type::const_iterator b_l, typename base_type::const_iterator e_l, typename base_type::const_iterator b_r, typename base_type::const_iterator e_r, bool compare_after = false) const;

      bool
      cmp_keys(const_key_reference r_lhs_key, const_key_reference r_rhs_key) const;

      inline static const_key_reference
      extract_key(const_reference r_val);

#ifdef _GLIBCXX_DEBUG
      bool
      operator()(const_key_reference r_lhs, const_key_reference r_rhs);
#endif

    private:
      inline static const_key_reference
      extract_key(const_reference r_val, true_type);

      inline static const_key_reference
      extract_key(const_reference r_val, false_type);

    private:
      static integral_constant<int,Set> s_set_ind;
    };

    PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC
    integral_constant<int,Set>
    PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC::s_set_ind;

    PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC
    PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC::
    synth_e_access_traits()
    { }

    PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC
    PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC::
    synth_e_access_traits(const E_Access_Traits& r_traits) :
      E_Access_Traits(r_traits)
    { }

    PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC
    inline bool
    PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC::
    equal_prefixes(typename base_type::const_iterator b_l, typename base_type::const_iterator e_l, typename base_type::const_iterator b_r, typename base_type::const_iterator e_r, bool compare_after /*= false */) const
    {
      while (b_l != e_l)
	{
	  if (b_r == e_r)
	    return (false);
	  if (base_type::e_pos(*b_l) != base_type::e_pos(*b_r))
	    return (false);
	  ++b_l;
	  ++b_r;
	}
      return (!compare_after || b_r == e_r);
    }

    PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC
    bool
    PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC::
    equal_keys(const_key_reference r_lhs_key, const_key_reference r_rhs_key) const
    {
      return (equal_prefixes(base_type::begin(r_lhs_key),
			     base_type::end(r_lhs_key),
			     base_type::begin(r_rhs_key),
			     base_type::end(r_rhs_key),
			     true));
    }

    PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC
    bool
    PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC::
    cmp_prefixes(typename base_type::const_iterator b_l, typename base_type::const_iterator e_l, typename base_type::const_iterator b_r, typename base_type::const_iterator e_r, bool compare_after /* = false*/) const
    {
      while (b_l != e_l)
	{
	  if (b_r == e_r)
	    return (false);
	  const typename base_type::size_type l_pos =
	    base_type::e_pos(*b_l);
	  const typename base_type::size_type r_pos =
	    base_type::e_pos(*b_r);
	  if (l_pos != r_pos)
	    return (l_pos < r_pos);
	  ++b_l;
	  ++b_r;
	}

      if (!compare_after)
	return (false);
      return (b_r != e_r);
    }

    PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC
    bool
    PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC::
    cmp_keys(const_key_reference r_lhs_key, const_key_reference r_rhs_key) const
    {
      return (cmp_prefixes(base_type::begin(r_lhs_key),
			   base_type::end(r_lhs_key),
			   base_type::begin(r_rhs_key),
			   base_type::end(r_rhs_key),
			   true));
    }

    PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC
    inline typename PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC::const_key_reference
    PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC::
    extract_key(const_reference r_val)
    {
      return (extract_key(r_val, s_set_ind));
    }

    PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC
    inline typename PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC::const_key_reference
    PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC::
    extract_key(const_reference r_val, true_type)
    {
      return (r_val);
    }

    PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC
    inline typename PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC::const_key_reference
    PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC::
    extract_key(const_reference r_val, false_type)
    {
      return (r_val.first);
    }

#ifdef _GLIBCXX_DEBUG
    PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC
    bool
    PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC::
    operator()(const_key_reference r_lhs, const_key_reference r_rhs)
    {
      return (cmp_keys(r_lhs, r_rhs));
    }
#endif

#undef PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC
#undef PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC

  } // namespace detail
} // namespace pb_ds

#endif


code:
// -*- C++ -*-

// Copyright (C) 2005, 2006 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library 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 2, or (at your option) any later
// version.

// This library 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 library; see the file COPYING.  If not, write to
// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
// MA 02111-1307, USA.

// As a special exception, you may use this file as part of a free
// software library without restriction.  Specifically, if other files
// instantiate templates or use macros or inline functions from this
// file, or you compile this file and link it with other files to
// produce an executable, this file does not by itself cause the
// resulting executable to be covered by the GNU General Public
// License.  This exception does not however invalidate any other
// reasons why the executable file might be covered by the GNU General
// Public License.

// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.

// Permission to use, copy, modify, sell, and distribute this software
// is hereby granted without fee, provided that the above copyright
// notice appears in all copies, and that both that copyright notice
// and this permission notice appear in supporting documentation. None
// of the above authors, nor IBM Haifa Research Laboratories, make any
// representation about the suitability of this software for any
// purpose. It is provided "as is" without express or implied
// warranty.

/**
 * @file trace_fn_imps.hpp
 * Contains an implementation class for pat_trie_.
 */

#ifdef PB_DS_PAT_TRIE_TRACE_

PB_DS_CLASS_T_DEC
void
PB_DS_CLASS_C_DEC::
trace() const
{
  std::cerr << std::endl;
  if (m_p_head->m_p_parent == NULL)
    return;
  trace_node(m_p_head->m_p_parent, 0);
  std::cerr << std::endl;
}

PB_DS_CLASS_T_DEC
void
PB_DS_CLASS_C_DEC::
trace_node(const_node_pointer p_nd, size_type level)
{
  for (size_type i = 0; i < level; ++i)
    std::cerr << ' ';
  std::cerr << p_nd << " ";
  std::cerr << ((p_nd->m_type == pat_trie_leaf_node_type) ? "l " : "i ");

  trace_node_metadata(p_nd, type_to_type<typename node::metadata_type>());
  typename e_access_traits::const_iterator el_it = pref_begin(p_nd);
  while (el_it != pref_end(p_nd))
    {
      std::cerr <<* el_it;
      ++el_it;
    }

  if (p_nd->m_type == pat_trie_leaf_node_type)
    {
      std::cerr << std::endl;
      return;
    }

  const_internal_node_pointer p_internal =
    static_cast<const_internal_node_pointer>(p_nd);

  std::cerr << " " <<
    static_cast<unsigned long>(p_internal->get_e_ind()) << std::endl;

  const size_type num_children = std::distance(p_internal->begin(),
					       p_internal->end());

  for (size_type child_i = 0; child_i < num_children; ++child_i)
    {
      typename internal_node::const_iterator child_it =
	p_internal->begin();
      std::advance(child_it, num_children - child_i - 1);
      trace_node(*child_it, level + 1);
    }
}

PB_DS_CLASS_T_DEC
template<typename Metadata_>
void
PB_DS_CLASS_C_DEC::
trace_node_metadata(const_node_pointer p_nd, type_to_type<Metadata_>)
{
  std::cerr << "(" << static_cast<unsigned long>(p_nd->get_metadata()) << ") ";
}

PB_DS_CLASS_T_DEC
void
PB_DS_CLASS_C_DEC::
trace_node_metadata(const_node_pointer, type_to_type<null_node_metadata>)
{ }

#endif


code:
// -*- C++ -*-

// Copyright (C) 2005, 2006 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library 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 2, or (at your option) any later
// version.

// This library 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 library; see the file COPYING.  If not, write to
// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
// MA 02111-1307, USA.

// As a special exception, you may use this file as part of a free
// software library without restriction.  Specifically, if other files
// instantiate templates or use macros or inline functions from this
// file, or you compile this file and link it with other files to
// produce an executable, this file does not by itself cause the
// resulting executable to be covered by the GNU General Public
// License.  This exception does not however invalidate any other
// reasons why the executable file might be covered by the GNU General
// Public License.

// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.

// Permission to use, copy, modify, sell, and distribute this software
// is hereby granted without fee, provided that the above copyright
// notice appears in all copies, and that both that copyright notice
// and this permission notice appear in supporting documentation. None
// of the above authors, nor IBM Haifa Research Laboratories, make any
// representation about the suitability of this software for any
// purpose. It is provided "as is" without express or implied
// warranty.

/**
 * @file traits.hpp
 * Contains an implementation class for pat_trie_.
 */

#ifndef PB_DS_PAT_TRIE_NODE_AND_IT_TRAITS_HPP
#define PB_DS_PAT_TRIE_NODE_AND_IT_TRAITS_HPP

#include <ext/pb_ds/detail/pat_trie_/node_base.hpp>
#include <ext/pb_ds/detail/pat_trie_/head.hpp>
#include <ext/pb_ds/detail/pat_trie_/leaf.hpp>
#include <ext/pb_ds/detail/pat_trie_/internal_node.hpp>
#include <ext/pb_ds/detail/pat_trie_/point_iterators.hpp>
#include <ext/pb_ds/detail/pat_trie_/node_iterators.hpp>
#include <ext/pb_ds/detail/pat_trie_/synth_e_access_traits.hpp>

namespace pb_ds
{
  namespace detail
  {

    template<typename Key,
	     typename Mapped,
	     class E_Access_Traits,
	     template<typename Const_Node_Iterator,
		      class Node_Iterator,
		      class Cmp_Fn_,
		      class Allocator_>
    class Node_Update,
	     class Allocator>
    struct trie_traits<
      Key,
      Mapped,
      E_Access_Traits,
      Node_Update,
      pat_trie_tag,
      Allocator>
    {
    private:
      typedef types_traits< Key, Mapped, Allocator, false> type_traits;

    public:
      typedef
      typename trie_node_metadata_selector<
      Key,
      Mapped,
      E_Access_Traits,
      Node_Update,
      Allocator>::type
      metadata_type;

      typedef E_Access_Traits e_access_traits;

      typedef
      synth_e_access_traits<
	type_traits,
	false,
	e_access_traits>
      synth_e_access_traits;

      typedef
      pat_trie_node_base<
	type_traits,
	synth_e_access_traits,
	metadata_type,
	Allocator>
      node;

      typedef
      pat_trie_leaf<
	type_traits,
	synth_e_access_traits,
	metadata_type,
	Allocator>
      leaf;

      typedef
      pat_trie_head<
	type_traits,
	synth_e_access_traits,
	metadata_type,
	Allocator>
      head;

      typedef
      pat_trie_internal_node<
	type_traits,
	synth_e_access_traits,
	metadata_type,
	Allocator>
      internal_node;

      typedef
      pat_trie_const_it_<
	type_traits,
	node,
	leaf,
	head,
	internal_node,
	true,
	Allocator>
      const_iterator;

      typedef
      pat_trie_it_<
	type_traits,
	node,
	leaf,
	head,
	internal_node,
	true,
	Allocator>
      iterator;

      typedef
      pat_trie_const_it_<
	type_traits,
	node,
	leaf,
	head,
	internal_node,
	false,
	Allocator>
      const_reverse_iterator;

      typedef
      pat_trie_it_<
	type_traits,
	node,
	leaf,
	head,
	internal_node,
	false,
	Allocator>
      reverse_iterator;

      typedef
      pat_trie_const_node_it_<
	node,
	leaf,
	head,
	internal_node,
	const_iterator,
	iterator,
	synth_e_access_traits,
	Allocator>
      const_node_iterator;

      typedef
      pat_trie_node_it_<
	node,
	leaf,
	head,
	internal_node,
	const_iterator,
	iterator,
	synth_e_access_traits,
	Allocator>
      node_iterator;

      typedef
      Node_Update<
	const_node_iterator,
	node_iterator,
	E_Access_Traits,
	Allocator>
      node_update;

      typedef
      pb_ds::null_trie_node_update<
	const_node_iterator,
	node_iterator,
	E_Access_Traits,
	Allocator>*
      null_node_update_pointer;
    };

    template<typename Key,
	     class E_Access_Traits,
	     template<typename Const_Node_Iterator,
		      class Node_Iterator,
		      class Cmp_Fn_,
		      class Allocator_>
    class Node_Update,
	     class Allocator>
    struct trie_traits<
      Key,
      null_mapped_type,
      E_Access_Traits,
      Node_Update,
      pat_trie_tag,
      Allocator>
    {
    private:
      typedef
      types_traits<
      Key,
      null_mapped_type,
      Allocator,
      false>
      type_traits;

    public:
      typedef
      typename trie_node_metadata_selector<
      Key,
      null_mapped_type,
      E_Access_Traits,
      Node_Update,
      Allocator>::type
      metadata_type;

      typedef E_Access_Traits e_access_traits;

      typedef
      synth_e_access_traits<
	type_traits,
	true,
	e_access_traits>
      synth_e_access_traits;

      typedef
      pat_trie_node_base<
	type_traits,
	synth_e_access_traits,
	metadata_type,
	Allocator>
      node;

      typedef
      pat_trie_leaf<
	type_traits,
	synth_e_access_traits,
	metadata_type,
	Allocator>
      leaf;

      typedef
      pat_trie_head<
	type_traits,
	synth_e_access_traits,
	metadata_type,
	Allocator>
      head;

      typedef
      pat_trie_internal_node<
	type_traits,
	synth_e_access_traits,
	metadata_type,
	Allocator>
      internal_node;

      typedef
      pat_trie_const_it_<
	type_traits,
	node,
	leaf,
	head,
	internal_node,
	true,
	Allocator>
      const_iterator;

      typedef const_iterator iterator;

      typedef
      pat_trie_const_it_<
	type_traits,
	node,
	leaf,
	head,
	internal_node,
	false,
	Allocator>
      const_reverse_iterator;

      typedef const_reverse_iterator reverse_iterator;

      typedef
      pat_trie_const_node_it_<
	node,
	leaf,
	head,
	internal_node,
	const_iterator,
	iterator,
	synth_e_access_traits,
	Allocator>
      const_node_iterator;

      typedef const_node_iterator node_iterator;

      typedef
      Node_Update<
	const_node_iterator,
	node_iterator,
	E_Access_Traits,
	Allocator>
      node_update;

      typedef
      pb_ds::null_trie_node_update<
	const_node_iterator,
	const_node_iterator,
	E_Access_Traits,
	Allocator>*
      null_node_update_pointer;
    };

  } // namespace detail
} // namespace pb_ds

#endif // #ifndef PB_DS_PAT_TRIE_NODE_AND_IT_TRAITS_HPP


code:
// -*- C++ -*-

// Copyright (C) 2005, 2006 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library 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 2, or (at your option) any later
// version.

// This library 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 library; see the file COPYING.  If not, write to
// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
// MA 02111-1307, USA.

// As a special exception, you may use this file as part of a free
// software library without restriction.  Specifically, if other files
// instantiate templates or use macros or inline functions from this
// file, or you compile this file and link it with other files to
// produce an executable, this file does not by itself cause the
// resulting executable to be covered by the GNU General Public
// License.  This exception does not however invalidate any other
// reasons why the executable file might be covered by the GNU General
// Public License.

// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.

// Permission to use, copy, modify, sell, and distribute this software
// is hereby granted without fee, provided that the above copyright
// notice appears in all copies, and that both that copyright notice
// and this permission notice appear in supporting documentation. None
// of the above authors, nor IBM Haifa Research Laboratories, make any
// representation about the suitability of this software for any
// purpose. It is provided "as is" without express or implied
// warranty.

/**
 * @file update_fn_imps.hpp
 * Contains an implementation class for pat_trie_.
 */

PB_DS_CLASS_T_DEC
inline void
PB_DS_CLASS_C_DEC::
apply_update(node_pointer /*p_nd*/, null_node_update_pointer)
{ }

PB_DS_CLASS_T_DEC
template<typename Node_Update_>
inline void
PB_DS_CLASS_C_DEC::
apply_update(node_pointer p_nd, Node_Update_*  /*p_update*/)
{
  Node_Update_::operator()(node_iterator(p_nd, this),
			   const_node_iterator(NULL, this));
}


code:
// -*- C++ -*-

// Copyright (C) 2005, 2006 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library 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 2, or (at your option) any later
// version.

// This library 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 library; see the file COPYING.  If not, write to
// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
// MA 02111-1307, USA.

// As a special exception, you may use this file as part of a free
// software library without restriction.  Specifically, if other files
// instantiate templates or use macros or inline functions from this
// file, or you compile this file and link it with other files to
// produce an executable, this file does not by itself cause the
// resulting executable to be covered by the GNU General Public
// License.  This exception does not however invalidate any other
// reasons why the executable file might be covered by the GNU General
// Public License.

// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.

// Permission to use, copy, modify, sell, and distribute this software
// is hereby granted without fee, provided that the above copyright
// notice appears in all copies, and that both that copyright notice
// and this permission notice appear in supporting documentation. None
// of the above authors, nor IBM Haifa Research Laboratories, make any
// representation about the suitability of this software for any
// purpose. It is provided "as is" without express or implied
// warranty.

/**
 * @file priority_queue_base_dispatch.hpp
 * Contains an pqiative container dispatching base.
 */

#ifndef PB_DS_PRIORITY_QUEUE_BASE_DS_DISPATCHER_HPP
#define PB_DS_PRIORITY_QUEUE_BASE_DS_DISPATCHER_HPP

#include <ext/pb_ds/detail/pairing_heap_/pairing_heap_.hpp>
#include <ext/pb_ds/detail/binomial_heap_/binomial_heap_.hpp>
#include <ext/pb_ds/detail/rc_binomial_heap_/rc_binomial_heap_.hpp>
#include <ext/pb_ds/detail/binary_heap_/binary_heap_.hpp>
#include <ext/pb_ds/detail/thin_heap_/thin_heap_.hpp>

namespace pb_ds
{
    namespace detail
    {

      template<typename Value_Type, typename Cmp_Fn, typename Tag, typename Allocator>
      struct priority_queue_base_dispatch;

      template<typename Value_Type, typename Cmp_Fn, typename Allocator>
      struct priority_queue_base_dispatch<Value_Type, Cmp_Fn, pairing_heap_tag, Allocator>
      {
	typedef pairing_heap_< Value_Type, Cmp_Fn, Allocator> type;
      };

      template<typename Value_Type, typename Cmp_Fn, typename Allocator>
      struct priority_queue_base_dispatch<Value_Type, Cmp_Fn, binomial_heap_tag, Allocator>
      {
	typedef binomial_heap_< Value_Type, Cmp_Fn, Allocator> type;
      };

      template<typename Value_Type, typename Cmp_Fn, typename Allocator>
      struct priority_queue_base_dispatch<Value_Type, Cmp_Fn, rc_binomial_heap_tag, Allocator>
      {
	typedef rc_binomial_heap_< Value_Type, Cmp_Fn, Allocator> type;
      };

      template<typename Value_Type, typename Cmp_Fn, typename Allocator>
      struct priority_queue_base_dispatch<Value_Type, Cmp_Fn, binary_heap_tag, Allocator>
      {
	typedef binary_heap_< Value_Type, Cmp_Fn, Allocator> type;
      };

      template<typename Value_Type, typename Cmp_Fn, typename Allocator>
      struct priority_queue_base_dispatch<Value_Type, Cmp_Fn, thin_heap_tag, Allocator>
      {
	typedef thin_heap_< Value_Type, Cmp_Fn, Allocator> type;
      };

    } // namespace detail
} // namespace pb_ds

#endif // #ifndef PB_DS_PRIORITY_QUEUE_BASE_DS_DISPATCHER_HPP


code:
// -*- C++ -*-

// Copyright (C) 2005, 2006 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library 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 2, or (at your option) any later
// version.

// This library 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 library; see the file COPYING.  If not, write to
// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
// MA 02111-1307, USA.

// As a special exception, you may use this file as part of a free
// software library without restriction.  Specifically, if other files
// instantiate templates or use macros or inline functions from this
// file, or you compile this file and link it with other files to
// produce an executable, this file does not by itself cause the
// resulting executable to be covered by the GNU General Public
// License.  This exception does not however invalidate any other
// reasons why the executable file might be covered by the GNU General
// Public License.

// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.

// Permission to use, copy, modify, sell, and distribute this software
// is hereby granted without fee, provided that the above copyright
// notice appears in all copies, and that both that copyright notice
// and this permission notice appear in supporting documentation. None
// of the above authors, nor IBM Haifa Research Laboratories, make any
// representation about the suitability of this software for any
// purpose. It is provided "as is" without express or implied
// warranty.

/**
 * @file constructors_destructor_fn_imps.hpp
 * Contains an implementation for rb_tree_.
 */

PB_DS_CLASS_T_DEC
template<typename It>
void
PB_DS_CLASS_C_DEC::
copy_from_range(It first_it, It last_it)
{
  while (first_it != last_it)
    insert(*(first_it++));
}

PB_DS_CLASS_T_DEC
PB_DS_CLASS_C_DEC::
PB_DS_CLASS_NAME()
{
  initialize();
  _GLIBCXX_DEBUG_ONLY(assert_valid();)
}

PB_DS_CLASS_T_DEC
PB_DS_CLASS_C_DEC::
PB_DS_CLASS_NAME(const Cmp_Fn& r_cmp_fn) :
  base_type(r_cmp_fn)
{
  initialize();
  _GLIBCXX_DEBUG_ONLY(assert_valid();)
}

PB_DS_CLASS_T_DEC
PB_DS_CLASS_C_DEC::
PB_DS_CLASS_NAME(const Cmp_Fn& r_cmp_fn, const node_update& r_node_update) :
  base_type(r_cmp_fn, r_node_update)
{
  initialize();
  _GLIBCXX_DEBUG_ONLY(assert_valid();)
}

PB_DS_CLASS_T_DEC
PB_DS_CLASS_C_DEC::
PB_DS_CLASS_NAME(const PB_DS_CLASS_C_DEC& other) :
  base_type(other)
{
  initialize();
  _GLIBCXX_DEBUG_ONLY(assert_valid();)
}

PB_DS_CLASS_T_DEC
void
PB_DS_CLASS_C_DEC::
swap(PB_DS_CLASS_C_DEC& other)
{
  _GLIBCXX_DEBUG_ONLY(assert_valid();)
  base_type::swap(other);
  _GLIBCXX_DEBUG_ONLY(assert_valid();)
}

PB_DS_CLASS_T_DEC
void
PB_DS_CLASS_C_DEC::
initialize()
{ base_type::m_p_head->m_red = true; }


code:
// -*- C++ -*-

// Copyright (C) 2005, 2006 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library 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 2, or (at your option) any later
// version.

// This library 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 library; see the file COPYING.  If not, write to
// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
// MA 02111-1307, USA.

// As a special exception, you may use this file as part of a free
// software library without restriction.  Specifically, if other files
// instantiate templates or use macros or inline functions from this
// file, or you compile this file and link it with other files to
// produce an executable, this file does not by itself cause the
// resulting executable to be covered by the GNU General Public
// License.  This exception does not however invalidate any other
// reasons why the executable file might be covered by the GNU General
// Public License.

// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.

// Permission to use, copy, modify, sell, and distribute this software
// is hereby granted without fee, provided that the above copyright
// notice appears in all copies, and that both that copyright notice
// and this permission notice appear in supporting documentation. None
// of the above authors, nor IBM Haifa Research Laboratories, make any
// representation about the suitability of this software for any
// purpose. It is provided "as is" without express or implied
// warranty.

/**
 * @file debug_fn_imps.hpp
 * Contains an implementation for rb_tree_.
 */

#ifdef _GLIBCXX_DEBUG

PB_DS_CLASS_T_DEC
typename PB_DS_CLASS_C_DEC::size_type
PB_DS_CLASS_C_DEC::
assert_node_consistent(const node_pointer p_nd) const
{
  if (p_nd == NULL)
    return 1;

  const size_type l_height = assert_node_consistent(p_nd->m_p_left);
  const size_type r_height = assert_node_consistent(p_nd->m_p_right);
  if (p_nd->m_red)
    {
      _GLIBCXX_DEBUG_ASSERT(is_effectively_black(p_nd->m_p_left));
      _GLIBCXX_DEBUG_ASSERT(is_effectively_black(p_nd->m_p_right));
    }
  _GLIBCXX_DEBUG_ASSERT(l_height == r_height);
  return (p_nd->m_red ? 0 : 1) + l_height;
}

PB_DS_CLASS_T_DEC
void
PB_DS_CLASS_C_DEC::
assert_valid() const
{
  base_type::assert_valid();
  const node_pointer p_head = base_type::m_p_head;
  _GLIBCXX_DEBUG_ASSERT(p_head->m_red);
  if (p_head->m_p_parent != NULL)
    {
      _GLIBCXX_DEBUG_ASSERT(!p_head->m_p_parent->m_red);
      assert_node_consistent(p_head->m_p_parent);
    }
}

#endif


code:
// -*- C++ -*-

// Copyright (C) 2005, 2006 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library 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 2, or (at your option) any later
// version.

// This library 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 library; see the file COPYING.  If not, write to
// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
// MA 02111-1307, USA.

// As a special exception, you may use this file as part of a free
// software library without restriction.  Specifically, if other files
// instantiate templates or use macros or inline functions from this
// file, or you compile this file and link it with other files to
// produce an executable, this file does not by itself cause the
// resulting executable to be covered by the GNU General Public
// License.  This exception does not however invalidate any other
// reasons why the executable file might be covered by the GNU General
// Public License.

// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.

// Permission to use, copy, modify, sell, and distribute this software
// is hereby granted without fee, provided that the above copyright
// notice appears in all copies, and that both that copyright notice
// and this permission notice appear in supporting documentation. None
// of the above authors, nor IBM Haifa Research Laboratories, make any
// representation about the suitability of this software for any
// purpose. It is provided "as is" without express or implied
// warranty.

/**
 * @file erase_fn_imps.hpp
 * Contains an implementation for rb_tree_.
 */

PB_DS_CLASS_T_DEC
inline bool
PB_DS_CLASS_C_DEC::
erase(const_key_reference r_key)
{
  point_iterator it = find(r_key);
  if (it == base_type::end())
    return false;
  erase(it);
  return true;
}

PB_DS_CLASS_T_DEC
inline typename PB_DS_CLASS_C_DEC::iterator
PB_DS_CLASS_C_DEC::
erase(iterator it)
{
  _GLIBCXX_DEBUG_ONLY(assert_valid());
  if (it == base_type::end())
    return it;

  iterator ret_it = it;
  ++ret_it;
  erase_node(it.m_p_nd);
  _GLIBCXX_DEBUG_ONLY(assert_valid());
  return ret_it;
}

PB_DS_CLASS_T_DEC
inline typename PB_DS_CLASS_C_DEC::reverse_iterator
PB_DS_CLASS_C_DEC::
erase(reverse_iterator it)
{
  _GLIBCXX_DEBUG_ONLY(assert_valid());
  if (it.m_p_nd == base_type::m_p_head)
    return it;

  reverse_iterator ret_it = it;
  ++ret_it;
  erase_node(it.m_p_nd);
  _GLIBCXX_DEBUG_ONLY(assert_valid());
  return ret_it;
}

PB_DS_CLASS_T_DEC
template<typename Pred>
inline typename PB_DS_CLASS_C_DEC::size_type
PB_DS_CLASS_C_DEC::
erase_if(Pred pred)
{
  _GLIBCXX_DEBUG_ONLY(assert_valid();)
  size_type num_ersd = 0;
  iterator it = base_type::begin();
  while (it != base_type::end())
    {
      if (pred(*it))
        {
	  ++num_ersd;
	  it = erase(it);
        }
      else
	++it;
    }

  _GLIBCXX_DEBUG_ONLY(assert_valid();)
  return num_ersd;
}

PB_DS_CLASS_T_DEC
void
PB_DS_CLASS_C_DEC::
erase_node(node_pointer p_nd)
{
  remove_node(p_nd);
  base_type::actual_erase_node(p_nd);
  _GLIBCXX_DEBUG_ONLY(assert_valid());
}

PB_DS_CLASS_T_DEC
void
PB_DS_CLASS_C_DEC::
remove_node(node_pointer p_z)
{
  update_min_max_for_erased_node(p_z);
  node_pointer p_y = p_z;
  node_pointer p_x = NULL;
  node_pointer p_new_x_parent = NULL;

  if (p_y->m_p_left == NULL)
    p_x = p_y->m_p_right;
  else if (p_y->m_p_right == NULL)
    p_x = p_y->m_p_left;
  else
    {
      p_y = p_y->m_p_right;
      while (p_y->m_p_left != NULL)
	p_y = p_y->m_p_left;
      p_x = p_y->m_p_right;
    }

  if (p_y == p_z)
    {
      p_new_x_parent = p_y->m_p_parent;
      if (p_x != NULL)
	p_x->m_p_parent = p_y->m_p_parent;

      if (base_type::m_p_head->m_p_parent == p_z)
	base_type::m_p_head->m_p_parent = p_x;
      else if (p_z->m_p_parent->m_p_left == p_z)
        {
	  p_y->m_p_left = p_z->m_p_parent;
	  p_z->m_p_parent->m_p_left = p_x;
        }
      else
        {
	  p_y->m_p_left = NULL;
	  p_z->m_p_parent->m_p_right = p_x;
        }
    }
  else
    {
      p_z->m_p_left->m_p_parent = p_y;
      p_y->m_p_left = p_z->m_p_left;
      if (p_y != p_z->m_p_right)
        {
	  p_new_x_parent = p_y->m_p_parent;
	  if (p_x != NULL)
	    p_x->m_p_parent = p_y->m_p_parent;
	  p_y->m_p_parent->m_p_left = p_x;
	  p_y->m_p_right = p_z->m_p_right;
	  p_z->m_p_right->m_p_parent = p_y;
        }
      else
	p_new_x_parent = p_y;

      if (base_type::m_p_head->m_p_parent == p_z)
	base_type::m_p_head->m_p_parent = p_y;
      else if (p_z->m_p_parent->m_p_left == p_z)
	p_z->m_p_parent->m_p_left = p_y;
      else
	p_z->m_p_parent->m_p_right = p_y;

      p_y->m_p_parent = p_z->m_p_parent;
      std::swap(p_y->m_red, p_z->m_red);
      p_y = p_z;
    }

  update_to_top(p_new_x_parent, (node_update* )this);

  if (p_y->m_red)
    return;

  remove_fixup(p_x, p_new_x_parent);
}

PB_DS_CLASS_T_DEC
void
PB_DS_CLASS_C_DEC::
remove_fixup(node_pointer p_x, node_pointer p_new_x_parent)
{
  _GLIBCXX_DEBUG_ASSERT(p_x == NULL || p_x->m_p_parent == p_new_x_parent);

  while (p_x != base_type::m_p_head->m_p_parent && is_effectively_black(p_x))
    if (p_x == p_new_x_parent->m_p_left)
      {
	node_pointer p_w = p_new_x_parent->m_p_right;
	if (p_w->m_red)
	  {
	    p_w->m_red = false;
	    p_new_x_parent->m_red = true;
	    base_type::rotate_left(p_new_x_parent);
	    p_w = p_new_x_parent->m_p_right;
	  }

	if (is_effectively_black(p_w->m_p_left)
	    && is_effectively_black(p_w->m_p_right))
	  {
	    p_w->m_red = true;
	    p_x = p_new_x_parent;
	    p_new_x_parent = p_new_x_parent->m_p_parent;
	  }
	else
	  {
	    if (is_effectively_black(p_w->m_p_right))
	      {
		if (p_w->m_p_left != NULL)
		  p_w->m_p_left->m_red = false;

		p_w->m_red = true;
		base_type::rotate_right(p_w);
		p_w = p_new_x_parent->m_p_right;
	      }

	    p_w->m_red = p_new_x_parent->m_red;
	    p_new_x_parent->m_red = false;

	    if (p_w->m_p_right != NULL)
	      p_w->m_p_right->m_red = false;

	    base_type::rotate_left(p_new_x_parent);
	    update_to_top(p_new_x_parent, (node_update* )this);
	    break;
	  }
      }
    else
      {
	node_pointer p_w = p_new_x_parent->m_p_left;
	if (p_w->m_red == true)
	  {
	    p_w->m_red = false;
	    p_new_x_parent->m_red = true;
	    base_type::rotate_right(p_new_x_parent);
	    p_w = p_new_x_parent->m_p_left;
	  }

	if (is_effectively_black(p_w->m_p_right)
	    && is_effectively_black(p_w->m_p_left))
	  {
	    p_w->m_red = true;
	    p_x = p_new_x_parent;
	    p_new_x_parent = p_new_x_parent->m_p_parent;
	  }
	else
	  {
	    if (is_effectively_black(p_w->m_p_left))
	      {
		if (p_w->m_p_right != NULL)
		  p_w->m_p_right->m_red = false;

		p_w->m_red = true;
		base_type::rotate_left(p_w);
		p_w = p_new_x_parent->m_p_left;
	      }

	    p_w->m_red = p_new_x_parent->m_red;
	    p_new_x_parent->m_red = false;

	    if (p_w->m_p_left != NULL)
	      p_w->m_p_left->m_red = false;

	    base_type::rotate_right(p_new_x_parent);
	    update_to_top(p_new_x_parent, (node_update* )this);
	    break;
	  }
      }

  if (p_x != NULL)
    p_x->m_red = false;
}


code:
// -*- C++ -*-

// Copyright (C) 2005, 2006 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library 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 2, or (at your option) any later
// version.

// This library 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 library; see the file COPYING.  If not, write to
// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
// MA 02111-1307, USA.

// As a special exception, you may use this file as part of a free
// software library without restriction.  Specifically, if other files
// instantiate templates or use macros or inline functions from this
// file, or you compile this file and link it with other files to
// produce an executable, this file does not by itself cause the
// resulting executable to be covered by the GNU General Public
// License.  This exception does not however invalidate any other
// reasons why the executable file might be covered by the GNU General
// Public License.

// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.

// Permission to use, copy, modify, sell, and distribute this software
// is hereby granted without fee, provided that the above copyright
// notice appears in all copies, and that both that copyright notice
// and this permission notice appear in supporting documentation. None
// of the above authors, nor IBM Haifa Research Laboratories, make any
// representation about the suitability of this software for any
// purpose. It is provided "as is" without express or implied
// warranty.

/**
 * @file find_fn_imps.hpp
 * Contains an implementation for rb_tree_.
 */


code:
// -*- C++ -*-

// Copyright (C) 2005, 2006 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library 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 2, or (at your option) any later
// version.

// This library 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 library; see the file COPYING.  If not, write to
// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
// MA 02111-1307, USA.

// As a special exception, you may use this file as part of a free
// software library without restriction.  Specifically, if other files
// instantiate templates or use macros or inline functions from this
// file, or you compile this file and link it with other files to
// produce an executable, this file does not by itself cause the
// resulting executable to be covered by the GNU General Public
// License.  This exception does not however invalidate any other
// reasons why the executable file might be covered by the GNU General
// Public License.

// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.

// Permission to use, copy, modify, sell, and distribute this software
// is hereby granted without fee, provided that the above copyright
// notice appears in all copies, and that both that copyright notice
// and this permission notice appear in supporting documentation. None
// of the above authors, nor IBM Haifa Research Laboratories, make any
// representation about the suitability of this software for any
// purpose. It is provided "as is" without express or implied
// warranty.

/**
 * @file info_fn_imps.hpp
 * Contains an implementation for rb_tree_.
 */

PB_DS_CLASS_T_DEC
inline bool
PB_DS_CLASS_C_DEC::
is_effectively_black(const node_pointer p_nd)
{ return (p_nd == NULL || !p_nd->m_red); }


code:
// -*- C++ -*-

// Copyright (C) 2005, 2006 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library 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 2, or (at your option) any later
// version.

// This library 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 library; see the file COPYING.  If not, write to
// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
// MA 02111-1307, USA.

// As a special exception, you may use this file as part of a free
// software library without restriction.  Specifically, if other files
// instantiate templates or use macros or inline functions from this
// file, or you compile this file and link it with other files to
// produce an executable, this file does not by itself cause the
// resulting executable to be covered by the GNU General Public
// License.  This exception does not however invalidate any other
// reasons why the executable file might be covered by the GNU General
// Public License.

// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.

// Permission to use, copy, modify, sell, and distribute this software
// is hereby granted without fee, provided that the above copyright
// notice appears in all copies, and that both that copyright notice
// and this permission notice appear in supporting documentation. None
// of the above authors, nor IBM Haifa Research Laboratories, make any
// representation about the suitability of this software for any
// purpose. It is provided "as is" without express or implied
// warranty.

/**
 * @file insert_fn_imps.hpp
 * Contains an implementation for rb_tree_.
 */

PB_DS_CLASS_T_DEC
inline std::pair<typename PB_DS_CLASS_C_DEC::point_iterator, bool>
PB_DS_CLASS_C_DEC::
insert(const_reference r_value)
{
  _GLIBCXX_DEBUG_ONLY(assert_valid();)
  std::pair<point_iterator, bool> ins_pair = base_type::insert_leaf(r_value);
  if (ins_pair.second == true)
    {
      ins_pair.first.m_p_nd->m_red = true;
      _GLIBCXX_DEBUG_ONLY(this->structure_only_assert_valid();)
      insert_fixup(ins_pair.first.m_p_nd);
    }

  _GLIBCXX_DEBUG_ONLY(assert_valid();)
  return ins_pair;
}

PB_DS_CLASS_T_DEC
inline void
PB_DS_CLASS_C_DEC::
insert_fixup(node_pointer p_nd)
{
  _GLIBCXX_DEBUG_ASSERT(p_nd->m_red == true);
  while (p_nd != base_type::m_p_head->m_p_parent && p_nd->m_p_parent->m_red)
    {
      if (p_nd->m_p_parent == p_nd->m_p_parent->m_p_parent->m_p_left)
        {
	  node_pointer p_y = p_nd->m_p_parent->m_p_parent->m_p_right;
	  if (p_y != NULL && p_y->m_red)
            {
	      p_nd->m_p_parent->m_red = false;
	      p_y->m_red = false;
	      p_nd->m_p_parent->m_p_parent->m_red = true;
	      p_nd = p_nd->m_p_parent->m_p_parent;
            }
	  else
            {
	      if (p_nd == p_nd->m_p_parent->m_p_right)
                {
		  p_nd = p_nd->m_p_parent;
		  base_type::rotate_left(p_nd);
                }
	      p_nd->m_p_parent->m_red = false;
	      p_nd->m_p_parent->m_p_parent->m_red = true;
	      base_type::rotate_right(p_nd->m_p_parent->m_p_parent);
            }
        }
      else
        {
	  node_pointer p_y = p_nd->m_p_parent->m_p_parent->m_p_left;
	  if (p_y != NULL && p_y->m_red)
            {
	      p_nd->m_p_parent->m_red = false;
	      p_y->m_red = false;
	      p_nd->m_p_parent->m_p_parent->m_red = true;
	      p_nd = p_nd->m_p_parent->m_p_parent;
            }
	  else
            {
	      if (p_nd == p_nd->m_p_parent->m_p_left)
                {
		  p_nd = p_nd->m_p_parent;
		  base_type::rotate_right(p_nd);
                }
	      p_nd->m_p_parent->m_red = false;
	      p_nd->m_p_parent->m_p_parent->m_red = true;
	      base_type::rotate_left(p_nd->m_p_parent->m_p_parent);
            }
        }
    }

  base_type::update_to_top(p_nd, (node_update* )this);
  base_type::m_p_head->m_p_parent->m_red = false;
}