the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 1507 lines 60 kB view raw
1////////////////////////////////////////////////////////////////////////////// 2// 3// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost 4// Software License, Version 1.0. (See accompanying file 5// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6// 7// See http://www.boost.org/libs/container for documentation. 8// 9////////////////////////////////////////////////////////////////////////////// 10 11#ifndef BOOST_CONTAINER_MAP_HPP 12#define BOOST_CONTAINER_MAP_HPP 13 14#if (defined _MSC_VER) && (_MSC_VER >= 1200) 15# pragma once 16#endif 17 18#include <boost/container/detail/config_begin.hpp> 19#include <boost/container/detail/workaround.hpp> 20 21#include <boost/container/container_fwd.hpp> 22#include <utility> 23#include <functional> 24#include <memory> 25#include <stdexcept> 26#include <boost/container/detail/tree.hpp> 27#include <boost/container/detail/value_init.hpp> 28#include <boost/type_traits/has_trivial_destructor.hpp> 29#include <boost/container/detail/mpl.hpp> 30#include <boost/container/detail/utilities.hpp> 31#include <boost/container/detail/pair.hpp> 32#include <boost/container/detail/type_traits.hpp> 33#include <boost/move/utility.hpp> 34#include <boost/move/detail/move_helpers.hpp> 35#include <boost/static_assert.hpp> 36#include <boost/container/detail/value_init.hpp> 37 38namespace boost { 39namespace container { 40 41/// @cond 42// Forward declarations of operators == and <, needed for friend declarations. 43template <class Key, class T, class Compare, class Allocator> 44inline bool operator==(const map<Key,T,Compare,Allocator>& x, 45 const map<Key,T,Compare,Allocator>& y); 46 47template <class Key, class T, class Compare, class Allocator> 48inline bool operator<(const map<Key,T,Compare,Allocator>& x, 49 const map<Key,T,Compare,Allocator>& y); 50/// @endcond 51 52//! A map is a kind of associative container that supports unique keys (contains at 53//! most one of each key value) and provides for fast retrieval of values of another 54//! type T based on the keys. The map class supports bidirectional iterators. 55//! 56//! A map satisfies all of the requirements of a container and of a reversible 57//! container and of an associative container. For a 58//! map<Key,T> the key_type is Key and the value_type is std::pair<const Key,T>. 59//! 60//! Compare is the ordering function for Keys (e.g. <i>std::less<Key></i>). 61//! 62//! Allocator is the allocator to allocate the value_types 63//! (e.g. <i>allocator< std::pair<const Key, T> > </i>). 64#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED 65template <class Key, class T, class Compare = std::less<Key>, class Allocator = std::allocator< std::pair< const Key, T> > > 66#else 67template <class Key, class T, class Compare, class Allocator> 68#endif 69class map 70{ 71 /// @cond 72 private: 73 BOOST_COPYABLE_AND_MOVABLE(map) 74 75 typedef std::pair<const Key, T> value_type_impl; 76 typedef container_detail::rbtree 77 <Key, value_type_impl, container_detail::select1st<value_type_impl>, Compare, Allocator> tree_t; 78 typedef container_detail::pair <Key, T> movable_value_type_impl; 79 typedef container_detail::tree_value_compare 80 < Key, value_type_impl, Compare, container_detail::select1st<value_type_impl> 81 > value_compare_impl; 82 tree_t m_tree; // red-black tree representing map 83 /// @endcond 84 85 public: 86 ////////////////////////////////////////////// 87 // 88 // types 89 // 90 ////////////////////////////////////////////// 91 92 typedef Key key_type; 93 typedef T mapped_type; 94 typedef std::pair<const Key, T> value_type; 95 typedef typename boost::container::allocator_traits<Allocator>::pointer pointer; 96 typedef typename boost::container::allocator_traits<Allocator>::const_pointer const_pointer; 97 typedef typename boost::container::allocator_traits<Allocator>::reference reference; 98 typedef typename boost::container::allocator_traits<Allocator>::const_reference const_reference; 99 typedef typename boost::container::allocator_traits<Allocator>::size_type size_type; 100 typedef typename boost::container::allocator_traits<Allocator>::difference_type difference_type; 101 typedef Allocator allocator_type; 102 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::stored_allocator_type) stored_allocator_type; 103 typedef BOOST_CONTAINER_IMPDEF(value_compare_impl) value_compare; 104 typedef Compare key_compare; 105 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::iterator) iterator; 106 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::const_iterator) const_iterator; 107 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::reverse_iterator) reverse_iterator; 108 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::const_reverse_iterator) const_reverse_iterator; 109 typedef std::pair<key_type, mapped_type> nonconst_value_type; 110 typedef BOOST_CONTAINER_IMPDEF(movable_value_type_impl) movable_value_type; 111 112 ////////////////////////////////////////////// 113 // 114 // construct/copy/destroy 115 // 116 ////////////////////////////////////////////// 117 118 //! <b>Effects</b>: Default constructs an empty map. 119 //! 120 //! <b>Complexity</b>: Constant. 121 map() 122 : m_tree() 123 { 124 //Allocator type must be std::pair<CONST Key, T> 125 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); 126 } 127 128 //! <b>Effects</b>: Constructs an empty map using the specified comparison object 129 //! and allocator. 130 //! 131 //! <b>Complexity</b>: Constant. 132 explicit map(const Compare& comp, 133 const allocator_type& a = allocator_type()) 134 : m_tree(comp, a) 135 { 136 //Allocator type must be std::pair<CONST Key, T> 137 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); 138 } 139 140 //! <b>Effects</b>: Constructs an empty map using the specified comparison object and 141 //! allocator, and inserts elements from the range [first ,last ). 142 //! 143 //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using 144 //! comp and otherwise N logN, where N is last - first. 145 template <class InputIterator> 146 map(InputIterator first, InputIterator last, const Compare& comp = Compare(), 147 const allocator_type& a = allocator_type()) 148 : m_tree(true, first, last, comp, a) 149 { 150 //Allocator type must be std::pair<CONST Key, T> 151 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); 152 } 153 154 //! <b>Effects</b>: Constructs an empty map using the specified comparison object and 155 //! allocator, and inserts elements from the ordered unique range [first ,last). This function 156 //! is more efficient than the normal range creation for ordered ranges. 157 //! 158 //! <b>Requires</b>: [first ,last) must be ordered according to the predicate and must be 159 //! unique values. 160 //! 161 //! <b>Complexity</b>: Linear in N. 162 template <class InputIterator> 163 map( ordered_unique_range_t, InputIterator first, InputIterator last 164 , const Compare& comp = Compare(), const allocator_type& a = allocator_type()) 165 : m_tree(ordered_range, first, last, comp, a) 166 { 167 //Allocator type must be std::pair<CONST Key, T> 168 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); 169 } 170 171 //! <b>Effects</b>: Copy constructs a map. 172 //! 173 //! <b>Complexity</b>: Linear in x.size(). 174 map(const map& x) 175 : m_tree(x.m_tree) 176 { 177 //Allocator type must be std::pair<CONST Key, T> 178 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); 179 } 180 181 //! <b>Effects</b>: Move constructs a map. Constructs *this using x's resources. 182 //! 183 //! <b>Complexity</b>: Constant. 184 //! 185 //! <b>Postcondition</b>: x is emptied. 186 map(BOOST_RV_REF(map) x) 187 : m_tree(boost::move(x.m_tree)) 188 { 189 //Allocator type must be std::pair<CONST Key, T> 190 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); 191 } 192 193 //! <b>Effects</b>: Copy constructs a map using the specified allocator. 194 //! 195 //! <b>Complexity</b>: Linear in x.size(). 196 map(const map& x, const allocator_type &a) 197 : m_tree(x.m_tree, a) 198 { 199 //Allocator type must be std::pair<CONST Key, T> 200 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); 201 } 202 203 //! <b>Effects</b>: Move constructs a map using the specified allocator. 204 //! Constructs *this using x's resources. 205 //! 206 //! <b>Complexity</b>: Constant if x == x.get_allocator(), linear otherwise. 207 //! 208 //! <b>Postcondition</b>: x is emptied. 209 map(BOOST_RV_REF(map) x, const allocator_type &a) 210 : m_tree(boost::move(x.m_tree), a) 211 { 212 //Allocator type must be std::pair<CONST Key, T> 213 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); 214 } 215 216 //! <b>Effects</b>: Makes *this a copy of x. 217 //! 218 //! <b>Complexity</b>: Linear in x.size(). 219 map& operator=(BOOST_COPY_ASSIGN_REF(map) x) 220 { m_tree = x.m_tree; return *this; } 221 222 //! <b>Effects</b>: this->swap(x.get()). 223 //! 224 //! <b>Complexity</b>: Constant. 225 map& operator=(BOOST_RV_REF(map) x) 226 { m_tree = boost::move(x.m_tree); return *this; } 227 228 //! <b>Effects</b>: Returns a copy of the Allocator that 229 //! was passed to the object's constructor. 230 //! 231 //! <b>Complexity</b>: Constant. 232 allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT 233 { return m_tree.get_allocator(); } 234 235 //! <b>Effects</b>: Returns a reference to the internal allocator. 236 //! 237 //! <b>Throws</b>: Nothing 238 //! 239 //! <b>Complexity</b>: Constant. 240 //! 241 //! <b>Note</b>: Non-standard extension. 242 stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT 243 { return m_tree.get_stored_allocator(); } 244 245 //! <b>Effects</b>: Returns a reference to the internal allocator. 246 //! 247 //! <b>Throws</b>: Nothing 248 //! 249 //! <b>Complexity</b>: Constant. 250 //! 251 //! <b>Note</b>: Non-standard extension. 252 const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT 253 { return m_tree.get_stored_allocator(); } 254 255 ////////////////////////////////////////////// 256 // 257 // iterators 258 // 259 ////////////////////////////////////////////// 260 261 //! <b>Effects</b>: Returns an iterator to the first element contained in the container. 262 //! 263 //! <b>Throws</b>: Nothing. 264 //! 265 //! <b>Complexity</b>: Constant. 266 iterator begin() BOOST_CONTAINER_NOEXCEPT 267 { return m_tree.begin(); } 268 269 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container. 270 //! 271 //! <b>Throws</b>: Nothing. 272 //! 273 //! <b>Complexity</b>: Constant. 274 const_iterator begin() const BOOST_CONTAINER_NOEXCEPT 275 { return this->cbegin(); } 276 277 //! <b>Effects</b>: Returns an iterator to the end of the container. 278 //! 279 //! <b>Throws</b>: Nothing. 280 //! 281 //! <b>Complexity</b>: Constant. 282 iterator end() BOOST_CONTAINER_NOEXCEPT 283 { return m_tree.end(); } 284 285 //! <b>Effects</b>: Returns a const_iterator to the end of the container. 286 //! 287 //! <b>Throws</b>: Nothing. 288 //! 289 //! <b>Complexity</b>: Constant. 290 const_iterator end() const BOOST_CONTAINER_NOEXCEPT 291 { return this->cend(); } 292 293 //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning 294 //! of the reversed container. 295 //! 296 //! <b>Throws</b>: Nothing. 297 //! 298 //! <b>Complexity</b>: Constant. 299 reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT 300 { return m_tree.rbegin(); } 301 302 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning 303 //! of the reversed container. 304 //! 305 //! <b>Throws</b>: Nothing. 306 //! 307 //! <b>Complexity</b>: Constant. 308 const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT 309 { return this->crbegin(); } 310 311 //! <b>Effects</b>: Returns a reverse_iterator pointing to the end 312 //! of the reversed container. 313 //! 314 //! <b>Throws</b>: Nothing. 315 //! 316 //! <b>Complexity</b>: Constant. 317 reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT 318 { return m_tree.rend(); } 319 320 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end 321 //! of the reversed container. 322 //! 323 //! <b>Throws</b>: Nothing. 324 //! 325 //! <b>Complexity</b>: Constant. 326 const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT 327 { return this->crend(); } 328 329 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container. 330 //! 331 //! <b>Throws</b>: Nothing. 332 //! 333 //! <b>Complexity</b>: Constant. 334 const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT 335 { return m_tree.begin(); } 336 337 //! <b>Effects</b>: Returns a const_iterator to the end of the container. 338 //! 339 //! <b>Throws</b>: Nothing. 340 //! 341 //! <b>Complexity</b>: Constant. 342 const_iterator cend() const BOOST_CONTAINER_NOEXCEPT 343 { return m_tree.end(); } 344 345 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning 346 //! of the reversed container. 347 //! 348 //! <b>Throws</b>: Nothing. 349 //! 350 //! <b>Complexity</b>: Constant. 351 const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT 352 { return m_tree.rbegin(); } 353 354 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end 355 //! of the reversed container. 356 //! 357 //! <b>Throws</b>: Nothing. 358 //! 359 //! <b>Complexity</b>: Constant. 360 const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT 361 { return m_tree.rend(); } 362 363 ////////////////////////////////////////////// 364 // 365 // capacity 366 // 367 ////////////////////////////////////////////// 368 369 //! <b>Effects</b>: Returns true if the container contains no elements. 370 //! 371 //! <b>Throws</b>: Nothing. 372 //! 373 //! <b>Complexity</b>: Constant. 374 bool empty() const BOOST_CONTAINER_NOEXCEPT 375 { return m_tree.empty(); } 376 377 //! <b>Effects</b>: Returns the number of the elements contained in the container. 378 //! 379 //! <b>Throws</b>: Nothing. 380 //! 381 //! <b>Complexity</b>: Constant. 382 size_type size() const BOOST_CONTAINER_NOEXCEPT 383 { return m_tree.size(); } 384 385 //! <b>Effects</b>: Returns the largest possible size of the container. 386 //! 387 //! <b>Throws</b>: Nothing. 388 //! 389 //! <b>Complexity</b>: Constant. 390 size_type max_size() const BOOST_CONTAINER_NOEXCEPT 391 { return m_tree.max_size(); } 392 393 ////////////////////////////////////////////// 394 // 395 // element access 396 // 397 ////////////////////////////////////////////// 398 399 #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) 400 //! Effects: If there is no key equivalent to x in the map, inserts 401 //! value_type(x, T()) into the map. 402 //! 403 //! Returns: Allocator reference to the mapped_type corresponding to x in *this. 404 //! 405 //! Complexity: Logarithmic. 406 mapped_type& operator[](const key_type &k); 407 408 //! Effects: If there is no key equivalent to x in the map, inserts 409 //! value_type(boost::move(x), T()) into the map (the key is move-constructed) 410 //! 411 //! Returns: Allocator reference to the mapped_type corresponding to x in *this. 412 //! 413 //! Complexity: Logarithmic. 414 mapped_type& operator[](key_type &&k); 415 #else 416 BOOST_MOVE_CONVERSION_AWARE_CATCH( operator[] , key_type, mapped_type&, this->priv_subscript) 417 #endif 418 419 //! Returns: Allocator reference to the element whose key is equivalent to x. 420 //! Throws: An exception object of type out_of_range if no such element is present. 421 //! Complexity: logarithmic. 422 T& at(const key_type& k) 423 { 424 iterator i = this->find(k); 425 if(i == this->end()){ 426 throw std::out_of_range("key not found"); 427 } 428 return i->second; 429 } 430 431 //! Returns: Allocator reference to the element whose key is equivalent to x. 432 //! Throws: An exception object of type out_of_range if no such element is present. 433 //! Complexity: logarithmic. 434 const T& at(const key_type& k) const 435 { 436 const_iterator i = this->find(k); 437 if(i == this->end()){ 438 throw std::out_of_range("key not found"); 439 } 440 return i->second; 441 } 442 443 ////////////////////////////////////////////// 444 // 445 // modifiers 446 // 447 ////////////////////////////////////////////// 448 449 //! <b>Effects</b>: Inserts x if and only if there is no element in the container 450 //! with key equivalent to the key of x. 451 //! 452 //! <b>Returns</b>: The bool component of the returned pair is true if and only 453 //! if the insertion takes place, and the iterator component of the pair 454 //! points to the element with key equivalent to the key of x. 455 //! 456 //! <b>Complexity</b>: Logarithmic. 457 std::pair<iterator,bool> insert(const value_type& x) 458 { return m_tree.insert_unique(x); } 459 460 //! <b>Effects</b>: Inserts a new value_type created from the pair if and only if 461 //! there is no element in the container with key equivalent to the key of x. 462 //! 463 //! <b>Returns</b>: The bool component of the returned pair is true if and only 464 //! if the insertion takes place, and the iterator component of the pair 465 //! points to the element with key equivalent to the key of x. 466 //! 467 //! <b>Complexity</b>: Logarithmic. 468 std::pair<iterator,bool> insert(const nonconst_value_type& x) 469 { return m_tree.insert_unique(x); } 470 471 //! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and 472 //! only if there is no element in the container with key equivalent to the key of x. 473 //! 474 //! <b>Returns</b>: The bool component of the returned pair is true if and only 475 //! if the insertion takes place, and the iterator component of the pair 476 //! points to the element with key equivalent to the key of x. 477 //! 478 //! <b>Complexity</b>: Logarithmic. 479 std::pair<iterator,bool> insert(BOOST_RV_REF(nonconst_value_type) x) 480 { return m_tree.insert_unique(boost::move(x)); } 481 482 //! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and 483 //! only if there is no element in the container with key equivalent to the key of x. 484 //! 485 //! <b>Returns</b>: The bool component of the returned pair is true if and only 486 //! if the insertion takes place, and the iterator component of the pair 487 //! points to the element with key equivalent to the key of x. 488 //! 489 //! <b>Complexity</b>: Logarithmic. 490 std::pair<iterator,bool> insert(BOOST_RV_REF(movable_value_type) x) 491 { return m_tree.insert_unique(boost::move(x)); } 492 493 //! <b>Effects</b>: Move constructs a new value from x if and only if there is 494 //! no element in the container with key equivalent to the key of x. 495 //! 496 //! <b>Returns</b>: The bool component of the returned pair is true if and only 497 //! if the insertion takes place, and the iterator component of the pair 498 //! points to the element with key equivalent to the key of x. 499 //! 500 //! <b>Complexity</b>: Logarithmic. 501 std::pair<iterator,bool> insert(BOOST_RV_REF(value_type) x) 502 { return m_tree.insert_unique(boost::move(x)); } 503 504 //! <b>Effects</b>: Inserts a copy of x in the container if and only if there is 505 //! no element in the container with key equivalent to the key of x. 506 //! p is a hint pointing to where the insert should start to search. 507 //! 508 //! <b>Returns</b>: An iterator pointing to the element with key equivalent 509 //! to the key of x. 510 //! 511 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t 512 //! is inserted right before p. 513 iterator insert(const_iterator position, const value_type& x) 514 { return m_tree.insert_unique(position, x); } 515 516 //! <b>Effects</b>: Move constructs a new value from x if and only if there is 517 //! no element in the container with key equivalent to the key of x. 518 //! p is a hint pointing to where the insert should start to search. 519 //! 520 //! <b>Returns</b>: An iterator pointing to the element with key equivalent 521 //! to the key of x. 522 //! 523 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t 524 //! is inserted right before p. 525 iterator insert(const_iterator position, BOOST_RV_REF(nonconst_value_type) x) 526 { return m_tree.insert_unique(position, boost::move(x)); } 527 528 //! <b>Effects</b>: Move constructs a new value from x if and only if there is 529 //! no element in the container with key equivalent to the key of x. 530 //! p is a hint pointing to where the insert should start to search. 531 //! 532 //! <b>Returns</b>: An iterator pointing to the element with key equivalent 533 //! to the key of x. 534 //! 535 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t 536 //! is inserted right before p. 537 iterator insert(const_iterator position, BOOST_RV_REF(movable_value_type) x) 538 { return m_tree.insert_unique(position, boost::move(x)); } 539 540 //! <b>Effects</b>: Inserts a copy of x in the container. 541 //! p is a hint pointing to where the insert should start to search. 542 //! 543 //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x. 544 //! 545 //! <b>Complexity</b>: Logarithmic. 546 iterator insert(const_iterator position, const nonconst_value_type& x) 547 { return m_tree.insert_unique(position, x); } 548 549 //! <b>Effects</b>: Inserts an element move constructed from x in the container. 550 //! p is a hint pointing to where the insert should start to search. 551 //! 552 //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x. 553 //! 554 //! <b>Complexity</b>: Logarithmic. 555 iterator insert(const_iterator position, BOOST_RV_REF(value_type) x) 556 { return m_tree.insert_unique(position, boost::move(x)); } 557 558 //! <b>Requires</b>: first, last are not iterators into *this. 559 //! 560 //! <b>Effects</b>: inserts each element from the range [first,last) if and only 561 //! if there is no element with key equivalent to the key of that element. 562 //! 563 //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last) 564 template <class InputIterator> 565 void insert(InputIterator first, InputIterator last) 566 { m_tree.insert_unique(first, last); } 567 568 #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) 569 570 //! <b>Effects</b>: Inserts an object x of type T constructed with 571 //! std::forward<Args>(args)... in the container if and only if there is 572 //! no element in the container with an equivalent key. 573 //! p is a hint pointing to where the insert should start to search. 574 //! 575 //! <b>Returns</b>: The bool component of the returned pair is true if and only 576 //! if the insertion takes place, and the iterator component of the pair 577 //! points to the element with key equivalent to the key of x. 578 //! 579 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t 580 //! is inserted right before p. 581 template <class... Args> 582 std::pair<iterator,bool> emplace(Args&&... args) 583 { return m_tree.emplace_unique(boost::forward<Args>(args)...); } 584 585 //! <b>Effects</b>: Inserts an object of type T constructed with 586 //! std::forward<Args>(args)... in the container if and only if there is 587 //! no element in the container with an equivalent key. 588 //! p is a hint pointing to where the insert should start to search. 589 //! 590 //! <b>Returns</b>: An iterator pointing to the element with key equivalent 591 //! to the key of x. 592 //! 593 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t 594 //! is inserted right before p. 595 template <class... Args> 596 iterator emplace_hint(const_iterator hint, Args&&... args) 597 { return m_tree.emplace_hint_unique(hint, boost::forward<Args>(args)...); } 598 599 #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING 600 601 #define BOOST_PP_LOCAL_MACRO(n) \ 602 BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ 603 std::pair<iterator,bool> emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ 604 { return m_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \ 605 \ 606 BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ 607 iterator emplace_hint(const_iterator hint \ 608 BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ 609 { return m_tree.emplace_hint_unique(hint \ 610 BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));} \ 611 //! 612 #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) 613 #include BOOST_PP_LOCAL_ITERATE() 614 615 #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING 616 617 //! <b>Effects</b>: Erases the element pointed to by position. 618 //! 619 //! <b>Returns</b>: Returns an iterator pointing to the element immediately 620 //! following q prior to the element being erased. If no such element exists, 621 //! returns end(). 622 //! 623 //! <b>Complexity</b>: Amortized constant time 624 iterator erase(const_iterator position) BOOST_CONTAINER_NOEXCEPT 625 { return m_tree.erase(position); } 626 627 //! <b>Effects</b>: Erases all elements in the container with key equivalent to x. 628 //! 629 //! <b>Returns</b>: Returns the number of erased elements. 630 //! 631 //! <b>Complexity</b>: log(size()) + count(k) 632 size_type erase(const key_type& x) BOOST_CONTAINER_NOEXCEPT 633 { return m_tree.erase(x); } 634 635 //! <b>Effects</b>: Erases all the elements in the range [first, last). 636 //! 637 //! <b>Returns</b>: Returns last. 638 //! 639 //! <b>Complexity</b>: log(size())+N where N is the distance from first to last. 640 iterator erase(const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT 641 { return m_tree.erase(first, last); } 642 643 //! <b>Effects</b>: Swaps the contents of *this and x. 644 //! 645 //! <b>Throws</b>: Nothing. 646 //! 647 //! <b>Complexity</b>: Constant. 648 void swap(map& x) 649 { m_tree.swap(x.m_tree); } 650 651 //! <b>Effects</b>: erase(a.begin(),a.end()). 652 //! 653 //! <b>Postcondition</b>: size() == 0. 654 //! 655 //! <b>Complexity</b>: linear in size(). 656 void clear() BOOST_CONTAINER_NOEXCEPT 657 { m_tree.clear(); } 658 659 ////////////////////////////////////////////// 660 // 661 // observers 662 // 663 ////////////////////////////////////////////// 664 665 //! <b>Effects</b>: Returns the comparison object out 666 //! of which a was constructed. 667 //! 668 //! <b>Complexity</b>: Constant. 669 key_compare key_comp() const 670 { return m_tree.key_comp(); } 671 672 //! <b>Effects</b>: Returns an object of value_compare constructed out 673 //! of the comparison object. 674 //! 675 //! <b>Complexity</b>: Constant. 676 value_compare value_comp() const 677 { return value_compare(m_tree.key_comp()); } 678 679 ////////////////////////////////////////////// 680 // 681 // map operations 682 // 683 ////////////////////////////////////////////// 684 685 //! <b>Returns</b>: An iterator pointing to an element with the key 686 //! equivalent to x, or end() if such an element is not found. 687 //! 688 //! <b>Complexity</b>: Logarithmic. 689 iterator find(const key_type& x) 690 { return m_tree.find(x); } 691 692 //! <b>Returns</b>: Allocator const_iterator pointing to an element with the key 693 //! equivalent to x, or end() if such an element is not found. 694 //! 695 //! <b>Complexity</b>: Logarithmic. 696 const_iterator find(const key_type& x) const 697 { return m_tree.find(x); } 698 699 //! <b>Returns</b>: The number of elements with key equivalent to x. 700 //! 701 //! <b>Complexity</b>: log(size())+count(k) 702 size_type count(const key_type& x) const 703 { return m_tree.find(x) == m_tree.end() ? 0 : 1; } 704 705 //! <b>Returns</b>: An iterator pointing to the first element with key not less 706 //! than k, or a.end() if such an element is not found. 707 //! 708 //! <b>Complexity</b>: Logarithmic 709 iterator lower_bound(const key_type& x) 710 { return m_tree.lower_bound(x); } 711 712 //! <b>Returns</b>: Allocator const iterator pointing to the first element with key not 713 //! less than k, or a.end() if such an element is not found. 714 //! 715 //! <b>Complexity</b>: Logarithmic 716 const_iterator lower_bound(const key_type& x) const 717 { return m_tree.lower_bound(x); } 718 719 //! <b>Returns</b>: An iterator pointing to the first element with key not less 720 //! than x, or end() if such an element is not found. 721 //! 722 //! <b>Complexity</b>: Logarithmic 723 iterator upper_bound(const key_type& x) 724 { return m_tree.upper_bound(x); } 725 726 //! <b>Returns</b>: Allocator const iterator pointing to the first element with key not 727 //! less than x, or end() if such an element is not found. 728 //! 729 //! <b>Complexity</b>: Logarithmic 730 const_iterator upper_bound(const key_type& x) const 731 { return m_tree.upper_bound(x); } 732 733 //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). 734 //! 735 //! <b>Complexity</b>: Logarithmic 736 std::pair<iterator,iterator> equal_range(const key_type& x) 737 { return m_tree.equal_range(x); } 738 739 //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). 740 //! 741 //! <b>Complexity</b>: Logarithmic 742 std::pair<const_iterator,const_iterator> equal_range(const key_type& x) const 743 { return m_tree.equal_range(x); } 744 745 /// @cond 746 template <class K1, class T1, class C1, class A1> 747 friend bool operator== (const map<K1, T1, C1, A1>&, 748 const map<K1, T1, C1, A1>&); 749 template <class K1, class T1, class C1, class A1> 750 friend bool operator< (const map<K1, T1, C1, A1>&, 751 const map<K1, T1, C1, A1>&); 752 private: 753 mapped_type& priv_subscript(const key_type &k) 754 { 755 //we can optimize this 756 iterator i = lower_bound(k); 757 // i->first is greater than or equivalent to k. 758 if (i == end() || key_comp()(k, (*i).first)){ 759 container_detail::value_init<mapped_type> m; 760 movable_value_type val(k, boost::move(m.m_t)); 761 i = insert(i, boost::move(val)); 762 } 763 return (*i).second; 764 } 765 766 mapped_type& priv_subscript(BOOST_RV_REF(key_type) mk) 767 { 768 key_type &k = mk; 769 //we can optimize this 770 iterator i = lower_bound(k); 771 // i->first is greater than or equivalent to k. 772 if (i == end() || key_comp()(k, (*i).first)){ 773 container_detail::value_init<mapped_type> m; 774 movable_value_type val(boost::move(k), boost::move(m.m_t)); 775 i = insert(i, boost::move(val)); 776 } 777 return (*i).second; 778 } 779 780 /// @endcond 781}; 782 783template <class Key, class T, class Compare, class Allocator> 784inline bool operator==(const map<Key,T,Compare,Allocator>& x, 785 const map<Key,T,Compare,Allocator>& y) 786 { return x.m_tree == y.m_tree; } 787 788template <class Key, class T, class Compare, class Allocator> 789inline bool operator<(const map<Key,T,Compare,Allocator>& x, 790 const map<Key,T,Compare,Allocator>& y) 791 { return x.m_tree < y.m_tree; } 792 793template <class Key, class T, class Compare, class Allocator> 794inline bool operator!=(const map<Key,T,Compare,Allocator>& x, 795 const map<Key,T,Compare,Allocator>& y) 796 { return !(x == y); } 797 798template <class Key, class T, class Compare, class Allocator> 799inline bool operator>(const map<Key,T,Compare,Allocator>& x, 800 const map<Key,T,Compare,Allocator>& y) 801 { return y < x; } 802 803template <class Key, class T, class Compare, class Allocator> 804inline bool operator<=(const map<Key,T,Compare,Allocator>& x, 805 const map<Key,T,Compare,Allocator>& y) 806 { return !(y < x); } 807 808template <class Key, class T, class Compare, class Allocator> 809inline bool operator>=(const map<Key,T,Compare,Allocator>& x, 810 const map<Key,T,Compare,Allocator>& y) 811 { return !(x < y); } 812 813template <class Key, class T, class Compare, class Allocator> 814inline void swap(map<Key,T,Compare,Allocator>& x, map<Key,T,Compare,Allocator>& y) 815 { x.swap(y); } 816 817/// @cond 818 819// Forward declaration of operators < and ==, needed for friend declaration. 820 821template <class Key, class T, class Compare, class Allocator> 822inline bool operator==(const multimap<Key,T,Compare,Allocator>& x, 823 const multimap<Key,T,Compare,Allocator>& y); 824 825template <class Key, class T, class Compare, class Allocator> 826inline bool operator<(const multimap<Key,T,Compare,Allocator>& x, 827 const multimap<Key,T,Compare,Allocator>& y); 828 829} //namespace container { 830 831//!has_trivial_destructor_after_move<> == true_type 832//!specialization for optimizations 833template <class K, class T, class C, class Allocator> 834struct has_trivial_destructor_after_move<boost::container::map<K, T, C, Allocator> > 835{ 836 static const bool value = has_trivial_destructor_after_move<Allocator>::value && has_trivial_destructor_after_move<C>::value; 837}; 838 839namespace container { 840 841/// @endcond 842 843//! A multimap is a kind of associative container that supports equivalent keys 844//! (possibly containing multiple copies of the same key value) and provides for 845//! fast retrieval of values of another type T based on the keys. The multimap class 846//! supports bidirectional iterators. 847//! 848//! A multimap satisfies all of the requirements of a container and of a reversible 849//! container and of an associative container. For a 850//! map<Key,T> the key_type is Key and the value_type is std::pair<const Key,T>. 851//! 852//! Compare is the ordering function for Keys (e.g. <i>std::less<Key></i>). 853//! 854//! Allocator is the allocator to allocate the value_types 855//!(e.g. <i>allocator< std::pair<<b>const</b> Key, T> ></i>). 856#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED 857template <class Key, class T, class Compare = std::less<Key>, class Allocator = std::allocator< std::pair< const Key, T> > > 858#else 859template <class Key, class T, class Compare, class Allocator> 860#endif 861class multimap 862{ 863 /// @cond 864 private: 865 BOOST_COPYABLE_AND_MOVABLE(multimap) 866 867 typedef std::pair<const Key, T> value_type_impl; 868 typedef container_detail::rbtree 869 <Key, value_type_impl, container_detail::select1st<value_type_impl>, Compare, Allocator> tree_t; 870 typedef container_detail::pair <Key, T> movable_value_type_impl; 871 typedef container_detail::tree_value_compare 872 < Key, value_type_impl, Compare, container_detail::select1st<value_type_impl> 873 > value_compare_impl; 874 tree_t m_tree; // red-black tree representing map 875 /// @endcond 876 877 public: 878 ////////////////////////////////////////////// 879 // 880 // types 881 // 882 ////////////////////////////////////////////// 883 884 typedef Key key_type; 885 typedef T mapped_type; 886 typedef std::pair<const Key, T> value_type; 887 typedef typename boost::container::allocator_traits<Allocator>::pointer pointer; 888 typedef typename boost::container::allocator_traits<Allocator>::const_pointer const_pointer; 889 typedef typename boost::container::allocator_traits<Allocator>::reference reference; 890 typedef typename boost::container::allocator_traits<Allocator>::const_reference const_reference; 891 typedef typename boost::container::allocator_traits<Allocator>::size_type size_type; 892 typedef typename boost::container::allocator_traits<Allocator>::difference_type difference_type; 893 typedef Allocator allocator_type; 894 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::stored_allocator_type) stored_allocator_type; 895 typedef BOOST_CONTAINER_IMPDEF(value_compare_impl) value_compare; 896 typedef Compare key_compare; 897 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::iterator) iterator; 898 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::const_iterator) const_iterator; 899 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::reverse_iterator) reverse_iterator; 900 typedef typename BOOST_CONTAINER_IMPDEF(tree_t::const_reverse_iterator) const_reverse_iterator; 901 typedef std::pair<key_type, mapped_type> nonconst_value_type; 902 typedef BOOST_CONTAINER_IMPDEF(movable_value_type_impl) movable_value_type; 903 904 ////////////////////////////////////////////// 905 // 906 // construct/copy/destroy 907 // 908 ////////////////////////////////////////////// 909 910 //! <b>Effects</b>: Default constructs an empty multimap. 911 //! 912 //! <b>Complexity</b>: Constant. 913 multimap() 914 : m_tree() 915 { 916 //Allocator type must be std::pair<CONST Key, T> 917 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); 918 } 919 920 //! <b>Effects</b>: Constructs an empty multimap using the specified comparison 921 //! object and allocator. 922 //! 923 //! <b>Complexity</b>: Constant. 924 explicit multimap(const Compare& comp, const allocator_type& a = allocator_type()) 925 : m_tree(comp, a) 926 { 927 //Allocator type must be std::pair<CONST Key, T> 928 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); 929 } 930 931 //! <b>Effects</b>: Constructs an empty multimap using the specified comparison object 932 //! and allocator, and inserts elements from the range [first ,last ). 933 //! 934 //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using 935 //! comp and otherwise N logN, where N is last - first. 936 template <class InputIterator> 937 multimap(InputIterator first, InputIterator last, 938 const Compare& comp = Compare(), 939 const allocator_type& a = allocator_type()) 940 : m_tree(false, first, last, comp, a) 941 { 942 //Allocator type must be std::pair<CONST Key, T> 943 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); 944 } 945 946 //! <b>Effects</b>: Constructs an empty multimap using the specified comparison object and 947 //! allocator, and inserts elements from the ordered range [first ,last). This function 948 //! is more efficient than the normal range creation for ordered ranges. 949 //! 950 //! <b>Requires</b>: [first ,last) must be ordered according to the predicate. 951 //! 952 //! <b>Complexity</b>: Linear in N. 953 template <class InputIterator> 954 multimap(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp = Compare(), 955 const allocator_type& a = allocator_type()) 956 : m_tree(ordered_range, first, last, comp, a) 957 {} 958 959 //! <b>Effects</b>: Copy constructs a multimap. 960 //! 961 //! <b>Complexity</b>: Linear in x.size(). 962 multimap(const multimap& x) 963 : m_tree(x.m_tree) 964 { 965 //Allocator type must be std::pair<CONST Key, T> 966 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); 967 } 968 969 //! <b>Effects</b>: Move constructs a multimap. Constructs *this using x's resources. 970 //! 971 //! <b>Complexity</b>: Constant. 972 //! 973 //! <b>Postcondition</b>: x is emptied. 974 multimap(BOOST_RV_REF(multimap) x) 975 : m_tree(boost::move(x.m_tree)) 976 { 977 //Allocator type must be std::pair<CONST Key, T> 978 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); 979 } 980 981 //! <b>Effects</b>: Copy constructs a multimap. 982 //! 983 //! <b>Complexity</b>: Linear in x.size(). 984 multimap(const multimap& x, const allocator_type &a) 985 : m_tree(x.m_tree, a) 986 { 987 //Allocator type must be std::pair<CONST Key, T> 988 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); 989 } 990 991 //! <b>Effects</b>: Move constructs a multimap using the specified allocator. 992 //! Constructs *this using x's resources. 993 //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise. 994 //! 995 //! <b>Postcondition</b>: x is emptied. 996 multimap(BOOST_RV_REF(multimap) x, const allocator_type &a) 997 : m_tree(boost::move(x.m_tree), a) 998 { 999 //Allocator type must be std::pair<CONST Key, T> 1000 BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); 1001 } 1002 1003 //! <b>Effects</b>: Makes *this a copy of x. 1004 //! 1005 //! <b>Complexity</b>: Linear in x.size(). 1006 multimap& operator=(BOOST_COPY_ASSIGN_REF(multimap) x) 1007 { m_tree = x.m_tree; return *this; } 1008 1009 //! <b>Effects</b>: this->swap(x.get()). 1010 //! 1011 //! <b>Complexity</b>: Constant. 1012 multimap& operator=(BOOST_RV_REF(multimap) x) 1013 { m_tree = boost::move(x.m_tree); return *this; } 1014 1015 //! <b>Effects</b>: Returns a copy of the Allocator that 1016 //! was passed to the object's constructor. 1017 //! 1018 //! <b>Complexity</b>: Constant. 1019 allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT 1020 { return m_tree.get_allocator(); } 1021 1022 //! <b>Effects</b>: Returns a reference to the internal allocator. 1023 //! 1024 //! <b>Throws</b>: Nothing 1025 //! 1026 //! <b>Complexity</b>: Constant. 1027 //! 1028 //! <b>Note</b>: Non-standard extension. 1029 stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT 1030 { return m_tree.get_stored_allocator(); } 1031 1032 //! <b>Effects</b>: Returns a reference to the internal allocator. 1033 //! 1034 //! <b>Throws</b>: Nothing 1035 //! 1036 //! <b>Complexity</b>: Constant. 1037 //! 1038 //! <b>Note</b>: Non-standard extension. 1039 const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT 1040 { return m_tree.get_stored_allocator(); } 1041 1042 ////////////////////////////////////////////// 1043 // 1044 // iterators 1045 // 1046 ////////////////////////////////////////////// 1047 1048 //! <b>Effects</b>: Returns an iterator to the first element contained in the container. 1049 //! 1050 //! <b>Throws</b>: Nothing. 1051 //! 1052 //! <b>Complexity</b>: Constant. 1053 iterator begin() BOOST_CONTAINER_NOEXCEPT 1054 { return m_tree.begin(); } 1055 1056 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container. 1057 //! 1058 //! <b>Throws</b>: Nothing. 1059 //! 1060 //! <b>Complexity</b>: Constant. 1061 const_iterator begin() const BOOST_CONTAINER_NOEXCEPT 1062 { return this->cbegin(); } 1063 1064 //! <b>Effects</b>: Returns an iterator to the end of the container. 1065 //! 1066 //! <b>Throws</b>: Nothing. 1067 //! 1068 //! <b>Complexity</b>: Constant. 1069 iterator end() BOOST_CONTAINER_NOEXCEPT 1070 { return m_tree.end(); } 1071 1072 //! <b>Effects</b>: Returns a const_iterator to the end of the container. 1073 //! 1074 //! <b>Throws</b>: Nothing. 1075 //! 1076 //! <b>Complexity</b>: Constant. 1077 const_iterator end() const BOOST_CONTAINER_NOEXCEPT 1078 { return this->cend(); } 1079 1080 //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning 1081 //! of the reversed container. 1082 //! 1083 //! <b>Throws</b>: Nothing. 1084 //! 1085 //! <b>Complexity</b>: Constant. 1086 reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT 1087 { return m_tree.rbegin(); } 1088 1089 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning 1090 //! of the reversed container. 1091 //! 1092 //! <b>Throws</b>: Nothing. 1093 //! 1094 //! <b>Complexity</b>: Constant. 1095 const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT 1096 { return this->crbegin(); } 1097 1098 //! <b>Effects</b>: Returns a reverse_iterator pointing to the end 1099 //! of the reversed container. 1100 //! 1101 //! <b>Throws</b>: Nothing. 1102 //! 1103 //! <b>Complexity</b>: Constant. 1104 reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT 1105 { return m_tree.rend(); } 1106 1107 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end 1108 //! of the reversed container. 1109 //! 1110 //! <b>Throws</b>: Nothing. 1111 //! 1112 //! <b>Complexity</b>: Constant. 1113 const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT 1114 { return this->crend(); } 1115 1116 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container. 1117 //! 1118 //! <b>Throws</b>: Nothing. 1119 //! 1120 //! <b>Complexity</b>: Constant. 1121 const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT 1122 { return m_tree.begin(); } 1123 1124 //! <b>Effects</b>: Returns a const_iterator to the end of the container. 1125 //! 1126 //! <b>Throws</b>: Nothing. 1127 //! 1128 //! <b>Complexity</b>: Constant. 1129 const_iterator cend() const BOOST_CONTAINER_NOEXCEPT 1130 { return m_tree.end(); } 1131 1132 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning 1133 //! of the reversed container. 1134 //! 1135 //! <b>Throws</b>: Nothing. 1136 //! 1137 //! <b>Complexity</b>: Constant. 1138 const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT 1139 { return m_tree.rbegin(); } 1140 1141 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end 1142 //! of the reversed container. 1143 //! 1144 //! <b>Throws</b>: Nothing. 1145 //! 1146 //! <b>Complexity</b>: Constant. 1147 const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT 1148 { return m_tree.rend(); } 1149 1150 ////////////////////////////////////////////// 1151 // 1152 // capacity 1153 // 1154 ////////////////////////////////////////////// 1155 1156 //! <b>Effects</b>: Returns true if the container contains no elements. 1157 //! 1158 //! <b>Throws</b>: Nothing. 1159 //! 1160 //! <b>Complexity</b>: Constant. 1161 bool empty() const BOOST_CONTAINER_NOEXCEPT 1162 { return m_tree.empty(); } 1163 1164 //! <b>Effects</b>: Returns the number of the elements contained in the container. 1165 //! 1166 //! <b>Throws</b>: Nothing. 1167 //! 1168 //! <b>Complexity</b>: Constant. 1169 size_type size() const BOOST_CONTAINER_NOEXCEPT 1170 { return m_tree.size(); } 1171 1172 //! <b>Effects</b>: Returns the largest possible size of the container. 1173 //! 1174 //! <b>Throws</b>: Nothing. 1175 //! 1176 //! <b>Complexity</b>: Constant. 1177 size_type max_size() const BOOST_CONTAINER_NOEXCEPT 1178 { return m_tree.max_size(); } 1179 1180 ////////////////////////////////////////////// 1181 // 1182 // modifiers 1183 // 1184 ////////////////////////////////////////////// 1185 1186 #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) 1187 1188 //! <b>Effects</b>: Inserts an object of type T constructed with 1189 //! std::forward<Args>(args)... in the container. 1190 //! p is a hint pointing to where the insert should start to search. 1191 //! 1192 //! <b>Returns</b>: An iterator pointing to the element with key equivalent 1193 //! to the key of x. 1194 //! 1195 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t 1196 //! is inserted right before p. 1197 template <class... Args> 1198 iterator emplace(Args&&... args) 1199 { return m_tree.emplace_equal(boost::forward<Args>(args)...); } 1200 1201 //! <b>Effects</b>: Inserts an object of type T constructed with 1202 //! std::forward<Args>(args)... in the container. 1203 //! p is a hint pointing to where the insert should start to search. 1204 //! 1205 //! <b>Returns</b>: An iterator pointing to the element with key equivalent 1206 //! to the key of x. 1207 //! 1208 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t 1209 //! is inserted right before p. 1210 template <class... Args> 1211 iterator emplace_hint(const_iterator hint, Args&&... args) 1212 { return m_tree.emplace_hint_equal(hint, boost::forward<Args>(args)...); } 1213 1214 #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING 1215 1216 #define BOOST_PP_LOCAL_MACRO(n) \ 1217 BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ 1218 iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ 1219 { return m_tree.emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \ 1220 \ 1221 BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ 1222 iterator emplace_hint(const_iterator hint \ 1223 BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ 1224 { return m_tree.emplace_hint_equal(hint \ 1225 BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));} \ 1226 //! 1227 #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) 1228 #include BOOST_PP_LOCAL_ITERATE() 1229 1230 #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING 1231 1232 //! <b>Effects</b>: Inserts x and returns the iterator pointing to the 1233 //! newly inserted element. 1234 //! 1235 //! <b>Complexity</b>: Logarithmic. 1236 iterator insert(const value_type& x) 1237 { return m_tree.insert_equal(x); } 1238 1239 //! <b>Effects</b>: Inserts a new value constructed from x and returns 1240 //! the iterator pointing to the newly inserted element. 1241 //! 1242 //! <b>Complexity</b>: Logarithmic. 1243 iterator insert(const nonconst_value_type& x) 1244 { return m_tree.insert_equal(x); } 1245 1246 //! <b>Effects</b>: Inserts a new value move-constructed from x and returns 1247 //! the iterator pointing to the newly inserted element. 1248 //! 1249 //! <b>Complexity</b>: Logarithmic. 1250 iterator insert(BOOST_RV_REF(nonconst_value_type) x) 1251 { return m_tree.insert_equal(boost::move(x)); } 1252 1253 //! <b>Effects</b>: Inserts a new value move-constructed from x and returns 1254 //! the iterator pointing to the newly inserted element. 1255 //! 1256 //! <b>Complexity</b>: Logarithmic. 1257 iterator insert(BOOST_RV_REF(movable_value_type) x) 1258 { return m_tree.insert_equal(boost::move(x)); } 1259 1260 //! <b>Effects</b>: Inserts a copy of x in the container. 1261 //! p is a hint pointing to where the insert should start to search. 1262 //! 1263 //! <b>Returns</b>: An iterator pointing to the element with key equivalent 1264 //! to the key of x. 1265 //! 1266 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t 1267 //! is inserted right before p. 1268 iterator insert(const_iterator position, const value_type& x) 1269 { return m_tree.insert_equal(position, x); } 1270 1271 //! <b>Effects</b>: Inserts a new value constructed from x in the container. 1272 //! p is a hint pointing to where the insert should start to search. 1273 //! 1274 //! <b>Returns</b>: An iterator pointing to the element with key equivalent 1275 //! to the key of x. 1276 //! 1277 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t 1278 //! is inserted right before p. 1279 iterator insert(const_iterator position, const nonconst_value_type& x) 1280 { return m_tree.insert_equal(position, x); } 1281 1282 //! <b>Effects</b>: Inserts a new value move constructed from x in the container. 1283 //! p is a hint pointing to where the insert should start to search. 1284 //! 1285 //! <b>Returns</b>: An iterator pointing to the element with key equivalent 1286 //! to the key of x. 1287 //! 1288 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t 1289 //! is inserted right before p. 1290 iterator insert(const_iterator position, BOOST_RV_REF(nonconst_value_type) x) 1291 { return m_tree.insert_equal(position, boost::move(x)); } 1292 1293 //! <b>Effects</b>: Inserts a new value move constructed from x in the container. 1294 //! p is a hint pointing to where the insert should start to search. 1295 //! 1296 //! <b>Returns</b>: An iterator pointing to the element with key equivalent 1297 //! to the key of x. 1298 //! 1299 //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t 1300 //! is inserted right before p. 1301 iterator insert(const_iterator position, BOOST_RV_REF(movable_value_type) x) 1302 { return m_tree.insert_equal(position, boost::move(x)); } 1303 1304 //! <b>Requires</b>: first, last are not iterators into *this. 1305 //! 1306 //! <b>Effects</b>: inserts each element from the range [first,last) . 1307 //! 1308 //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last) 1309 template <class InputIterator> 1310 void insert(InputIterator first, InputIterator last) 1311 { m_tree.insert_equal(first, last); } 1312 1313 //! <b>Effects</b>: Erases the element pointed to by position. 1314 //! 1315 //! <b>Returns</b>: Returns an iterator pointing to the element immediately 1316 //! following q prior to the element being erased. If no such element exists, 1317 //! returns end(). 1318 //! 1319 //! <b>Complexity</b>: Amortized constant time 1320 iterator erase(const_iterator position) BOOST_CONTAINER_NOEXCEPT 1321 { return m_tree.erase(position); } 1322 1323 //! <b>Effects</b>: Erases all elements in the container with key equivalent to x. 1324 //! 1325 //! <b>Returns</b>: Returns the number of erased elements. 1326 //! 1327 //! <b>Complexity</b>: log(size()) + count(k) 1328 size_type erase(const key_type& x) BOOST_CONTAINER_NOEXCEPT 1329 { return m_tree.erase(x); } 1330 1331 //! <b>Effects</b>: Erases all the elements in the range [first, last). 1332 //! 1333 //! <b>Returns</b>: Returns last. 1334 //! 1335 //! <b>Complexity</b>: log(size())+N where N is the distance from first to last. 1336 iterator erase(const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT 1337 { return m_tree.erase(first, last); } 1338 1339 //! <b>Effects</b>: Swaps the contents of *this and x. 1340 //! 1341 //! <b>Throws</b>: Nothing. 1342 //! 1343 //! <b>Complexity</b>: Constant. 1344 void swap(multimap& x) 1345 { m_tree.swap(x.m_tree); } 1346 1347 //! <b>Effects</b>: erase(a.begin(),a.end()). 1348 //! 1349 //! <b>Postcondition</b>: size() == 0. 1350 //! 1351 //! <b>Complexity</b>: linear in size(). 1352 void clear() BOOST_CONTAINER_NOEXCEPT 1353 { m_tree.clear(); } 1354 1355 ////////////////////////////////////////////// 1356 // 1357 // observers 1358 // 1359 ////////////////////////////////////////////// 1360 1361 //! <b>Effects</b>: Returns the comparison object out 1362 //! of which a was constructed. 1363 //! 1364 //! <b>Complexity</b>: Constant. 1365 key_compare key_comp() const 1366 { return m_tree.key_comp(); } 1367 1368 //! <b>Effects</b>: Returns an object of value_compare constructed out 1369 //! of the comparison object. 1370 //! 1371 //! <b>Complexity</b>: Constant. 1372 value_compare value_comp() const 1373 { return value_compare(m_tree.key_comp()); } 1374 1375 ////////////////////////////////////////////// 1376 // 1377 // map operations 1378 // 1379 ////////////////////////////////////////////// 1380 1381 //! <b>Returns</b>: An iterator pointing to an element with the key 1382 //! equivalent to x, or end() if such an element is not found. 1383 //! 1384 //! <b>Complexity</b>: Logarithmic. 1385 iterator find(const key_type& x) 1386 { return m_tree.find(x); } 1387 1388 //! <b>Returns</b>: Allocator const iterator pointing to an element with the key 1389 //! equivalent to x, or end() if such an element is not found. 1390 //! 1391 //! <b>Complexity</b>: Logarithmic. 1392 const_iterator find(const key_type& x) const 1393 { return m_tree.find(x); } 1394 1395 //! <b>Returns</b>: The number of elements with key equivalent to x. 1396 //! 1397 //! <b>Complexity</b>: log(size())+count(k) 1398 size_type count(const key_type& x) const 1399 { return m_tree.count(x); } 1400 1401 //! <b>Returns</b>: An iterator pointing to the first element with key not less 1402 //! than k, or a.end() if such an element is not found. 1403 //! 1404 //! <b>Complexity</b>: Logarithmic 1405 iterator lower_bound(const key_type& x) 1406 {return m_tree.lower_bound(x); } 1407 1408 //! <b>Returns</b>: Allocator const iterator pointing to the first element with key not 1409 //! less than k, or a.end() if such an element is not found. 1410 //! 1411 //! <b>Complexity</b>: Logarithmic 1412 const_iterator lower_bound(const key_type& x) const 1413 { return m_tree.lower_bound(x); } 1414 1415 //! <b>Returns</b>: An iterator pointing to the first element with key not less 1416 //! than x, or end() if such an element is not found. 1417 //! 1418 //! <b>Complexity</b>: Logarithmic 1419 iterator upper_bound(const key_type& x) 1420 { return m_tree.upper_bound(x); } 1421 1422 //! <b>Returns</b>: Allocator const iterator pointing to the first element with key not 1423 //! less than x, or end() if such an element is not found. 1424 //! 1425 //! <b>Complexity</b>: Logarithmic 1426 const_iterator upper_bound(const key_type& x) const 1427 { return m_tree.upper_bound(x); } 1428 1429 //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). 1430 //! 1431 //! <b>Complexity</b>: Logarithmic 1432 std::pair<iterator,iterator> equal_range(const key_type& x) 1433 { return m_tree.equal_range(x); } 1434 1435 //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). 1436 //! 1437 //! <b>Complexity</b>: Logarithmic 1438 std::pair<const_iterator,const_iterator> equal_range(const key_type& x) const 1439 { return m_tree.equal_range(x); } 1440 1441 /// @cond 1442 template <class K1, class T1, class C1, class A1> 1443 friend bool operator== (const multimap<K1, T1, C1, A1>& x, 1444 const multimap<K1, T1, C1, A1>& y); 1445 1446 template <class K1, class T1, class C1, class A1> 1447 friend bool operator< (const multimap<K1, T1, C1, A1>& x, 1448 const multimap<K1, T1, C1, A1>& y); 1449 /// @endcond 1450}; 1451 1452template <class Key, class T, class Compare, class Allocator> 1453inline bool operator==(const multimap<Key,T,Compare,Allocator>& x, 1454 const multimap<Key,T,Compare,Allocator>& y) 1455{ return x.m_tree == y.m_tree; } 1456 1457template <class Key, class T, class Compare, class Allocator> 1458inline bool operator<(const multimap<Key,T,Compare,Allocator>& x, 1459 const multimap<Key,T,Compare,Allocator>& y) 1460{ return x.m_tree < y.m_tree; } 1461 1462template <class Key, class T, class Compare, class Allocator> 1463inline bool operator!=(const multimap<Key,T,Compare,Allocator>& x, 1464 const multimap<Key,T,Compare,Allocator>& y) 1465{ return !(x == y); } 1466 1467template <class Key, class T, class Compare, class Allocator> 1468inline bool operator>(const multimap<Key,T,Compare,Allocator>& x, 1469 const multimap<Key,T,Compare,Allocator>& y) 1470{ return y < x; } 1471 1472template <class Key, class T, class Compare, class Allocator> 1473inline bool operator<=(const multimap<Key,T,Compare,Allocator>& x, 1474 const multimap<Key,T,Compare,Allocator>& y) 1475{ return !(y < x); } 1476 1477template <class Key, class T, class Compare, class Allocator> 1478inline bool operator>=(const multimap<Key,T,Compare,Allocator>& x, 1479 const multimap<Key,T,Compare,Allocator>& y) 1480{ return !(x < y); } 1481 1482template <class Key, class T, class Compare, class Allocator> 1483inline void swap(multimap<Key,T,Compare,Allocator>& x, multimap<Key,T,Compare,Allocator>& y) 1484{ x.swap(y); } 1485 1486/// @cond 1487 1488} //namespace container { 1489 1490//!has_trivial_destructor_after_move<> == true_type 1491//!specialization for optimizations 1492template <class K, class T, class C, class Allocator> 1493struct has_trivial_destructor_after_move<boost::container::multimap<K, T, C, Allocator> > 1494{ 1495 static const bool value = has_trivial_destructor_after_move<Allocator>::value && has_trivial_destructor_after_move<C>::value; 1496}; 1497 1498namespace container { 1499 1500/// @endcond 1501 1502}} 1503 1504#include <boost/container/detail/config_end.hpp> 1505 1506#endif /* BOOST_CONTAINER_MAP_HPP */ 1507