libstdc++
bin_search_tree_/split_join_fn_imps.hpp
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // Copyright (C) 2005, 2006, 2009, 2010, 2011 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the terms
00007 // of the GNU General Public License as published by the Free Software
00008 // Foundation; either version 3, or (at your option) any later
00009 // version.
00010 
00011 // This library is distributed in the hope that it will be useful, but
00012 // WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // General Public License for more details.
00015 
00016 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License and
00021 // a copy of the GCC Runtime Library Exception along with this program;
00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023 // <http://www.gnu.org/licenses/>.
00024 
00025 // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.
00026 
00027 // Permission to use, copy, modify, sell, and distribute this software
00028 // is hereby granted without fee, provided that the above copyright
00029 // notice appears in all copies, and that both that copyright notice
00030 // and this permission notice appear in supporting documentation. None
00031 // of the above authors, nor IBM Haifa Research Laboratories, make any
00032 // representation about the suitability of this software for any
00033 // purpose. It is provided "as is" without express or implied
00034 // warranty.
00035 
00036 /**
00037  * @file bin_search_tree_/split_join_fn_imps.hpp
00038  * Contains an implementation class for bin_search_tree_.
00039  */
00040 
00041 PB_DS_CLASS_T_DEC
00042 bool
00043 PB_DS_CLASS_C_DEC::
00044 join_prep(PB_DS_CLASS_C_DEC& other)
00045 {
00046   PB_DS_ASSERT_VALID((*this))
00047   PB_DS_ASSERT_VALID(other)
00048   if (other.m_size == 0)
00049     return false;
00050 
00051   if (m_size == 0)
00052     {
00053       value_swap(other);
00054       return false;
00055     }
00056 
00057   const bool greater =
00058     Cmp_Fn::operator()(PB_DS_V2F(m_p_head->m_p_right->m_value),
00059                PB_DS_V2F(other.m_p_head->m_p_left->m_value));
00060 
00061   const bool lesser =
00062     Cmp_Fn::operator()(PB_DS_V2F(other.m_p_head->m_p_right->m_value),
00063                PB_DS_V2F(m_p_head->m_p_left->m_value));
00064 
00065   if (!greater && !lesser)
00066     __throw_join_error();
00067 
00068   if (lesser)
00069     value_swap(other);
00070 
00071   m_size += other.m_size;
00072   _GLIBCXX_DEBUG_ONLY(debug_base::join(other);)
00073   return true;
00074 }
00075 
00076 PB_DS_CLASS_T_DEC
00077 void
00078 PB_DS_CLASS_C_DEC::
00079 join_finish(PB_DS_CLASS_C_DEC& other)
00080 {
00081   initialize_min_max();
00082   other.initialize();
00083 }
00084 
00085 PB_DS_CLASS_T_DEC
00086 bool
00087 PB_DS_CLASS_C_DEC::
00088 split_prep(key_const_reference r_key, PB_DS_CLASS_C_DEC& other)
00089 {
00090   PB_DS_ASSERT_VALID((*this))
00091   PB_DS_ASSERT_VALID(other)
00092   other.clear();
00093 
00094   if (m_size == 0)
00095     {
00096       PB_DS_ASSERT_VALID((*this))
00097       PB_DS_ASSERT_VALID(other)
00098       return false;
00099     }
00100 
00101   if (Cmp_Fn::operator()(r_key, PB_DS_V2F(m_p_head->m_p_left->m_value)))
00102     {
00103       value_swap(other);
00104       PB_DS_ASSERT_VALID((*this))
00105       PB_DS_ASSERT_VALID(other)
00106       return false;
00107     }
00108 
00109   if (!Cmp_Fn::operator()(r_key, PB_DS_V2F(m_p_head->m_p_right->m_value)))
00110     {
00111       PB_DS_ASSERT_VALID((*this))
00112       PB_DS_ASSERT_VALID(other)
00113       return false;
00114     }
00115 
00116   if (m_size == 1)
00117     {
00118       value_swap(other);
00119       PB_DS_ASSERT_VALID((*this))
00120       PB_DS_ASSERT_VALID(other)
00121       return false;
00122     }
00123 
00124   _GLIBCXX_DEBUG_ONLY(debug_base::split(r_key,(Cmp_Fn& )(*this), other);)
00125   return true;
00126 }
00127 
00128 PB_DS_CLASS_T_DEC
00129 void
00130 PB_DS_CLASS_C_DEC::
00131 split_finish(PB_DS_CLASS_C_DEC& other)
00132 {
00133   other.initialize_min_max();
00134   other.m_size = std::distance(other.begin(), other.end());
00135   m_size -= other.m_size;
00136   initialize_min_max();
00137   PB_DS_ASSERT_VALID((*this))
00138   PB_DS_ASSERT_VALID(other)
00139 }
00140 
00141 PB_DS_CLASS_T_DEC
00142 typename PB_DS_CLASS_C_DEC::size_type
00143 PB_DS_CLASS_C_DEC::
00144 recursive_count(node_pointer p) const
00145 {
00146   if (p == 0)
00147     return 0;
00148   return 1 + recursive_count(p->m_p_left) + recursive_count(p->m_p_right);
00149 }
00150