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 _Alloc::pointer pointer; 00146 typedef typename _Alloc::const_pointer const_pointer; 00147 typedef typename _Alloc::reference reference; 00148 typedef typename _Alloc::const_reference const_reference; 00149 typedef typename _Rep_type::allocator_type allocator_type; 00150 typedef typename _Rep_type::iterator iterator; 00151 typedef typename _Rep_type::const_iterator const_iterator; 00152 typedef typename _Rep_type::size_type size_type; 00153 typedef typename _Rep_type::difference_type difference_type; 00154 typedef typename _Rep_type::reverse_iterator reverse_iterator; 00155 typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; 00156 00157 // [23.3.2] construct/copy/destroy 00158 // (get_allocator() is also listed in this section) 00159 /** 00160 * @brief Default constructor creates no elements. 00161 */ 00162 multimap() 00163 : _M_t(_Compare(), allocator_type()) { } 00164 00165 // for some reason this was made a separate function 00166 /** 00167 * @brief Default constructor creates no elements. 00168 */ 00169 explicit 00170 multimap(const _Compare& __comp, 00171 const allocator_type& __a = allocator_type()) 00172 : _M_t(__comp, __a) { } 00173 00174 /** 00175 * @brief %Multimap copy constructor. 00176 * @param x A %multimap of identical element and allocator types. 00177 * 00178 * The newly-created %multimap uses a copy of the allocation object used 00179 * by @a x. 00180 */ 00181 multimap(const multimap& __x) 00182 : _M_t(__x._M_t) { } 00183 00184 /** 00185 * @brief Builds a %multimap from a range. 00186 * @param first An input iterator. 00187 * @param last An input iterator. 00188 * 00189 * Create a %multimap consisting of copies of the elements from 00190 * [first,last). This is linear in N if the range is already sorted, 00191 * and NlogN otherwise (where N is distance(first,last)). 00192 */ 00193 template <typename _InputIterator> 00194 multimap(_InputIterator __first, _InputIterator __last) 00195 : _M_t(_Compare(), allocator_type()) 00196 { _M_t.insert_equal(__first, __last); } 00197 00198 /** 00199 * @brief Builds a %multimap from a range. 00200 * @param first An input iterator. 00201 * @param last An input iterator. 00202 * @param comp A comparison functor. 00203 * @param a An allocator object. 00204 * 00205 * Create a %multimap consisting of copies of the elements from 00206 * [first,last). This is linear in N if the range is already sorted, 00207 * and NlogN otherwise (where N is distance(first,last)). 00208 */ 00209 template <typename _InputIterator> 00210 multimap(_InputIterator __first, _InputIterator __last, 00211 const _Compare& __comp, 00212 const allocator_type& __a = allocator_type()) 00213 : _M_t(__comp, __a) 00214 { _M_t.insert_equal(__first, __last); } 00215 00216 // FIXME There is no dtor declared, but we should have something generated 00217 // by Doxygen. I don't know what tags to add to this paragraph to make 00218 // that happen: 00219 /** 00220 * The dtor only erases the elements, and note that if the elements 00221 * themselves are pointers, the pointed-to memory is not touched in any 00222 * way. Managing the pointer is the user's responsibilty. 00223 */ 00224 00225 /** 00226 * @brief %Multimap assignment operator. 00227 * @param x A %multimap of identical element and allocator types. 00228 * 00229 * All the elements of @a x are copied, but unlike the copy constructor, 00230 * the allocator object is not copied. 00231 */ 00232 multimap& 00233 operator=(const multimap& __x) 00234 { 00235 _M_t = __x._M_t; 00236 return *this; 00237 } 00238 00239 /// Get a copy of the memory allocation object. 00240 allocator_type 00241 get_allocator() const 00242 { return _M_t.get_allocator(); } 00243 00244 // iterators 00245 /** 00246 * Returns a read/write iterator that points to the first pair in the 00247 * %multimap. Iteration is done in ascending order according to the 00248 * keys. 00249 */ 00250 iterator 00251 begin() 00252 { return _M_t.begin(); } 00253 00254 /** 00255 * Returns a read-only (constant) iterator that points to the first pair 00256 * in the %multimap. Iteration is done in ascending order according to 00257 * the keys. 00258 */ 00259 const_iterator 00260 begin() const 00261 { return _M_t.begin(); } 00262 00263 /** 00264 * Returns a read/write iterator that points one past the last pair in 00265 * the %multimap. Iteration is done in ascending order according to the 00266 * keys. 00267 */ 00268 iterator 00269 end() 00270 { return _M_t.end(); } 00271 00272 /** 00273 * Returns a read-only (constant) iterator that points one past the last 00274 * pair in the %multimap. Iteration is done in ascending order according 00275 * to the keys. 00276 */ 00277 const_iterator 00278 end() const 00279 { return _M_t.end(); } 00280 00281 /** 00282 * Returns a read/write reverse iterator that points to the last pair in 00283 * the %multimap. Iteration is done in descending order according to the 00284 * keys. 00285 */ 00286 reverse_iterator 00287 rbegin() 00288 { return _M_t.rbegin(); } 00289 00290 /** 00291 * Returns a read-only (constant) reverse iterator that points to the 00292 * last pair in the %multimap. Iteration is done in descending order 00293 * according to the keys. 00294 */ 00295 const_reverse_iterator 00296 rbegin() const 00297 { return _M_t.rbegin(); } 00298 00299 /** 00300 * Returns a read/write reverse iterator that points to one before the 00301 * first pair in the %multimap. Iteration is done in descending order 00302 * according to the keys. 00303 */ 00304 reverse_iterator 00305 rend() 00306 { return _M_t.rend(); } 00307 00308 /** 00309 * Returns a read-only (constant) reverse iterator that points to one 00310 * before the first pair in the %multimap. Iteration is done in 00311 * descending order according to the keys. 00312 */ 00313 const_reverse_iterator 00314 rend() const 00315 { return _M_t.rend(); } 00316 00317 // capacity 00318 /** Returns true if the %multimap is empty. */ 00319 bool 00320 empty() const 00321 { return _M_t.empty(); } 00322 00323 /** Returns the size of the %multimap. */ 00324 size_type 00325 size() const 00326 { return _M_t.size(); } 00327 00328 /** Returns the maximum size of the %multimap. */ 00329 size_type 00330 max_size() const 00331 { return _M_t.max_size(); } 00332 00333 // modifiers 00334 /** 00335 * @brief Inserts a std::pair into the %multimap. 00336 * @param x Pair to be inserted (see std::make_pair for easy creation 00337 * of pairs). 00338 * @return An iterator that points to the inserted (key,value) pair. 00339 * 00340 * This function inserts a (key, value) pair into the %multimap. 00341 * Contrary to a std::map the %multimap does not rely on unique keys and 00342 * thus multiple pairs with the same key can be inserted. 00343 * 00344 * Insertion requires logarithmic time. 00345 */ 00346 iterator 00347 insert(const value_type& __x) 00348 { return _M_t.insert_equal(__x); } 00349 00350 /** 00351 * @brief Inserts a std::pair into the %multimap. 00352 * @param position An iterator that serves as a hint as to where the 00353 * pair should be inserted. 00354 * @param x Pair to be inserted (see std::make_pair for easy creation 00355 * of pairs). 00356 * @return An iterator that points to the inserted (key,value) pair. 00357 * 00358 * This function inserts a (key, value) pair into the %multimap. 00359 * Contrary to a std::map the %multimap does not rely on unique keys and 00360 * thus multiple pairs with the same key can be inserted. 00361 * Note that the first parameter is only a hint and can potentially 00362 * improve the performance of the insertion process. A bad hint would 00363 * cause no gains in efficiency. 00364 * 00365 * See http://gcc.gnu.org/onlinedocs/libstdc++/23_containers/howto.html#4 00366 * for more on "hinting". 00367 * 00368 * Insertion requires logarithmic time (if the hint is not taken). 00369 */ 00370 iterator 00371 insert(iterator __position, const value_type& __x) 00372 { return _M_t.insert_equal(__position, __x); } 00373 00374 /** 00375 * @brief A template function that attemps to insert a range of elements. 00376 * @param first Iterator pointing to the start of the range to be 00377 * inserted. 00378 * @param last Iterator pointing to the end of the range. 00379 * 00380 * Complexity similar to that of the range constructor. 00381 */ 00382 template <typename _InputIterator> 00383 void 00384 insert(_InputIterator __first, _InputIterator __last) 00385 { _M_t.insert_equal(__first, __last); } 00386 00387 /** 00388 * @brief Erases an element from a %multimap. 00389 * @param position An iterator pointing to the element to be erased. 00390 * 00391 * This function erases an element, pointed to by the given iterator, 00392 * from a %multimap. Note that this function only erases the element, 00393 * and that if the element is itself a pointer, the pointed-to memory is 00394 * not touched in any way. Managing the pointer is the user's 00395 * responsibilty. 00396 */ 00397 void 00398 erase(iterator __position) 00399 { _M_t.erase(__position); } 00400 00401 /** 00402 * @brief Erases elements according to the provided key. 00403 * @param x Key of element to be erased. 00404 * @return The number of elements erased. 00405 * 00406 * This function erases all elements located by the given key from a 00407 * %multimap. 00408 * Note that this function only erases the element, and that if 00409 * the element is itself a pointer, the pointed-to memory is not touched 00410 * in any way. Managing the pointer is the user's responsibilty. 00411 */ 00412 size_type 00413 erase(const key_type& __x) 00414 { return _M_t.erase(__x); } 00415 00416 /** 00417 * @brief Erases a [first,last) range of elements from a %multimap. 00418 * @param first Iterator pointing to the start of the range to be 00419 * erased. 00420 * @param last Iterator pointing to the end of the range to be erased. 00421 * 00422 * This function erases a sequence of elements from a %multimap. 00423 * Note that this function only erases the elements, and that if 00424 * the elements themselves are pointers, the pointed-to memory is not 00425 * touched in any way. Managing the pointer is the user's responsibilty. 00426 */ 00427 void 00428 erase(iterator __first, iterator __last) 00429 { _M_t.erase(__first, __last); } 00430 00431 /** 00432 * @brief Swaps data with another %multimap. 00433 * @param x A %multimap of the same element and allocator types. 00434 * 00435 * This exchanges the elements between two multimaps in constant time. 00436 * (It is only swapping a pointer, an integer, and an instance of 00437 * the @c Compare type (which itself is often stateless and empty), so it 00438 * should be quite fast.) 00439 * Note that the global std::swap() function is specialized such that 00440 * std::swap(m1,m2) will feed to this function. 00441 */ 00442 void 00443 swap(multimap& __x) 00444 { _M_t.swap(__x._M_t); } 00445 00446 /** 00447 * Erases all elements in a %multimap. Note that this function only 00448 * erases the elements, and that if the elements themselves are pointers, 00449 * the pointed-to memory is not touched in any way. Managing the pointer 00450 * is the user's responsibilty. 00451 */ 00452 void 00453 clear() 00454 { _M_t.clear(); } 00455 00456 // observers 00457 /** 00458 * Returns the key comparison object out of which the %multimap 00459 * was constructed. 00460 */ 00461 key_compare 00462 key_comp() const 00463 { return _M_t.key_comp(); } 00464 00465 /** 00466 * Returns a value comparison object, built from the key comparison 00467 * object out of which the %multimap was constructed. 00468 */ 00469 value_compare 00470 value_comp() const 00471 { return value_compare(_M_t.key_comp()); } 00472 00473 // multimap operations 00474 /** 00475 * @brief Tries to locate an element in a %multimap. 00476 * @param x Key of (key, value) pair to be located. 00477 * @return Iterator pointing to sought-after element, 00478 * or end() if not found. 00479 * 00480 * This function takes a key and tries to locate the element with which 00481 * the key matches. If successful the function returns an iterator 00482 * pointing to the sought after %pair. If unsuccessful it returns the 00483 * past-the-end ( @c end() ) iterator. 00484 */ 00485 iterator 00486 find(const key_type& __x) 00487 { return _M_t.find(__x); } 00488 00489 /** 00490 * @brief Tries to locate an element in a %multimap. 00491 * @param x Key of (key, value) pair to be located. 00492 * @return Read-only (constant) iterator pointing to sought-after 00493 * element, or end() if not found. 00494 * 00495 * This function takes a key and tries to locate the element with which 00496 * the key matches. If successful the function returns a constant 00497 * iterator pointing to the sought after %pair. If unsuccessful it 00498 * returns the past-the-end ( @c end() ) iterator. 00499 */ 00500 const_iterator 00501 find(const key_type& __x) const 00502 { return _M_t.find(__x); } 00503 00504 /** 00505 * @brief Finds the number of elements with given key. 00506 * @param x Key of (key, value) pairs to be located. 00507 * @return Number of elements with specified key. 00508 */ 00509 size_type 00510 count(const key_type& __x) const 00511 { return _M_t.count(__x); } 00512 00513 /** 00514 * @brief Finds the beginning of a subsequence matching given key. 00515 * @param x Key of (key, value) pair to be located. 00516 * @return Iterator pointing to first element equal to or greater 00517 * than key, or end(). 00518 * 00519 * This function returns the first element of a subsequence of elements 00520 * that matches the given key. If unsuccessful it returns an iterator 00521 * pointing to the first element that has a greater value than given key 00522 * or end() if no such element exists. 00523 */ 00524 iterator 00525 lower_bound(const key_type& __x) 00526 { return _M_t.lower_bound(__x); } 00527 00528 /** 00529 * @brief Finds the beginning of a subsequence matching given key. 00530 * @param x Key of (key, value) pair to be located. 00531 * @return Read-only (constant) iterator pointing to first element 00532 * equal to or greater than key, or end(). 00533 * 00534 * This function returns the first element of a subsequence of elements 00535 * that matches the given key. If unsuccessful the iterator will point 00536 * to the next greatest element or, if no such greater element exists, to 00537 * end(). 00538 */ 00539 const_iterator 00540 lower_bound(const key_type& __x) const 00541 { return _M_t.lower_bound(__x); } 00542 00543 /** 00544 * @brief Finds the end of a subsequence matching given key. 00545 * @param x Key of (key, value) pair to be located. 00546 * @return Iterator pointing to the first element 00547 * greater than key, or end(). 00548 */ 00549 iterator 00550 upper_bound(const key_type& __x) 00551 { return _M_t.upper_bound(__x); } 00552 00553 /** 00554 * @brief Finds the end of a subsequence matching given key. 00555 * @param x Key of (key, value) pair to be located. 00556 * @return Read-only (constant) iterator pointing to first iterator 00557 * greater than key, or end(). 00558 */ 00559 const_iterator 00560 upper_bound(const key_type& __x) const 00561 { return _M_t.upper_bound(__x); } 00562 00563 /** 00564 * @brief Finds a subsequence matching given key. 00565 * @param x Key of (key, value) pairs to be located. 00566 * @return Pair of iterators that possibly points to the subsequence 00567 * matching given key. 00568 * 00569 * This function is equivalent to 00570 * @code 00571 * std::make_pair(c.lower_bound(val), 00572 * c.upper_bound(val)) 00573 * @endcode 00574 * (but is faster than making the calls separately). 00575 */ 00576 pair<iterator,iterator> 00577 equal_range(const key_type& __x) 00578 { return _M_t.equal_range(__x); } 00579 00580 /** 00581 * @brief Finds a subsequence matching given key. 00582 * @param x Key of (key, value) pairs to be located. 00583 * @return Pair of read-only (constant) iterators that possibly points 00584 * to the subsequence matching given key. 00585 * 00586 * This function is equivalent to 00587 * @code 00588 * std::make_pair(c.lower_bound(val), 00589 * c.upper_bound(val)) 00590 * @endcode 00591 * (but is faster than making the calls separately). 00592 */ 00593 pair<const_iterator,const_iterator> 00594 equal_range(const key_type& __x) const 00595 { return _M_t.equal_range(__x); } 00596 00597 template <typename _K1, typename _T1, typename _C1, typename _A1> 00598 friend bool 00599 operator== (const multimap<_K1,_T1,_C1,_A1>&, 00600 const multimap<_K1,_T1,_C1,_A1>&); 00601 00602 template <typename _K1, typename _T1, typename _C1, typename _A1> 00603 friend bool 00604 operator< (const multimap<_K1,_T1,_C1,_A1>&, 00605 const multimap<_K1,_T1,_C1,_A1>&); 00606 }; 00607 00608 /** 00609 * @brief Multimap equality comparison. 00610 * @param x A %multimap. 00611 * @param y A %multimap of the same type as @a x. 00612 * @return True iff the size and elements of the maps are equal. 00613 * 00614 * This is an equivalence relation. It is linear in the size of the 00615 * multimaps. Multimaps are considered equivalent if their sizes are equal, 00616 * and if corresponding elements compare equal. 00617 */ 00618 template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> 00619 inline bool 00620 operator==(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, 00621 const multimap<_Key,_Tp,_Compare,_Alloc>& __y) 00622 { return __x._M_t == __y._M_t; } 00623 00624 /** 00625 * @brief Multimap ordering relation. 00626 * @param x A %multimap. 00627 * @param y A %multimap of the same type as @a x. 00628 * @return True iff @a x is lexicographically less than @a y. 00629 * 00630 * This is a total ordering relation. It is linear in the size of the 00631 * multimaps. The elements must be comparable with @c <. 00632 * 00633 * See std::lexicographical_compare() for how the determination is made. 00634 */ 00635 template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> 00636 inline bool 00637 operator<(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, 00638 const multimap<_Key,_Tp,_Compare,_Alloc>& __y) 00639 { return __x._M_t < __y._M_t; } 00640 00641 /// Based on operator== 00642 template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> 00643 inline bool 00644 operator!=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, 00645 const multimap<_Key,_Tp,_Compare,_Alloc>& __y) 00646 { return !(__x == __y); } 00647 00648 /// Based on operator< 00649 template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> 00650 inline bool 00651 operator>(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, 00652 const multimap<_Key,_Tp,_Compare,_Alloc>& __y) 00653 { return __y < __x; } 00654 00655 /// Based on operator< 00656 template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> 00657 inline bool 00658 operator<=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, 00659 const multimap<_Key,_Tp,_Compare,_Alloc>& __y) 00660 { return !(__y < __x); } 00661 00662 /// Based on operator< 00663 template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> 00664 inline bool 00665 operator>=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, 00666 const multimap<_Key,_Tp,_Compare,_Alloc>& __y) 00667 { return !(__x < __y); } 00668 00669 /// See std::multimap::swap(). 00670 template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> 00671 inline void 00672 swap(multimap<_Key,_Tp,_Compare,_Alloc>& __x, 00673 multimap<_Key,_Tp,_Compare,_Alloc>& __y) 00674 { __x.swap(__y); } 00675 } // namespace std 00676 00677 #endif /* _MULTIMAP_H */