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