libstdc++
|
00001 // -*- C++ -*- 00002 00003 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 00004 // Free Software Foundation, Inc. 00005 // 00006 // This file is part of the GNU ISO C++ Library. This library is free 00007 // software; you can redistribute it and/or modify it under the terms 00008 // of the GNU General Public License as published by the Free Software 00009 // Foundation; either version 3, or (at your option) any later 00010 // version. 00011 00012 // This library is distributed in the hope that it will be useful, but 00013 // WITHOUT ANY WARRANTY; without even the implied warranty of 00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 // General Public License for more details. 00016 00017 // Under Section 7 of GPL version 3, you are granted additional 00018 // permissions described in the GCC Runtime Library Exception, version 00019 // 3.1, as published by the Free Software Foundation. 00020 00021 // You should have received a copy of the GNU General Public License and 00022 // a copy of the GCC Runtime Library Exception along with this program; 00023 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00024 // <http://www.gnu.org/licenses/>. 00025 00026 // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. 00027 00028 // Permission to use, copy, modify, sell, and distribute this software 00029 // is hereby granted without fee, provided that the above copyright 00030 // notice appears in all copies, and that both that copyright notice 00031 // and this permission notice appear in supporting documentation. None 00032 // of the above authors, nor IBM Haifa Research Laboratories, make any 00033 // representation about the suitability of this software for any 00034 // purpose. It is provided "as is" without express or implied 00035 // warranty. 00036 00037 /** 00038 * @file bin_search_tree_/constructors_destructor_fn_imps.hpp 00039 * Contains an implementation class for bin_search_tree_. 00040 */ 00041 00042 PB_DS_CLASS_T_DEC 00043 typename PB_DS_CLASS_C_DEC::node_allocator 00044 PB_DS_CLASS_C_DEC::s_node_allocator; 00045 00046 PB_DS_CLASS_T_DEC 00047 PB_DS_CLASS_C_DEC:: 00048 PB_DS_BIN_TREE_NAME() : m_p_head(s_node_allocator.allocate(1)), m_size(0) 00049 { 00050 initialize(); 00051 PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) 00052 } 00053 00054 PB_DS_CLASS_T_DEC 00055 PB_DS_CLASS_C_DEC:: 00056 PB_DS_BIN_TREE_NAME(const Cmp_Fn& r_cmp_fn) : 00057 Cmp_Fn(r_cmp_fn), m_p_head(s_node_allocator.allocate(1)), m_size(0) 00058 { 00059 initialize(); 00060 PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) 00061 } 00062 00063 PB_DS_CLASS_T_DEC 00064 PB_DS_CLASS_C_DEC:: 00065 PB_DS_BIN_TREE_NAME(const Cmp_Fn& r_cmp_fn, const node_update& r_node_update) : 00066 Cmp_Fn(r_cmp_fn), 00067 node_update(r_node_update), 00068 m_p_head(s_node_allocator.allocate(1)), 00069 m_size(0) 00070 { 00071 initialize(); 00072 PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) 00073 } 00074 00075 PB_DS_CLASS_T_DEC 00076 PB_DS_CLASS_C_DEC:: 00077 PB_DS_BIN_TREE_NAME(const PB_DS_CLASS_C_DEC& other) : 00078 #ifdef _GLIBCXX_DEBUG 00079 debug_base(other), 00080 #endif 00081 #ifdef PB_DS_TREE_TRACE 00082 PB_DS_TREE_TRACE_BASE_C_DEC(other), 00083 #endif 00084 Cmp_Fn(other), 00085 node_update(other), 00086 m_p_head(s_node_allocator.allocate(1)), 00087 m_size(0) 00088 { 00089 initialize(); 00090 m_size = other.m_size; 00091 PB_DS_STRUCT_ONLY_ASSERT_VALID(other) 00092 00093 __try 00094 { 00095 m_p_head->m_p_parent = recursive_copy_node(other.m_p_head->m_p_parent); 00096 if (m_p_head->m_p_parent != 0) 00097 m_p_head->m_p_parent->m_p_parent = m_p_head; 00098 m_size = other.m_size; 00099 initialize_min_max(); 00100 } 00101 __catch(...) 00102 { 00103 _GLIBCXX_DEBUG_ONLY(debug_base::clear();) 00104 s_node_allocator.deallocate(m_p_head, 1); 00105 __throw_exception_again; 00106 } 00107 PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) 00108 } 00109 00110 PB_DS_CLASS_T_DEC 00111 void 00112 PB_DS_CLASS_C_DEC:: 00113 swap(PB_DS_CLASS_C_DEC& other) 00114 { 00115 PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) 00116 PB_DS_STRUCT_ONLY_ASSERT_VALID(other) 00117 value_swap(other); 00118 std::swap((Cmp_Fn& )(*this), (Cmp_Fn& )other); 00119 PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) 00120 PB_DS_STRUCT_ONLY_ASSERT_VALID(other) 00121 } 00122 00123 PB_DS_CLASS_T_DEC 00124 void 00125 PB_DS_CLASS_C_DEC:: 00126 value_swap(PB_DS_CLASS_C_DEC& other) 00127 { 00128 _GLIBCXX_DEBUG_ONLY(debug_base::swap(other);) 00129 std::swap(m_p_head, other.m_p_head); 00130 std::swap(m_size, other.m_size); 00131 } 00132 00133 PB_DS_CLASS_T_DEC 00134 PB_DS_CLASS_C_DEC:: 00135 ~PB_DS_BIN_TREE_NAME() 00136 { 00137 clear(); 00138 s_node_allocator.deallocate(m_p_head, 1); 00139 } 00140 00141 PB_DS_CLASS_T_DEC 00142 void 00143 PB_DS_CLASS_C_DEC:: 00144 initialize() 00145 { 00146 m_p_head->m_p_parent = 0; 00147 m_p_head->m_p_left = m_p_head; 00148 m_p_head->m_p_right = m_p_head; 00149 m_size = 0; 00150 } 00151 00152 PB_DS_CLASS_T_DEC 00153 typename PB_DS_CLASS_C_DEC::node_pointer 00154 PB_DS_CLASS_C_DEC:: 00155 recursive_copy_node(const node_pointer p_nd) 00156 { 00157 if (p_nd == 0) 00158 return (0); 00159 00160 node_pointer p_ret = s_node_allocator.allocate(1); 00161 __try 00162 { 00163 new (p_ret) node(*p_nd); 00164 } 00165 __catch(...) 00166 { 00167 s_node_allocator.deallocate(p_ret, 1); 00168 __throw_exception_again; 00169 } 00170 00171 p_ret->m_p_left = p_ret->m_p_right = 0; 00172 00173 __try 00174 { 00175 p_ret->m_p_left = recursive_copy_node(p_nd->m_p_left); 00176 p_ret->m_p_right = recursive_copy_node(p_nd->m_p_right); 00177 } 00178 __catch(...) 00179 { 00180 clear_imp(p_ret); 00181 __throw_exception_again; 00182 } 00183 00184 if (p_ret->m_p_left != 0) 00185 p_ret->m_p_left->m_p_parent = p_ret; 00186 00187 if (p_ret->m_p_right != 0) 00188 p_ret->m_p_right->m_p_parent = p_ret; 00189 00190 PB_DS_ASSERT_NODE_CONSISTENT(p_ret) 00191 return p_ret; 00192 } 00193 00194 PB_DS_CLASS_T_DEC 00195 void 00196 PB_DS_CLASS_C_DEC:: 00197 initialize_min_max() 00198 { 00199 if (m_p_head->m_p_parent == 0) 00200 { 00201 m_p_head->m_p_left = m_p_head->m_p_right = m_p_head; 00202 return; 00203 } 00204 00205 { 00206 node_pointer p_min = m_p_head->m_p_parent; 00207 while (p_min->m_p_left != 0) 00208 p_min = p_min->m_p_left; 00209 m_p_head->m_p_left = p_min; 00210 } 00211 00212 { 00213 node_pointer p_max = m_p_head->m_p_parent; 00214 while (p_max->m_p_right != 0) 00215 p_max = p_max->m_p_right; 00216 m_p_head->m_p_right = p_max; 00217 } 00218 } 00219