1 // Map implementation -*- C++ -*-
2 
3 // Copyright (C) 2001, 2002 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,1997
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_map.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 _CPP_BITS_STL_MAP_H
62 #define _CPP_BITS_STL_MAP_H 1
63 
64 #include <bits/concept_check.h>
65 
66 namespace std
67 {
68 
69 /**
70  *  @brief A standard container made up of pairs (see std::pair in <utility>)
71  *         which can be retrieved based on a key.
72  *
73  *  This is an associative container.  Values contained within it can be
74  *  quickly retrieved through a key element.  Example:  MyMap["First"] would
75  *  return the data associated with the key "First".
76 */
77 template <class _Key, class _Tp, class _Compare = less<_Key>,
78           class _Alloc = allocator<pair<const _Key, _Tp> > >
79 class map
80 {
81   // concept requirements
82   __glibcpp_class_requires(_Tp, _SGIAssignableConcept)
83   __glibcpp_class_requires4(_Compare, bool, _Key, _Key, _BinaryFunctionConcept);
84 
85 public:
86   // typedefs:
87   typedef _Key                 key_type;
88   typedef _Tp                   data_type;
89   typedef _Tp                   mapped_type;
90   typedef pair<const _Key, _Tp> value_type;
91   typedef _Compare             key_compare;
92 
93   class value_compare
94     : public binary_function<value_type, value_type, bool> {
95   friend class map<_Key,_Tp,_Compare,_Alloc>;
96   protected :
97     _Compare comp;
98     value_compare(_Compare __c) : comp(__c) {}
99   public:
100     bool operator()(const value_type& __x, const value_type& __y) const {
101       return comp(__x.first, __y.first);
102     }
103   };
104 
105 private:
106   typedef _Rb_tree<key_type, value_type,
107                    _Select1st<value_type>, key_compare, _Alloc> _Rep_type;
108   _Rep_type _M_t;  // red-black tree representing map
109 public:
110   typedef typename _Rep_type::pointer pointer;
111   typedef typename _Rep_type::const_pointer const_pointer;
112   typedef typename _Rep_type::reference reference;
113   typedef typename _Rep_type::const_reference const_reference;
114   typedef typename _Rep_type::iterator iterator;
115   typedef typename _Rep_type::const_iterator const_iterator;
116   typedef typename _Rep_type::reverse_iterator reverse_iterator;
117   typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator;
118   typedef typename _Rep_type::size_type size_type;
119   typedef typename _Rep_type::difference_type difference_type;
120   typedef typename _Rep_type::allocator_type allocator_type;
121 
122   // allocation/deallocation
123 
124   map() : _M_t(_Compare(), allocator_type()) {}
125   explicit map(const _Compare& __comp,
126                const allocator_type& __a = allocator_type())
127     : _M_t(__comp, __a) {}
128 
129   template <class _InputIterator>
130   map(_InputIterator __first, _InputIterator __last)
131     : _M_t(_Compare(), allocator_type())
132     { _M_t.insert_unique(__first, __last); }
133 
134   template <class _InputIterator>
135   map(_InputIterator __first, _InputIterator __last, const _Compare& __comp,
136       const allocator_type& __a = allocator_type())
137     : _M_t(__comp, __a) { _M_t.insert_unique(__first, __last); }
138   map(const map<_Key,_Tp,_Compare,_Alloc>& __x) : _M_t(__x._M_t) {}
139 
140   map<_Key,_Tp,_Compare,_Alloc>&
141   operator=(const map<_Key, _Tp, _Compare, _Alloc>& __x)
142   {
143     _M_t = __x._M_t;
144     return *this;
145   }
146 
147   // accessors:
148 
149   key_compare key_comp() const { return _M_t.key_comp(); }
150   value_compare value_comp() const { return value_compare(_M_t.key_comp()); }
151   allocator_type get_allocator() const { return _M_t.get_allocator(); }
152 
153   /**
154    *  Returns a read/write iterator that points to the first pair in the map.
155    *  Iteration is done in ascending order according to the keys.
156   */
157   iterator begin() { return _M_t.begin(); }
158 
159   /**
160    *  Returns a read-only (constant) iterator that points to the first pair
161    *  in the map.  Iteration is done in ascending order according to the keys.
162   */
163   const_iterator begin() const { return _M_t.begin(); }
164 
165   /**
166    *  Returns a read/write iterator that points one past the last pair in the
167    *  map.  Iteration is done in ascending order according to the keys.
168   */
169   iterator end() { return _M_t.end(); }
170 
171   /**
172    *  Returns a read-only (constant) iterator that points one past the last
173    *  pair in the map.  Iteration is done in ascending order according to the
174    *  keys.
175   */
176   const_iterator end() const { return _M_t.end(); }
177 
178   /**
179    *  Returns a read/write reverse iterator that points to the last pair in
180    *  the map.  Iteration is done in descending order according to the keys.
181   */
182   reverse_iterator rbegin() { return _M_t.rbegin(); }
183 
184   /**
185    *  Returns a read-only (constant) reverse iterator that points to the last
186    *  pair in the map.  Iteration is done in descending order according to
187    *  the keys.
188   */
189   const_reverse_iterator rbegin() const { return _M_t.rbegin(); }
190 
191   /**
192    *  Returns a read/write reverse iterator that points to one before the
193    *  first pair in the map.  Iteration is done in descending order according
194    *  to the keys.
195   */
196   reverse_iterator rend() { return _M_t.rend(); }
197 
198   /**
199    *  Returns a read-only (constant) reverse iterator that points to one
200    *  before the first pair in the map.  Iteration is done in descending order
201    *  according to the keys.
202   */
203   const_reverse_iterator rend() const { return _M_t.rend(); }
204 
205   /** Returns true if the map is empty.  (Thus begin() would equal end().)  */
206   bool empty() const { return _M_t.empty(); }
207   /** Returns the size of the map.  */
208   size_type size() const { return _M_t.size(); }
209   /** Returns the maximum size of the map.  */
210   size_type max_size() const { return _M_t.max_size(); }
211 
212   /**
213    *  @brief Subscript ( [] ) access to map data.
214    *  @param  k  The key for which data should be retrieved.
215    *
216    *  Allows for easy lookup with the subscript ( [] ) operator.  Returns the
217    *  data associated with the key specified in subscript.  If the key does
218    *  not exist a pair with that key is created with a default value, which
219    *  is then returned.
220   */
221   _Tp& operator[](const key_type& __k) {
222     iterator __i = lower_bound(__k);
223     // __i->first is greater than or equivalent to __k.
224     if (__i == end() || key_comp()(__k, (*__i).first))
225       __i = insert(__i, value_type(__k, _Tp()));
226     return (*__i).second;
227   }
228 
229   void swap(map<_Key,_Tp,_Compare,_Alloc>& __x) { _M_t.swap(__x._M_t); }
230 
231   // insert/erase
232   /**
233    *  @brief Attempts to insert a std::pair into the map.
234    *  @param  x  Pair to be inserted (see std::make_pair for easy creation of
235    *             pairs).
236    *  @return  A pair of which the first element is an iterator that points
237    *           to the possibly inserted pair, a second element of type bool
238    *           to show if the pair was actually inserted.
239    *
240    *  This function attempts to insert a (key, value) pair into the map.  A
241    *  map relies on unique keys and thus a pair is only inserted if its first
242    *  element (the key) is not already present in the map.
243   */
244   pair<iterator,bool> insert(const value_type& __x)
245     { return _M_t.insert_unique(__x); }
246 
247   /**
248    *  @brief Attempts to insert a std::pair into the map.
249    *  @param  position  An iterator that serves as a hint as to where the
250    *                    pair should be inserted.
251    *  @param  x  Pair to be inserted (see std::make_pair for easy creation of
252    *             pairs).
253    *  @return  An iterator that points to the inserted (key,value) pair.
254    *
255    *  This function is not concerned about whether the insertion took place
256    *  or not and thus does not return a boolean like the single-argument
257    *  insert() does.  Note that the first parameter is only a hint and can
258    *  potentially improve the performance of the insertion process.  A bad
259    *  hint would cause no gains in efficiency.
260   */
261   iterator insert(iterator position, const value_type& __x)
262     { return _M_t.insert_unique(position, __x); }
263 
264   /**
265    *  @brief A template function that attemps to insert elements from
266    *         another range (possibly another map).
267    *  @param  first  Iterator pointing to the start of the range to be inserted.
268    *  @param  last  Iterator pointing to the end of the range.
269   */
270   template <class _InputIterator>
271   void insert(_InputIterator __first, _InputIterator __last) {
272     _M_t.insert_unique(__first, __last);
273   }
274 
275   /**
276    *  @brief Erases an element from a map.
277    *  @param  position  An iterator pointing to the element to be erased.
278    *
279    *  This function erases an element, pointed to by the given iterator, from
280    *  a map.  Note that this function only erases the element, and that if
281    *  the element is itself a pointer, the pointed-to memory is not touched
282    *  in any way.  Managing the pointer is the user's responsibilty.
283   */
284   void erase(iterator __position) { _M_t.erase(__position); }
285 
286   /**
287    *  @brief Erases an element according to the provided key.
288    *  @param  x  Key of element to be erased.
289    *  @return  Doc me! (Number of elements that match key? Only makes sense
290    *           with multimap)
291    *
292    *  This function erases an element, located by the given key, from a map.
293    *  Note that this function only erases the element, and that if
294    *  the element is itself a pointer, the pointed-to memory is not touched
295    *  in any way.  Managing the pointer is the user's responsibilty.
296   */
297   size_type erase(const key_type& __x) { return _M_t.erase(__x); }
298 
299   /**
300    *  @brief Erases a [first,last) range of elements from a map.
301    *  @param  first  Iterator pointing to the start of the range to be erased.
302    *  @param  last  Iterator pointing to the end of the range to be erased.
303    *
304    *  This function erases a sequence of elements from a map.
305    *  Note that this function only erases the element, and that if
306    *  the element is itself a pointer, the pointed-to memory is not touched
307    *  in any way.  Managing the pointer is the user's responsibilty.
308   */
309   void erase(iterator __first, iterator __last)
310     { _M_t.erase(__first, __last); }
311 
312   /** Erases all elements in a map.  Note that this function only erases
313    *  the elements, and that if the elements themselves are pointers, the
314    *  pointed-to memory is not touched in any way.  Managing the pointer is
315    *  the user's responsibilty.
316   */
317   void clear() { _M_t.clear(); }
318 
319   // map operations:
320 
321   /**
322    *  @brief Tries to locate an element in a map.
323    *  @param  x  Key of (key, value) pair to be located.
324    *  @return  Iterator pointing to sought-after element, or end() if not
325    *           found.
326    *
327    *  This function takes a key and tries to locate the element with which
328    *  the key matches.  If successful the function returns an iterator
329    *  pointing to the sought after pair. If unsuccessful it returns the
330    *  one past the end ( end() ) iterator.
331   */
332   iterator find(const key_type& __x) { return _M_t.find(__x); }
333 
334   /**
335    *  @brief Tries to locate an element in a map.
336    *  @param  x  Key of (key, value) pair to be located.
337    *  @return  Read-only (constant) iterator pointing to sought-after
338    *           element, or end() if not found.
339    *
340    *  This function takes a key and tries to locate the element with which
341    *  the key matches.  If successful the function returns a constant iterator
342    *  pointing to the sought after pair. If unsuccessful it returns the
343    *  one past the end ( end() ) iterator.
344   */
345   const_iterator find(const key_type& __x) const { return _M_t.find(__x); }
346 
347   /**
348    *  @brief Finds the number of elements with given key.
349    *  @param  x  Key of (key, value) pairs to be located.
350    *  @return Number of elements with specified key.
351    *
352    *  This function only makes sense for multimaps.
353   */
354   size_type count(const key_type& __x) const {
355     return _M_t.find(__x) == _M_t.end() ? 0 : 1;
356   }
357 
358   /**
359    *  @brief Finds the beginning of a subsequence matching given key.
360    *  @param  x  Key of (key, value) pair to be located.
361    *  @return  Iterator pointing to first element matching given key, or
362    *           end() if not found.
363    *
364    *  This function is useful only with std::multimap.  It returns the first
365    *  element of a subsequence of elements that matches the given key.  If
366    *  unsuccessful it returns an iterator pointing to the first element that
367    *  has a greater value than given key or end() if no such element exists.
368   */
369   iterator lower_bound(const key_type& __x) {return _M_t.lower_bound(__x); }
370 
371   /**
372    *  @brief Finds the beginning of a subsequence matching given key.
373    *  @param  x  Key of (key, value) pair to be located.
374    *  @return  Read-only (constant) iterator pointing to first element
375    *           matching given key, or end() if not found.
376    *
377    *  This function is useful only with std::multimap.  It returns the first
378    *  element of a subsequence of elements that matches the given key.  If
379    *  unsuccessful the iterator will point to the next greatest element or,
380    *  if no such greater element exists, to end().
381   */
382   const_iterator lower_bound(const key_type& __x) const {
383     return _M_t.lower_bound(__x);
384   }
385 
386   /**
387    *  @brief Finds the end of a subsequence matching given key.
388    *  @param  x  Key of (key, value) pair to be located.
389    *  @return Iterator pointing to last element matching given key.
390    *
391    *  This function only makes sense with multimaps.
392   */
393   iterator upper_bound(const key_type& __x) {return _M_t.upper_bound(__x); }
394 
395   /**
396    *  @brief Finds the end of a subsequence matching given key.
397    *  @param  x  Key of (key, value) pair to be located.
398    *  @return  Read-only (constant) iterator pointing to last element matching
399    *           given key.
400    *
401    *  This function only makes sense with multimaps.
402   */
403   const_iterator upper_bound(const key_type& __x) const {
404     return _M_t.upper_bound(__x);
405   }
406 
407   /**
408    *  @brief Finds a subsequence matching given key.
409    *  @param  x  Key of (key, value) pairs to be located.
410    *  @return  Pair of iterators that possibly points to the subsequence
411    *           matching given key.
412    *
413    *  This function improves on lower_bound() and upper_bound() by giving a more
414    *  elegant and efficient solution.  It returns a pair of which the first
415    *  element possibly points to the first element matching the given key
416    *  and the second element possibly points to the last element matching the
417    *  given key.  If unsuccessful the first element of the returned pair will
418    *  contain an iterator pointing to the next greatest element or, if no such
419    *  greater element exists, to end().
420    *
421    *  This function only makes sense for multimaps.
422   */
423   pair<iterator,iterator> equal_range(const key_type& __x) {
424     return _M_t.equal_range(__x);
425   }
426 
427   /**
428    *  @brief Finds a subsequence matching given key.
429    *  @param  x  Key of (key, value) pairs to be located.
430    *  @return  Pair of read-only (constant) iterators that possibly points to
431    *           the subsequence matching given key.
432    *
433    *  This function improves on lower_bound() and upper_bound() by giving a more
434    *  elegant and efficient solution.  It returns a pair of which the first
435    *  element possibly points to the first element matching the given key
436    *  and the second element possibly points to the last element matching the
437    *  given key.  If unsuccessful the first element of the returned pair will
438    *  contain an iterator pointing to the next greatest element or, if no such
439    *  a greater element exists, to end().
440    *
441    *  This function only makes sense for multimaps.
442   */
443   pair<const_iterator,const_iterator> equal_range(const key_type& __x) const {
444     return _M_t.equal_range(__x);
445   }
446 
447   template <class _K1, class _T1, class _C1, class _A1>
448   friend bool operator== (const map<_K1, _T1, _C1, _A1>&,
449                           const map<_K1, _T1, _C1, _A1>&);
450   template <class _K1, class _T1, class _C1, class _A1>
451   friend bool operator< (const map<_K1, _T1, _C1, _A1>&,
452                          const map<_K1, _T1, _C1, _A1>&);
453 };
454 
455 template <class _Key, class _Tp, class _Compare, class _Alloc>
456 inline bool operator==(const map<_Key,_Tp,_Compare,_Alloc>& __x,
457                        const map<_Key,_Tp,_Compare,_Alloc>& __y) {
458   return __x._M_t == __y._M_t;
459 }
460 
461 template <class _Key, class _Tp, class _Compare, class _Alloc>
462 inline bool operator<(const map<_Key,_Tp,_Compare,_Alloc>& __x,
463                       const map<_Key,_Tp,_Compare,_Alloc>& __y) {
464   return __x._M_t < __y._M_t;
465 }
466 
467 template <class _Key, class _Tp, class _Compare, class _Alloc>
468 inline bool operator!=(const map<_Key,_Tp,_Compare,_Alloc>& __x,
469                        const map<_Key,_Tp,_Compare,_Alloc>& __y) {
470   return !(__x == __y);
471 }
472 
473 template <class _Key, class _Tp, class _Compare, class _Alloc>
474 inline bool operator>(const map<_Key,_Tp,_Compare,_Alloc>& __x,
475                       const map<_Key,_Tp,_Compare,_Alloc>& __y) {
476   return __y < __x;
477 }
478 
479 template <class _Key, class _Tp, class _Compare, class _Alloc>
480 inline bool operator<=(const map<_Key,_Tp,_Compare,_Alloc>& __x,
481                        const map<_Key,_Tp,_Compare,_Alloc>& __y) {
482   return !(__y < __x);
483 }
484 
485 template <class _Key, class _Tp, class _Compare, class _Alloc>
486 inline bool operator>=(const map<_Key,_Tp,_Compare,_Alloc>& __x,
487                        const map<_Key,_Tp,_Compare,_Alloc>& __y) {
488   return !(__x < __y);
489 }
490 
491 template <class _Key, class _Tp, class _Compare, class _Alloc>
492 inline void swap(map<_Key,_Tp,_Compare,_Alloc>& __x,
493                  map<_Key,_Tp,_Compare,_Alloc>& __y) {
494   __x.swap(__y);
495 }
496 
497 } // namespace std
498 
499 #endif /* _CPP_BITS_STL_MAP_H */
500 
501 // Local Variables:
502 // mode:C++
503 // End:
504