epoc32/include/tools/stlport/stl/_hashtable.h
author William Roberts <williamr@symbian.org>
Wed, 31 Mar 2010 12:33:34 +0100
branchSymbian3
changeset 4 837f303aceeb
permissions -rw-r--r--
Current Symbian^3 public API header files (from PDK 3.0.h)
This is the epoc32/include tree with the "platform" subtrees removed, and
all but a selected few mbg and rsg files removed.
     1 /*
     2  *
     3  * Copyright (c) 1994
     4  * Hewlett-Packard Company
     5  *
     6  * Copyright (c) 1996,1997
     7  * Silicon Graphics Computer Systems, Inc.
     8  *
     9  * Copyright (c) 1997
    10  * Moscow Center for SPARC Technology
    11  *
    12  * Copyright (c) 1999
    13  * Boris Fomitchev
    14  *
    15  * This material is provided "as is", with absolutely no warranty expressed
    16  * or implied. Any use is at your own risk.
    17  *
    18  * Permission to use or copy this software for any purpose is hereby granted
    19  * without fee, provided the above notices are retained on all copies.
    20  * Permission to modify the code and to distribute modified code is granted,
    21  * provided the above notices are retained, and a notice that the code was
    22  * modified is included with the above copyright notice.
    23  *
    24  */
    25 
    26 /* NOTE: This is an internal header file, included by other STL headers.
    27  *   You should not attempt to use it directly.
    28  */
    29 
    30 #ifndef _STLP_INTERNAL_HASHTABLE_H
    31 #define _STLP_INTERNAL_HASHTABLE_H
    32 
    33 #ifndef _STLP_INTERNAL_VECTOR_H
    34 #  include <stl/_vector.h>
    35 #endif
    36 
    37 #ifndef _STLP_INTERNAL_SLIST_H
    38 #  include <stl/_slist.h>
    39 #endif
    40 
    41 #ifndef _STLP_INTERNAL_ITERATOR_H
    42 #  include <stl/_iterator.h>
    43 #endif
    44 
    45 #ifndef _STLP_INTERNAL_FUNCTION_BASE_H
    46 #  include <stl/_function_base.h>
    47 #endif
    48 
    49 #ifndef _STLP_INTERNAL_ALGOBASE_H
    50 #  include <stl/_algobase.h>
    51 #endif
    52 
    53 #ifndef _STLP_HASH_FUN_H
    54 #  include <stl/_hash_fun.h>
    55 #endif
    56 
    57 /*
    58  * Hashtable class, used to implement the hashed associative containers
    59  * hash_set, hash_map, hash_multiset, hash_multimap,
    60  * unordered_set, unordered_map, unordered_multiset, unordered_multimap.
    61  */
    62 
    63 _STLP_BEGIN_NAMESPACE
    64 
    65 #if defined (_STLP_USE_TEMPLATE_EXPORT)
    66 //Export of the classes used to represent buckets in the hashtable implementation.
    67 #  if !defined (_STLP_USE_PTR_SPECIALIZATIONS)
    68 //If pointer specialization is enabled vector<_Slist_node_base*> will use the void*
    69 //storage type for which internal classes have already been exported.
    70 _STLP_EXPORT_TEMPLATE_CLASS allocator<_STLP_PRIV _Slist_node_base*>;
    71 
    72 _STLP_MOVE_TO_PRIV_NAMESPACE
    73 _STLP_EXPORT_TEMPLATE_CLASS _STLP_alloc_proxy<_Slist_node_base**, _Slist_node_base*,
    74                                               allocator<_Slist_node_base*> >;
    75 _STLP_EXPORT_TEMPLATE_CLASS _Vector_base<_Slist_node_base*,
    76                                          allocator<_Slist_node_base*> >;
    77 _STLP_MOVE_TO_STD_NAMESPACE
    78 #  endif
    79 
    80 #  if defined (_STLP_DEBUG)
    81 _STLP_MOVE_TO_PRIV_NAMESPACE
    82 #    define _STLP_NON_DBG_VECTOR _STLP_NON_DBG_NAME(vector)
    83 _STLP_EXPORT_TEMPLATE_CLASS __construct_checker<_STLP_NON_DBG_VECTOR<_Slist_node_base*, allocator<_Slist_node_base*> > >;
    84 _STLP_EXPORT_TEMPLATE_CLASS _STLP_NON_DBG_VECTOR<_Slist_node_base*, allocator<_Slist_node_base*> >;
    85 #    undef _STLP_NON_DBG_VECTOR
    86 _STLP_MOVE_TO_STD_NAMESPACE
    87 #  endif
    88 
    89 _STLP_EXPORT_TEMPLATE_CLASS vector<_STLP_PRIV _Slist_node_base*,
    90                                    allocator<_STLP_PRIV _Slist_node_base*> >;
    91 #endif
    92 
    93 #if defined (_STLP_DEBUG)
    94 #  define hashtable _STLP_NON_DBG_NAME(hashtable)
    95 _STLP_MOVE_TO_PRIV_NAMESPACE
    96 #endif
    97 
    98 // some compilers require the names of template parameters to be the same
    99 template <class _Val, class _Key, class _HF,
   100           class _Traits, class _ExK, class _EqK, class _All>
   101 class hashtable;
   102 
   103 #if !defined (_STLP_DEBUG)
   104 _STLP_MOVE_TO_PRIV_NAMESPACE
   105 #endif
   106 
   107 template <class _BaseIte, class _Traits>
   108 struct _Ht_iterator {
   109   typedef typename _Traits::_ConstTraits _ConstTraits;
   110   typedef typename _Traits::_NonConstTraits _NonConstTraits;
   111 
   112   typedef _Ht_iterator<_BaseIte,_Traits> _Self;
   113 
   114   typedef typename _Traits::value_type value_type;
   115   typedef typename _Traits::pointer pointer;
   116   typedef typename _Traits::reference reference;
   117   typedef forward_iterator_tag iterator_category;
   118   typedef ptrdiff_t difference_type;
   119   typedef size_t size_type;
   120 
   121   typedef _Ht_iterator<_BaseIte, _NonConstTraits> iterator;
   122   typedef _Ht_iterator<_BaseIte, _ConstTraits> const_iterator;
   123 
   124   _Ht_iterator() {}
   125   //copy constructor for iterator and constructor from iterator for const_iterator
   126   _Ht_iterator(const iterator& __it) : _M_ite(__it._M_ite) {}
   127   _Ht_iterator(_BaseIte __it) : _M_ite(__it) {}
   128 
   129   reference operator*() const {
   130     return *_M_ite;
   131   }
   132   _STLP_DEFINE_ARROW_OPERATOR
   133 
   134   _Self& operator++() {
   135     ++_M_ite;
   136     return *this;
   137   }
   138   _Self operator++(int) {
   139     _Self __tmp = *this;
   140     ++*this;
   141     return __tmp;
   142   }
   143 
   144   bool operator == (const_iterator __rhs) const {
   145     return _M_ite == __rhs._M_ite;
   146   }
   147   bool operator != (const_iterator __rhs) const {
   148     return _M_ite != __rhs._M_ite;
   149   }
   150 
   151   _BaseIte _M_ite;
   152 };
   153 
   154 _STLP_MOVE_TO_STD_NAMESPACE
   155 
   156 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
   157 template <class _BaseIte, class _Traits>
   158 struct __type_traits<_STLP_PRIV _Ht_iterator<_BaseIte, _Traits> > {
   159   typedef __false_type   has_trivial_default_constructor;
   160   typedef __true_type    has_trivial_copy_constructor;
   161   typedef __true_type    has_trivial_assignment_operator;
   162   typedef __true_type    has_trivial_destructor;
   163   typedef __false_type   is_POD_type;
   164 };
   165 #endif /* _STLP_CLASS_PARTIAL_SPECIALIZATION */
   166 
   167 #if defined (_STLP_USE_OLD_HP_ITERATOR_QUERIES)
   168 template <class _BaseIte, class _Traits>
   169 inline
   170 #  if defined (_STLP_NESTED_TYPE_PARAM_BUG)
   171 _STLP_TYPENAME_ON_RETURN_TYPE _Traits::value_type *
   172 #  else
   173 _STLP_TYPENAME_ON_RETURN_TYPE _STLP_PRIV _Ht_iterator<_BaseIte,_Traits>::value_type *
   174 #  endif
   175 value_type(const _STLP_PRIV _Ht_iterator<_BaseIte,_Traits>&) {
   176   typedef typename _STLP_PRIV _Ht_iterator<_BaseIte,_Traits>::value_type _Val;
   177   return (_Val*) 0;
   178 }
   179 template <class _BaseIte, class _Traits>
   180 inline forward_iterator_tag iterator_category(const _STLP_PRIV _Ht_iterator<_BaseIte,_Traits>&)
   181 { return forward_iterator_tag(); }
   182 template <class _BaseIte, class _Traits>
   183 inline ptrdiff_t* distance_type(const _STLP_PRIV _Ht_iterator<_BaseIte,_Traits>&)
   184 { return (ptrdiff_t*) 0; }
   185 #endif
   186 
   187 _STLP_MOVE_TO_PRIV_NAMESPACE
   188 
   189 template <class _Dummy>
   190 class _Stl_prime {
   191 public:
   192   //Returns the maximum number of buckets handled by the hashtable implementation
   193   static size_t _STLP_CALL _S_max_nb_buckets();
   194 
   195   //Returns the bucket size next to a required size
   196   static size_t _STLP_CALL _S_next_size(size_t);
   197 };
   198 
   199 #if defined (_STLP_USE_TEMPLATE_EXPORT)
   200 _STLP_EXPORT_TEMPLATE_CLASS _Stl_prime<bool>;
   201 #endif
   202 
   203 typedef _Stl_prime<bool> _Stl_prime_type;
   204 
   205 #if !defined (_STLP_DEBUG)
   206 _STLP_MOVE_TO_STD_NAMESPACE
   207 #endif
   208 
   209 /*
   210  * Hashtables handle allocators a bit differently than other containers
   211  * do. If we're using standard-conforming allocators, then a hashtable
   212  * unconditionally has a member variable to hold its allocator, even if
   213  * it so happens that all instances of the allocator type are identical.
   214  * This is because, for hashtables, this extra storage is negligible.
   215  * Additionally, a base class wouldn't serve any other purposes; it
   216  * wouldn't, for example, simplify the exception-handling code.
   217  */
   218 template <class _Val, class _Key, class _HF,
   219           class _Traits, class _ExK, class _EqK, class _All>
   220 class hashtable {
   221   typedef hashtable<_Val, _Key, _HF, _Traits, _ExK, _EqK, _All> _Self;
   222   typedef typename _Traits::_NonConstTraits _NonConstTraits;
   223   typedef typename _Traits::_ConstTraits _ConstTraits;
   224   typedef typename _Traits::_NonConstLocalTraits _NonConstLocalTraits;
   225   typedef typename _Traits::_ConstLocalTraits _ConstLocalTraits;
   226 
   227 public:
   228   typedef _Key key_type;
   229   typedef _Val value_type;
   230   typedef _HF hasher;
   231   typedef _EqK key_equal;
   232 
   233   typedef size_t            size_type;
   234   typedef ptrdiff_t         difference_type;
   235   typedef typename _NonConstTraits::pointer pointer;
   236   typedef const value_type* const_pointer;
   237   typedef typename _NonConstTraits::reference reference;
   238   typedef const value_type& const_reference;
   239   typedef forward_iterator_tag _Iterator_category;
   240 
   241   hasher hash_funct() const { return _M_hash; }
   242   key_equal key_eq() const { return _M_equals; }
   243 
   244 private:
   245   _STLP_FORCE_ALLOCATORS(_Val, _All)
   246 #if defined (_STLP_DEBUG)
   247   typedef _STLP_PRIV _STLP_NON_DBG_NAME(slist)<value_type, _All> _ElemsCont;
   248 #else
   249   typedef slist<value_type, _All> _ElemsCont;
   250 #endif
   251   typedef typename _ElemsCont::iterator _ElemsIte;
   252   typedef typename _ElemsCont::const_iterator _ElemsConstIte;
   253   typedef _STLP_PRIV _Slist_node_base _BucketType;
   254   typedef typename _Alloc_traits<_BucketType*, _All>::allocator_type _M_bucket_allocator_type;
   255   /*
   256    * We are going to use vector of _Slist_node_base pointers for 2 reasons:
   257    *  - limit code bloat, all hashtable instanciation use the same buckets representation.
   258    *  - avoid _STLP_DEBUG performance trouble: with a vector of iterator on slist the resize
   259    *    method would be too slow because the slist::splice_after method become linear on
   260    *    the number of iterators in the buckets rather than constant in time as the iterator
   261    *    has to be move from a slist to the other.
   262    */
   263 #if defined (_STLP_DEBUG)
   264   typedef _STLP_PRIV _STLP_NON_DBG_NAME(vector)<_BucketType*, _M_bucket_allocator_type> _BucketVector;
   265 #else
   266   typedef vector<_BucketType*, _M_bucket_allocator_type> _BucketVector;
   267 #endif
   268 
   269   hasher                _M_hash;
   270   key_equal             _M_equals;
   271   _ExK                  _M_get_key;
   272   _ElemsCont            _M_elems;
   273   _BucketVector         _M_buckets;
   274   size_type             _M_num_elements;
   275   float                 _M_max_load_factor;
   276   _STLP_KEY_TYPE_FOR_CONT_EXT(key_type)
   277 
   278 public:
   279   typedef _STLP_PRIV _Ht_iterator<_ElemsIte, _NonConstTraits> iterator;
   280   typedef _STLP_PRIV _Ht_iterator<_ElemsIte, _ConstTraits> const_iterator;
   281   //TODO: Avoids this debug check and make the local_iterator different from
   282   //iterator in debug mode too.
   283 #if !defined (_STLP_DEBUG)
   284   typedef _STLP_PRIV _Ht_iterator<_ElemsIte, _NonConstLocalTraits> local_iterator;
   285   typedef _STLP_PRIV _Ht_iterator<_ElemsIte, _ConstLocalTraits> const_local_iterator;
   286 #else
   287   typedef iterator       local_iterator;
   288   typedef const_iterator const_local_iterator;
   289 #endif
   290 
   291   typedef typename _Alloc_traits<_Val, _All>::allocator_type allocator_type;
   292   allocator_type get_allocator() const { return _M_elems.get_allocator(); }
   293 
   294 #if !defined (_STLP_DONT_SUP_DFLT_PARAM)
   295   hashtable(size_type __n,
   296             const _HF&  __hf,
   297             const _EqK& __eql,
   298             const _ExK& __ext,
   299             const allocator_type& __a = allocator_type())
   300 #else
   301   hashtable(size_type __n,
   302             const _HF&  __hf,
   303             const _EqK& __eql,
   304             const _ExK& __ext)
   305     : _M_hash(__hf),
   306       _M_equals(__eql),
   307       _M_get_key(__ext),
   308       _M_elems(allocator_type()),
   309       _M_buckets(_STLP_CONVERT_ALLOCATOR(__a, _BucketType*)),
   310       _M_num_elements(0),
   311       _M_max_load_factor(1.0f)
   312   { _M_initialize_buckets(__n); }
   313 
   314   hashtable(size_type __n,
   315             const _HF&  __hf,
   316             const _EqK& __eql,
   317             const _ExK& __ext,
   318             const allocator_type& __a)
   319 #endif
   320     : _M_hash(__hf),
   321       _M_equals(__eql),
   322       _M_get_key(__ext),
   323       _M_elems(__a),
   324       _M_buckets(_STLP_CONVERT_ALLOCATOR(__a, _BucketType*)),
   325       _M_num_elements(0),
   326       _M_max_load_factor(1.0f)
   327   { _M_initialize_buckets(__n); }
   328 
   329 #if !defined (_STLP_DONT_SUP_DFLT_PARAM)
   330   hashtable(size_type __n,
   331             const _HF&    __hf,
   332             const _EqK&   __eql,
   333             const allocator_type& __a = allocator_type())
   334 #else
   335   hashtable(size_type __n,
   336             const _HF&    __hf,
   337             const _EqK&   __eql)
   338     : _M_hash(__hf),
   339       _M_equals(__eql),
   340       _M_get_key(_ExK()),
   341       _M_elems(allocator_type()),
   342       _M_buckets(_STLP_CONVERT_ALLOCATOR(__a, _BucketType*)),
   343       _M_num_elements(0),
   344       _M_max_load_factor(1.0f)
   345   { _M_initialize_buckets(__n); }
   346 
   347   hashtable(size_type __n,
   348             const _HF&    __hf,
   349             const _EqK&   __eql,
   350             const allocator_type& __a)
   351 #endif
   352     : _M_hash(__hf),
   353       _M_equals(__eql),
   354       _M_get_key(_ExK()),
   355       _M_elems(__a),
   356       _M_buckets(_STLP_CONVERT_ALLOCATOR(__a, _BucketType*)),
   357       _M_num_elements(0),
   358       _M_max_load_factor(1.0f)
   359   { _M_initialize_buckets(__n); }
   360 
   361   hashtable(const _Self& __ht)
   362     : _M_hash(__ht._M_hash),
   363       _M_equals(__ht._M_equals),
   364       _M_get_key(__ht._M_get_key),
   365       _M_elems(__ht.get_allocator()),
   366       _M_buckets(_STLP_CONVERT_ALLOCATOR(__ht.get_allocator(), _BucketType*)),
   367       _M_num_elements(0),
   368       _M_max_load_factor(1.0f)
   369   { _M_copy_from(__ht); }
   370 
   371   hashtable(__move_source<_Self> src)
   372     : _M_hash(_STLP_PRIV _AsMoveSource(src.get()._M_hash)),
   373       _M_equals(_STLP_PRIV _AsMoveSource(src.get()._M_equals)),
   374       _M_get_key(_STLP_PRIV _AsMoveSource(src.get()._M_get_key)),
   375       _M_elems(__move_source<_ElemsCont>(src.get()._M_elems)),
   376       _M_buckets(__move_source<_BucketVector>(src.get()._M_buckets)),
   377       _M_num_elements(src.get()._M_num_elements),
   378       _M_max_load_factor(src.get()._M_max_load_factor) {}
   379 
   380   _Self& operator= (const _Self& __ht) {
   381     if (&__ht != this) {
   382       clear();
   383       _M_hash = __ht._M_hash;
   384       _M_equals = __ht._M_equals;
   385       _M_get_key = __ht._M_get_key;
   386       _M_copy_from(__ht);
   387     }
   388     return *this;
   389   }
   390 
   391   ~hashtable() { clear(); }
   392 
   393   size_type size() const { return _M_num_elements; }
   394   size_type max_size() const { return size_type(-1); }
   395   bool empty() const { return size() == 0; }
   396 
   397   void swap(_Self& __ht) {
   398     _STLP_STD::swap(_M_hash, __ht._M_hash);
   399     _STLP_STD::swap(_M_equals, __ht._M_equals);
   400     _STLP_STD::swap(_M_get_key, __ht._M_get_key);
   401     _M_elems.swap(__ht._M_elems);
   402     _M_buckets.swap(__ht._M_buckets);
   403     _STLP_STD::swap(_M_num_elements, __ht._M_num_elements);
   404     _STLP_STD::swap(_M_max_load_factor, __ht._M_max_load_factor);
   405   }
   406 
   407   iterator begin() { return _M_elems.begin(); }
   408   iterator end() { return _M_elems.end(); }
   409   local_iterator begin(size_type __n) { return _ElemsIte(_M_buckets[__n]); }
   410   local_iterator end(size_type __n) { return _ElemsIte(_M_buckets[__n + 1]); }
   411 
   412   const_iterator begin() const { return __CONST_CAST(_ElemsCont&, _M_elems).begin(); }
   413   const_iterator end() const { return __CONST_CAST(_ElemsCont&, _M_elems).end(); }
   414   const_local_iterator begin(size_type __n) const { return _ElemsIte(_M_buckets[__n]); }
   415   const_local_iterator end(size_type __n) const { return _ElemsIte(_M_buckets[__n + 1]); }
   416 
   417   //static bool _STLP_CALL _M_equal (const _Self&, const _Self&);
   418 
   419 public:
   420   //The number of buckets is size() - 1 because the last bucket always contains
   421   //_M_elems.end() to make algo easier to implement.
   422   size_type bucket_count() const { return _M_buckets.size() - 1; }
   423   size_type max_bucket_count() const { return _STLP_PRIV _Stl_prime_type::_S_max_nb_buckets(); }
   424   size_type elems_in_bucket(size_type __bucket) const
   425   { return distance(_ElemsIte(_M_buckets[__bucket]), _ElemsIte(_M_buckets[__bucket + 1])); }
   426 
   427   _STLP_TEMPLATE_FOR_CONT_EXT
   428   size_type bucket(const _KT& __k) const { return _M_bkt_num_key(__k); }
   429 
   430   // hash policy
   431   float load_factor() const { return (float)size() / (float)bucket_count(); }
   432   float max_load_factor() const { return _M_max_load_factor; }
   433   void max_load_factor(float __z) { _M_max_load_factor = __z;}
   434 
   435   pair<iterator, bool> insert_unique(const value_type& __obj) {
   436     resize(_M_num_elements + 1);
   437     return insert_unique_noresize(__obj);
   438   }
   439 
   440   iterator insert_equal(const value_type& __obj) {
   441     resize(_M_num_elements + 1);
   442     return insert_equal_noresize(__obj);
   443   }
   444 
   445 protected:
   446   iterator _M_insert_noresize(size_type __n, const value_type& __obj);
   447 public:
   448   pair<iterator, bool> insert_unique_noresize(const value_type& __obj);
   449   iterator insert_equal_noresize(const value_type& __obj);
   450 
   451 #if defined (_STLP_MEMBER_TEMPLATES)
   452   template <class _InputIterator>
   453   void insert_unique(_InputIterator __f, _InputIterator __l)
   454   { insert_unique(__f, __l, _STLP_ITERATOR_CATEGORY(__f, _InputIterator)); }
   455 
   456   template <class _InputIterator>
   457   void insert_equal(_InputIterator __f, _InputIterator __l)
   458   { insert_equal(__f, __l, _STLP_ITERATOR_CATEGORY(__f, _InputIterator)); }
   459 
   460   template <class _InputIterator>
   461   void insert_unique(_InputIterator __f, _InputIterator __l,
   462                      const input_iterator_tag &) {
   463     for ( ; __f != __l; ++__f)
   464       insert_unique(*__f);
   465   }
   466 
   467   template <class _InputIterator>
   468   void insert_equal(_InputIterator __f, _InputIterator __l,
   469                     const input_iterator_tag &) {
   470     for ( ; __f != __l; ++__f)
   471       insert_equal(*__f);
   472   }
   473 
   474   template <class _ForwardIterator>
   475   void insert_unique(_ForwardIterator __f, _ForwardIterator __l,
   476                      const forward_iterator_tag &) {
   477     size_type __n = distance(__f, __l);
   478     resize(_M_num_elements + __n);
   479     for ( ; __n > 0; --__n, ++__f)
   480       insert_unique_noresize(*__f);
   481   }
   482 
   483   template <class _ForwardIterator>
   484   void insert_equal(_ForwardIterator __f, _ForwardIterator __l,
   485                     const forward_iterator_tag &) {
   486     size_type __n = distance(__f, __l);
   487     resize(_M_num_elements + __n);
   488     for ( ; __n > 0; --__n, ++__f)
   489       insert_equal_noresize(*__f);
   490   }
   491 
   492 #else /* _STLP_MEMBER_TEMPLATES */
   493   void insert_unique(const value_type* __f, const value_type* __l) {
   494     size_type __n = __l - __f;
   495     resize(_M_num_elements + __n);
   496     for ( ; __n > 0; --__n, ++__f)
   497       insert_unique_noresize(*__f);
   498   }
   499 
   500   void insert_equal(const value_type* __f, const value_type* __l) {
   501     size_type __n = __l - __f;
   502     resize(_M_num_elements + __n);
   503     for ( ; __n > 0; --__n, ++__f)
   504       insert_equal_noresize(*__f);
   505   }
   506 
   507   void insert_unique(const_iterator __f, const_iterator __l) {
   508     size_type __n = distance(__f, __l);
   509     resize(_M_num_elements + __n);
   510     for ( ; __n > 0; --__n, ++__f)
   511       insert_unique_noresize(*__f);
   512   }
   513 
   514   void insert_equal(const_iterator __f, const_iterator __l) {
   515     size_type __n = distance(__f, __l);
   516     resize(_M_num_elements + __n);
   517     for ( ; __n > 0; --__n, ++__f)
   518       insert_equal_noresize(*__f);
   519   }
   520 #endif /*_STLP_MEMBER_TEMPLATES */
   521 
   522   //reference find_or_insert(const value_type& __obj);
   523 
   524 private:
   525   _STLP_TEMPLATE_FOR_CONT_EXT
   526   _ElemsIte _M_find(const _KT& __key) const {
   527     size_type __n = _M_bkt_num_key(__key);
   528     _ElemsIte __first(_M_buckets[__n]);
   529     _ElemsIte __last(_M_buckets[__n + 1]);
   530     for ( ; (__first != __last) && !_M_equals(_M_get_key(*__first), __key); ++__first);
   531     if (__first != __last)
   532       return __first;
   533     else
   534       return __CONST_CAST(_ElemsCont&, _M_elems).end();
   535   }
   536 
   537 public:
   538   _STLP_TEMPLATE_FOR_CONT_EXT
   539   iterator find(const _KT& __key) { return _M_find(__key); }
   540   _STLP_TEMPLATE_FOR_CONT_EXT
   541   const_iterator find(const _KT& __key) const { return _M_find(__key); }
   542 
   543   _STLP_TEMPLATE_FOR_CONT_EXT
   544   size_type count(const _KT& __key) const {
   545     const size_type __n = _M_bkt_num_key(__key);
   546 
   547     _ElemsIte __cur(_M_buckets[__n]);
   548     _ElemsIte __last(_M_buckets[__n + 1]);
   549     for (; __cur != __last; ++__cur) {
   550       if (_M_equals(_M_get_key(*__cur), __key)) {
   551         size_type __result = 1;
   552         for (++__cur;
   553              __cur != __last && _M_equals(_M_get_key(*__cur), __key);
   554              ++__result, ++__cur);
   555         return __result;
   556       }
   557     }
   558     return 0;
   559   }
   560 
   561   _STLP_TEMPLATE_FOR_CONT_EXT
   562   pair<iterator, iterator> equal_range(const _KT& __key) {
   563     typedef pair<iterator, iterator> _Pii;
   564     const size_type __n = _M_bkt_num_key(__key);
   565 
   566     for (_ElemsIte __first(_M_buckets[__n]), __last(_M_buckets[__n + 1]);
   567          __first != __last; ++__first) {
   568       if (_M_equals(_M_get_key(*__first), __key)) {
   569         _ElemsIte __cur(__first);
   570         for (++__cur; (__cur != __last) && _M_equals(_M_get_key(*__cur), __key); ++__cur);
   571         return _Pii(__first, __cur);
   572       }
   573     }
   574     return _Pii(end(), end());
   575   }
   576 
   577   _STLP_TEMPLATE_FOR_CONT_EXT
   578   pair<const_iterator, const_iterator> equal_range(const _KT& __key) const {
   579     typedef pair<const_iterator, const_iterator> _Pii;
   580     const size_type __n = _M_bkt_num_key(__key);
   581 
   582     for (_ElemsIte __first(_M_buckets[__n]), __last(_M_buckets[__n + 1]);
   583          __first != __last; ++__first) {
   584       if (_M_equals(_M_get_key(*__first), __key)) {
   585         _ElemsIte __cur(__first);
   586         for (++__cur; (__cur != __last) && _M_equals(_M_get_key(*__cur), __key); ++__cur);
   587         return _Pii(__first, __cur);
   588       }
   589     }
   590     return _Pii(end(), end());
   591   }
   592 
   593   size_type erase(const key_type& __key);
   594   void erase(const_iterator __it);
   595   void erase(const_iterator __first, const_iterator __last);
   596 
   597 private:
   598   void _M_rehash(size_type __num_buckets);
   599 #if defined (_STLP_DEBUG)
   600   void _M_check() const;
   601 #endif
   602 
   603 public:
   604   void rehash(size_type __num_buckets_hint);
   605   void resize(size_type __num_elements_hint);
   606   void clear();
   607 
   608   // this is for hash_map::operator[]
   609   reference _M_insert(const value_type& __obj);
   610 
   611 private:
   612   //__n is set to the first bucket that has to be modified if any
   613   //erase/insert operation is done after the returned iterator.
   614   iterator _M_before_begin(size_type &__n) const;
   615 
   616   static iterator _S_before_begin(const _ElemsCont& __elems, const _BucketVector& __buckets,
   617                                   size_type &__n);
   618 
   619   void _M_initialize_buckets(size_type __n) {
   620     const size_type __n_buckets = _STLP_PRIV _Stl_prime_type::_S_next_size(__n) + 1;
   621     _M_buckets.reserve(__n_buckets);
   622     _M_buckets.assign(__n_buckets, __STATIC_CAST(_BucketType*, 0));
   623   }
   624 
   625   _STLP_TEMPLATE_FOR_CONT_EXT
   626   size_type _M_bkt_num_key(const _KT& __key) const
   627   { return _M_bkt_num_key(__key, bucket_count()); }
   628 
   629   size_type _M_bkt_num(const value_type& __obj) const
   630   { return _M_bkt_num_key(_M_get_key(__obj)); }
   631 
   632   _STLP_TEMPLATE_FOR_CONT_EXT
   633   size_type _M_bkt_num_key(const _KT& __key, size_type __n) const
   634   { return _M_hash(__key) % __n; }
   635 
   636   size_type _M_bkt_num(const value_type& __obj, size_t __n) const
   637   { return _M_bkt_num_key(_M_get_key(__obj), __n); }
   638 
   639   void _M_copy_from(const _Self& __ht);
   640 };
   641 
   642 #if defined (_STLP_DEBUG)
   643 #  undef hashtable
   644 _STLP_MOVE_TO_STD_NAMESPACE
   645 #endif
   646 
   647 _STLP_END_NAMESPACE
   648 
   649 #if !defined (_STLP_LINK_TIME_INSTANTIATION)
   650 #  include <stl/_hashtable.c>
   651 #endif
   652 
   653 #if defined (_STLP_DEBUG)
   654 #  include <stl/debug/_hashtable.h>
   655 #endif
   656 
   657 _STLP_BEGIN_NAMESPACE
   658 
   659 #define _STLP_TEMPLATE_HEADER template <class _Val, class _Key, class _HF, class _Traits, class _ExK, class _EqK, class _All>
   660 #define _STLP_TEMPLATE_CONTAINER hashtable<_Val,_Key,_HF,_Traits,_ExK,_EqK,_All>
   661 #include <stl/_relops_hash_cont.h>
   662 #undef _STLP_TEMPLATE_CONTAINER
   663 #undef _STLP_TEMPLATE_HEADER
   664 
   665 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
   666 template <class _Val, class _Key, class _HF, class _Traits, class _ExK, class _EqK, class _All>
   667 struct __move_traits<hashtable<_Val, _Key, _HF, _Traits, _ExK, _EqK, _All> > {
   668   //Hashtables are movable:
   669   typedef __stlp_movable implemented;
   670 
   671   //Completeness depends on many template parameters, for the moment we consider it not complete:
   672   typedef __false_type complete;
   673 };
   674 #endif
   675 
   676 _STLP_END_NAMESPACE
   677 
   678 #endif /* _STLP_INTERNAL_HASHTABLE_H */
   679 
   680 // Local Variables:
   681 // mode:C++
   682 // End: