libstdc++
|
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 pat_trie_/find_fn_imps.hpp 00038 * Contains an implementation class for pat_trie. 00039 */ 00040 00041 PB_DS_CLASS_T_DEC 00042 inline typename PB_DS_CLASS_C_DEC::point_iterator 00043 PB_DS_CLASS_C_DEC:: 00044 find(key_const_reference r_key) 00045 { 00046 PB_DS_ASSERT_VALID((*this)) 00047 node_pointer p_nd = find_imp(r_key); 00048 00049 if (p_nd == 0 || p_nd->m_type != leaf_node) 00050 { 00051 PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) 00052 return end(); 00053 } 00054 00055 if (synth_access_traits::equal_keys(PB_DS_V2F(static_cast<leaf_pointer>(p_nd)->value()), r_key)) 00056 { 00057 PB_DS_CHECK_KEY_EXISTS(r_key) 00058 return iterator(p_nd); 00059 } 00060 00061 PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) 00062 return end(); 00063 } 00064 00065 PB_DS_CLASS_T_DEC 00066 inline typename PB_DS_CLASS_C_DEC::point_const_iterator 00067 PB_DS_CLASS_C_DEC:: 00068 find(key_const_reference r_key) const 00069 { 00070 PB_DS_ASSERT_VALID((*this)) 00071 00072 node_const_pointer p_nd = const_cast<PB_DS_CLASS_C_DEC* >(this)->find_imp(r_key); 00073 00074 if (p_nd == 0 || p_nd->m_type != leaf_node) 00075 { 00076 PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) 00077 return end(); 00078 } 00079 00080 if (synth_access_traits::equal_keys(PB_DS_V2F(static_cast<leaf_const_pointer>(p_nd)->value()), r_key)) 00081 { 00082 PB_DS_CHECK_KEY_EXISTS(r_key) 00083 return const_iterator(const_cast<node_pointer>(p_nd)); 00084 } 00085 00086 PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) 00087 return end(); 00088 } 00089 00090 PB_DS_CLASS_T_DEC 00091 inline typename PB_DS_CLASS_C_DEC::node_pointer 00092 PB_DS_CLASS_C_DEC:: 00093 find_imp(key_const_reference r_key) 00094 { 00095 if (empty()) 00096 return 0; 00097 00098 typename synth_access_traits::const_iterator b_it = 00099 synth_access_traits::begin(r_key); 00100 typename synth_access_traits::const_iterator e_it = 00101 synth_access_traits::end(r_key); 00102 00103 node_pointer p_nd = m_p_head->m_p_parent; 00104 _GLIBCXX_DEBUG_ASSERT(p_nd != 0); 00105 00106 while (p_nd->m_type != leaf_node) 00107 { 00108 _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == i_node); 00109 node_pointer p_next_nd = static_cast<inode_pointer>(p_nd)->get_child_node(b_it, e_it, this); 00110 00111 if (p_next_nd == 0) 00112 return p_nd; 00113 p_nd = p_next_nd; 00114 } 00115 return p_nd; 00116 } 00117 00118 PB_DS_CLASS_T_DEC 00119 inline typename PB_DS_CLASS_C_DEC::node_pointer 00120 PB_DS_CLASS_C_DEC:: 00121 lower_bound_imp(key_const_reference r_key) 00122 { 00123 if (empty()) 00124 return (m_p_head); 00125 00126 node_pointer p_nd = m_p_head->m_p_parent; 00127 _GLIBCXX_DEBUG_ASSERT(p_nd != 0); 00128 00129 typename PB_DS_CLASS_C_DEC::a_const_iterator b_it = 00130 synth_access_traits::begin(r_key); 00131 00132 typename PB_DS_CLASS_C_DEC::a_const_iterator e_it = 00133 synth_access_traits::end(r_key); 00134 00135 size_type checked_ind = 0; 00136 while (true) 00137 { 00138 if (p_nd->m_type == leaf_node) 00139 { 00140 if (!synth_access_traits::cmp_keys(PB_DS_V2F(static_cast<leaf_const_pointer>(p_nd)->value()), r_key)) 00141 return p_nd; 00142 iterator it(p_nd); 00143 ++it; 00144 return it.m_p_nd; 00145 } 00146 00147 _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == i_node); 00148 const size_type new_checked_ind = 00149 static_cast<inode_pointer>(p_nd)->get_e_ind(); 00150 00151 p_nd = 00152 static_cast<inode_pointer>(p_nd)->get_lower_bound_child_node( b_it, e_it, checked_ind, this); 00153 checked_ind = new_checked_ind; 00154 } 00155 } 00156 00157 PB_DS_CLASS_T_DEC 00158 inline typename PB_DS_CLASS_C_DEC::point_iterator 00159 PB_DS_CLASS_C_DEC:: 00160 lower_bound(key_const_reference r_key) 00161 { return point_iterator(lower_bound_imp(r_key)); } 00162 00163 PB_DS_CLASS_T_DEC 00164 inline typename PB_DS_CLASS_C_DEC::point_const_iterator 00165 PB_DS_CLASS_C_DEC:: 00166 lower_bound(key_const_reference r_key) const 00167 { 00168 return point_const_iterator(const_cast<PB_DS_CLASS_C_DEC* >(this)->lower_bound_imp(r_key)); 00169 } 00170 00171 PB_DS_CLASS_T_DEC 00172 inline typename PB_DS_CLASS_C_DEC::point_iterator 00173 PB_DS_CLASS_C_DEC:: 00174 upper_bound(key_const_reference r_key) 00175 { 00176 point_iterator l_bound_it = lower_bound(r_key); 00177 00178 _GLIBCXX_DEBUG_ASSERT(l_bound_it == end() || 00179 !synth_access_traits::cmp_keys(PB_DS_V2F(*l_bound_it), 00180 r_key)); 00181 00182 if (l_bound_it == end() || 00183 synth_access_traits::cmp_keys(r_key, PB_DS_V2F(*l_bound_it))) 00184 return l_bound_it; 00185 00186 return ++l_bound_it; 00187 } 00188 00189 PB_DS_CLASS_T_DEC 00190 inline typename PB_DS_CLASS_C_DEC::point_const_iterator 00191 PB_DS_CLASS_C_DEC:: 00192 upper_bound(key_const_reference r_key) const 00193 { 00194 point_const_iterator l_bound_it = lower_bound(r_key); 00195 00196 _GLIBCXX_DEBUG_ASSERT(l_bound_it == end() || 00197 !synth_access_traits::cmp_keys(PB_DS_V2F(*l_bound_it), 00198 r_key)); 00199 00200 if (l_bound_it == end() || 00201 synth_access_traits::cmp_keys(r_key, PB_DS_V2F(*l_bound_it))) 00202 return l_bound_it; 00203 return ++l_bound_it; 00204 } 00205 00206 PB_DS_CLASS_T_DEC 00207 inline typename PB_DS_CLASS_C_DEC::a_const_iterator 00208 PB_DS_CLASS_C_DEC:: 00209 pref_begin(node_const_pointer p_nd) 00210 { 00211 if (p_nd->m_type == leaf_node) 00212 return (synth_access_traits::begin(PB_DS_V2F(static_cast<leaf_const_pointer>(p_nd)->value()))); 00213 00214 _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == i_node); 00215 return static_cast<inode_const_pointer>(p_nd)->pref_b_it(); 00216 } 00217 00218 PB_DS_CLASS_T_DEC 00219 inline typename PB_DS_CLASS_C_DEC::a_const_iterator 00220 PB_DS_CLASS_C_DEC:: 00221 pref_end(node_const_pointer p_nd) 00222 { 00223 if (p_nd->m_type == leaf_node) 00224 return (synth_access_traits::end(PB_DS_V2F(static_cast<leaf_const_pointer>(p_nd)->value()))); 00225 00226 _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == i_node); 00227 return static_cast<inode_const_pointer>(p_nd)->pref_e_it(); 00228 } 00229 00230 PB_DS_CLASS_T_DEC 00231 inline typename PB_DS_CLASS_C_DEC::leaf_const_pointer 00232 PB_DS_CLASS_C_DEC:: 00233 leftmost_descendant(node_const_pointer p_nd) 00234 { 00235 if (p_nd->m_type == leaf_node) 00236 return static_cast<leaf_const_pointer>(p_nd); 00237 return static_cast<inode_const_pointer>(p_nd)->leftmost_descendant(); 00238 } 00239 00240 PB_DS_CLASS_T_DEC 00241 inline typename PB_DS_CLASS_C_DEC::leaf_pointer 00242 PB_DS_CLASS_C_DEC:: 00243 leftmost_descendant(node_pointer p_nd) 00244 { 00245 if (p_nd->m_type == leaf_node) 00246 return static_cast<leaf_pointer>(p_nd); 00247 return static_cast<inode_pointer>(p_nd)->leftmost_descendant(); 00248 } 00249 00250 PB_DS_CLASS_T_DEC 00251 inline typename PB_DS_CLASS_C_DEC::leaf_const_pointer 00252 PB_DS_CLASS_C_DEC:: 00253 rightmost_descendant(node_const_pointer p_nd) 00254 { 00255 if (p_nd->m_type == leaf_node) 00256 return static_cast<leaf_const_pointer>(p_nd); 00257 return static_cast<inode_const_pointer>(p_nd)->rightmost_descendant(); 00258 } 00259 00260 PB_DS_CLASS_T_DEC 00261 inline typename PB_DS_CLASS_C_DEC::leaf_pointer 00262 PB_DS_CLASS_C_DEC:: 00263 rightmost_descendant(node_pointer p_nd) 00264 { 00265 if (p_nd->m_type == leaf_node) 00266 return static_cast<leaf_pointer>(p_nd); 00267 return static_cast<inode_pointer>(p_nd)->rightmost_descendant(); 00268 } 00269