00001 // Multimap implementation -*- C++ -*- 00002 00003 // Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 2, or (at your option) 00009 // any later version. 00010 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // You should have received a copy of the GNU General Public License along 00017 // with this library; see the file COPYING. If not, write to the Free 00018 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 00019 // USA. 00020 00021 // As a special exception, you may use this file as part of a free software 00022 // library without restriction. Specifically, if other files instantiate 00023 // templates or use macros or inline functions from this file, or you compile 00024 // this file and link it with other files to produce an executable, this 00025 // file does not by itself cause the resulting executable to be covered by 00026 // the GNU General Public License. This exception does not however 00027 // invalidate any other reasons why the executable file might be covered by 00028 // the GNU General Public License. 00029 00030 /* 00031 * 00032 * Copyright (c) 1994 00033 * Hewlett-Packard Company 00034 * 00035 * Permission to use, copy, modify, distribute and sell this software 00036 * and its documentation for any purpose is hereby granted without fee, 00037 * provided that the above copyright notice appear in all copies and 00038 * that both that copyright notice and this permission notice appear 00039 * in supporting documentation. Hewlett-Packard Company makes no 00040 * representations about the suitability of this software for any 00041 * purpose. It is provided "as is" without express or implied warranty. 00042 * 00043 * 00044 * Copyright (c) 1996,1997 00045 * Silicon Graphics Computer Systems, Inc. 00046 * 00047 * Permission to use, copy, modify, distribute and sell this software 00048 * and its documentation for any purpose is hereby granted without fee, 00049 * provided that the above copyright notice appear in all copies and 00050 * that both that copyright notice and this permission notice appear 00051 * in supporting documentation. Silicon Graphics makes no 00052 * representations about the suitability of this software for any 00053 * purpose. It is provided "as is" without express or implied warranty. 00054 */ 00055 00056 /** @file stl_multimap.h 00057 * This is an internal header file, included by other library headers. 00058 * You should not attempt to use it directly. 00059 */ 00060 00061 #ifndef _MULTIMAP_H 00062 #define _MULTIMAP_H 1 00063 00064 #include <bits/concept_check.h> 00065 00066 namespace _GLIBCXX_STD 00067 { 00068 // Forward declaration of operators < and ==, needed for friend declaration. 00069 00070 template <typename _Key, typename _Tp, 00071 typename _Compare = less<_Key>, 00072 typename _Alloc = allocator<pair<const _Key, _Tp> > > 00073 class multimap; 00074 00075 template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> 00076 inline bool 00077 operator==(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, 00078 const multimap<_Key,_Tp,_Compare,_Alloc>& __y); 00079 00080 template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> 00081 inline bool 00082 operator<(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, 00083 const multimap<_Key,_Tp,_Compare,_Alloc>& __y); 00084 00085 /** 00086 * @brief A standard container made up of (key,value) pairs, which can be 00087 * retrieved based on a key, in logarithmic time. 00088 * 00089 * @ingroup Containers 00090 * @ingroup Assoc_containers 00091 * 00092 * Meets the requirements of a <a href="tables.html#65">container</a>, a 00093 * <a href="tables.html#66">reversible container</a>, and an 00094 * <a href="tables.html#69">associative container</a> (using equivalent 00095 * keys). For a @c multimap<Key,T> the key_type is Key, the mapped_type 00096 * is T, and the value_type is std::pair<const Key,T>. 00097 * 00098 * Multimaps support bidirectional iterators. 00099 * 00100 * @if maint 00101 * The private tree data is declared exactly the same way for map and 00102 * multimap; the distinction is made entirely in how the tree functions are 00103 * called (*_unique versus *_equal, same as the standard). 00104 * @endif 00105 */ 00106 template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> 00107 class multimap 00108 { 00109 // concept requirements 00110 __glibcxx_class_requires(_Tp, _SGIAssignableConcept) 00111 __glibcxx_class_requires4(_Compare, bool, _Key, _Key, 00112 _BinaryFunctionConcept) 00113 00114 public: 00115 typedef _Key key_type; 00116 typedef _Tp mapped_type; 00117 typedef pair<const _Key, _Tp> value_type; 00118 typedef _Compare key_compare; 00119 00120 class value_compare 00121 : public binary_function<value_type, value_type, bool> 00122 { 00123 friend class multimap<_Key,_Tp,_Compare,_Alloc>; 00124 protected: 00125 _Compare comp; 00126 00127 value_compare(_Compare __c) 00128 : comp(__c) { } 00129 00130 public: 00131 bool operator()(const value_type& __x, const value_type& __y) const 00132 { return comp(__x.first, __y.first); } 00133 }; 00134 00135 private: 00136 /// @if maint This turns a red-black tree into a [multi]map. @endif 00137 typedef _Rb_tree<key_type, value_type, 00138 _Select1st<value_type>, key_compare, _Alloc> _Rep_type; 00139 /// @if maint The actual tree structure. @endif 00140 _Rep_type _M_t; 00141 00142 public: 00143 // many of these are specified differently in ISO, but the following are 00144 // "functionally equivalent" 00145 typedef typename _Rep_type::allocator_type allocator_type; 00146 typedef typename _Rep_type::reference reference; 00147 typedef typename _Rep_type::const_reference const_reference; 00148 typedef typename _Rep_type::iterator iterator; 00149 typedef typename _Rep_type::const_iterator const_iterator; 00150 typedef typename _Rep_type::size_type size_type; 00151 typedef typename _Rep_type::difference_type difference_type; 00152 typedef typename _Rep_type::pointer pointer; 00153 typedef typename _Rep_type::const_pointer const_pointer; 00154 typedef typename _Rep_type::reverse_iterator reverse_iterator; 00155 typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; 00156 00157 00158 // [23.3.2] construct/copy/destroy 00159 // (get_allocator() is also listed in this section) 00160 /** 00161 * @brief Default constructor creates no elements. 00162 */ 00163 multimap() 00164 : _M_t(_Compare(), allocator_type()) { } 00165 00166 // for some reason this was made a separate function 00167 /** 00168 * @brief Default constructor creates no elements. 00169 */ 00170 explicit 00171 multimap(const _Compare& __comp, 00172 const allocator_type& __a = allocator_type()) 00173 : _M_t(__comp, __a) { } 00174 00175 /** 00176 * @brief %Multimap copy constructor. 00177 * @param x A %multimap of identical element and allocator types. 00178 * 00179 * The newly-created %multimap uses a copy of the allocation object used 00180 * by @a x. 00181 */ 00182 multimap(const multimap& __x) 00183 : _M_t(__x._M_t) { } 00184 00185 /** 00186 * @brief Builds a %multimap from a range. 00187 * @param first An input iterator. 00188 * @param last An input iterator. 00189 * 00190 * Create a %multimap consisting of copies of the elements from 00191 * [first,last). This is linear in N if the range is already sorted, 00192 * and NlogN otherwise (where N is distance(first,last)). 00193 */ 00194 template <typename _InputIterator> 00195 multimap(_InputIterator __first, _InputIterator __last) 00196 : _M_t(_Compare(), allocator_type()) 00197 { _M_t.insert_equal(__first, __last); } 00198 00199 /** 00200 * @brief Builds a %multimap from a range. 00201 * @param first An input iterator. 00202 * @param last An input iterator. 00203 * @param comp A comparison functor. 00204 * @param a An allocator object. 00205 * 00206 * Create a %multimap consisting of copies of the elements from 00207 * [first,last). This is linear in N if the range is already sorted, 00208 * and NlogN otherwise (where N is distance(first,last)). 00209 */ 00210 template <typename _InputIterator> 00211 multimap(_InputIterator __first, _InputIterator __last, 00212 const _Compare& __comp, 00213 const allocator_type& __a = allocator_type()) 00214 : _M_t(__comp, __a) 00215 { _M_t.insert_equal(__first, __last); } 00216 00217 // FIXME There is no dtor declared, but we should have something generated 00218 // by Doxygen. I don't know what tags to add to this paragraph to make 00219 // that happen: 00220 /** 00221 * The dtor only erases the elements, and note that if the elements 00222 * themselves are pointers, the pointed-to memory is not touched in any 00223 * way. Managing the pointer is the user's responsibilty. 00224 */ 00225 00226 /** 00227 * @brief %Multimap assignment operator. 00228 * @param x A %multimap of identical element and allocator types. 00229 * 00230 * All the elements of @a x are copied, but unlike the copy constructor, 00231 * the allocator object is not copied. 00232 */ 00233 multimap& 00234 operator=(const multimap& __x) 00235 { 00236 _M_t = __x._M_t; 00237 return *this; 00238 } 00239 00240 /// Get a copy of the memory allocation object. 00241 allocator_type 00242 get_allocator() const 00243 { return _M_t.get_allocator(); } 00244 00245 // iterators 00246 /** 00247 * Returns a read/write iterator that points to the first pair in the 00248 * %multimap. Iteration is done in ascending order according to the 00249 * keys. 00250 */ 00251 iterator 00252 begin() 00253 { return _M_t.begin(); } 00254 00255 /** 00256 * Returns a read-only (constant) iterator that points to the first pair 00257 * in the %multimap. Iteration is done in ascending order according to 00258 * the keys. 00259 */ 00260 const_iterator 00261 begin() const 00262 { return _M_t.begin(); } 00263 00264 /** 00265 * Returns a read/write iterator that points one past the last pair in 00266 * the %multimap. Iteration is done in ascending order according to the 00267 * keys. 00268 */ 00269 iterator 00270 end() 00271 { return _M_t.end(); } 00272 00273 /** 00274 * Returns a read-only (constant) iterator that points one past the last 00275 * pair in the %multimap. Iteration is done in ascending order according 00276 * to the keys. 00277 */ 00278 const_iterator 00279 end() const 00280 { return _M_t.end(); } 00281 00282 /** 00283 * Returns a read/write reverse iterator that points to the last pair in 00284 * the %multimap. Iteration is done in descending order according to the 00285 * keys. 00286 */ 00287 reverse_iterator 00288 rbegin() 00289 { return _M_t.rbegin(); } 00290 00291 /** 00292 * Returns a read-only (constant) reverse iterator that points to the 00293 * last pair in the %multimap. Iteration is done in descending order 00294 * according to the keys. 00295 */ 00296 const_reverse_iterator 00297 rbegin() const 00298 { return _M_t.rbegin(); } 00299 00300 /** 00301 * Returns a read/write reverse iterator that points to one before the 00302 * first pair in the %multimap. Iteration is done in descending order 00303 * according to the keys. 00304 */ 00305 reverse_iterator 00306 rend() 00307 { return _M_t.rend(); } 00308 00309 /** 00310 * Returns a read-only (constant) reverse iterator that points to one 00311 * before the first pair in the %multimap. Iteration is done in 00312 * descending order according to the keys. 00313 */ 00314 const_reverse_iterator 00315 rend() const 00316 { return _M_t.rend(); } 00317 00318 // capacity 00319 /** Returns true if the %multimap is empty. */ 00320 bool 00321 empty() const 00322 { return _M_t.empty(); } 00323 00324 /** Returns the size of the %multimap. */ 00325 size_type 00326 size() const 00327 { return _M_t.size(); } 00328 00329 /** Returns the maximum size of the %multimap. */ 00330 size_type 00331 max_size() const 00332 { return _M_t.max_size(); } 00333 00334 // modifiers 00335 /** 00336 * @brief Inserts a std::pair into the %multimap. 00337 * @param x Pair to be inserted (see std::make_pair for easy creation 00338 * of pairs). 00339 * @return An iterator that points to the inserted (key,value) pair. 00340 * 00341 * This function inserts a (key, value) pair into the %multimap. 00342 * Contrary to a std::map the %multimap does not rely on unique keys and 00343 * thus multiple pairs with the same key can be inserted. 00344 * 00345 * Insertion requires logarithmic time. 00346 */ 00347 iterator 00348 insert(const value_type& __x) 00349 { return _M_t.insert_equal(__x); } 00350 00351 /** 00352 * @brief Inserts a std::pair into the %multimap. 00353 * @param position An iterator that serves as a hint as to where the 00354 * pair should be inserted. 00355 * @param x Pair to be inserted (see std::make_pair for easy creation 00356 * of pairs). 00357 * @return An iterator that points to the inserted (key,value) pair. 00358 * 00359 * This function inserts a (key, value) pair into the %multimap. 00360 * Contrary to a std::map the %multimap does not rely on unique keys and 00361 * thus multiple pairs with the same key can be inserted. 00362 * Note that the first parameter is only a hint and can potentially 00363 * improve the performance of the insertion process. A bad hint would 00364 * cause no gains in efficiency. 00365 * 00366 * See http://gcc.gnu.org/onlinedocs/libstdc++/23_containers/howto.html#4 00367 * for more on "hinting". 00368 * 00369 * Insertion requires logarithmic time (if the hint is not taken). 00370 */ 00371 iterator 00372 insert(iterator __position, const value_type& __x) 00373 { return _M_t.insert_equal(__position, __x); } 00374 00375 /** 00376 * @brief A template function that attemps to insert a range of elements. 00377 * @param first Iterator pointing to the start of the range to be 00378 * inserted. 00379 * @param last Iterator pointing to the end of the range. 00380 * 00381 * Complexity similar to that of the range constructor. 00382 */ 00383 template <typename _InputIterator> 00384 void 00385 insert(_InputIterator __first, _InputIterator __last) 00386 { _M_t.insert_equal(__first, __last); } 00387 00388 /** 00389 * @brief Erases an element from a %multimap. 00390 * @param position An iterator pointing to the element to be erased. 00391 * 00392 * This function erases an element, pointed to by the given iterator, 00393 * from a %multimap. Note that this function only erases the element, 00394 * and that if the element is itself a pointer, the pointed-to memory is 00395 * not touched in any way. Managing the pointer is the user's 00396 * responsibilty. 00397 */ 00398 void 00399 erase(iterator __position) 00400 { _M_t.erase(__position); } 00401 00402 /** 00403 * @brief Erases elements according to the provided key. 00404 * @param x Key of element to be erased. 00405 * @return The number of elements erased. 00406 * 00407 * This function erases all elements located by the given key from a 00408 * %multimap. 00409 * Note that this function only erases the element, and that if 00410 * the element is itself a pointer, the pointed-to memory is not touched 00411 * in any way. Managing the pointer is the user's responsibilty. 00412 */ 00413 size_type 00414 erase(const key_type& __x) 00415 { return _M_t.erase(__x); } 00416 00417 /** 00418 * @brief Erases a [first,last) range of elements from a %multimap. 00419 * @param first Iterator pointing to the start of the range to be 00420 * erased. 00421 * @param last Iterator pointing to the end of the range to be erased. 00422 * 00423 * This function erases a sequence of elements from a %multimap. 00424 * Note that this function only erases the elements, and that if 00425 * the elements themselves are pointers, the pointed-to memory is not 00426 * touched in any way. Managing the pointer is the user's responsibilty. 00427 */ 00428 void 00429 erase(iterator __first, iterator __last) 00430 { _M_t.erase(__first, __last); } 00431 00432 /** 00433 * @brief Swaps data with another %multimap. 00434 * @param x A %multimap of the same element and allocator types. 00435 * 00436 * This exchanges the elements between two multimaps in constant time. 00437 * (It is only swapping a pointer, an integer, and an instance of 00438 * the @c Compare type (which itself is often stateless and empty), so it 00439 * should be quite fast.) 00440 * Note that the global std::swap() function is specialized such that 00441 * std::swap(m1,m2) will feed to this function. 00442 */ 00443 void 00444 swap(multimap& __x) 00445 { _M_t.swap(__x._M_t); } 00446 00447 /** 00448 * Erases all elements in a %multimap. Note that this function only 00449 * erases the elements, and that if the elements themselves are pointers, 00450 * the pointed-to memory is not touched in any way. Managing the pointer 00451 * is the user's responsibilty. 00452 */ 00453 void 00454 clear() 00455 { _M_t.clear(); } 00456 00457 // observers 00458 /** 00459 * Returns the key comparison object out of which the %multimap 00460 * was constructed. 00461 */ 00462 key_compare 00463 key_comp() const 00464 { return _M_t.key_comp(); } 00465 00466 /** 00467 * Returns a value comparison object, built from the key comparison 00468 * object out of which the %multimap was constructed. 00469 */ 00470 value_compare 00471 value_comp() const 00472 { return value_compare(_M_t.key_comp()); } 00473 00474 // multimap operations 00475 /** 00476 * @brief Tries to locate an element in a %multimap. 00477 * @param x Key of (key, value) pair to be located. 00478 * @return Iterator pointing to sought-after element, 00479 * or end() if not found. 00480 * 00481 * This function takes a key and tries to locate the element with which 00482 * the key matches. If successful the function returns an iterator 00483 * pointing to the sought after %pair. If unsuccessful it returns the 00484 * past-the-end ( @c end() ) iterator. 00485 */ 00486 iterator 00487 find(const key_type& __x) 00488 { return _M_t.find(__x); } 00489 00490 /** 00491 * @brief Tries to locate an element in a %multimap. 00492 * @param x Key of (key, value) pair to be located. 00493 * @return Read-only (constant) iterator pointing to sought-after 00494 * element, or end() if not found. 00495 * 00496 * This function takes a key and tries to locate the element with which 00497 * the key matches. If successful the function returns a constant 00498 * iterator pointing to the sought after %pair. If unsuccessful it 00499 * returns the past-the-end ( @c end() ) iterator. 00500 */ 00501 const_iterator 00502 find(const key_type& __x) const 00503 { return _M_t.find(__x); } 00504 00505 /** 00506 * @brief Finds the number of elements with given key. 00507 * @param x Key of (key, value) pairs to be located. 00508 * @return Number of elements with specified key. 00509 */ 00510 size_type 00511 count(const key_type& __x) const 00512 { return _M_t.count(__x); } 00513 00514 /** 00515 * @brief Finds the beginning of a subsequence matching given key. 00516 * @param x Key of (key, value) pair to be located. 00517 * @return Iterator pointing to first element equal to or greater 00518 * than key, or end(). 00519 * 00520 * This function returns the first element of a subsequence of elements 00521 * that matches the given key. If unsuccessful it returns an iterator 00522 * pointing to the first element that has a greater value than given key 00523 * or end() if no such element exists. 00524 */ 00525 iterator 00526 lower_bound(const key_type& __x) 00527 { return _M_t.lower_bound(__x); } 00528 00529 /** 00530 * @brief Finds the beginning of a subsequence matching given key. 00531 * @param x Key of (key, value) pair to be located. 00532 * @return Read-only (constant) iterator pointing to first element 00533 * equal to or greater than key, or end(). 00534 * 00535 * This function returns the first element of a subsequence of elements 00536 * that matches the given key. If unsuccessful the iterator will point 00537 * to the next greatest element or, if no such greater element exists, to 00538 * end(). 00539 */ 00540 const_iterator 00541 lower_bound(const key_type& __x) const 00542 { return _M_t.lower_bound(__x); } 00543 00544 /** 00545 * @brief Finds the end of a subsequence matching given key. 00546 * @param x Key of (key, value) pair to be located. 00547 * @return Iterator pointing to the first element 00548 * greater than key, or end(). 00549 */ 00550 iterator 00551 upper_bound(const key_type& __x) 00552 { return _M_t.upper_bound(__x); } 00553 00554 /** 00555 * @brief Finds the end of a subsequence matching given key. 00556 * @param x Key of (key, value) pair to be located. 00557 * @return Read-only (constant) iterator pointing to first iterator 00558 * greater than key, or end(). 00559 */ 00560 const_iterator 00561 upper_bound(const key_type& __x) const 00562 { return _M_t.upper_bound(__x); } 00563 00564 /** 00565 * @brief Finds a subsequence matching given key. 00566 * @param x Key of (key, value) pairs to be located. 00567 * @return Pair of iterators that possibly points to the subsequence 00568 * matching given key. 00569 * 00570 * This function is equivalent to 00571 * @code 00572 * std::make_pair(c.lower_bound(val), 00573 * c.upper_bound(val)) 00574 * @endcode 00575 * (but is faster than making the calls separately). 00576 */ 00577 pair<iterator,iterator> 00578 equal_range(const key_type& __x) 00579 { return _M_t.equal_range(__x); } 00580 00581 /** 00582 * @brief Finds a subsequence matching given key. 00583 * @param x Key of (key, value) pairs to be located. 00584 * @return Pair of read-only (constant) iterators that possibly points 00585 * to the subsequence matching given key. 00586 * 00587 * This function is equivalent to 00588 * @code 00589 * std::make_pair(c.lower_bound(val), 00590 * c.upper_bound(val)) 00591 * @endcode 00592 * (but is faster than making the calls separately). 00593 */ 00594 pair<const_iterator,const_iterator> 00595 equal_range(const key_type& __x) const 00596 { return _M_t.equal_range(__x); } 00597 00598 template <typename _K1, typename _T1, typename _C1, typename _A1> 00599 friend bool 00600 operator== (const multimap<_K1,_T1,_C1,_A1>&, 00601 const multimap<_K1,_T1,_C1,_A1>&); 00602 00603 template <typename _K1, typename _T1, typename _C1, typename _A1> 00604 friend bool 00605 operator< (const multimap<_K1,_T1,_C1,_A1>&, 00606 const multimap<_K1,_T1,_C1,_A1>&); 00607 }; 00608 00609 /** 00610 * @brief Multimap equality comparison. 00611 * @param x A %multimap. 00612 * @param y A %multimap of the same type as @a x. 00613 * @return True iff the size and elements of the maps are equal. 00614 * 00615 * This is an equivalence relation. It is linear in the size of the 00616 * multimaps. Multimaps are considered equivalent if their sizes are equal, 00617 * and if corresponding elements compare equal. 00618 */ 00619 template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> 00620 inline bool 00621 operator==(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, 00622 const multimap<_Key,_Tp,_Compare,_Alloc>& __y) 00623 { return __x._M_t == __y._M_t; } 00624 00625 /** 00626 * @brief Multimap ordering relation. 00627 * @param x A %multimap. 00628 * @param y A %multimap of the same type as @a x. 00629 * @return True iff @a x is lexicographically less than @a y. 00630 * 00631 * This is a total ordering relation. It is linear in the size of the 00632 * multimaps. The elements must be comparable with @c <. 00633 * 00634 * See std::lexicographical_compare() for how the determination is made. 00635 */ 00636 template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> 00637 inline bool 00638 operator<(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, 00639 const multimap<_Key,_Tp,_Compare,_Alloc>& __y) 00640 { return __x._M_t < __y._M_t; } 00641 00642 /// Based on operator== 00643 template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> 00644 inline bool 00645 operator!=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, 00646 const multimap<_Key,_Tp,_Compare,_Alloc>& __y) 00647 { return !(__x == __y); } 00648 00649 /// Based on operator< 00650 template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> 00651 inline bool 00652 operator>(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, 00653 const multimap<_Key,_Tp,_Compare,_Alloc>& __y) 00654 { return __y < __x; } 00655 00656 /// Based on operator< 00657 template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> 00658 inline bool 00659 operator<=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, 00660 const multimap<_Key,_Tp,_Compare,_Alloc>& __y) 00661 { return !(__y < __x); } 00662 00663 /// Based on operator< 00664 template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> 00665 inline bool 00666 operator>=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, 00667 const multimap<_Key,_Tp,_Compare,_Alloc>& __y) 00668 { return !(__x < __y); } 00669 00670 /// See std::multimap::swap(). 00671 template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> 00672 inline void 00673 swap(multimap<_Key,_Tp,_Compare,_Alloc>& __x, 00674 multimap<_Key,_Tp,_Compare,_Alloc>& __y) 00675 { __x.swap(__y); } 00676 } // namespace std 00677 00678 #endif /* _MULTIMAP_H */