const node_iterator_base<Value, cache>& y)
{ return x.m_cur != y.m_cur; }
- template<typename Value, bool is_const, bool cache>
+ template<typename Value, bool constant_iterators, bool cache>
struct node_iterator
: public node_iterator_base<Value, cache>
{
- typedef Value value_type;
- typedef typename IF<is_const, const Value*, Value*>::type pointer;
- typedef typename IF<is_const, const Value&, Value&>::type reference;
- typedef std::ptrdiff_t difference_type;
- typedef std::forward_iterator_tag iterator_category;
+ typedef Value value_type;
+ typedef typename IF<constant_iterators, const Value*, Value*>::type
+ pointer;
+ typedef typename IF<constant_iterators, const Value&, Value&>::type
+ reference;
+ typedef std::ptrdiff_t difference_type;
+ typedef std::forward_iterator_tag iterator_category;
explicit
node_iterator(hash_node<Value, cache>* p = 0)
: node_iterator_base<Value, cache>(p) { }
- node_iterator(const node_iterator<Value, false, cache>& x)
- : node_iterator_base<Value, cache>(x.m_cur) { }
-
reference
operator*() const
{ return this->m_cur->m_v; }
}
};
+ template<typename Value, bool constant_iterators, bool cache>
+ struct node_const_iterator
+ : public node_iterator_base<Value, cache>
+ {
+ typedef Value value_type;
+ typedef const Value* pointer;
+ typedef const Value& reference;
+ typedef std::ptrdiff_t difference_type;
+ typedef std::forward_iterator_tag iterator_category;
+
+ explicit
+ node_const_iterator(hash_node<Value, cache>* p = 0)
+ : node_iterator_base<Value, cache>(p) { }
+
+ node_const_iterator(const node_iterator<Value, constant_iterators,
+ cache>& x)
+ : node_iterator_base<Value, cache>(x.m_cur) { }
+
+ reference
+ operator*() const
+ { return this->m_cur->m_v; }
+
+ pointer
+ operator->() const
+ { return &this->m_cur->m_v; }
+
+ node_const_iterator&
+ operator++()
+ {
+ this->incr();
+ return *this;
+ }
+
+ node_const_iterator
+ operator++(int)
+ {
+ node_const_iterator tmp(*this);
+ this->incr();
+ return tmp;
+ }
+ };
+
template<typename Value, bool cache>
struct hashtable_iterator_base
{
const hashtable_iterator_base<Value, cache>& y)
{ return x.m_cur_node != y.m_cur_node; }
- template<typename Value, bool is_const, bool cache>
+ template<typename Value, bool constant_iterators, bool cache>
struct hashtable_iterator
: public hashtable_iterator_base<Value, cache>
{
- typedef Value value_type;
- typedef typename IF<is_const, const Value*, Value*>::type pointer;
- typedef typename IF<is_const, const Value&, Value&>::type reference;
- typedef std::ptrdiff_t difference_type;
- typedef std::forward_iterator_tag iterator_category;
+ typedef Value value_type;
+ typedef typename IF<constant_iterators, const Value*, Value*>::type
+ pointer;
+ typedef typename IF<constant_iterators, const Value&, Value&>::type
+ reference;
+ typedef std::ptrdiff_t difference_type;
+ typedef std::forward_iterator_tag iterator_category;
hashtable_iterator(hash_node<Value, cache>* p,
hash_node<Value, cache>** b)
hashtable_iterator(hash_node<Value, cache>** b)
: hashtable_iterator_base<Value, cache>(*b, b) { }
- hashtable_iterator(const hashtable_iterator<Value, false, cache>& x)
- : hashtable_iterator_base<Value, cache>(x.m_cur_node, x.m_cur_bucket) { }
-
reference
operator*() const
{ return this->m_cur_node->m_v; }
return tmp; }
};
+ template<typename Value, bool constant_iterators, bool cache>
+ struct hashtable_const_iterator
+ : public hashtable_iterator_base<Value, cache>
+ {
+ typedef Value value_type;
+ typedef const Value* pointer;
+ typedef const Value& reference;
+ typedef std::ptrdiff_t difference_type;
+ typedef std::forward_iterator_tag iterator_category;
+
+ hashtable_const_iterator(hash_node<Value, cache>* p,
+ hash_node<Value, cache>** b)
+ : hashtable_iterator_base<Value, cache>(p, b) { }
+
+ explicit
+ hashtable_const_iterator(hash_node<Value, cache>** b)
+ : hashtable_iterator_base<Value, cache>(*b, b) { }
+
+ hashtable_const_iterator(const hashtable_iterator<Value,
+ constant_iterators, cache>& x)
+ : hashtable_iterator_base<Value, cache>(x.m_cur_node, x.m_cur_bucket) { }
+
+ reference
+ operator*() const
+ { return this->m_cur_node->m_v; }
+
+ pointer
+ operator->() const
+ { return &this->m_cur_node->m_v; }
+
+ hashtable_const_iterator&
+ operator++()
+ {
+ this->incr();
+ return *this;
+ }
+
+ hashtable_const_iterator
+ operator++(int)
+ {
+ hashtable_const_iterator tmp(*this);
+ this->incr();
+ return tmp; }
+ };
} // namespace Internal
// ----------------------------------------------------------------------
// Storing it may improve lookup speed by reducing the number of times
// we need to call the Equal function.
- // mutable_iterators: bool. true if hashtable::iterator is a mutable
- // iterator, false if iterator and const_iterator are both const
- // iterators. This is true for unordered_map and unordered_multimap,
- // false for unordered_set and unordered_multiset.
+ // constant_iterators: bool. true if iterator and const_iterator are
+ // both constant iterator types. This is true for unordered_set and
+ // unordered_multiset, false for unordered_map and unordered_multimap.
// unique_keys: bool. true if the return value of hashtable::count(k)
// is always at most one, false if it may be an arbitrary number. This
typename H1, typename H2,
typename H, typename RehashPolicy,
bool cache_hash_code,
- bool mutable_iterators,
+ bool constant_iterators,
bool unique_keys>
class hashtable
: public Internal::rehash_base<RehashPolicy,
hashtable<Key, Value, Allocator, ExtractKey,
Equal, H1, H2, H, RehashPolicy,
- cache_hash_code, mutable_iterators,
+ cache_hash_code, constant_iterators,
unique_keys> >,
public Internal::hash_code_base<Key, Value, ExtractKey, Equal, H1, H2, H,
cache_hash_code>,
public Internal::map_base<Key, Value, ExtractKey, unique_keys,
hashtable<Key, Value, Allocator, ExtractKey,
Equal, H1, H2, H, RehashPolicy,
- cache_hash_code, mutable_iterators,
+ cache_hash_code, constant_iterators,
unique_keys> >
{
public:
typedef typename Allocator::reference reference;
typedef typename Allocator::const_reference const_reference;
- typedef Internal::node_iterator<value_type, !mutable_iterators,
+ typedef Internal::node_iterator<value_type, constant_iterators,
cache_hash_code>
local_iterator;
- typedef Internal::node_iterator<value_type, true, cache_hash_code>
+ typedef Internal::node_const_iterator<value_type, constant_iterators,
+ cache_hash_code>
const_local_iterator;
- typedef Internal::hashtable_iterator<value_type, !mutable_iterators,
+ typedef Internal::hashtable_iterator<value_type, constant_iterators,
cache_hash_code>
iterator;
- typedef Internal::hashtable_iterator<value_type, true, cache_hash_code>
+ typedef Internal::hashtable_const_iterator<value_type, constant_iterators,
+ cache_hash_code>
const_iterator;
private:
std::pair<iterator, bool>, iterator>::type
Insert_Return_Type;
+ typedef typename Internal::IF<unique_keys,
+ Internal::extract1st<Insert_Return_Type>,
+ Internal::identity<Insert_Return_Type>
+ >::type
+ Insert_Conv_Type;
+
node*
find_node(node* p, const key_type& k,
typename hashtable::hash_code_t c) const;
return this->insert(v, std::tr1::integral_constant<bool,
unique_keys>());
}
-
- Insert_Return_Type
+
+ iterator
+ insert(iterator, const value_type& v)
+ { return iterator(Insert_Conv_Type()(this->insert(v))); }
+
+ const_iterator
insert(const_iterator, const value_type& v)
- { return this->insert(v); }
+ { return const_iterator(Insert_Conv_Type()(this->insert(v))); }
template<typename InIter>
void
insert(InIter first, InIter last);
- void
- erase(const_iterator);
+ iterator
+ erase(iterator);
+ const_iterator
+ erase(const_iterator);
+
size_type
erase(const key_type&);
-
- void
+
+ iterator
+ erase(iterator, iterator);
+
+ const_iterator
erase(const_iterator, const_iterator);
-
+
void
clear();
+
+ private:
+ // For erase(iterator) and erase(const_iterator).
+ void m_erase(node*, node**);
public:
// Set number of buckets to be apropriate for container of n element.
- void rehash (size_type n);
+ void rehash(size_type n);
private:
// Unconditionally change size of bucket array to n.
- void m_rehash (size_type n);
+ void m_rehash(size_type n);
};
//----------------------------------------------------------------------
template<typename K, typename V,
typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP,
- bool c, bool m, bool u>
- typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, m, u>::node*
- hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, m, u>::
+ bool c, bool ci, bool u>
+ typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::node*
+ hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
m_allocate_node(const value_type& v)
{
node* n = m_node_allocator.allocate(1);
template<typename K, typename V,
typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP,
- bool c, bool m, bool u>
+ bool c, bool ci, bool u>
void
- hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, m, u>::
+ hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
m_deallocate_node(node* n)
{
get_allocator().destroy(&n->m_v);
template<typename K, typename V,
typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP,
- bool c, bool m, bool u>
+ bool c, bool ci, bool u>
void
- hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, m, u>::
+ hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
m_deallocate_nodes(node** array, size_type n)
{
for (size_type i = 0; i < n; ++i)
template<typename K, typename V,
typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP,
- bool c, bool m, bool u>
- typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, m, u>::node**
- hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, m, u>::
+ bool c, bool ci, bool u>
+ typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::node**
+ hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
m_allocate_buckets(size_type n)
{
bucket_allocator_t alloc(m_node_allocator);
template<typename K, typename V,
typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP,
- bool c, bool m, bool u>
+ bool c, bool ci, bool u>
void
- hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, m, u>::
+ hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
m_deallocate_buckets(node** p, size_type n)
{
bucket_allocator_t alloc(m_node_allocator);
template<typename K, typename V,
typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP,
- bool c, bool m, bool u>
- hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, m, u>::
+ bool c, bool ci, bool u>
+ hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
hashtable(size_type bucket_hint,
const H1& h1, const H2& h2, const H& h,
const Eq& eq, const Ex& exk,
template<typename K, typename V,
typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP,
- bool c, bool m, bool u>
+ bool c, bool ci, bool u>
template<typename InIter>
- hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, m, u>::
+ hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
hashtable(InIter f, InIter l,
size_type bucket_hint,
const H1& h1, const H2& h2, const H& h,
template<typename K, typename V,
typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP,
- bool c, bool m, bool u>
- hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, m, u>::
+ bool c, bool ci, bool u>
+ hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
hashtable(const hashtable& ht)
: Internal::rehash_base<RP, hashtable>(ht),
Internal::hash_code_base<K, V, Ex, Eq, H1, H2, H, c>(ht),
template<typename K, typename V,
typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP,
- bool c, bool m, bool u>
- hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, m, u>&
- hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, m, u>::
+ bool c, bool ci, bool u>
+ hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>&
+ hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
operator=(const hashtable& ht)
{
hashtable tmp(ht);
template<typename K, typename V,
typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP,
- bool c, bool m, bool u>
- hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, m, u>::
+ bool c, bool ci, bool u>
+ hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
~hashtable()
{
clear();
template<typename K, typename V,
typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP,
- bool c, bool m, bool u>
+ bool c, bool ci, bool u>
void
- hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, m, u>::
+ hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
swap(hashtable& x)
{
// The only base class with member variables is hash_code_base. We
template<typename K, typename V,
typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP,
- bool c, bool m, bool u>
+ bool c, bool ci, bool u>
void
- hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, m, u>::
+ hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
rehash_policy(const RP& pol)
{
m_rehash_policy = pol;
template<typename K, typename V,
typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP,
- bool c, bool m, bool u>
- typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, m, u>::iterator
- hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, m, u>::
+ bool c, bool ci, bool u>
+ typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::iterator
+ hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
find(const key_type& k)
{
typename hashtable::hash_code_t code = this->m_hash_code (k);
template<typename K, typename V,
typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP,
- bool c, bool m, bool u>
- typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, m, u>::const_iterator
- hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, m, u>::
+ bool c, bool ci, bool u>
+ typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::const_iterator
+ hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
find(const key_type& k) const
{
typename hashtable::hash_code_t code = this->m_hash_code (k);
template<typename K, typename V,
typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP,
- bool c, bool m, bool u>
- typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, m, u>::size_type
- hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, m, u>::
+ bool c, bool ci, bool u>
+ typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::size_type
+ hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
count(const key_type& k) const
{
typename hashtable::hash_code_t code = this->m_hash_code (k);
template<typename K, typename V,
typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP,
- bool c, bool m, bool u>
+ bool c, bool ci, bool u>
std::pair<typename hashtable<K, V, A, Ex, Eq, H1,
- H2, H, RP, c, m, u>::iterator,
+ H2, H, RP, c, ci, u>::iterator,
typename hashtable<K, V, A, Ex, Eq, H1,
- H2, H, RP, c, m, u>::iterator>
- hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, m, u>::
+ H2, H, RP, c, ci, u>::iterator>
+ hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
equal_range(const key_type& k)
{
typename hashtable::hash_code_t code = this->m_hash_code (k);
template<typename K, typename V,
typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP,
- bool c, bool m, bool u>
+ bool c, bool ci, bool u>
std::pair<typename hashtable<K, V, A, Ex, Eq, H1,
- H2, H, RP, c, m, u>::const_iterator,
+ H2, H, RP, c, ci, u>::const_iterator,
typename hashtable<K, V, A, Ex, Eq, H1,
- H2, H, RP, c, m, u>::const_iterator>
- hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, m, u>::
+ H2, H, RP, c, ci, u>::const_iterator>
+ hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
equal_range(const key_type& k) const
{
typename hashtable::hash_code_t code = this->m_hash_code (k);
template<typename K, typename V,
typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP,
- bool c, bool m, bool u>
- typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, m, u>::node*
- hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, m, u>::
+ bool c, bool ci, bool u>
+ typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::node*
+ hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
find_node(node* p, const key_type& k,
typename hashtable::hash_code_t code) const
{
template<typename K, typename V,
typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP,
- bool c, bool m, bool u>
+ bool c, bool ci, bool u>
std::pair<typename hashtable<K, V, A, Ex, Eq, H1,
- H2, H, RP, c, m, u>::iterator, bool>
- hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, m, u>::
+ H2, H, RP, c, ci, u>::iterator, bool>
+ hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
insert(const value_type& v, std::tr1::true_type)
{
const key_type& k = this->m_extract(v);
template<typename K, typename V,
typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP,
- bool c, bool m, bool u>
- typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, m, u>::iterator
- hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, m, u>::
+ bool c, bool ci, bool u>
+ typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::iterator
+ hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
insert(const value_type& v, std::tr1::false_type)
{
std::pair<bool, std::size_t> do_rehash
template<typename K, typename V,
typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP,
- bool c, bool m, bool u>
+ bool c, bool ci, bool u>
template<typename InIter>
void
- hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, m, u>::
+ hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
insert(InIter first, InIter last)
{
size_type n_elt = Internal::distance_fw (first, last);
this->insert (*first);
}
- // XXX We're following the TR in giving this a return type of void,
- // but that ought to change. The return type should be const_iterator,
- // and it should return the iterator following the one we've erased.
- // That would simplify range erase.
template<typename K, typename V,
typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP,
- bool c, bool m, bool u>
- void
- hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, m, u>::
+ bool c, bool ci, bool u>
+ typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::iterator
+ hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
+ erase(iterator i)
+ {
+ iterator result = i;
+ ++result;
+ m_erase(i.m_cur_node, i.m_cur_bucket);
+ return result;
+ }
+
+ template<typename K, typename V,
+ typename A, typename Ex, typename Eq,
+ typename H1, typename H2, typename H, typename RP,
+ bool c, bool ci, bool u>
+ typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::const_iterator
+ hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
erase(const_iterator i)
{
- node* p = i.m_cur_node;
- node* cur = *i.m_cur_bucket;
- if (cur == p)
- *i.m_cur_bucket = cur->m_next;
- else
- {
- node* next = cur->m_next;
- while (next != p)
- {
- cur = next;
- next = cur->m_next;
- }
- cur->m_next = next->m_next;
- }
-
- m_deallocate_node (p);
- --m_element_count;
+ const_iterator result = i;
+ ++result;
+ m_erase(i.m_cur_node, i.m_cur_bucket);
+ return result;
}
template<typename K, typename V,
typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP,
- bool c, bool m, bool u>
- typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, m, u>::size_type
- hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, m, u>::
+ bool c, bool ci, bool u>
+ typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::size_type
+ hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
erase(const key_type& k)
{
typename hashtable::hash_code_t code = this->m_hash_code (k);
// ??? This could be optimized by taking advantage of the bucket
// structure, but it's not clear that it's worth doing. It probably
// wouldn't even be an optimization unless the load factor is large.
- template <typename K, typename V,
- typename A, typename Ex, typename Eq,
- typename H1, typename H2, typename H, typename RP,
- bool c, bool m, bool u>
- void
- hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, m, u>::
+ template<typename K, typename V,
+ typename A, typename Ex, typename Eq,
+ typename H1, typename H2, typename H, typename RP,
+ bool c, bool ci, bool u>
+ typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::iterator
+ hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
+ erase(iterator first, iterator last)
+ {
+ while (first != last)
+ first = this->erase(first);
+ return last;
+ }
+
+ template<typename K, typename V,
+ typename A, typename Ex, typename Eq,
+ typename H1, typename H2, typename H, typename RP,
+ bool c, bool ci, bool u>
+ typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::const_iterator
+ hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
erase(const_iterator first, const_iterator last)
{
while (first != last)
- {
- const_iterator next = first;
- ++next;
- this->erase(first);
- first = next;
- }
+ first = this->erase(first);
+ return last;
}
template<typename K, typename V,
typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP,
- bool c, bool m, bool u>
+ bool c, bool ci, bool u>
void
- hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, m, u>::
+ hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
clear()
{
m_deallocate_nodes(m_buckets, m_bucket_count);
template<typename K, typename V,
typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP,
- bool c, bool m, bool u>
+ bool c, bool ci, bool u>
void
- hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, m, u>::
+ hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
m_rehash(size_type N)
{
node** new_array = m_allocate_buckets (N);
__throw_exception_again;
}
}
-
+
+ template<typename K, typename V,
+ typename A, typename Ex, typename Eq,
+ typename H1, typename H2, typename H, typename RP,
+ bool c, bool ci, bool u>
+ void
+ hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
+ m_erase(node* p, node** b)
+ {
+ node* cur = *b;
+ if (cur == p)
+ *b = cur->m_next;
+ else
+ {
+ node* next = cur->m_next;
+ while (next != p)
+ {
+ cur = next;
+ next = cur->m_next;
+ }
+ cur->m_next = next->m_next;
+ }
+
+ m_deallocate_node (p);
+ --m_element_count;
+ }
}
} // Namespace std::tr1