epoc32/include/tools/stlport/stl/_hashtable.c
branchSymbian3
changeset 4 837f303aceeb
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/epoc32/include/tools/stlport/stl/_hashtable.c	Wed Mar 31 12:33:34 2010 +0100
     1.3 @@ -0,0 +1,478 @@
     1.4 +/*
     1.5 + * Copyright (c) 1994
     1.6 + * Hewlett-Packard Company
     1.7 + *
     1.8 + * Copyright (c) 1996,1997
     1.9 + * Silicon Graphics Computer Systems, Inc.
    1.10 + *
    1.11 + * Copyright (c) 1997
    1.12 + * Moscow Center for SPARC Technology
    1.13 + *
    1.14 + * Copyright (c) 1999
    1.15 + * Boris Fomitchev
    1.16 + *
    1.17 + * This material is provided "as is", with absolutely no warranty expressed
    1.18 + * or implied. Any use is at your own risk.
    1.19 + *
    1.20 + * Permission to use or copy this software for any purpose is hereby granted
    1.21 + * without fee, provided the above notices are retained on all copies.
    1.22 + * Permission to modify the code and to distribute modified code is granted,
    1.23 + * provided the above notices are retained, and a notice that the code was
    1.24 + * modified is included with the above copyright notice.
    1.25 + *
    1.26 + */
    1.27 +#ifndef _STLP_HASHTABLE_C
    1.28 +#define _STLP_HASHTABLE_C
    1.29 +
    1.30 +#ifndef _STLP_INTERNAL_HASHTABLE_H
    1.31 +#  include <stl/_hashtable.h>
    1.32 +#endif
    1.33 +
    1.34 +_STLP_BEGIN_NAMESPACE
    1.35 +
    1.36 +#if defined (_STLP_EXPOSE_GLOBALS_IMPLEMENTATION)
    1.37 +
    1.38 +_STLP_MOVE_TO_PRIV_NAMESPACE
    1.39 +
    1.40 +#  define __PRIME_LIST_BODY { \
    1.41 +  7ul,          23ul, \
    1.42 +  53ul,         97ul,         193ul,       389ul,       769ul,      \
    1.43 +  1543ul,       3079ul,       6151ul,      12289ul,     24593ul,    \
    1.44 +  49157ul,      98317ul,      196613ul,    393241ul,    786433ul,   \
    1.45 +  1572869ul,    3145739ul,    6291469ul,   12582917ul,  25165843ul, \
    1.46 +  50331653ul,   100663319ul,  201326611ul, 402653189ul, 805306457ul,\
    1.47 +  1610612741ul, 3221225473ul, 4294967291ul  \
    1.48 +}
    1.49 +
    1.50 +template <class _Dummy>
    1.51 +size_t _STLP_CALL
    1.52 +_Stl_prime<_Dummy>::_S_max_nb_buckets() {
    1.53 +  const size_t _list[] = __PRIME_LIST_BODY;
    1.54 +#  ifndef __MWERKS__
    1.55 +  return _list[(sizeof(_list)/sizeof(_list[0])) - 1];
    1.56 +#  else
    1.57 +  return _list[30/sizeof(size_t) - 1]; // stupid MWERKS!
    1.58 +#  endif
    1.59 +}
    1.60 +
    1.61 +template <class _Dummy>
    1.62 +size_t _STLP_CALL
    1.63 +_Stl_prime<_Dummy>::_S_next_size(size_t __n) {
    1.64 +  static const size_t _list[] = __PRIME_LIST_BODY;
    1.65 +  const size_t* __first = _list;
    1.66 +#  ifndef __MWERKS__
    1.67 +  const size_t* __last =  _list + (sizeof(_list)/sizeof(_list[0]));
    1.68 +#  else
    1.69 +  const size_t* __last =  _list + (30/sizeof(size_t)); // stupid MWERKS
    1.70 +#  endif
    1.71 +  const size_t* pos = __lower_bound(__first, __last, __n, 
    1.72 +                                    __less((size_t*)0), __less((size_t*)0), (ptrdiff_t*)0);
    1.73 +  return (pos == __last ? *(__last - 1) : *pos);
    1.74 +}
    1.75 +
    1.76 +#  undef __PRIME_LIST_BODY
    1.77 +
    1.78 +_STLP_MOVE_TO_STD_NAMESPACE
    1.79 +
    1.80 +#endif
    1.81 +
    1.82 +#if defined (_STLP_DEBUG)
    1.83 +#  define hashtable _STLP_NON_DBG_NAME(hashtable)
    1.84 +_STLP_MOVE_TO_PRIV_NAMESPACE
    1.85 +#endif
    1.86 +
    1.87 +// fbp: these defines are for outline methods definitions.
    1.88 +// needed to definitions to be portable. Should not be used in method bodies.
    1.89 +
    1.90 +#if defined ( _STLP_NESTED_TYPE_PARAM_BUG )
    1.91 +#  define __size_type__       size_t
    1.92 +#  define size_type           size_t
    1.93 +#  define value_type          _Val
    1.94 +#  define key_type            _Key
    1.95 +#  define __reference__       _Val&
    1.96 +
    1.97 +#  define __iterator__        _Ht_iterator<_Val, _STLP_HEADER_TYPENAME _Traits::_NonConstTraits, \
    1.98 +                                           _Key, _HF, _ExK, _EqK, _All>
    1.99 +#  define __const_iterator__  _Ht_iterator<_Val, _STLP_HEADER_TYPENAME _Traits::_ConstTraits, \
   1.100 +                                           _Key, _HF, _ExK, _EqK, _All>
   1.101 +#else
   1.102 +#  define __size_type__       _STLP_TYPENAME_ON_RETURN_TYPE hashtable<_Val, _Key, _HF, _Traits, _ExK, _EqK, _All>::size_type
   1.103 +#  define __reference__       _STLP_TYPENAME_ON_RETURN_TYPE  hashtable<_Val, _Key, _HF, _Traits, _ExK, _EqK, _All>::reference
   1.104 +#  define __iterator__        _STLP_TYPENAME_ON_RETURN_TYPE hashtable<_Val, _Key, _HF, _Traits, _ExK, _EqK, _All>::iterator
   1.105 +#  define __const_iterator__  _STLP_TYPENAME_ON_RETURN_TYPE hashtable<_Val, _Key, _HF, _Traits, _ExK, _EqK, _All>::const_iterator
   1.106 +#endif
   1.107 +
   1.108 +/*
   1.109 + * This method is too difficult to implement for hashtable that do not
   1.110 + * require a sorted operation on the stored type.
   1.111 +template <class _Val, class _Key, class _HF,
   1.112 +          class _Traits, class _ExK, class _EqK, class _All>
   1.113 +bool hashtable<_Val,_Key,_HF,_Traits,_ExK,_EqK,_All>::_M_equal(
   1.114 +              const hashtable<_Val,_Key,_HF,_Traits,_ExK,_EqK,_All>& __ht1,
   1.115 +              const hashtable<_Val,_Key,_HF,_Traits,_ExK,_EqK,_All>& __ht2) {
   1.116 +  return __ht1._M_buckets == __ht2._M_buckets &&
   1.117 +         __ht1._M_elems == __ht2._M_elems;
   1.118 +}
   1.119 +*/
   1.120 +
   1.121 +/* Returns the iterator before the first iterator of the bucket __n and set
   1.122 + * __n to the first previous bucket having the same first iterator as bucket
   1.123 + * __n.
   1.124 + */
   1.125 +template <class _Val, class _Key, class _HF,
   1.126 +          class _Traits, class _ExK, class _EqK, class _All>
   1.127 +__iterator__
   1.128 +hashtable<_Val,_Key,_HF,_Traits,_ExK,_EqK,_All>
   1.129 +  ::_M_before_begin(size_type &__n) const {
   1.130 +  return _S_before_begin(_M_elems, _M_buckets, __n);
   1.131 +}
   1.132 +
   1.133 +template <class _Val, class _Key, class _HF,
   1.134 +          class _Traits, class _ExK, class _EqK, class _All>
   1.135 +__iterator__
   1.136 +hashtable<_Val,_Key,_HF,_Traits,_ExK,_EqK,_All>
   1.137 +  ::_S_before_begin(const _ElemsCont& __elems, const _BucketVector& __buckets,
   1.138 +                    size_type &__n) {
   1.139 +  _ElemsCont &__mutable_elems = __CONST_CAST(_ElemsCont&, __elems);
   1.140 +  typename _BucketVector::const_iterator __bpos(__buckets.begin() + __n);
   1.141 +
   1.142 +  _ElemsIte __pos(*__bpos);
   1.143 +  if (__pos == __mutable_elems.begin()) {
   1.144 +    __n = 0;
   1.145 +    return __mutable_elems.before_begin();
   1.146 +  }
   1.147 +
   1.148 +  typename _BucketVector::const_iterator __bcur(__bpos);
   1.149 +  _BucketType *__pos_node = __pos._M_node;
   1.150 +  for (--__bcur; __pos_node == *__bcur; --__bcur);
   1.151 +
   1.152 +  __n = __bcur - __buckets.begin() + 1;
   1.153 +  _ElemsIte __cur(*__bcur);
   1.154 +  _ElemsIte __prev = __cur++;
   1.155 +  for (; __cur != __pos; ++__prev, ++__cur);
   1.156 +  return __prev;
   1.157 +}
   1.158 +
   1.159 +
   1.160 +template <class _Val, class _Key, class _HF,
   1.161 +          class _Traits, class _ExK, class _EqK, class _All>
   1.162 +__iterator__
   1.163 +hashtable<_Val,_Key,_HF,_Traits,_ExK,_EqK,_All>
   1.164 +  ::_M_insert_noresize(size_type __n, const value_type& __obj) {
   1.165 +  //We always insert this element as 1st in the bucket to not break
   1.166 +  //the elements order as equal elements must be kept next to each other.
   1.167 +  size_type __prev = __n;
   1.168 +  _ElemsIte __pos = _M_before_begin(__prev)._M_ite;
   1.169 +
   1.170 +  fill(_M_buckets.begin() + __prev, _M_buckets.begin() + __n + 1,
   1.171 +       _M_elems.insert_after(__pos, __obj)._M_node);
   1.172 +  ++_M_num_elements;
   1.173 +  return iterator(_ElemsIte(_M_buckets[__n]));
   1.174 +}
   1.175 +
   1.176 +template <class _Val, class _Key, class _HF,
   1.177 +          class _Traits, class _ExK, class _EqK, class _All>
   1.178 +pair<__iterator__, bool>
   1.179 +hashtable<_Val,_Key,_HF,_Traits,_ExK,_EqK,_All>
   1.180 +  ::insert_unique_noresize(const value_type& __obj) {
   1.181 +  const size_type __n = _M_bkt_num(__obj);
   1.182 +  _ElemsIte __cur(_M_buckets[__n]);
   1.183 +  _ElemsIte __last(_M_buckets[__n + 1]);
   1.184 +
   1.185 +  if (__cur != __last) {
   1.186 +    for (; __cur != __last; ++__cur) {
   1.187 +      if (_M_equals(_M_get_key(*__cur), _M_get_key(__obj))) {
   1.188 +        //We check that equivalent keys have equals hash code as otherwise, on resize,
   1.189 +        //equivalent value might not be in the same bucket
   1.190 +        _STLP_ASSERT(_M_hash(_M_get_key(*__cur)) == _M_hash(_M_get_key(__obj)))
   1.191 +        return pair<iterator, bool>(iterator(__cur), false);
   1.192 +      }
   1.193 +    }
   1.194 +    /* Here we do not rely on the _M_insert_noresize method as we know
   1.195 +     * that we cannot break element orders, elements are unique, and
   1.196 +     * insertion after the first bucket element is faster than what is
   1.197 +     * done in _M_insert_noresize.
   1.198 +     */
   1.199 +    __cur = _M_elems.insert_after(_ElemsIte(_M_buckets[__n]), __obj);
   1.200 +    ++_M_num_elements;
   1.201 +    return pair<iterator, bool>(iterator(__cur), true);
   1.202 +  }
   1.203 +
   1.204 +  return pair<iterator, bool>(_M_insert_noresize(__n, __obj), true);
   1.205 +}
   1.206 +
   1.207 +template <class _Val, class _Key, class _HF,
   1.208 +          class _Traits, class _ExK, class _EqK, class _All>
   1.209 +__iterator__
   1.210 +hashtable<_Val,_Key,_HF,_Traits,_ExK,_EqK,_All>
   1.211 +  ::insert_equal_noresize(const value_type& __obj) {
   1.212 +  const size_type __n = _M_bkt_num(__obj);
   1.213 +  {
   1.214 +    _ElemsIte __cur(_M_buckets[__n]);
   1.215 +    _ElemsIte __last(_M_buckets[__n + 1]);
   1.216 +
   1.217 +    for (; __cur != __last; ++__cur) {
   1.218 +      if (_M_equals(_M_get_key(*__cur), _M_get_key(__obj))) {
   1.219 +        //We check that equivalent keys have equals hash code as otherwise, on resize,
   1.220 +        //equivalent value might not be in the same bucket
   1.221 +        _STLP_ASSERT(_M_hash(_M_get_key(*__cur)) == _M_hash(_M_get_key(__obj)))
   1.222 +        ++_M_num_elements;
   1.223 +        return _M_elems.insert_after(__cur, __obj);
   1.224 +      }
   1.225 +    }
   1.226 +  }
   1.227 +
   1.228 +  return _M_insert_noresize(__n, __obj);
   1.229 +}
   1.230 +
   1.231 +template <class _Val, class _Key, class _HF,
   1.232 +          class _Traits, class _ExK, class _EqK, class _All>
   1.233 +__reference__
   1.234 +hashtable<_Val,_Key,_HF,_Traits,_ExK,_EqK,_All>
   1.235 +  ::_M_insert(const value_type& __obj) {
   1.236 +  resize(_M_num_elements + 1);
   1.237 +  return *insert_unique_noresize(__obj).first;
   1.238 +}
   1.239 +
   1.240 +/*
   1.241 +template <class _Val, class _Key, class _HF,
   1.242 +          class _Traits, class _ExK, class _EqK, class _All>
   1.243 +__reference__
   1.244 +hashtable<_Val,_Key,_HF,_Traits,_ExK,_EqK,_All>
   1.245 +  ::find_or_insert(const value_type& __obj) {
   1.246 +  _Node* __first = _M_find(_M_get_key(__obj));
   1.247 +  if (__first)
   1.248 +    return __first->_M_val;
   1.249 +  else
   1.250 +    return _M_insert(__obj);
   1.251 +}
   1.252 +*/
   1.253 +
   1.254 +template <class _Val, class _Key, class _HF,
   1.255 +          class _Traits, class _ExK, class _EqK, class _All>
   1.256 +__size_type__
   1.257 +hashtable<_Val,_Key,_HF,_Traits,_ExK,_EqK,_All>
   1.258 +  ::erase(const key_type& __key) {
   1.259 +  const size_type __n = _M_bkt_num_key(__key);
   1.260 +
   1.261 +  _ElemsIte __cur(_M_buckets[__n]);
   1.262 +  _ElemsIte __last(_M_buckets[__n + 1]);
   1.263 +  if (__cur == __last)
   1.264 +    return 0;
   1.265 +
   1.266 +  size_type __erased = 0;
   1.267 +  if (_M_equals(_M_get_key(*__cur), __key)) {
   1.268 +    //We look for the pos before __cur:
   1.269 +    size_type __prev_b = __n;
   1.270 +    _ElemsIte __prev = _M_before_begin(__prev_b)._M_ite;
   1.271 +    do {
   1.272 +      __cur = _M_elems.erase_after(__prev);
   1.273 +      ++__erased;
   1.274 +    } while ((__cur != __last) && _M_equals(_M_get_key(*__cur), __key));
   1.275 +    fill(_M_buckets.begin() + __prev_b, _M_buckets.begin() + __n + 1, __cur._M_node);
   1.276 +  }
   1.277 +  else {
   1.278 +    _ElemsIte __prev = __cur++;
   1.279 +    for (; __cur != __last; ++__prev, ++__cur) {
   1.280 +      if (_M_equals(_M_get_key(*__cur), __key)) {
   1.281 +        do {
   1.282 +          __cur = _M_elems.erase_after(__prev);
   1.283 +          ++__erased;
   1.284 +        } while ((__cur != __last) && _M_equals(_M_get_key(*__cur), __key));
   1.285 +        break;
   1.286 +      }
   1.287 +    }
   1.288 +  }
   1.289 +
   1.290 +  _M_num_elements -= __erased;
   1.291 +  return __erased;
   1.292 +}
   1.293 +
   1.294 +template <class _Val, class _Key, class _HF,
   1.295 +          class _Traits, class _ExK, class _EqK, class _All>
   1.296 +void hashtable<_Val,_Key,_HF,_Traits,_ExK,_EqK,_All>
   1.297 +  ::erase(const_iterator __it) {
   1.298 +  const size_type __n = _M_bkt_num(*__it);
   1.299 +  _ElemsIte __cur(_M_buckets[__n]);
   1.300 +
   1.301 +  if (__cur == __it._M_ite) {
   1.302 +    size_type __prev_b = __n;
   1.303 +    _ElemsIte __prev = _M_before_begin(__prev_b)._M_ite;
   1.304 +    fill(_M_buckets.begin() + __prev_b, _M_buckets.begin() + __n + 1,
   1.305 +         _M_elems.erase_after(__prev)._M_node);
   1.306 +    --_M_num_elements;
   1.307 +  }
   1.308 +  else {
   1.309 +    _ElemsIte __prev = __cur++;
   1.310 +    _ElemsIte __last(_M_buckets[__n + 1]);
   1.311 +    for (; __cur != __last; ++__prev, ++__cur) {
   1.312 +      if (__cur == __it._M_ite) {
   1.313 +        _M_elems.erase_after(__prev);
   1.314 +        --_M_num_elements;
   1.315 +        break;
   1.316 +      }
   1.317 +    }
   1.318 +  }
   1.319 +}
   1.320 +
   1.321 +template <class _Val, class _Key, class _HF,
   1.322 +          class _Traits, class _ExK, class _EqK, class _All>
   1.323 +void hashtable<_Val,_Key,_HF,_Traits,_ExK,_EqK,_All>
   1.324 +  ::erase(const_iterator __first, const_iterator __last) {
   1.325 +  if (__first == __last)
   1.326 +    return;
   1.327 +  size_type __f_bucket = _M_bkt_num(*__first);
   1.328 +  size_type __l_bucket = __last != end() ? _M_bkt_num(*__last) : (_M_buckets.size() - 1);
   1.329 +
   1.330 +  _ElemsIte __cur(_M_buckets[__f_bucket]);
   1.331 +  _ElemsIte __prev;
   1.332 +  if (__cur == __first._M_ite) {
   1.333 +    __prev = _M_before_begin(__f_bucket)._M_ite;
   1.334 +  }
   1.335 +  else {
   1.336 +    _ElemsIte __last(_M_buckets[++__f_bucket]);
   1.337 +    __prev = __cur++;
   1.338 +    for (; (__cur != __last) && (__cur != __first._M_ite); ++__prev, ++__cur);
   1.339 +  }
   1.340 +  //We do not use the slist::erase_after method taking a range to count the
   1.341 +  //number of erased elements:
   1.342 +  while (__cur != __last._M_ite) {
   1.343 +    __cur = _M_elems.erase_after(__prev);
   1.344 +    --_M_num_elements;
   1.345 +  }
   1.346 +  fill(_M_buckets.begin() + __f_bucket, _M_buckets.begin() + __l_bucket + 1, __cur._M_node);
   1.347 +}
   1.348 +
   1.349 +template <class _Val, class _Key, class _HF,
   1.350 +          class _Traits, class _ExK, class _EqK, class _All>
   1.351 +void hashtable<_Val,_Key,_HF,_Traits,_ExK,_EqK,_All>
   1.352 +  ::rehash(size_type __num_buckets_hint) {
   1.353 +  if ((bucket_count() >= __num_buckets_hint) &&
   1.354 +      (max_load_factor() > load_factor()))
   1.355 +    return;
   1.356 +
   1.357 +  //Here if max_load_factor is lower than 1.0 the resulting value might not be representable
   1.358 +  //as a size_type. The result concerning the respect of the max_load_factor will then be
   1.359 +  //undefined.
   1.360 +  __num_buckets_hint = (max) (__num_buckets_hint, (size_type)((float)size() / max_load_factor()));
   1.361 +  size_type __num_buckets = _STLP_PRIV _Stl_prime_type::_S_next_size(__num_buckets_hint);
   1.362 +  _M_rehash(__num_buckets);
   1.363 +}
   1.364 +
   1.365 +template <class _Val, class _Key, class _HF,
   1.366 +          class _Traits, class _ExK, class _EqK, class _All>
   1.367 +void hashtable<_Val,_Key,_HF,_Traits,_ExK,_EqK,_All>
   1.368 +  ::resize(size_type __num_elements_hint) {
   1.369 +  if (((float)__num_elements_hint / (float)bucket_count() <= max_load_factor()) &&
   1.370 +      (max_load_factor() >= load_factor())) {
   1.371 +    return;
   1.372 +  }
   1.373 +
   1.374 +  size_type __num_buckets_hint = (size_type)((float)(max) (__num_elements_hint, size()) / max_load_factor());
   1.375 +  size_type __num_buckets = _STLP_PRIV _Stl_prime_type::_S_next_size(__num_buckets_hint);
   1.376 +#if defined (_STLP_DEBUG)
   1.377 +  _M_check();
   1.378 +#endif
   1.379 +  _M_rehash(__num_buckets);
   1.380 +}
   1.381 +
   1.382 +template <class _Val, class _Key, class _HF,
   1.383 +          class _Traits, class _ExK, class _EqK, class _All>
   1.384 +void hashtable<_Val,_Key,_HF,_Traits,_ExK,_EqK,_All>
   1.385 +  ::_M_rehash(size_type __num_buckets) {
   1.386 +  _ElemsCont __tmp_elems(_M_elems.get_allocator());
   1.387 +  _BucketVector __tmp(__num_buckets + 1, __STATIC_CAST(_BucketType*, 0), _M_buckets.get_allocator());
   1.388 +  _ElemsIte __cur, __last(_M_elems.end());
   1.389 +  while (!_M_elems.empty()) {
   1.390 +    __cur = _M_elems.begin();
   1.391 +    size_type __new_bucket = _M_bkt_num(*__cur, __num_buckets);
   1.392 +    _ElemsIte __ite(__cur), __before_ite(__cur);
   1.393 +    for (++__ite;
   1.394 +         __ite != __last && _M_equals(_M_get_key(*__cur), _M_get_key(*__ite));
   1.395 +         ++__ite, ++__before_ite);
   1.396 +    size_type __prev_bucket = __new_bucket;
   1.397 +    _ElemsIte  __prev = _S_before_begin(__tmp_elems, __tmp, __prev_bucket)._M_ite;
   1.398 +    __tmp_elems.splice_after(__prev, _M_elems, _M_elems.before_begin(), __before_ite);
   1.399 +    fill(__tmp.begin() + __prev_bucket, __tmp.begin() + __new_bucket + 1, __cur._M_node);
   1.400 +  }
   1.401 +  _M_elems.swap(__tmp_elems);
   1.402 +  _M_buckets.swap(__tmp);
   1.403 +}
   1.404 +
   1.405 +#if defined (_STLP_DEBUG)
   1.406 +template <class _Val, class _Key, class _HF,
   1.407 +          class _Traits, class _ExK, class _EqK, class _All>
   1.408 +void hashtable<_Val,_Key,_HF,_Traits,_ExK,_EqK,_All>::_M_check() const {
   1.409 +  //We check that hash code of stored keys haven't change and also that equivalent
   1.410 +  //relation hasn't been modified
   1.411 +  size_t __num_buckets = bucket_count();
   1.412 +  for (size_t __b = 0; __b < __num_buckets; ++__b) {
   1.413 +    _ElemsIte __cur(_M_buckets[__b]), __last(_M_buckets[__b + 1]);
   1.414 +    _ElemsIte __fst(__cur), __snd(__cur);
   1.415 +    for (; __cur != __last; ++__cur) {
   1.416 +      _STLP_ASSERT( _M_bkt_num(*__cur, __num_buckets) == __b )
   1.417 +      _STLP_ASSERT( !_M_equals(_M_get_key(*__fst), _M_get_key(*__cur)) || _M_equals(_M_get_key(*__snd), _M_get_key(*__cur)) )
   1.418 +      if (__fst != __snd)
   1.419 +        ++__fst;
   1.420 +      if (__snd != __cur)
   1.421 +        ++__snd;
   1.422 +    }
   1.423 +  }
   1.424 +}
   1.425 +#endif
   1.426 +
   1.427 +template <class _Val, class _Key, class _HF,
   1.428 +          class _Traits, class _ExK, class _EqK, class _All>
   1.429 +void hashtable<_Val,_Key,_HF,_Traits,_ExK,_EqK,_All>::clear() {
   1.430 +  _M_elems.clear();
   1.431 +  _M_buckets.assign(_M_buckets.size(), __STATIC_CAST(_BucketType*, 0));
   1.432 +  _M_num_elements = 0;
   1.433 +}
   1.434 +
   1.435 +template <class _Val, class _Key, class _HF,
   1.436 +          class _Traits, class _ExK, class _EqK, class _All>
   1.437 +void hashtable<_Val,_Key,_HF,_Traits,_ExK,_EqK,_All>
   1.438 +  ::_M_copy_from(const hashtable<_Val,_Key,_HF,_Traits,_ExK,_EqK,_All>& __ht) {
   1.439 +  _M_elems.clear();
   1.440 +  _M_elems.insert(_M_elems.end(), __ht._M_elems.begin(), __ht._M_elems.end());
   1.441 +  _M_buckets.resize(__ht._M_buckets.size());
   1.442 +  _ElemsConstIte __src(__ht._M_elems.begin()), __src_end(__ht._M_elems.end());
   1.443 +  _ElemsIte __dst(_M_elems.begin());
   1.444 +  typename _BucketVector::const_iterator __src_b(__ht._M_buckets.begin()),
   1.445 +                                         __src_end_b(__ht._M_buckets.end());
   1.446 +  typename _BucketVector::iterator __dst_b(_M_buckets.begin()), __dst_end_b(_M_buckets.end());
   1.447 +  for (; __src != __src_end; ++__src, ++__dst) {
   1.448 +    for (; __src_b != __src_end_b; ++__src_b, ++__dst_b) {
   1.449 +      if (*__src_b == __src._M_node) {
   1.450 +        *__dst_b = __dst._M_node;
   1.451 +      }
   1.452 +      else
   1.453 +        break;
   1.454 +    }
   1.455 +  }
   1.456 +  fill(__dst_b, __dst_end_b, __STATIC_CAST(_BucketType*, 0));
   1.457 +  _M_num_elements = __ht._M_num_elements;
   1.458 +  _M_max_load_factor = __ht._M_max_load_factor;
   1.459 +}
   1.460 +
   1.461 +#undef __iterator__
   1.462 +#undef const_iterator
   1.463 +#undef __size_type__
   1.464 +#undef __reference__
   1.465 +#undef size_type
   1.466 +#undef value_type
   1.467 +#undef key_type
   1.468 +#undef __stl_num_primes
   1.469 +
   1.470 +#if defined (_STLP_DEBUG)
   1.471 +#  undef hashtable
   1.472 +_STLP_MOVE_TO_STD_NAMESPACE
   1.473 +#endif
   1.474 +
   1.475 +_STLP_END_NAMESPACE
   1.476 +
   1.477 +#endif /*  _STLP_HASHTABLE_C */
   1.478 +
   1.479 +// Local Variables:
   1.480 +// mode:C++
   1.481 +// End: