stl_multiset.h revision 132720
1// Multiset implementation -*- C++ -*-
2
3// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library.  This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 2, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14// GNU General Public License for more details.
15
16// You should have received a copy of the GNU General Public License along
17// with this library; see the file COPYING.  If not, write to the Free
18// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19// USA.
20
21// As a special exception, you may use this file as part of a free software
22// library without restriction.  Specifically, if other files instantiate
23// templates or use macros or inline functions from this file, or you compile
24// this file and link it with other files to produce an executable, this
25// file does not by itself cause the resulting executable to be covered by
26// the GNU General Public License.  This exception does not however
27// invalidate any other reasons why the executable file might be covered by
28// the GNU General Public License.
29
30/*
31 *
32 * Copyright (c) 1994
33 * Hewlett-Packard Company
34 *
35 * Permission to use, copy, modify, distribute and sell this software
36 * and its documentation for any purpose is hereby granted without fee,
37 * provided that the above copyright notice appear in all copies and
38 * that both that copyright notice and this permission notice appear
39 * in supporting documentation.  Hewlett-Packard Company makes no
40 * representations about the suitability of this software for any
41 * purpose.  It is provided "as is" without express or implied warranty.
42 *
43 *
44 * Copyright (c) 1996
45 * Silicon Graphics Computer Systems, Inc.
46 *
47 * Permission to use, copy, modify, distribute and sell this software
48 * and its documentation for any purpose is hereby granted without fee,
49 * provided that the above copyright notice appear in all copies and
50 * that both that copyright notice and this permission notice appear
51 * in supporting documentation.  Silicon Graphics makes no
52 * representations about the suitability of this software for any
53 * purpose.  It is provided "as is" without express or implied warranty.
54 */
55
56/** @file stl_multiset.h
57 *  This is an internal header file, included by other library headers.
58 *  You should not attempt to use it directly.
59 */
60
61#ifndef _MULTISET_H
62#define _MULTISET_H 1
63
64#include <bits/concept_check.h>
65
66namespace _GLIBCXX_STD
67{
68
69  // Forward declaration of operators < and ==, needed for friend declaration.
70  template <class _Key, class _Compare = less<_Key>,
71	    class _Alloc = allocator<_Key> >
72    class multiset;
73
74  template <class _Key, class _Compare, class _Alloc>
75    inline bool
76    operator==(const multiset<_Key,_Compare,_Alloc>& __x,
77	       const multiset<_Key,_Compare,_Alloc>& __y);
78
79  template <class _Key, class _Compare, class _Alloc>
80    inline bool
81    operator<(const multiset<_Key,_Compare,_Alloc>& __x,
82	      const multiset<_Key,_Compare,_Alloc>& __y);
83
84  /**
85   *  @brief A standard container made up of elements, which can be retrieved
86   *  in logarithmic time.
87   *
88   *  @ingroup Containers
89   *  @ingroup Assoc_containers
90   *
91   *  Meets the requirements of a <a href="tables.html#65">container</a>, a
92   *  <a href="tables.html#66">reversible container</a>, and an
93   *  <a href="tables.html#69">associative container</a> (using equivalent
94   *  keys).  For a @c multiset<Key> the key_type and value_type are Key.
95   *
96   *  Multisets support bidirectional iterators.
97   *
98   *  @if maint
99   *  The private tree data is declared exactly the same way for set and
100   *  multiset; the distinction is made entirely in how the tree functions are
101   *  called (*_unique versus *_equal, same as the standard).
102   *  @endif
103  */
104  template <class _Key, class _Compare, class _Alloc>
105    class multiset
106    {
107      // concept requirements
108      __glibcxx_class_requires(_Key, _SGIAssignableConcept)
109      __glibcxx_class_requires4(_Compare, bool, _Key, _Key,
110				_BinaryFunctionConcept)
111
112    public:
113      // typedefs:
114      typedef _Key     key_type;
115      typedef _Key     value_type;
116      typedef _Compare key_compare;
117      typedef _Compare value_compare;
118
119    private:
120      /// @if maint  This turns a red-black tree into a [multi]set.  @endif
121      typedef _Rb_tree<key_type, value_type,
122		       _Identity<value_type>, key_compare, _Alloc> _Rep_type;
123      /// @if maint  The actual tree structure.  @endif
124      _Rep_type _M_t;
125
126    public:
127      typedef typename _Alloc::pointer pointer;
128      typedef typename _Alloc::const_pointer const_pointer;
129      typedef typename _Alloc::reference reference;
130      typedef typename _Alloc::const_reference const_reference;
131      // _GLIBCXX_RESOLVE_LIB_DEFECTS
132      // DR 103. set::iterator is required to be modifiable,
133      // but this allows modification of keys.
134      typedef typename _Rep_type::const_iterator iterator;
135      typedef typename _Rep_type::const_iterator const_iterator;
136      typedef typename _Rep_type::const_reverse_iterator reverse_iterator;
137      typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator;
138      typedef typename _Rep_type::size_type size_type;
139      typedef typename _Rep_type::difference_type difference_type;
140      typedef typename _Rep_type::allocator_type allocator_type;
141
142    // allocation/deallocation
143
144    /**
145     *  @brief  Default constructor creates no elements.
146     */
147      multiset()
148      : _M_t(_Compare(), allocator_type()) { }
149
150      explicit
151      multiset(const _Compare& __comp,
152	       const allocator_type& __a = allocator_type())
153      : _M_t(__comp, __a) { }
154
155      /**
156       *  @brief  Builds a %multiset from a range.
157       *  @param  first  An input iterator.
158       *  @param  last  An input iterator.
159       *
160       *  Create a %multiset consisting of copies of the elements from
161       *  [first,last).  This is linear in N if the range is already sorted,
162       *  and NlogN otherwise (where N is distance(first,last)).
163       */
164      template <class _InputIterator>
165        multiset(_InputIterator __first, _InputIterator __last)
166	: _M_t(_Compare(), allocator_type())
167        { _M_t.insert_equal(__first, __last); }
168
169      /**
170       *  @brief  Builds a %multiset from a range.
171       *  @param  first  An input iterator.
172       *  @param  last  An input iterator.
173       *  @param  comp  A comparison functor.
174       *  @param  a  An allocator object.
175       *
176       *  Create a %multiset consisting of copies of the elements from
177       *  [first,last).  This is linear in N if the range is already sorted,
178       *  and NlogN otherwise (where N is distance(first,last)).
179       */
180      template <class _InputIterator>
181        multiset(_InputIterator __first, _InputIterator __last,
182		 const _Compare& __comp,
183		 const allocator_type& __a = allocator_type())
184	: _M_t(__comp, __a)
185        { _M_t.insert_equal(__first, __last); }
186
187      /**
188       *  @brief  %Multiset copy constructor.
189       *  @param  x  A %multiset of identical element and allocator types.
190       *
191       *  The newly-created %multiset uses a copy of the allocation object used
192       *  by @a x.
193       */
194      multiset(const multiset<_Key,_Compare,_Alloc>& __x)
195      : _M_t(__x._M_t) { }
196
197      /**
198       *  @brief  %Multiset assignment operator.
199       *  @param  x  A %multiset of identical element and allocator types.
200       *
201       *  All the elements of @a x are copied, but unlike the copy constructor,
202       *  the allocator object is not copied.
203       */
204      multiset<_Key,_Compare,_Alloc>&
205      operator=(const multiset<_Key,_Compare,_Alloc>& __x)
206      {
207	_M_t = __x._M_t;
208	return *this;
209      }
210
211      // accessors:
212
213      ///  Returns the comparison object.
214      key_compare
215      key_comp() const
216      { return _M_t.key_comp(); }
217      ///  Returns the comparison object.
218      value_compare
219      value_comp() const
220      { return _M_t.key_comp(); }
221      ///  Returns the memory allocation object.
222      allocator_type
223      get_allocator() const
224      { return _M_t.get_allocator(); }
225
226      /**
227       *  Returns a read/write iterator that points to the first element in the
228       *  %multiset.  Iteration is done in ascending order according to the
229       *  keys.
230       */
231      iterator
232      begin() const
233      { return _M_t.begin(); }
234
235      /**
236       *  Returns a read/write iterator that points one past the last element in
237       *  the %multiset.  Iteration is done in ascending order according to the
238       *  keys.
239       */
240      iterator
241      end() const
242      { return _M_t.end(); }
243
244      /**
245       *  Returns a read/write reverse iterator that points to the last element
246       *  in the %multiset.  Iteration is done in descending order according to
247       *  the keys.
248       */
249      reverse_iterator
250      rbegin() const
251      { return _M_t.rbegin(); }
252
253      /**
254       *  Returns a read/write reverse iterator that points to the last element
255       *  in the %multiset.  Iteration is done in descending order according to
256       *  the keys.
257       */
258      reverse_iterator
259      rend() const
260      { return _M_t.rend(); }
261
262      ///  Returns true if the %set is empty.
263      bool
264      empty() const
265      { return _M_t.empty(); }
266
267      ///  Returns the size of the %set.
268      size_type
269      size() const
270      { return _M_t.size(); }
271
272      ///  Returns the maximum size of the %set.
273      size_type
274      max_size() const
275      { return _M_t.max_size(); }
276
277      /**
278       *  @brief  Swaps data with another %multiset.
279       *  @param  x  A %multiset of the same element and allocator types.
280       *
281       *  This exchanges the elements between two multisets in constant time.
282       *  (It is only swapping a pointer, an integer, and an instance of the @c
283       *  Compare type (which itself is often stateless and empty), so it should
284       *  be quite fast.)
285       *  Note that the global std::swap() function is specialized such that
286       *  std::swap(s1,s2) will feed to this function.
287       */
288      void
289      swap(multiset<_Key,_Compare,_Alloc>& __x)
290      { _M_t.swap(__x._M_t); }
291
292      // insert/erase
293      /**
294       *  @brief Inserts an element into the %multiset.
295       *  @param  x  Element to be inserted.
296       *  @return An iterator that points to the inserted element.
297       *
298       *  This function inserts an element into the %multiset.  Contrary
299       *  to a std::set the %multiset does not rely on unique keys and thus
300       *  multiple copies of the same element can be inserted.
301       *
302       *  Insertion requires logarithmic time.
303       */
304      iterator
305      insert(const value_type& __x)
306      { return _M_t.insert_equal(__x); }
307
308      /**
309       *  @brief Inserts an element into the %multiset.
310       *  @param  position  An iterator that serves as a hint as to where the
311       *                    element should be inserted.
312       *  @param  x  Element to be inserted.
313       *  @return An iterator that points to the inserted element.
314       *
315       *  This function inserts an element into the %multiset.  Contrary
316       *  to a std::set the %multiset does not rely on unique keys and thus
317       *  multiple copies of the same element can be inserted.
318       *
319       *  Note that the first parameter is only a hint and can potentially
320       *  improve the performance of the insertion process.  A bad hint would
321       *  cause no gains in efficiency.
322       *
323       *  See http://gcc.gnu.org/onlinedocs/libstdc++/23_containers/howto.html#4
324       *  for more on "hinting".
325       *
326       *  Insertion requires logarithmic time (if the hint is not taken).
327       */
328      iterator
329      insert(iterator __position, const value_type& __x)
330      {
331	typedef typename _Rep_type::iterator _Rep_iterator;
332	return _M_t.insert_equal((_Rep_iterator&)__position, __x);
333      }
334
335      /**
336       *  @brief A template function that attemps to insert a range of elements.
337       *  @param  first  Iterator pointing to the start of the range to be
338       *                 inserted.
339       *  @param  last  Iterator pointing to the end of the range.
340       *
341       *  Complexity similar to that of the range constructor.
342       */
343      template <class _InputIterator>
344        void
345        insert(_InputIterator __first, _InputIterator __last)
346        { _M_t.insert_equal(__first, __last); }
347
348      /**
349       *  @brief Erases an element from a %multiset.
350       *  @param  position  An iterator pointing to the element to be erased.
351       *
352       *  This function erases an element, pointed to by the given iterator,
353       *  from a %multiset.  Note that this function only erases the element,
354       *  and that if the element is itself a pointer, the pointed-to memory is
355       *  not touched in any way.  Managing the pointer is the user's
356       *  responsibilty.
357       */
358      void
359      erase(iterator __position)
360      {
361	typedef typename _Rep_type::iterator _Rep_iterator;
362	_M_t.erase((_Rep_iterator&)__position);
363      }
364
365      /**
366       *  @brief Erases elements according to the provided key.
367       *  @param  x  Key of element to be erased.
368       *  @return  The number of elements erased.
369       *
370       *  This function erases all elements located by the given key from a
371       *  %multiset.
372       *  Note that this function only erases the element, and that if
373       *  the element is itself a pointer, the pointed-to memory is not touched
374       *  in any way.  Managing the pointer is the user's responsibilty.
375       */
376      size_type
377      erase(const key_type& __x)
378      { return _M_t.erase(__x); }
379
380      /**
381       *  @brief Erases a [first,last) range of elements from a %multiset.
382       *  @param  first  Iterator pointing to the start of the range to be
383       *                 erased.
384       *  @param  last  Iterator pointing to the end of the range to be erased.
385       *
386       *  This function erases a sequence of elements from a %multiset.
387       *  Note that this function only erases the elements, and that if
388       *  the elements themselves are pointers, the pointed-to memory is not
389       *  touched in any way.  Managing the pointer is the user's responsibilty.
390       */
391      void
392      erase(iterator __first, iterator __last)
393      {
394	typedef typename _Rep_type::iterator _Rep_iterator;
395	_M_t.erase((_Rep_iterator&)__first, (_Rep_iterator&)__last);
396      }
397
398      /**
399       *  Erases all elements in a %multiset.  Note that this function only
400       *  erases the elements, and that if the elements themselves are pointers,
401       *  the pointed-to memory is not touched in any way.  Managing the pointer
402       *  is the user's responsibilty.
403       */
404      void
405      clear()
406      { _M_t.clear(); }
407
408      // multiset operations:
409
410      /**
411       *  @brief Finds the number of elements with given key.
412       *  @param  x  Key of elements to be located.
413       *  @return Number of elements with specified key.
414       */
415      size_type
416      count(const key_type& __x) const
417      { return _M_t.count(__x); }
418
419      // _GLIBCXX_RESOLVE_LIB_DEFECTS
420      // 214.  set::find() missing const overload
421      //@{
422      /**
423       *  @brief Tries to locate an element in a %set.
424       *  @param  x  Element to be located.
425       *  @return  Iterator pointing to sought-after element, or end() if not
426       *           found.
427       *
428       *  This function takes a key and tries to locate the element with which
429       *  the key matches.  If successful the function returns an iterator
430       *  pointing to the sought after element.  If unsuccessful it returns the
431       *  past-the-end ( @c end() ) iterator.
432       */
433      iterator
434      find(const key_type& __x)
435      { return _M_t.find(__x); }
436
437      const_iterator
438      find(const key_type& __x) const
439      { return _M_t.find(__x); }
440      //@}
441
442      //@{
443      /**
444       *  @brief Finds the beginning of a subsequence matching given key.
445       *  @param  x  Key to be located.
446       *  @return  Iterator pointing to first element equal to or greater
447       *           than key, or end().
448       *
449       *  This function returns the first element of a subsequence of elements
450       *  that matches the given key.  If unsuccessful it returns an iterator
451       *  pointing to the first element that has a greater value than given key
452       *  or end() if no such element exists.
453       */
454      iterator
455      lower_bound(const key_type& __x)
456      { return _M_t.lower_bound(__x); }
457
458      const_iterator
459      lower_bound(const key_type& __x) const
460      { return _M_t.lower_bound(__x); }
461      //@}
462
463      //@{
464      /**
465       *  @brief Finds the end of a subsequence matching given key.
466       *  @param  x  Key to be located.
467       *  @return Iterator pointing to the first element
468       *          greater than key, or end().
469       */
470      iterator
471      upper_bound(const key_type& __x)
472      { return _M_t.upper_bound(__x); }
473
474      const_iterator
475      upper_bound(const key_type& __x) const
476      { return _M_t.upper_bound(__x); }
477      //@}
478
479      //@{
480      /**
481       *  @brief Finds a subsequence matching given key.
482       *  @param  x  Key to be located.
483       *  @return  Pair of iterators that possibly points to the subsequence
484       *           matching given key.
485       *
486       *  This function is equivalent to
487       *  @code
488       *    std::make_pair(c.lower_bound(val),
489       *                   c.upper_bound(val))
490       *  @endcode
491       *  (but is faster than making the calls separately).
492       *
493       *  This function probably only makes sense for multisets.
494       */
495      pair<iterator,iterator>
496      equal_range(const key_type& __x)
497      { return _M_t.equal_range(__x); }
498
499      pair<const_iterator,const_iterator>
500      equal_range(const key_type& __x) const
501      { return _M_t.equal_range(__x); }
502
503      template <class _K1, class _C1, class _A1>
504        friend bool
505        operator== (const multiset<_K1,_C1,_A1>&,
506		    const multiset<_K1,_C1,_A1>&);
507
508      template <class _K1, class _C1, class _A1>
509        friend bool
510        operator< (const multiset<_K1,_C1,_A1>&,
511		   const multiset<_K1,_C1,_A1>&);
512    };
513
514  /**
515   *  @brief  Multiset equality comparison.
516   *  @param  x  A %multiset.
517   *  @param  y  A %multiset of the same type as @a x.
518   *  @return  True iff the size and elements of the multisets are equal.
519   *
520   *  This is an equivalence relation.  It is linear in the size of the
521   *  multisets.
522   *  Multisets are considered equivalent if their sizes are equal, and if
523   *  corresponding elements compare equal.
524  */
525  template <class _Key, class _Compare, class _Alloc>
526    inline bool
527    operator==(const multiset<_Key,_Compare,_Alloc>& __x,
528	       const multiset<_Key,_Compare,_Alloc>& __y)
529    { return __x._M_t == __y._M_t; }
530
531  /**
532   *  @brief  Multiset ordering relation.
533   *  @param  x  A %multiset.
534   *  @param  y  A %multiset of the same type as @a x.
535   *  @return  True iff @a x is lexicographically less than @a y.
536   *
537   *  This is a total ordering relation.  It is linear in the size of the
538   *  maps.  The elements must be comparable with @c <.
539   *
540   *  See std::lexicographical_compare() for how the determination is made.
541  */
542  template <class _Key, class _Compare, class _Alloc>
543    inline bool
544    operator<(const multiset<_Key,_Compare,_Alloc>& __x,
545	      const multiset<_Key,_Compare,_Alloc>& __y)
546    { return __x._M_t < __y._M_t; }
547
548  ///  Returns !(x == y).
549  template <class _Key, class _Compare, class _Alloc>
550    inline bool
551    operator!=(const multiset<_Key,_Compare,_Alloc>& __x,
552	       const multiset<_Key,_Compare,_Alloc>& __y)
553    { return !(__x == __y); }
554
555  ///  Returns y < x.
556  template <class _Key, class _Compare, class _Alloc>
557    inline bool
558    operator>(const multiset<_Key,_Compare,_Alloc>& __x,
559	      const multiset<_Key,_Compare,_Alloc>& __y)
560    { return __y < __x; }
561
562  ///  Returns !(y < x)
563  template <class _Key, class _Compare, class _Alloc>
564    inline bool
565    operator<=(const multiset<_Key,_Compare,_Alloc>& __x,
566	       const multiset<_Key,_Compare,_Alloc>& __y)
567    { return !(__y < __x); }
568
569  ///  Returns !(x < y)
570  template <class _Key, class _Compare, class _Alloc>
571    inline bool
572    operator>=(const multiset<_Key,_Compare,_Alloc>& __x,
573	       const multiset<_Key,_Compare,_Alloc>& __y)
574    { return !(__x < __y); }
575
576  /// See std::multiset::swap().
577  template <class _Key, class _Compare, class _Alloc>
578    inline void
579    swap(multiset<_Key,_Compare,_Alloc>& __x,
580	 multiset<_Key,_Compare,_Alloc>& __y)
581    { __x.swap(__y); }
582
583} // namespace std
584
585#endif /* _MULTISET_H */
586