Home | History | Annotate | Download | only in stl
      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
     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
    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