• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2004
3  * Francois Dumont
4  *
5  * This material is provided "as is", with absolutely no warranty expressed
6  * or implied. Any use is at your own risk.
7  *
8  * Permission to use or copy this software for any purpose is hereby granted
9  * without fee, provided the above notices are retained on all copies.
10  * Permission to modify the code and to distribute modified code is granted,
11  * provided the above notices are retained, and a notice that the code was
12  * modified is included with the above copyright notice.
13  *
14  */
15 
16 /* NOTE: This is an internal header file, included by other STL headers.
17  *   You should not attempt to use it directly.
18  */
19 
20 #ifndef _STLP_INTERNAL_UNORDERED_MAP_H
21 #define _STLP_INTERNAL_UNORDERED_MAP_H
22 
23 #ifndef _STLP_INTERNAL_HASHTABLE_H
24 #  include <stl/_hashtable.h>
25 #endif
26 
27 _STLP_BEGIN_NAMESPACE
28 
29 //Specific iterator traits creation
_STLP_CREATE_HASH_ITERATOR_TRAITS(UnorderedMapTraitsT,traits)30 _STLP_CREATE_HASH_ITERATOR_TRAITS(UnorderedMapTraitsT, traits)
31 
32 _STLP_BEGIN_TR1_NAMESPACE
33 
34 template <class _Key, class _Tp, _STLP_DFL_TMPL_PARAM(_HashFcn,hash<_Key>),
35           _STLP_DFL_TMPL_PARAM(_EqualKey, equal_to<_Key>),
36           _STLP_DEFAULT_PAIR_ALLOCATOR_SELECT(_STLP_CONST _Key, _Tp) >
37 class unordered_map
38 #if defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND)
39                : public __stlport_class<unordered_map<_Key, _Tp, _HashFcn, _EqualKey, _Alloc> >
40 #endif
41 {
42 private:
43   typedef unordered_map<_Key, _Tp, _HashFcn, _EqualKey, _Alloc> _Self;
44 public:
45   typedef _Key key_type;
46   typedef _Tp data_type;
47   typedef _Tp mapped_type;
48   typedef pair<_STLP_CONST key_type, data_type> value_type;
49 private:
50   //Specific iterator traits creation
51   typedef _STLP_PRIV _UnorderedMapTraitsT<value_type> _UnorderedMapTraits;
52 
53 public:
54   typedef hashtable<value_type, key_type, _HashFcn, _UnorderedMapTraits,
55                     _STLP_SELECT1ST(value_type,  _Key), _EqualKey, _Alloc > _Ht;
56 
57   typedef typename _Ht::hasher hasher;
58   typedef typename _Ht::key_equal key_equal;
59 
60   typedef typename _Ht::size_type size_type;
61   typedef typename _Ht::difference_type difference_type;
62   typedef typename _Ht::pointer pointer;
63   typedef typename _Ht::const_pointer const_pointer;
64   typedef typename _Ht::reference reference;
65   typedef typename _Ht::const_reference const_reference;
66 
67   typedef typename _Ht::iterator iterator;
68   typedef typename _Ht::const_iterator const_iterator;
69   typedef typename _Ht::local_iterator local_iterator;
70   typedef typename _Ht::const_local_iterator const_local_iterator;
71 
72   typedef typename _Ht::allocator_type allocator_type;
73 
74   hasher hash_function() const { return _M_ht.hash_funct(); }
75   key_equal key_eq() const { return _M_ht.key_eq(); }
76   allocator_type get_allocator() const { return _M_ht.get_allocator(); }
77 
78 private:
79   _Ht _M_ht;
80   _STLP_KEY_TYPE_FOR_CONT_EXT(key_type)
81 
82 public:
83   explicit unordered_map(size_type __n = 0, const hasher& __hf = hasher(),
84                          const key_equal& __eql = key_equal(),
85                          const allocator_type& __a = allocator_type())
86     : _M_ht(__n, __hf, __eql, __a) {}
87 
88 #if !defined (_STLP_NO_MOVE_SEMANTIC)
89   unordered_map(__move_source<_Self> src)
90     : _M_ht(__move_source<_Ht>(src.get()._M_ht)) {}
91 #endif
92 
93 #if defined (_STLP_MEMBER_TEMPLATES)
94   template <class _InputIterator>
95   unordered_map(_InputIterator __f, _InputIterator __l,
96                 size_type __n = 0, const hasher& __hf = hasher(),
97                 const key_equal& __eql = key_equal(),
98                 const allocator_type& __a = allocator_type())
99     : _M_ht(__n, __hf, __eql, __a)
100   { _M_ht.insert_unique(__f, __l); }
101 #else
102   unordered_map(const value_type* __f, const value_type* __l,
103                 size_type __n = 0, const hasher& __hf = hasher(),
104                 const key_equal& __eql = key_equal(),
105                 const allocator_type& __a = allocator_type())
106     : _M_ht(__n, __hf, __eql, __a)
107   { _M_ht.insert_unique(__f, __l); }
108 
109   unordered_map(const_iterator __f, const_iterator __l,
110                 size_type __n = 0, const hasher& __hf = hasher(),
111                 const key_equal& __eql = key_equal(),
112                 const allocator_type& __a = allocator_type())
113     : _M_ht(__n, __hf, __eql, __a)
114   { _M_ht.insert_unique(__f, __l); }
115 #endif /*_STLP_MEMBER_TEMPLATES */
116 
117   _Self& operator = (const _Self& __other)
118   { _M_ht = __other._M_ht; return *this; }
119 
120   size_type size() const { return _M_ht.size(); }
121   size_type max_size() const { return _M_ht.max_size(); }
122   bool empty() const { return _M_ht.empty(); }
123   void swap(_Self& __hs) { _M_ht.swap(__hs._M_ht); }
124 #if defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND) && !defined (_STLP_FUNCTION_TMPL_PARTIAL_ORDER)
125   void _M_swap_workaround(_Self& __x) { swap(__x); }
126 #endif
127 
128   iterator begin() { return _M_ht.begin(); }
129   iterator end() { return _M_ht.end(); }
130   const_iterator begin() const { return _M_ht.begin(); }
131   const_iterator end() const { return _M_ht.end(); }
132 
133   pair<iterator,bool> insert(const value_type& __obj)
134   { return _M_ht.insert_unique(__obj); }
135   iterator insert(const_iterator /*__hint*/, const value_type& __obj)
136   { return _M_ht.insert_unique(__obj); }
137 #if defined (_STLP_MEMBER_TEMPLATES)
138   template <class _InputIterator>
139   void insert(_InputIterator __f, _InputIterator __l)
140 #else
141   void insert(const value_type* __f, const value_type* __l)
142   { _M_ht.insert_unique(__f,__l); }
143   void insert(const_iterator __f, const_iterator __l)
144 #endif /*_STLP_MEMBER_TEMPLATES */
145   { _M_ht.insert_unique(__f, __l); }
146 
147   _STLP_TEMPLATE_FOR_CONT_EXT
148   iterator find(const _KT& __key) { return _M_ht.find(__key); }
149   _STLP_TEMPLATE_FOR_CONT_EXT
150   const_iterator find(const _KT& __key) const { return _M_ht.find(__key); }
151 
152   _STLP_TEMPLATE_FOR_CONT_EXT
153   _Tp& operator[](const _KT& __key) {
154     iterator __it = _M_ht.find(__key);
155     return (__it == _M_ht.end() ?
156       _M_ht._M_insert(value_type(__key, _STLP_DEFAULT_CONSTRUCTED(_Tp))).second :
157       (*__it).second );
158   }
159 
160   _STLP_TEMPLATE_FOR_CONT_EXT
161   size_type count(const _KT& __key) const { return _M_ht.count(__key); }
162 
163   _STLP_TEMPLATE_FOR_CONT_EXT
164   pair<iterator, iterator> equal_range(const _KT& __key)
165   { return _M_ht.equal_range(__key); }
166   _STLP_TEMPLATE_FOR_CONT_EXT
167   pair<const_iterator, const_iterator> equal_range(const _KT& __key) const
168   { return _M_ht.equal_range(__key); }
169 
170   size_type erase(const key_type& __key) {return _M_ht.erase(__key); }
171   void erase(const_iterator __it) { _M_ht.erase(__it); }
172   void erase(const_iterator __f, const_iterator __l) { _M_ht.erase(__f, __l); }
173   void clear() { _M_ht.clear(); }
174 
175   size_type bucket_count() const { return _M_ht.bucket_count(); }
176   size_type max_bucket_count() const { return _M_ht.max_bucket_count(); }
177   size_type bucket_size(size_type __n) const { return _M_ht.elems_in_bucket(__n); }
178   _STLP_TEMPLATE_FOR_CONT_EXT
179   size_type bucket(const _KT& __k) const { return _M_ht.bucket(__k); }
180   local_iterator begin(size_type __n) { return _M_ht.begin(__n); }
181   local_iterator end(size_type __n) { return _M_ht.end(__n); }
182   const_local_iterator begin(size_type __n) const { return _M_ht.begin(__n); }
183   const_local_iterator end(size_type __n) const { return _M_ht.end(__n); }
184 
185   float load_factor() const { return _M_ht.load_factor(); }
186   float max_load_factor() const { return _M_ht.max_load_factor(); }
187   void max_load_factor(float __val) { _M_ht.max_load_factor(__val); }
188   void rehash(size_type __hint) { _M_ht.rehash(__hint); }
189 
190 #if defined (__DMC__) // disable operator==(pair<x,unordered_map>, pair<x,unordered_map>)
191   bool operator==(const _Self&) const;
192 #endif
193 };
194 
195 _STLP_END_NAMESPACE
196 
197 //Specific iterator traits creation
_STLP_CREATE_HASH_ITERATOR_TRAITS(UnorderedMultimapTraitsT,traits)198 _STLP_CREATE_HASH_ITERATOR_TRAITS(UnorderedMultimapTraitsT, traits)
199 
200 _STLP_BEGIN_TR1_NAMESPACE
201 
202 template <class _Key, class _Tp, _STLP_DFL_TMPL_PARAM(_HashFcn,hash<_Key>),
203           _STLP_DFL_TMPL_PARAM(_EqualKey, equal_to<_Key>),
204           _STLP_DEFAULT_PAIR_ALLOCATOR_SELECT(_STLP_CONST _Key, _Tp) >
205 class unordered_multimap
206 #if defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND)
207                     : public __stlport_class<unordered_multimap<_Key, _Tp, _HashFcn, _EqualKey, _Alloc> >
208 #endif
209 {
210 private:
211   typedef unordered_multimap<_Key, _Tp, _HashFcn, _EqualKey, _Alloc> _Self;
212 public:
213   typedef _Key key_type;
214   typedef _Tp data_type;
215   typedef _Tp mapped_type;
216   typedef pair<_STLP_CONST key_type, data_type> value_type;
217 private:
218   //Specific iterator traits creation
219   typedef _STLP_PRIV _UnorderedMultimapTraitsT<value_type> _UnorderedMultimapTraits;
220 
221 public:
222   typedef hashtable<value_type, key_type, _HashFcn, _UnorderedMultimapTraits,
223                     _STLP_SELECT1ST(value_type,  _Key), _EqualKey, _Alloc > _Ht;
224 
225   typedef typename _Ht::hasher hasher;
226   typedef typename _Ht::key_equal key_equal;
227 
228   typedef typename _Ht::size_type size_type;
229   typedef typename _Ht::difference_type difference_type;
230   typedef typename _Ht::pointer pointer;
231   typedef typename _Ht::const_pointer const_pointer;
232   typedef typename _Ht::reference reference;
233   typedef typename _Ht::const_reference const_reference;
234 
235   typedef typename _Ht::iterator iterator;
236   typedef typename _Ht::const_iterator const_iterator;
237   typedef typename _Ht::local_iterator local_iterator;
238   typedef typename _Ht::const_local_iterator const_local_iterator;
239 
240   typedef typename _Ht::allocator_type allocator_type;
241 
242   hasher hash_function() const { return _M_ht.hash_funct(); }
243   key_equal key_eq() const { return _M_ht.key_eq(); }
244   allocator_type get_allocator() const { return _M_ht.get_allocator(); }
245 
246 private:
247   _Ht _M_ht;
248   _STLP_KEY_TYPE_FOR_CONT_EXT(key_type)
249 
250 public:
251   explicit unordered_multimap(size_type __n = 0, const hasher& __hf = hasher(),
252                               const key_equal& __eql = key_equal(),
253                               const allocator_type& __a = allocator_type())
254     : _M_ht(__n, __hf, __eql, __a) {}
255 
256 #if !defined (_STLP_NO_MOVE_SEMANTIC)
257   unordered_multimap(__move_source<_Self> src)
258     : _M_ht(__move_source<_Ht>(src.get()._M_ht)) {}
259 #endif
260 
261 #if defined (_STLP_MEMBER_TEMPLATES)
262   template <class _InputIterator>
263   unordered_multimap(_InputIterator __f, _InputIterator __l,
264                      size_type __n = 0, const hasher& __hf = hasher(),
265                      const key_equal& __eql = key_equal(),
266                      const allocator_type& __a = allocator_type())
267     : _M_ht(__n, __hf, __eql, __a)
268   { _M_ht.insert_equal(__f, __l); }
269 #else
270   unordered_multimap(const value_type* __f, const value_type* __l,
271                      size_type __n = 0, const hasher& __hf = hasher(),
272                      const key_equal& __eql = key_equal(),
273                      const allocator_type& __a = allocator_type())
274     : _M_ht(__n, __hf, __eql, __a)
275   { _M_ht.insert_equal(__f, __l); }
276 
277   unordered_multimap(const_iterator __f, const_iterator __l,
278                      size_type __n = 0, const hasher& __hf = hasher(),
279                      const key_equal& __eql = key_equal(),
280                      const allocator_type& __a = allocator_type())
281     : _M_ht(__n, __hf, __eql, __a)
282   { _M_ht.insert_equal(__f, __l); }
283 #endif /*_STLP_MEMBER_TEMPLATES */
284 
285   _Self& operator = (const _Self& __other)
286   { _M_ht = __other._M_ht; return *this; }
287 
288   size_type size() const { return _M_ht.size(); }
289   size_type max_size() const { return _M_ht.max_size(); }
290   bool empty() const { return _M_ht.empty(); }
291   void swap(_Self& __hs) { _M_ht.swap(__hs._M_ht); }
292 #if defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND) && !defined (_STLP_FUNCTION_TMPL_PARTIAL_ORDER)
293   void _M_swap_workaround(_Self& __x) { swap(__x); }
294 #endif
295 
296   iterator begin() { return _M_ht.begin(); }
297   iterator end() { return _M_ht.end(); }
298   const_iterator begin() const { return _M_ht.begin(); }
299   const_iterator end() const { return _M_ht.end(); }
300 
301   iterator insert(const value_type& __obj)
302   { return _M_ht.insert_equal(__obj); }
303   iterator insert(const_iterator /*__hint*/, const value_type& __obj)
304   { return _M_ht.insert_equal(__obj); }
305 #if defined (_STLP_MEMBER_TEMPLATES)
306   template <class _InputIterator>
307   void insert(_InputIterator __f, _InputIterator __l)
308 #else
309   void insert(const value_type* __f, const value_type* __l)
310   { _M_ht.insert_equal(__f,__l); }
311   void insert(const_iterator __f, const_iterator __l)
312 #endif /*_STLP_MEMBER_TEMPLATES */
313   { _M_ht.insert_equal(__f, __l); }
314 
315   _STLP_TEMPLATE_FOR_CONT_EXT
316   iterator find(const _KT& __key) { return _M_ht.find(__key); }
317   _STLP_TEMPLATE_FOR_CONT_EXT
318   const_iterator find(const _KT& __key) const { return _M_ht.find(__key); }
319 
320   _STLP_TEMPLATE_FOR_CONT_EXT
321   size_type count(const _KT& __key) const { return _M_ht.count(__key); }
322 
323   _STLP_TEMPLATE_FOR_CONT_EXT
324   pair<iterator, iterator> equal_range(const _KT& __key)
325   { return _M_ht.equal_range(__key); }
326   _STLP_TEMPLATE_FOR_CONT_EXT
327   pair<const_iterator, const_iterator> equal_range(const _KT& __key) const
328   { return _M_ht.equal_range(__key); }
329 
330   size_type erase(const key_type& __key) {return _M_ht.erase(__key); }
331   void erase(const_iterator __it) { _M_ht.erase(__it); }
332   void erase(const_iterator __f, const_iterator __l) { _M_ht.erase(__f, __l); }
333   void clear() { _M_ht.clear(); }
334 
335   size_type bucket_count() const { return _M_ht.bucket_count(); }
336   size_type max_bucket_count() const { return _M_ht.max_bucket_count(); }
337   size_type bucket_size(size_type __n) const { return _M_ht.elems_in_bucket(__n); }
338   _STLP_TEMPLATE_FOR_CONT_EXT
339   size_type bucket(const _KT& __k) const { return _M_ht.bucket(__k); }
340   local_iterator begin(size_type __n) { return _M_ht.begin(__n); }
341   local_iterator end(size_type __n) { return _M_ht.end(__n); }
342   const_local_iterator begin(size_type __n) const { return _M_ht.begin(__n); }
343   const_local_iterator end(size_type __n) const { return _M_ht.end(__n); }
344 
345   float load_factor() const { return _M_ht.load_factor(); }
346   float max_load_factor() const { return _M_ht.max_load_factor(); }
347   void max_load_factor(float __val) { _M_ht.max_load_factor(__val); }
348   void rehash(size_type __hint) { _M_ht.rehash(__hint); }
349 };
350 
351 #define _STLP_TEMPLATE_HEADER template <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc>
352 #define _STLP_TEMPLATE_CONTAINER unordered_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>
353 
354 #include <stl/_relops_hash_cont.h>
355 
356 #undef _STLP_TEMPLATE_CONTAINER
357 #define _STLP_TEMPLATE_CONTAINER unordered_multimap<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>
358 
359 #include <stl/_relops_hash_cont.h>
360 
361 #undef _STLP_TEMPLATE_CONTAINER
362 #undef _STLP_TEMPLATE_HEADER
363 
364 _STLP_END_NAMESPACE
365 
366 // Specialization of insert_iterator so that it will work for unordered_map
367 // and unordered_multimap.
368 
369 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
370 #  if !defined (_STLP_NO_MOVE_SEMANTIC)
371 template <class _Key, class _Tp, class _HashFn,  class _EqKey, class _Alloc>
372 struct __move_traits<_STLP_TR1 unordered_map<_Key, _Tp, _HashFn, _EqKey, _Alloc> > :
373   _STLP_PRIV __move_traits_help<typename _STLP_TR1 unordered_map<_Key, _Tp, _HashFn, _EqKey, _Alloc>::_Ht>
374 {};
375 
376 template <class _Key, class _Tp, class _HashFn,  class _EqKey, class _Alloc>
377 struct __move_traits<_STLP_TR1 unordered_multimap<_Key, _Tp, _HashFn, _EqKey, _Alloc> > :
378   _STLP_PRIV __move_traits_help<typename _STLP_TR1 unordered_map<_Key, _Tp, _HashFn, _EqKey, _Alloc>::_Ht>
379 {};
380 #  endif
381 
382 template <class _Key, class _Tp, class _HashFn,  class _EqKey, class _Alloc>
383 class insert_iterator<_STLP_TR1 unordered_map<_Key, _Tp, _HashFn, _EqKey, _Alloc> > {
384 protected:
385   typedef _STLP_TR1 unordered_map<_Key, _Tp, _HashFn, _EqKey, _Alloc> _Container;
386   _Container* container;
387 public:
388   typedef _Container          container_type;
389   typedef output_iterator_tag iterator_category;
390   typedef void                value_type;
391   typedef void                difference_type;
392   typedef void                pointer;
393   typedef void                reference;
394 
395   insert_iterator(_Container& __x) : container(&__x) {}
396   insert_iterator(_Container& __x, typename _Container::iterator)
397     : container(&__x) {}
398   insert_iterator<_Container>&
399   operator=(const typename _Container::value_type& __val) {
400     container->insert(__val);
401     return *this;
402   }
403   insert_iterator<_Container>& operator*() { return *this; }
404   insert_iterator<_Container>& operator++() { return *this; }
405   insert_iterator<_Container>& operator++(int) { return *this; }
406 };
407 
408 template <class _Key, class _Tp, class _HashFn,  class _EqKey, class _Alloc>
409 class insert_iterator<_STLP_TR1 unordered_multimap<_Key, _Tp, _HashFn, _EqKey, _Alloc> > {
410 protected:
411   typedef _STLP_TR1 unordered_multimap<_Key, _Tp, _HashFn, _EqKey, _Alloc> _Container;
412   _Container* container;
413   typename _Container::iterator iter;
414 public:
415   typedef _Container          container_type;
416   typedef output_iterator_tag iterator_category;
417   typedef void                value_type;
418   typedef void                difference_type;
419   typedef void                pointer;
420   typedef void                reference;
421 
422   insert_iterator(_Container& __x) : container(&__x) {}
423   insert_iterator(_Container& __x, typename _Container::iterator)
424     : container(&__x) {}
425   insert_iterator<_Container>&
426   operator=(const typename _Container::value_type& __val) {
427     container->insert(__val);
428     return *this;
429   }
430   insert_iterator<_Container>& operator*() { return *this; }
431   insert_iterator<_Container>& operator++() { return *this; }
432   insert_iterator<_Container>& operator++(int) { return *this; }
433 };
434 
435 #endif /* _STLP_CLASS_PARTIAL_SPECIALIZATION */
436 
437 _STLP_END_NAMESPACE
438 
439 #endif /* _STLP_INTERNAL_UNORDERED_MAP_H */
440 
441 // Local Variables:
442 // mode:C++
443 // End:
444