📄 stl_hashtable.h
字号:
size_type _M_bkt_num(const value_type& __obj) const { return _M_bkt_num_key(_M_get_key(__obj)); } size_type _M_bkt_num_key(const key_type& __key, size_t __n) const { return _M_hash(__key) % __n; } size_type _M_bkt_num(const value_type& __obj, size_t __n) const { return _M_bkt_num_key(_M_get_key(__obj), __n); } _Node* _M_new_node(const value_type& __obj) { _Node* __n = _M_get_node(); __n->_M_next = 0; __STL_TRY { construct(&__n->_M_val, __obj); return __n; } __STL_UNWIND(_M_put_node(__n)); } void _M_delete_node(_Node* __n) { destroy(&__n->_M_val); _M_put_node(__n); } void _M_erase_bucket(const size_type __n, _Node* __first, _Node* __last); void _M_erase_bucket(const size_type __n, _Node* __last); void _M_copy_from(const hashtable& __ht);};template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>_Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&_Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++(){ const _Node* __old = _M_cur; _M_cur = _M_cur->_M_next; if (!_M_cur) { size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val); while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size()) _M_cur = _M_ht->_M_buckets[__bucket]; } return *this;}template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>inline _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>_Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++(int){ iterator __tmp = *this; ++*this; return __tmp;}template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>_Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&_Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++(){ const _Node* __old = _M_cur; _M_cur = _M_cur->_M_next; if (!_M_cur) { size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val); while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size()) _M_cur = _M_ht->_M_buckets[__bucket]; } return *this;}template <class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All>inline _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>_Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++(int){ const_iterator __tmp = *this; ++*this; return __tmp;}template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>bool operator==(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1, const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2){ typedef typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::_Node _Node; if (__ht1._M_buckets.size() != __ht2._M_buckets.size()) return false; for (size_t __n = 0; __n < __ht1._M_buckets.size(); ++__n) { _Node* __cur1 = __ht1._M_buckets[__n]; _Node* __cur2 = __ht2._M_buckets[__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 _Ex, class _Eq, class _All>inline bool operator!=(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1, const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2) { return !(__ht1 == __ht2);}template <class _Val, class _Key, class _HF, class _Extract, class _EqKey, class _All>inline void swap(hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht1, hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht2) { __ht1.swap(__ht2);}template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>pair<typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator, bool> hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> ::insert_unique_noresize(const value_type& __obj){ const size_type __n = _M_bkt_num(__obj); _Node* __first = _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; return pair<iterator, bool>(iterator(__tmp, this), true);}template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> ::insert_equal_noresize(const value_type& __obj){ const size_type __n = _M_bkt_num(__obj); _Node* __first = _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; return iterator(__tmp, this); } _Node* __tmp = _M_new_node(__obj); __tmp->_M_next = __first; _M_buckets[__n] = __tmp; ++_M_num_elements; return iterator(__tmp, this);}template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::reference hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::find_or_insert(const value_type& __obj){ resize(_M_num_elements + 1); size_type __n = _M_bkt_num(__obj); _Node* __first = _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 __cur->_M_val; _Node* __tmp = _M_new_node(__obj); __tmp->_M_next = __first; _M_buckets[__n] = __tmp; ++_M_num_elements; return __tmp->_M_val;}template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>pair<typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator, typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator> hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::equal_range(const key_type& __key){ typedef pair<iterator, iterator> _Pii; const size_type __n = _M_bkt_num_key(__key); for (_Node* __first = _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(_M_buckets[__m], this)); return _Pii(iterator(__first, this), end()); } return _Pii(end(), end());}template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>pair<typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::const_iterator, typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::const_iterator> hashtable<_Val,_Key,_HF,_Ex,_Eq,_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 = _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]) return _Pii(const_iterator(__first, this), const_iterator(_M_buckets[__m], this)); return _Pii(const_iterator(__first, this), end()); } } return _Pii(end(), end());}template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::size_type hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const key_type& __key){ const size_type __n = _M_bkt_num_key(__key); _Node* __first = _M_buckets[__n]; size_type __erased = 0; if (__first) { _Node* __cur = __first; _Node* __next = __cur->_M_next; while (__next) { if (_M_equals(_M_get_key(__next->_M_val), __key)) { __cur->_M_next = __next->_M_next; _M_delete_node(__next); __next = __cur->_M_next; ++__erased; --_M_num_elements; } else { __cur = __next; __next = __cur->_M_next; } } if (_M_equals(_M_get_key(__first->_M_val), __key)) { _M_buckets[__n] = __first->_M_next; _M_delete_node(__first); ++__erased; --_M_num_elements; } } return __erased;}template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const iterator& __it){ _Node* __p = __it._M_cur; if (__p) { const size_type __n = _M_bkt_num(__p->_M_val); _Node* __cur = _M_buckets[__n]; if (__cur == __p) { _M_buckets[__n] = __cur->_M_next; _M_delete_node(__cur); --_M_num_elements; } else { _Node* __next = __cur->_M_next; while (__next) { if (__next == __p) { __cur->_M_next = __next->_M_next; _M_delete_node(__next); --_M_num_elements; break; } else { __cur = __next; __next = __cur->_M_next; } } } }}template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> ::erase(iterator __first, iterator __last){ size_type __f_bucket = __first._M_cur ? _M_bkt_num(__first._M_cur->_M_val) : _M_buckets.size(); size_type __l_bucket = __last._M_cur ? _M_bkt_num(__last._M_cur->_M_val) : _M_buckets.size(); if (__first._M_cur == __last._M_cur) return; else if (__f_bucket == __l_bucket) _M_erase_bucket(__f_bucket, __first._M_cur, __last._M_cur); else { _M_erase_bucket(__f_bucket, __first._M_cur, 0); for (size_type __n = __f_bucket + 1; __n < __l_bucket; ++__n) _M_erase_bucket(__n, 0); if (__l_bucket != _M_buckets.size()) _M_erase_bucket(__l_bucket, __last._M_cur); }}template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>inline voidhashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const_iterator __first, const_iterator __last){ erase(iterator(const_cast<_Node*>(__first._M_cur), const_cast<hashtable*>(__first._M_ht)), iterator(const_cast<_Node*>(__last._M_cur), const_cast<hashtable*>(__last._M_ht)));}template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>inline voidhashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const const_iterator& __it){ erase(iterator(const_cast<_Node*>(__it._M_cur), const_cast<hashtable*>(__it._M_ht)));}template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> ::resize(size_type __num_elements_hint){ const size_type __old_n = _M_buckets.size(); if (__num_elements_hint > __old_n) { const size_type __n = _M_next_size(__num_elements_hint); if (__n > __old_n) { vector<_Node*, _All> __tmp(__n, (_Node*)(0), _M_buckets.get_allocator()); __STL_TRY { for (size_type __bucket = 0; __bucket < __old_n; ++__bucket) { _Node* __first = _M_buckets[__bucket]; while (__first) { size_type __new_bucket = _M_bkt_num(__first->_M_val, __n); _M_buckets[__bucket] = __first->_M_next; __first->_M_next = __tmp[__new_bucket]; __tmp[__new_bucket] = __first; __first = _M_buckets[__bucket]; } } _M_buckets.swap(__tmp); }# ifdef __STL_USE_EXCEPTIONS catch(...) { for (size_type __bucket = 0; __bucket < __tmp.size(); ++__bucket) { while (__tmp[__bucket]) { _Node* __next = __tmp[__bucket]->_M_next; _M_delete_node(__tmp[__bucket]); __tmp[__bucket] = __next; } } throw; }# endif /* __STL_USE_EXCEPTIONS */ } }}template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> ::_M_erase_bucket(const size_type __n, _Node* __first, _Node* __last){ _Node* __cur = _M_buckets[__n]; if (__cur == __first) _M_erase_bucket(__n, __last); else { _Node* __next; for (__next = __cur->_M_next; __next != __first; __cur = __next, __next = __cur->_M_next) ; while (__next != __last) { __cur->_M_next = __next->_M_next; _M_delete_node(__next); __next = __cur->_M_next; --_M_num_elements; } }}template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> ::_M_erase_bucket(const size_type __n, _Node* __last){ _Node* __cur = _M_buckets[__n]; while (__cur != __last) { _Node* __next = __cur->_M_next; _M_delete_node(__cur); __cur = __next; _M_buckets[__n] = __cur; --_M_num_elements; }}template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::clear(){ for (size_type __i = 0; __i < _M_buckets.size(); ++__i) { _Node* __cur = _M_buckets[__i]; while (__cur != 0) { _Node* __next = __cur->_M_next; _M_delete_node(__cur); __cur = __next; } _M_buckets[__i] = 0; } _M_num_elements = 0;} template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> ::_M_copy_from(const hashtable& __ht){ _M_buckets.clear(); _M_buckets.reserve(__ht._M_buckets.size()); _M_buckets.insert(_M_buckets.end(), __ht._M_buckets.size(), (_Node*) 0); __STL_TRY { for (size_type __i = 0; __i < __ht._M_buckets.size(); ++__i) { const _Node* __cur = __ht._M_buckets[__i]; if (__cur) { _Node* __local_copy = _M_new_node(__cur->_M_val); _M_buckets[__i] = __local_copy; for (_Node* __next = __cur->_M_next; __next; __cur = __next, __next = __cur->_M_next) { __local_copy->_M_next = _M_new_node(__next->_M_val); __local_copy = __local_copy->_M_next; } } } _M_num_elements = __ht._M_num_elements; } __STL_UNWIND(clear());}} // namespace std#endif /* __SGI_STL_INTERNAL_HASHTABLE_H */// Local Variables:// mode:C++// End:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -