📄 _hashtable.c
字号:
/* * * * Copyright (c) 1994 * Hewlett-Packard Company * * Copyright (c) 1996,1997 * Silicon Graphics Computer Systems, Inc. * * Copyright (c) 1997 * Moscow Center for SPARC Technology * * Copyright (c) 1999 * Boris Fomitchev * * This material is provided "as is", with absolutely no warranty expressed * or implied. Any use is at your own risk. * * Permission to use or copy this software for any purpose is hereby granted * without fee, provided the above notices are retained on all copies. * Permission to modify the code and to distribute modified code is granted, * provided the above notices are retained, and a notice that the code was * modified is included with the above copyright notice. * */#ifndef _STLP_HASHTABLE_C#define _STLP_HASHTABLE_C#ifndef _STLP_INTERNAL_HASHTABLE_H# include <stl/_hashtable.h>#endif#ifdef _STLP_DEBUG# define hashtable __WORKAROUND_DBG_RENAME(hashtable)#endif_STLP_BEGIN_NAMESPACE# define __PRIME_LIST_BODY { \ 53ul, 97ul, 193ul, 389ul, 769ul, \ 1543ul, 3079ul, 6151ul, 12289ul, 24593ul, \ 49157ul, 98317ul, 196613ul, 393241ul, 786433ul, \ 1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul, \ 50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul,\ 1610612741ul, 3221225473ul, 4294967291ul \}#if ( _STLP_STATIC_TEMPLATE_DATA > 0 )template <class _Tp>const size_t _Stl_prime<_Tp>::_M_list[__stl_num_primes] = __PRIME_LIST_BODY;#else__DECLARE_INSTANCE(const size_t, _Stl_prime_type::_M_list[], =__PRIME_LIST_BODY);#endif /* _STLP_STATIC_TEMPLATE_DATA */# undef __PRIME_LIST_BODY// fbp: these defines are for outline methods definitions.// needed to definitions to be portable. Should not be used in method bodies.# if defined ( _STLP_NESTED_TYPE_PARAM_BUG )# define __size_type__ size_t# define size_type size_t# define value_type _Val# define key_type _Key# define _Node _Hashtable_node<_Val># define __reference__ _Val&# define __iterator__ _Ht_iterator<_Val, _Nonconst_traits<_Val>, _Key, _HF, _ExK, _EqK, _All># define __const_iterator__ _Ht_iterator<_Val, _Const_traits<_Val>, _Key, _HF, _ExK, _EqK, _All># else# define __size_type__ _STLP_TYPENAME_ON_RETURN_TYPE hashtable<_Val, _Key, _HF, _ExK, _EqK, _All>::size_type# define __reference__ _STLP_TYPENAME_ON_RETURN_TYPE hashtable<_Val, _Key, _HF, _ExK, _EqK, _All>::reference# define __iterator__ _STLP_TYPENAME_ON_RETURN_TYPE hashtable<_Val, _Key, _HF, _ExK, _EqK, _All>::iterator# endiftemplate <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>_Hashtable_node<_Val>*_Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::_M_skip_to_next() { size_t __bucket = _M_ht->_M_bkt_num(_M_cur->_M_val); size_t __h_sz; __h_sz = this->_M_ht->bucket_count(); _Node* __i=0; while (__i==0 && ++__bucket < __h_sz) __i = (_Node*)_M_ht->_M_buckets[__bucket]; return __i;}template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>__size_type__hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>::_M_next_size(size_type __n) const { const size_type* __first = (const size_type*)_Stl_prime_type::_M_list; const size_type* __last = (const size_type*)_Stl_prime_type::_M_list + (int)__stl_num_primes; const size_type* pos = __lower_bound(__first, __last, __n, __less((size_type*)0), (ptrdiff_t*)0); return (pos == __last ? *(__last - 1) : *pos);}template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>bool hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>::_M_equal( const hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>& __ht1, const hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>& __ht2){ // typedef _Hashtable_node<_Val> _Node; if (__ht1.bucket_count() != __ht2.bucket_count()) return false; for (size_t __n = 0; __n < __ht1.bucket_count(); ++__n) { const _Node* __cur1 = __ht1._M_get_bucket(__n); const _Node* __cur2 = __ht2._M_get_bucket(__n); for ( ; __cur1 && __cur2 && __cur1->_M_val == __cur2->_M_val; __cur1 = __cur1->_M_next, __cur2 = __cur2->_M_next) {} if (__cur1 || __cur2) return false; } return true;} template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>pair< _Ht_iterator<_Val, _Nonconst_traits<_Val>, _Key, _HF, _ExK, _EqK, _All> , bool> hashtable<_Val,_Key,_HF,_ExK,_EqK,_All> ::insert_unique_noresize(const value_type& __obj){ const size_type __n = _M_bkt_num(__obj); _Node* __first = (_Node*)_M_buckets[__n]; for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) return pair<iterator, bool>(iterator(__cur, this), false); _Node* __tmp = _M_new_node(__obj); __tmp->_M_next = __first; _M_buckets[__n] = __tmp; ++_M_num_elements._M_data; return pair<iterator, bool>(iterator(__tmp, this), true);}template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>__iterator__ hashtable<_Val,_Key,_HF,_ExK,_EqK,_All> ::insert_equal_noresize(const value_type& __obj){ const size_type __n = _M_bkt_num(__obj); _Node* __first = (_Node*)_M_buckets[__n]; for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) { _Node* __tmp = _M_new_node(__obj); __tmp->_M_next = __cur->_M_next; __cur->_M_next = __tmp; ++_M_num_elements._M_data; return iterator(__tmp, this); } _Node* __tmp = _M_new_node(__obj); __tmp->_M_next = __first; _M_buckets[__n] = __tmp; ++_M_num_elements._M_data; return iterator(__tmp, this);}template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>__reference__ hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>::_M_insert(const value_type& __obj){ resize(_M_num_elements._M_data + 1); size_type __n = _M_bkt_num(__obj); _Node* __first = (_Node*)_M_buckets[__n]; _Node* __tmp = _M_new_node(__obj); __tmp->_M_next = __first; _M_buckets[__n] = __tmp; ++_M_num_elements._M_data; return __tmp->_M_val;}template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>__reference__ hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>::find_or_insert(const value_type& __obj){ _Node* __first = _M_find(_M_get_key(__obj)); if (__first) return __first->_M_val; else return _M_insert(__obj);}template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>pair< _Ht_iterator<_Val, _Nonconst_traits<_Val>, _Key, _HF, _ExK, _EqK, _All>, _Ht_iterator<_Val, _Nonconst_traits<_Val>, _Key, _HF, _ExK, _EqK, _All> > hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>::equal_range(const key_type& __key){ typedef pair<iterator, iterator> _Pii; const size_type __n = _M_bkt_num_key(__key); for (_Node* __first = (_Node*)_M_buckets[__n]; __first; __first = __first->_M_next) if (_M_equals(_M_get_key(__first->_M_val), __key)) { for (_Node* __cur = __first->_M_next; __cur; __cur = __cur->_M_next) if (!_M_equals(_M_get_key(__cur->_M_val), __key)) return _Pii(iterator(__first, this), iterator(__cur, this)); for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m) if (_M_buckets[__m]) return _Pii(iterator(__first, this), iterator((_Node*)_M_buckets[__m], this)); return _Pii(iterator(__first, this), end()); } return _Pii(end(), end());}template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>pair< _Ht_iterator<_Val, _Const_traits<_Val>, _Key, _HF, _ExK, _EqK, _All>, _Ht_iterator<_Val, _Const_traits<_Val>, _Key, _HF, _ExK, _EqK, _All> > hashtable<_Val,_Key,_HF,_ExK,_EqK,_All> ::equal_range(const key_type& __key) const{ typedef pair<const_iterator, const_iterator> _Pii; const size_type __n = _M_bkt_num_key(__key); for (const _Node* __first = (_Node*)_M_buckets[__n] ; __first; __first = __first->_M_next) { if (_M_equals(_M_get_key(__first->_M_val), __key)) { for (const _Node* __cur = __first->_M_next; __cur; __cur = __cur->_M_next) if (!_M_equals(_M_get_key(__cur->_M_val), __key)) return _Pii(const_iterator(__first, this), const_iterator(__cur, this)); for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m) if (_M_buckets[__m])
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -