1 // -*- C++ -*- 2 3 // Copyright (C) 2005, 2006, 2009 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the terms 7 // of the GNU General Public License as published by the Free Software 8 // Foundation; either version 3, or (at your option) any later 9 // version. 10 11 // This library is distributed in the hope that it will be useful, but 12 // WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 // General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 // <http://www.gnu.org/licenses/>. 24 25 // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. 26 27 // Permission to use, copy, modify, sell, and distribute this software 28 // is hereby granted without fee, provided that the above copyright 29 // notice appears in all copies, and that both that copyright notice 30 // and this permission notice appear in supporting documentation. None 31 // of the above authors, nor IBM Haifa Research Laboratories, make any 32 // representation about the suitability of this software for any 33 // purpose. It is provided "as is" without express or implied 34 // warranty. 35 36 /** 37 * @file ov_tree_map_.hpp 38 * Contains an implementation class for ov_tree_. 39 */ 40 41 #include <map> 42 #include <set> 43 #include <ext/pb_ds/tree_policy.hpp> 44 #include <ext/pb_ds/detail/eq_fn/eq_by_less.hpp> 45 #include <ext/pb_ds/detail/types_traits.hpp> 46 #include <ext/pb_ds/detail/debug_map_base.hpp> 47 #include <ext/pb_ds/detail/type_utils.hpp> 48 #include <ext/pb_ds/exception.hpp> 49 #include <ext/pb_ds/detail/tree_trace_base.hpp> 50 #include <utility> 51 #include <functional> 52 #include <algorithm> 53 #include <vector> 54 #include <assert.h> 55 #include <debug/debug.h> 56 57 namespace __gnu_pbds 58 { 59 namespace detail 60 { 61 #define PB_DS_CLASS_T_DEC \ 62 template<typename Key, typename Mapped, class Cmp_Fn, \ 63 class Node_And_It_Traits, class Allocator> 64 65 #ifdef PB_DS_DATA_TRUE_INDICATOR 66 #define PB_DS_OV_TREE_CLASS_NAME ov_tree_data_ 67 #endif 68 69 #ifdef PB_DS_DATA_FALSE_INDICATOR 70 #define PB_DS_OV_TREE_CLASS_NAME ov_tree_no_data_ 71 #endif 72 73 #ifdef PB_DS_DATA_TRUE_INDICATOR 74 #define PB_DS_CONST_NODE_ITERATOR_NAME ov_tree_const_node_iterator_data_ 75 #else 76 #define PB_DS_CONST_NODE_ITERATOR_NAME ov_tree_const_node_iterator_no_data_ 77 #endif 78 79 #define PB_DS_CLASS_C_DEC \ 80 PB_DS_OV_TREE_CLASS_NAME<Key, Mapped, Cmp_Fn, Node_And_It_Traits, Allocator> 81 82 #define PB_DS_TYPES_TRAITS_C_DEC \ 83 types_traits<Key, Mapped, Allocator, false> 84 85 #ifdef _GLIBCXX_DEBUG 86 #define PB_DS_DEBUG_MAP_BASE_C_DEC \ 87 debug_map_base<Key, eq_by_less<Key, Cmp_Fn>, \ 88 typename Allocator::template rebind<Key>::other::const_reference> 89 #endif 90 91 #ifdef PB_DS_DATA_TRUE_INDICATOR 92 #define PB_DS_V2F(X) (X).first 93 #define PB_DS_V2S(X) (X).second 94 #define PB_DS_EP2VP(X)& ((X)->m_value) 95 #endif 96 97 #ifdef PB_DS_DATA_FALSE_INDICATOR 98 #define PB_DS_V2F(X) (X) 99 #define PB_DS_V2S(X) Mapped_Data() 100 #define PB_DS_EP2VP(X)& ((X)->m_value.first) 101 #endif 102 103 #ifdef PB_DS_TREE_TRACE 104 #define PB_DS_TREE_TRACE_BASE_C_DEC \ 105 tree_trace_base<typename Node_And_It_Traits::const_node_iterator, \ 106 typename Node_And_It_Traits::node_iterator, \ 107 Cmp_Fn, false, Allocator> 108 #endif 109 110 // Ordered-vector tree associative-container. 111 template<typename Key, typename Mapped, class Cmp_Fn, 112 class Node_And_It_Traits, class Allocator> 113 class PB_DS_OV_TREE_CLASS_NAME : 114 #ifdef _GLIBCXX_DEBUG 115 protected PB_DS_DEBUG_MAP_BASE_C_DEC, 116 #endif 117 #ifdef PB_DS_TREE_TRACE 118 public PB_DS_TREE_TRACE_BASE_C_DEC, 119 #endif 120 public Cmp_Fn, 121 public Node_And_It_Traits::node_update, 122 public PB_DS_TYPES_TRAITS_C_DEC 123 { 124 private: 125 typedef PB_DS_TYPES_TRAITS_C_DEC traits_base; 126 127 typedef typename remove_const<typename traits_base::value_type>::type non_const_value_type; 128 129 typedef typename Allocator::template rebind<non_const_value_type>::other value_allocator; 130 typedef typename value_allocator::pointer value_vector; 131 132 133 typedef Cmp_Fn cmp_fn_base; 134 135 #ifdef _GLIBCXX_DEBUG 136 typedef PB_DS_DEBUG_MAP_BASE_C_DEC debug_base; 137 #endif 138 139 typedef typename traits_base::pointer mapped_pointer_; 140 typedef typename traits_base::const_pointer const_mapped_pointer_; 141 142 typedef typename Node_And_It_Traits::metadata_type metadata_type; 143 144 typedef typename Allocator::template rebind<metadata_type>::other metadata_allocator; 145 typedef typename metadata_allocator::pointer metadata_pointer; 146 typedef typename metadata_allocator::const_reference const_metadata_reference; 147 typedef typename metadata_allocator::reference metadata_reference; 148 149 typedef 150 typename Node_And_It_Traits::null_node_update_pointer 151 null_node_update_pointer; 152 153 public: 154 155 typedef Allocator allocator_type; 156 typedef typename Allocator::size_type size_type; 157 typedef typename Allocator::difference_type difference_type; 158 159 typedef Cmp_Fn cmp_fn; 160 161 typedef typename Node_And_It_Traits::node_update node_update; 162 163 typedef typename traits_base::key_type key_type; 164 typedef typename traits_base::key_pointer key_pointer; 165 typedef typename traits_base::const_key_pointer const_key_pointer; 166 typedef typename traits_base::key_reference key_reference; 167 typedef typename traits_base::const_key_reference const_key_reference; 168 typedef typename traits_base::mapped_type mapped_type; 169 typedef typename traits_base::mapped_pointer mapped_pointer; 170 typedef typename traits_base::const_mapped_pointer const_mapped_pointer; 171 typedef typename traits_base::mapped_reference mapped_reference; 172 typedef typename traits_base::const_mapped_reference const_mapped_reference; 173 typedef typename traits_base::value_type value_type; 174 typedef typename traits_base::pointer pointer; 175 typedef typename traits_base::const_pointer const_pointer; 176 typedef typename traits_base::reference reference; 177 typedef typename traits_base::const_reference const_reference; 178 179 typedef const_pointer const_point_iterator; 180 181 #ifdef PB_DS_DATA_TRUE_INDICATOR 182 typedef pointer point_iterator; 183 #else 184 typedef const_point_iterator point_iterator; 185 #endif 186 187 typedef const_point_iterator const_iterator; 188 189 typedef point_iterator iterator; 190 191 #include <ext/pb_ds/detail/ov_tree_map_/cond_dtor.hpp> 192 193 typedef 194 typename Node_And_It_Traits::const_node_iterator 195 const_node_iterator; 196 197 typedef typename Node_And_It_Traits::node_iterator node_iterator; 198 199 public: 200 201 PB_DS_OV_TREE_CLASS_NAME(); 202 203 PB_DS_OV_TREE_CLASS_NAME(const Cmp_Fn&); 204 205 PB_DS_OV_TREE_CLASS_NAME(const Cmp_Fn&, const node_update&); 206 207 PB_DS_OV_TREE_CLASS_NAME(const PB_DS_CLASS_C_DEC&); 208 209 ~PB_DS_OV_TREE_CLASS_NAME(); 210 211 void 212 swap(PB_DS_CLASS_C_DEC&); 213 214 template<typename It> 215 void 216 copy_from_range(It, It); 217 218 inline size_type 219 max_size() const; 220 221 inline bool 222 empty() const; 223 224 inline size_type 225 size() const; 226 227 Cmp_Fn& 228 get_cmp_fn(); 229 230 const Cmp_Fn& 231 get_cmp_fn() const; 232 233 inline mapped_reference 234 operator[](const_key_reference r_key) 235 { 236 #ifdef PB_DS_DATA_TRUE_INDICATOR 237 _GLIBCXX_DEBUG_ONLY(assert_valid();) 238 point_iterator it = lower_bound(r_key); 239 if (it != end() && !Cmp_Fn::operator()(r_key, PB_DS_V2F(*it))) 240 { 241 _GLIBCXX_DEBUG_ONLY(debug_base::check_key_exists(r_key)); 242 _GLIBCXX_DEBUG_ONLY(assert_valid();) 243 return it->second; 244 } 245 246 _GLIBCXX_DEBUG_ONLY(assert_valid();) 247 return (insert_new_val(it, std::make_pair(r_key, mapped_type()))->second); 248 #else 249 insert(r_key); 250 return traits_base::s_null_mapped; 251 #endif 252 } 253 254 inline std::pair<point_iterator, bool> 255 insert(const_reference r_value) 256 { 257 _GLIBCXX_DEBUG_ONLY(assert_valid();) 258 const_key_reference r_key = PB_DS_V2F(r_value); 259 point_iterator it = lower_bound(r_key); 260 261 if (it != end()&& !Cmp_Fn::operator()(r_key, PB_DS_V2F(*it))) 262 { 263 _GLIBCXX_DEBUG_ONLY(assert_valid();) 264 _GLIBCXX_DEBUG_ONLY(debug_base::check_key_exists(r_key)); 265 return std::make_pair(it, false); 266 } 267 268 _GLIBCXX_DEBUG_ONLY(assert_valid();) 269 return std::make_pair(insert_new_val(it, r_value), true); 270 } 271 272 inline point_iterator 273 lower_bound(const_key_reference r_key) 274 { 275 pointer it = m_a_values; 276 pointer e_it = m_a_values + m_size; 277 while (it != e_it) 278 { 279 pointer mid_it = it + ((e_it - it) >> 1); 280 if (cmp_fn_base::operator()(PB_DS_V2F(*mid_it), r_key)) 281 it = ++mid_it; 282 else 283 e_it = mid_it; 284 } 285 return it; 286 } 287 288 inline const_point_iterator 289 lower_bound(const_key_reference r_key) const 290 { return const_cast<PB_DS_CLASS_C_DEC& >(*this).lower_bound(r_key); } 291 292 inline point_iterator 293 upper_bound(const_key_reference r_key) 294 { 295 iterator pot_it = lower_bound(r_key); 296 if (pot_it != end()&& !Cmp_Fn::operator()(r_key, PB_DS_V2F(*pot_it))) 297 { 298 _GLIBCXX_DEBUG_ONLY(debug_base::check_key_exists(r_key)); 299 return ++pot_it; 300 } 301 302 _GLIBCXX_DEBUG_ONLY(debug_base::check_key_does_not_exist(r_key)); 303 return pot_it; 304 } 305 306 inline const_point_iterator 307 upper_bound(const_key_reference r_key) const 308 { return const_cast<PB_DS_CLASS_C_DEC&>(*this).upper_bound(r_key); } 309 310 inline point_iterator 311 find(const_key_reference r_key) 312 { 313 _GLIBCXX_DEBUG_ONLY(assert_valid();) 314 iterator pot_it = lower_bound(r_key); 315 if (pot_it != end() && !Cmp_Fn::operator()(r_key, PB_DS_V2F(*pot_it))) 316 { 317 _GLIBCXX_DEBUG_ONLY(debug_base::check_key_exists(r_key)); 318 return pot_it; 319 } 320 321 _GLIBCXX_DEBUG_ONLY(debug_base::check_key_does_not_exist(r_key)); 322 return end(); 323 } 324 325 inline const_point_iterator 326 find(const_key_reference r_key) const 327 { return (const_cast<PB_DS_CLASS_C_DEC& >(*this).find(r_key)); } 328 329 bool 330 erase(const_key_reference); 331 332 template<typename Pred> 333 inline size_type 334 erase_if(Pred); 335 336 inline iterator 337 erase(iterator it) 338 { return erase_imp<iterator>(it); } 339 340 void 341 clear(); 342 343 void 344 join(PB_DS_CLASS_C_DEC&); 345 346 void 347 split(const_key_reference, PB_DS_CLASS_C_DEC&); 348 349 inline iterator 350 begin() 351 { return m_a_values; } 352 353 inline const_iterator 354 begin() const 355 { return m_a_values; } 356 357 inline iterator 358 end() 359 { return m_end_it; } 360 361 inline const_iterator 362 end() const 363 { return m_end_it; } 364 365 inline const_node_iterator 366 node_begin() const; 367 368 inline const_node_iterator 369 node_end() const; 370 371 inline node_iterator 372 node_begin(); 373 374 inline node_iterator 375 node_end(); 376 377 private: 378 379 inline void 380 update(node_iterator /*it*/, null_node_update_pointer); 381 382 template<typename Node_Update> 383 void 384 update(node_iterator, Node_Update*); 385 386 void 387 reallocate_metadata(null_node_update_pointer, size_type); 388 389 template<typename Node_Update_> 390 void 391 reallocate_metadata(Node_Update_*, size_type); 392 393 template<typename It> 394 void 395 copy_from_ordered_range(It, It); 396 397 void 398 value_swap(PB_DS_CLASS_C_DEC&); 399 400 template<typename It> 401 void 402 copy_from_ordered_range(It, It, It, It); 403 404 template<typename Ptr> 405 inline static Ptr 406 mid_pointer(Ptr p_begin, Ptr p_end) 407 { 408 _GLIBCXX_DEBUG_ASSERT(p_end >= p_begin); 409 return (p_begin + (p_end - p_begin) / 2); 410 } 411 412 inline iterator 413 insert_new_val(iterator it, const_reference r_value) 414 { 415 _GLIBCXX_DEBUG_ONLY(assert_valid();) 416 #ifdef PB_DS_REGRESSION 417 typename Allocator::group_throw_prob_adjustor adjust(m_size); 418 #endif 419 420 _GLIBCXX_DEBUG_ONLY(debug_base::check_key_does_not_exist(PB_DS_V2F(r_value))); 421 422 value_vector a_values = s_value_alloc.allocate(m_size + 1); 423 424 iterator source_it = begin(); 425 iterator source_end_it = end(); 426 iterator target_it = a_values; 427 iterator ret_it; 428 429 cond_dtor<size_type> cd(a_values, target_it, m_size + 1); 430 while (source_it != it) 431 { 432 new (const_cast<void* >(static_cast<const void* >(target_it))) 433 value_type(*source_it++); 434 ++target_it; 435 } 436 437 new (const_cast<void* >(static_cast<const void* >(ret_it = target_it))) 438 value_type(r_value); 439 ++target_it; 440 441 while (source_it != source_end_it) 442 { 443 new (const_cast<void* >(static_cast<const void* >(target_it))) 444 value_type(*source_it++); 445 ++target_it; 446 } 447 448 reallocate_metadata((node_update* )this, m_size + 1); 449 cd.set_no_action(); 450 if (m_size != 0) 451 { 452 cond_dtor<size_type> cd1(m_a_values, m_end_it, m_size); 453 } 454 455 ++m_size; 456 m_a_values = a_values; 457 m_end_it = m_a_values + m_size; 458 _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(r_value))); 459 update(node_begin(), (node_update* )this); 460 _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) 461 return ret_it; 462 } 463 464 #ifdef _GLIBCXX_DEBUG 465 void 466 assert_valid() const; 467 468 void 469 assert_iterators() const; 470 #endif 471 472 template<typename It> 473 It 474 erase_imp(It it); 475 476 inline const_node_iterator 477 PB_DS_node_begin_imp() const; 478 479 inline const_node_iterator 480 PB_DS_node_end_imp() const; 481 482 inline node_iterator 483 PB_DS_node_begin_imp(); 484 485 inline node_iterator 486 PB_DS_node_end_imp(); 487 488 private: 489 static value_allocator s_value_alloc; 490 static metadata_allocator s_metadata_alloc; 491 492 value_vector m_a_values; 493 metadata_pointer m_a_metadata; 494 iterator m_end_it; 495 size_type m_size; 496 }; 497 498 #include <ext/pb_ds/detail/ov_tree_map_/constructors_destructor_fn_imps.hpp> 499 #include <ext/pb_ds/detail/ov_tree_map_/iterators_fn_imps.hpp> 500 #include <ext/pb_ds/detail/ov_tree_map_/debug_fn_imps.hpp> 501 #include <ext/pb_ds/detail/ov_tree_map_/erase_fn_imps.hpp> 502 #include <ext/pb_ds/detail/ov_tree_map_/insert_fn_imps.hpp> 503 #include <ext/pb_ds/detail/ov_tree_map_/info_fn_imps.hpp> 504 #include <ext/pb_ds/detail/ov_tree_map_/split_join_fn_imps.hpp> 505 #include <ext/pb_ds/detail/bin_search_tree_/policy_access_fn_imps.hpp> 506 507 #undef PB_DS_CLASS_C_DEC 508 #undef PB_DS_CLASS_T_DEC 509 #undef PB_DS_OV_TREE_CLASS_NAME 510 #undef PB_DS_TYPES_TRAITS_C_DEC 511 #undef PB_DS_DEBUG_MAP_BASE_C_DEC 512 #ifdef PB_DS_TREE_TRACE 513 #undef PB_DS_TREE_TRACE_BASE_C_DEC 514 #endif 515 516 #undef PB_DS_V2F 517 #undef PB_DS_EP2VP 518 #undef PB_DS_V2S 519 #undef PB_DS_CONST_NODE_ITERATOR_NAME 520 521 } // namespace detail 522 } // namespace __gnu_pbds 523