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