libstdc++
|
00001 // -*- C++ -*- 00002 00003 // Copyright (C) 2005, 2006, 2009, 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 thin_heap_/thin_heap_.hpp 00038 * Contains an implementation class for a thin heap. 00039 */ 00040 00041 #ifndef PB_DS_THIN_HEAP_HPP 00042 #define PB_DS_THIN_HEAP_HPP 00043 00044 #include <algorithm> 00045 #include <ext/pb_ds/detail/cond_dealtor.hpp> 00046 #include <ext/pb_ds/detail/type_utils.hpp> 00047 #include <ext/pb_ds/detail/left_child_next_sibling_heap_/left_child_next_sibling_heap_.hpp> 00048 #include <debug/debug.h> 00049 00050 namespace __gnu_pbds 00051 { 00052 namespace detail 00053 { 00054 #define PB_DS_CLASS_T_DEC \ 00055 template<typename Value_Type, typename Cmp_Fn, typename _Alloc> 00056 00057 #define PB_DS_CLASS_C_DEC \ 00058 thin_heap<Value_Type, Cmp_Fn, _Alloc> 00059 00060 #ifdef _GLIBCXX_DEBUG 00061 #define PB_DS_BASE_T_P \ 00062 <Value_Type, Cmp_Fn, typename _Alloc::size_type, _Alloc, true> 00063 #else 00064 #define PB_DS_BASE_T_P \ 00065 <Value_Type, Cmp_Fn, typename _Alloc::size_type, _Alloc> 00066 #endif 00067 00068 00069 /** 00070 * Thin heap. 00071 * 00072 * @ingroup heap-detail 00073 * 00074 * See Tarjan and Kaplan. 00075 */ 00076 template<typename Value_Type, typename Cmp_Fn, typename _Alloc> 00077 class thin_heap 00078 : public left_child_next_sibling_heap PB_DS_BASE_T_P 00079 { 00080 private: 00081 typedef typename _Alloc::template rebind<Value_Type>::other __rebind_a; 00082 typedef left_child_next_sibling_heap PB_DS_BASE_T_P base_type; 00083 00084 protected: 00085 typedef typename base_type::node node; 00086 typedef typename base_type::node_pointer node_pointer; 00087 typedef typename base_type::node_const_pointer node_const_pointer; 00088 00089 public: 00090 typedef Value_Type value_type; 00091 typedef Cmp_Fn cmp_fn; 00092 typedef _Alloc allocator_type; 00093 typedef typename _Alloc::size_type size_type; 00094 typedef typename _Alloc::difference_type difference_type; 00095 00096 typedef typename __rebind_a::pointer pointer; 00097 typedef typename __rebind_a::const_pointer const_pointer; 00098 typedef typename __rebind_a::reference reference; 00099 typedef typename __rebind_a::const_reference const_reference; 00100 00101 typedef typename base_type::point_iterator point_iterator; 00102 typedef typename base_type::point_const_iterator point_const_iterator; 00103 typedef typename base_type::iterator iterator; 00104 typedef typename base_type::const_iterator const_iterator; 00105 00106 00107 inline point_iterator 00108 push(const_reference); 00109 00110 void 00111 modify(point_iterator, const_reference); 00112 00113 inline const_reference 00114 top() const; 00115 00116 void 00117 pop(); 00118 00119 void 00120 erase(point_iterator); 00121 00122 inline void 00123 clear(); 00124 00125 template<typename Pred> 00126 size_type 00127 erase_if(Pred); 00128 00129 template<typename Pred> 00130 void 00131 split(Pred, PB_DS_CLASS_C_DEC&); 00132 00133 void 00134 join(PB_DS_CLASS_C_DEC&); 00135 00136 protected: 00137 thin_heap(); 00138 00139 thin_heap(const Cmp_Fn&); 00140 00141 thin_heap(const PB_DS_CLASS_C_DEC&); 00142 00143 void 00144 swap(PB_DS_CLASS_C_DEC&); 00145 00146 ~thin_heap(); 00147 00148 template<typename It> 00149 void 00150 copy_from_range(It, It); 00151 00152 #ifdef _GLIBCXX_DEBUG 00153 void 00154 assert_valid(const char*, int) const; 00155 00156 void 00157 assert_max(const char*, int) const; 00158 #endif 00159 00160 #ifdef PB_DS_THIN_HEAP_TRACE_ 00161 void 00162 trace() const; 00163 #endif 00164 00165 private: 00166 enum 00167 { 00168 max_rank = (sizeof(size_type) << 4) + 2 00169 }; 00170 00171 void 00172 initialize(); 00173 00174 inline void 00175 update_max(node_pointer); 00176 00177 inline void 00178 fix(node_pointer); 00179 00180 inline void 00181 fix_root(node_pointer); 00182 00183 inline void 00184 fix_sibling_rank_1_unmarked(node_pointer); 00185 00186 inline void 00187 fix_sibling_rank_1_marked(node_pointer); 00188 00189 inline void 00190 fix_sibling_general_unmarked(node_pointer); 00191 00192 inline void 00193 fix_sibling_general_marked(node_pointer); 00194 00195 inline void 00196 fix_child(node_pointer); 00197 00198 inline static void 00199 make_root(node_pointer); 00200 00201 inline void 00202 make_root_and_link(node_pointer); 00203 00204 inline void 00205 remove_max_node(); 00206 00207 void 00208 to_aux_except_max(); 00209 00210 inline void 00211 add_to_aux(node_pointer); 00212 00213 inline void 00214 make_from_aux(); 00215 00216 inline size_type 00217 rank_bound(); 00218 00219 inline void 00220 make_child_of(node_pointer, node_pointer); 00221 00222 inline void 00223 remove_node(node_pointer); 00224 00225 inline node_pointer 00226 join(node_pointer, node_pointer) const; 00227 00228 #ifdef _GLIBCXX_DEBUG 00229 void 00230 assert_node_consistent(node_const_pointer, bool, const char*, int) const; 00231 00232 void 00233 assert_aux_null(const char*, int) const; 00234 #endif 00235 00236 node_pointer m_p_max; 00237 node_pointer m_a_aux[max_rank]; 00238 }; 00239 00240 enum 00241 { 00242 num_distinct_rank_bounds = 48 00243 }; 00244 00245 // Taken from the SGI implementation; acknowledged in the docs. 00246 static const std::size_t g_a_rank_bounds[num_distinct_rank_bounds] = 00247 { 00248 /* Dealing cards... */ 00249 /* 0 */ 0ul, 00250 /* 1 */ 1ul, 00251 /* 2 */ 1ul, 00252 /* 3 */ 2ul, 00253 /* 4 */ 4ul, 00254 /* 5 */ 6ul, 00255 /* 6 */ 11ul, 00256 /* 7 */ 17ul, 00257 /* 8 */ 29ul, 00258 /* 9 */ 46ul, 00259 /* 10 */ 76ul, 00260 /* 11 */ 122ul, 00261 /* 12 */ 199ul, 00262 /* 13 */ 321ul, 00263 /* 14 */ 521ul, 00264 /* 15 */ 842ul, 00265 /* 16 */ 1364ul, 00266 /* 17 */ 2206ul, 00267 /* 18 */ 3571ul, 00268 /* 19 */ 5777ul, 00269 /* 20 */ 9349ul, 00270 /* 21 */ 15126ul, 00271 /* 22 */ 24476ul, 00272 /* 23 */ 39602ul, 00273 /* 24 */ 64079ul, 00274 /* 25 */ 103681ul, 00275 /* 26 */ 167761ul, 00276 /* 27 */ 271442ul, 00277 /* 28 */ 439204ul, 00278 /* 29 */ 710646ul, 00279 /* 30 */ 1149851ul, 00280 /* 31 */ 1860497ul, 00281 /* 32 */ 3010349ul, 00282 /* 33 */ 4870846ul, 00283 /* 34 */ 7881196ul, 00284 /* 35 */ 12752042ul, 00285 /* 36 */ 20633239ul, 00286 /* 37 */ 33385282ul, 00287 /* 38 */ 54018521ul, 00288 /* 39 */ 87403803ul, 00289 /* 40 */ 141422324ul, 00290 /* 41 */ 228826127ul, 00291 /* 42 */ 370248451ul, 00292 /* 43 */ 599074578ul, 00293 /* 44 */ 969323029ul, 00294 /* 45 */ 1568397607ul, 00295 /* 46 */ 2537720636ul, 00296 /* 47 */ 4106118243ul 00297 /* Pot's good, let's play */ 00298 }; 00299 00300 #define PB_DS_ASSERT_NODE_CONSISTENT(_Node, _Bool) \ 00301 _GLIBCXX_DEBUG_ONLY(assert_node_consistent(_Node, _Bool, \ 00302 __FILE__, __LINE__);) 00303 00304 #define PB_DS_ASSERT_AUX_NULL(X) \ 00305 _GLIBCXX_DEBUG_ONLY(X.assert_aux_null(__FILE__, __LINE__);) 00306 00307 #include <ext/pb_ds/detail/thin_heap_/constructors_destructor_fn_imps.hpp> 00308 #include <ext/pb_ds/detail/thin_heap_/debug_fn_imps.hpp> 00309 #include <ext/pb_ds/detail/thin_heap_/trace_fn_imps.hpp> 00310 #include <ext/pb_ds/detail/thin_heap_/find_fn_imps.hpp> 00311 #include <ext/pb_ds/detail/thin_heap_/insert_fn_imps.hpp> 00312 #include <ext/pb_ds/detail/thin_heap_/erase_fn_imps.hpp> 00313 #include <ext/pb_ds/detail/thin_heap_/split_join_fn_imps.hpp> 00314 00315 #undef PB_DS_ASSERT_AUX_NULL 00316 #undef PB_DS_ASSERT_NODE_CONSISTENT 00317 #undef PB_DS_CLASS_C_DEC 00318 #undef PB_DS_CLASS_T_DEC 00319 #undef PB_DS_BASE_T_P 00320 00321 } // namespace detail 00322 } // namespace __gnu_pbds 00323 00324 #endif