Commit 3c9b5053 by Paolo Carlini Committed by Paolo Carlini

PR libstdc++/24061 (issue 6.19)

2005-10-09  Paolo Carlini  <pcarlini@suse.de>

	PR libstdc++/24061 (issue 6.19)
	* include/tr1/hashtable (struct node_const_iterator, struct
	hashtable_const_iterator): New, add const variants to enable separate
	overloadings for iterator and const_iterator in unordered_set and
	unordered_multiset (as required by issue 6.19).
	(class hashtable): Change the mutable_iterators template parameter
	to constant_iterators and adjust throughout the logic.
	(hashtable::insert(iterator, const value_type&), erase(iterator)
	erase(iterator, iterator)): New, as per issue 6.19.
	(hashtable::m_erase(node*, node**)): New, called by erase(iterator)
	and erase(const_iterator).
	(hashtable::Insert_Conv_Type): New, used by insert(iterator,
	const value_type&) and insert(const_iterator, const value_type&)
	to delegate the work to insert(const value_type&).
	* include/tr1/unordered_map (class unordered_map, unordered_multimap):
	Adjust typedefs.
	* include/tr1/unordered_set (class unordered_set, unordered_multiset):
	Likewise.
	* testsuite/tr1/6_containers/unordered/erase/24061-map.cc: New.
	* testsuite/tr1/6_containers/unordered/erase/24061-multimap.cc: New.
	* testsuite/tr1/6_containers/unordered/erase/24061-multiset.cc: New.
	* testsuite/tr1/6_containers/unordered/erase/24061-set.cc: New.
	* testsuite/tr1/6_containers/unordered/insert/24061-map.cc: New.
	* testsuite/tr1/6_containers/unordered/insert/24061-multimap.cc: New.
	* testsuite/tr1/6_containers/unordered/insert/24061-multiset.cc: New.
	* testsuite/tr1/6_containers/unordered/insert/24061-set.cc: New.

From-SVN: r105138
parent d8aa8596
2005-10-09 Paolo Carlini <pcarlini@suse.de>
PR libstdc++/24061 (issue 6.19)
* include/tr1/hashtable (struct node_const_iterator, struct
hashtable_const_iterator): New, add const variants to enable separate
overloadings for iterator and const_iterator in unordered_set and
unordered_multiset (as required by issue 6.19).
(class hashtable): Change the mutable_iterators template parameter
to constant_iterators and adjust throughout the logic.
(hashtable::insert(iterator, const value_type&), erase(iterator)
erase(iterator, iterator)): New, as per issue 6.19.
(hashtable::m_erase(node*, node**)): New, called by erase(iterator)
and erase(const_iterator).
(hashtable::Insert_Conv_Type): New, used by insert(iterator,
const value_type&) and insert(const_iterator, const value_type&)
to delegate the work to insert(const value_type&).
* include/tr1/unordered_map (class unordered_map, unordered_multimap):
Adjust typedefs.
* include/tr1/unordered_set (class unordered_set, unordered_multiset):
Likewise.
* testsuite/tr1/6_containers/unordered/erase/24061-map.cc: New.
* testsuite/tr1/6_containers/unordered/erase/24061-multimap.cc: New.
* testsuite/tr1/6_containers/unordered/erase/24061-multiset.cc: New.
* testsuite/tr1/6_containers/unordered/erase/24061-set.cc: New.
* testsuite/tr1/6_containers/unordered/insert/24061-map.cc: New.
* testsuite/tr1/6_containers/unordered/insert/24061-multimap.cc: New.
* testsuite/tr1/6_containers/unordered/insert/24061-multiset.cc: New.
* testsuite/tr1/6_containers/unordered/insert/24061-set.cc: New.
2005-10-08 Kazu Hirata <kazu@codesourcery.com> 2005-10-08 Kazu Hirata <kazu@codesourcery.com>
Merge from csl-arm-branch: Merge from csl-arm-branch:
......
...@@ -157,23 +157,22 @@ namespace Internal ...@@ -157,23 +157,22 @@ namespace Internal
const node_iterator_base<Value, cache>& y) const node_iterator_base<Value, cache>& y)
{ return x.m_cur != y.m_cur; } { 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 struct node_iterator
: public node_iterator_base<Value, cache> : public node_iterator_base<Value, cache>
{ {
typedef Value value_type; typedef Value value_type;
typedef typename IF<is_const, const Value*, Value*>::type pointer; typedef typename IF<constant_iterators, const Value*, Value*>::type
typedef typename IF<is_const, const Value&, Value&>::type reference; pointer;
typedef std::ptrdiff_t difference_type; typedef typename IF<constant_iterators, const Value&, Value&>::type
typedef std::forward_iterator_tag iterator_category; reference;
typedef std::ptrdiff_t difference_type;
typedef std::forward_iterator_tag iterator_category;
explicit explicit
node_iterator(hash_node<Value, cache>* p = 0) node_iterator(hash_node<Value, cache>* p = 0)
: node_iterator_base<Value, cache>(p) { } : node_iterator_base<Value, cache>(p) { }
node_iterator(const node_iterator<Value, false, cache>& x)
: node_iterator_base<Value, cache>(x.m_cur) { }
reference reference
operator*() const operator*() const
{ return this->m_cur->m_v; } { return this->m_cur->m_v; }
...@@ -198,6 +197,48 @@ namespace Internal ...@@ -198,6 +197,48 @@ namespace Internal
} }
}; };
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> template<typename Value, bool cache>
struct hashtable_iterator_base struct hashtable_iterator_base
{ {
...@@ -248,15 +289,17 @@ namespace Internal ...@@ -248,15 +289,17 @@ namespace Internal
const hashtable_iterator_base<Value, cache>& y) const hashtable_iterator_base<Value, cache>& y)
{ return x.m_cur_node != y.m_cur_node; } { 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 struct hashtable_iterator
: public hashtable_iterator_base<Value, cache> : public hashtable_iterator_base<Value, cache>
{ {
typedef Value value_type; typedef Value value_type;
typedef typename IF<is_const, const Value*, Value*>::type pointer; typedef typename IF<constant_iterators, const Value*, Value*>::type
typedef typename IF<is_const, const Value&, Value&>::type reference; pointer;
typedef std::ptrdiff_t difference_type; typedef typename IF<constant_iterators, const Value&, Value&>::type
typedef std::forward_iterator_tag iterator_category; reference;
typedef std::ptrdiff_t difference_type;
typedef std::forward_iterator_tag iterator_category;
hashtable_iterator(hash_node<Value, cache>* p, hashtable_iterator(hash_node<Value, cache>* p,
hash_node<Value, cache>** b) hash_node<Value, cache>** b)
...@@ -266,9 +309,6 @@ namespace Internal ...@@ -266,9 +309,6 @@ namespace Internal
hashtable_iterator(hash_node<Value, cache>** b) hashtable_iterator(hash_node<Value, cache>** b)
: hashtable_iterator_base<Value, cache>(*b, 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 reference
operator*() const operator*() const
{ return this->m_cur_node->m_v; } { return this->m_cur_node->m_v; }
...@@ -292,6 +332,50 @@ namespace Internal ...@@ -292,6 +332,50 @@ namespace Internal
return tmp; } 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 } // namespace Internal
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
...@@ -843,10 +927,9 @@ namespace tr1 ...@@ -843,10 +927,9 @@ namespace tr1
// Storing it may improve lookup speed by reducing the number of times // Storing it may improve lookup speed by reducing the number of times
// we need to call the Equal function. // we need to call the Equal function.
// mutable_iterators: bool. true if hashtable::iterator is a mutable // constant_iterators: bool. true if iterator and const_iterator are
// iterator, false if iterator and const_iterator are both const // both constant iterator types. This is true for unordered_set and
// iterators. This is true for unordered_map and unordered_multimap, // unordered_multiset, false for unordered_map and unordered_multimap.
// false for unordered_set and unordered_multiset.
// unique_keys: bool. true if the return value of hashtable::count(k) // 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 // is always at most one, false if it may be an arbitrary number. This
...@@ -859,20 +942,20 @@ namespace tr1 ...@@ -859,20 +942,20 @@ namespace tr1
typename H1, typename H2, typename H1, typename H2,
typename H, typename RehashPolicy, typename H, typename RehashPolicy,
bool cache_hash_code, bool cache_hash_code,
bool mutable_iterators, bool constant_iterators,
bool unique_keys> bool unique_keys>
class hashtable class hashtable
: public Internal::rehash_base<RehashPolicy, : public Internal::rehash_base<RehashPolicy,
hashtable<Key, Value, Allocator, ExtractKey, hashtable<Key, Value, Allocator, ExtractKey,
Equal, H1, H2, H, RehashPolicy, Equal, H1, H2, H, RehashPolicy,
cache_hash_code, mutable_iterators, cache_hash_code, constant_iterators,
unique_keys> >, unique_keys> >,
public Internal::hash_code_base<Key, Value, ExtractKey, Equal, H1, H2, H, public Internal::hash_code_base<Key, Value, ExtractKey, Equal, H1, H2, H,
cache_hash_code>, cache_hash_code>,
public Internal::map_base<Key, Value, ExtractKey, unique_keys, public Internal::map_base<Key, Value, ExtractKey, unique_keys,
hashtable<Key, Value, Allocator, ExtractKey, hashtable<Key, Value, Allocator, ExtractKey,
Equal, H1, H2, H, RehashPolicy, Equal, H1, H2, H, RehashPolicy,
cache_hash_code, mutable_iterators, cache_hash_code, constant_iterators,
unique_keys> > unique_keys> >
{ {
public: public:
...@@ -887,16 +970,18 @@ namespace tr1 ...@@ -887,16 +970,18 @@ namespace tr1
typedef typename Allocator::reference reference; typedef typename Allocator::reference reference;
typedef typename Allocator::const_reference const_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> cache_hash_code>
local_iterator; 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; const_local_iterator;
typedef Internal::hashtable_iterator<value_type, !mutable_iterators, typedef Internal::hashtable_iterator<value_type, constant_iterators,
cache_hash_code> cache_hash_code>
iterator; 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; const_iterator;
private: private:
...@@ -1068,6 +1153,12 @@ namespace tr1 ...@@ -1068,6 +1153,12 @@ namespace tr1
std::pair<iterator, bool>, iterator>::type std::pair<iterator, bool>, iterator>::type
Insert_Return_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* node*
find_node(node* p, const key_type& k, find_node(node* p, const key_type& k,
typename hashtable::hash_code_t c) const; typename hashtable::hash_code_t c) const;
...@@ -1085,34 +1176,48 @@ namespace tr1 ...@@ -1085,34 +1176,48 @@ namespace tr1
return this->insert(v, std::tr1::integral_constant<bool, return this->insert(v, std::tr1::integral_constant<bool,
unique_keys>()); 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) insert(const_iterator, const value_type& v)
{ return this->insert(v); } { return const_iterator(Insert_Conv_Type()(this->insert(v))); }
template<typename InIter> template<typename InIter>
void void
insert(InIter first, InIter last); insert(InIter first, InIter last);
void iterator
erase(const_iterator); erase(iterator);
const_iterator
erase(const_iterator);
size_type size_type
erase(const key_type&); erase(const key_type&);
void iterator
erase(iterator, iterator);
const_iterator
erase(const_iterator, const_iterator); erase(const_iterator, const_iterator);
void void
clear(); clear();
private:
// For erase(iterator) and erase(const_iterator).
void m_erase(node*, node**);
public: public:
// Set number of buckets to be apropriate for container of n element. // Set number of buckets to be apropriate for container of n element.
void rehash (size_type n); void rehash(size_type n);
private: private:
// Unconditionally change size of bucket array to n. // Unconditionally change size of bucket array to n.
void m_rehash (size_type n); void m_rehash(size_type n);
}; };
//---------------------------------------------------------------------- //----------------------------------------------------------------------
...@@ -1121,9 +1226,9 @@ namespace tr1 ...@@ -1121,9 +1226,9 @@ namespace tr1
template<typename K, typename V, template<typename K, typename V,
typename A, typename Ex, typename Eq, typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP, typename H1, typename H2, typename H, typename RP,
bool c, bool m, bool u> bool c, bool ci, bool u>
typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, m, u>::node* 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, m, u>:: hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
m_allocate_node(const value_type& v) m_allocate_node(const value_type& v)
{ {
node* n = m_node_allocator.allocate(1); node* n = m_node_allocator.allocate(1);
...@@ -1143,9 +1248,9 @@ namespace tr1 ...@@ -1143,9 +1248,9 @@ namespace tr1
template<typename K, typename V, template<typename K, typename V,
typename A, typename Ex, typename Eq, typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP, typename H1, typename H2, typename H, typename RP,
bool c, bool m, bool u> bool c, bool ci, bool u>
void 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) m_deallocate_node(node* n)
{ {
get_allocator().destroy(&n->m_v); get_allocator().destroy(&n->m_v);
...@@ -1155,9 +1260,9 @@ namespace tr1 ...@@ -1155,9 +1260,9 @@ namespace tr1
template<typename K, typename V, template<typename K, typename V,
typename A, typename Ex, typename Eq, typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP, typename H1, typename H2, typename H, typename RP,
bool c, bool m, bool u> bool c, bool ci, bool u>
void 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) m_deallocate_nodes(node** array, size_type n)
{ {
for (size_type i = 0; i < n; ++i) for (size_type i = 0; i < n; ++i)
...@@ -1176,9 +1281,9 @@ namespace tr1 ...@@ -1176,9 +1281,9 @@ namespace tr1
template<typename K, typename V, template<typename K, typename V,
typename A, typename Ex, typename Eq, typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP, typename H1, typename H2, typename H, typename RP,
bool c, bool m, bool u> bool c, bool ci, bool u>
typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, m, u>::node** 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, m, u>:: hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
m_allocate_buckets(size_type n) m_allocate_buckets(size_type n)
{ {
bucket_allocator_t alloc(m_node_allocator); bucket_allocator_t alloc(m_node_allocator);
...@@ -1194,9 +1299,9 @@ namespace tr1 ...@@ -1194,9 +1299,9 @@ namespace tr1
template<typename K, typename V, template<typename K, typename V,
typename A, typename Ex, typename Eq, typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP, typename H1, typename H2, typename H, typename RP,
bool c, bool m, bool u> bool c, bool ci, bool u>
void 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) m_deallocate_buckets(node** p, size_type n)
{ {
bucket_allocator_t alloc(m_node_allocator); bucket_allocator_t alloc(m_node_allocator);
...@@ -1206,8 +1311,8 @@ namespace tr1 ...@@ -1206,8 +1311,8 @@ namespace tr1
template<typename K, typename V, template<typename K, typename V,
typename A, typename Ex, typename Eq, typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP, typename H1, typename H2, typename H, typename RP,
bool c, bool m, bool u> bool c, bool ci, 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, ci, u>::
hashtable(size_type bucket_hint, hashtable(size_type bucket_hint,
const H1& h1, const H2& h2, const H& h, const H1& h1, const H2& h2, const H& h,
const Eq& eq, const Ex& exk, const Eq& eq, const Ex& exk,
...@@ -1227,9 +1332,9 @@ namespace tr1 ...@@ -1227,9 +1332,9 @@ namespace tr1
template<typename K, typename V, template<typename K, typename V,
typename A, typename Ex, typename Eq, typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP, typename H1, typename H2, typename H, typename RP,
bool c, bool m, bool u> bool c, bool ci, bool u>
template<typename InIter> 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, hashtable(InIter f, InIter l,
size_type bucket_hint, size_type bucket_hint,
const H1& h1, const H2& h2, const H& h, const H1& h1, const H2& h2, const H& h,
...@@ -1265,8 +1370,8 @@ namespace tr1 ...@@ -1265,8 +1370,8 @@ namespace tr1
template<typename K, typename V, template<typename K, typename V,
typename A, typename Ex, typename Eq, typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP, typename H1, typename H2, typename H, typename RP,
bool c, bool m, bool u> bool c, bool ci, 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, ci, u>::
hashtable(const hashtable& ht) hashtable(const hashtable& ht)
: Internal::rehash_base<RP, hashtable>(ht), : Internal::rehash_base<RP, hashtable>(ht),
Internal::hash_code_base<K, V, Ex, Eq, H1, H2, H, c>(ht), Internal::hash_code_base<K, V, Ex, Eq, H1, H2, H, c>(ht),
...@@ -1303,9 +1408,9 @@ namespace tr1 ...@@ -1303,9 +1408,9 @@ namespace tr1
template<typename K, typename V, template<typename K, typename V,
typename A, typename Ex, typename Eq, typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP, typename H1, typename H2, typename H, typename RP,
bool c, bool m, bool u> bool c, bool ci, 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, ci, 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, ci, u>::
operator=(const hashtable& ht) operator=(const hashtable& ht)
{ {
hashtable tmp(ht); hashtable tmp(ht);
...@@ -1316,8 +1421,8 @@ namespace tr1 ...@@ -1316,8 +1421,8 @@ namespace tr1
template<typename K, typename V, template<typename K, typename V,
typename A, typename Ex, typename Eq, typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP, typename H1, typename H2, typename H, typename RP,
bool c, bool m, bool u> bool c, bool ci, 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, ci, u>::
~hashtable() ~hashtable()
{ {
clear(); clear();
...@@ -1327,9 +1432,9 @@ namespace tr1 ...@@ -1327,9 +1432,9 @@ namespace tr1
template<typename K, typename V, template<typename K, typename V,
typename A, typename Ex, typename Eq, typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP, typename H1, typename H2, typename H, typename RP,
bool c, bool m, bool u> bool c, bool ci, bool u>
void 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) swap(hashtable& x)
{ {
// The only base class with member variables is hash_code_base. We // The only base class with member variables is hash_code_base. We
...@@ -1348,9 +1453,9 @@ namespace tr1 ...@@ -1348,9 +1453,9 @@ namespace tr1
template<typename K, typename V, template<typename K, typename V,
typename A, typename Ex, typename Eq, typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP, typename H1, typename H2, typename H, typename RP,
bool c, bool m, bool u> bool c, bool ci, bool u>
void 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) rehash_policy(const RP& pol)
{ {
m_rehash_policy = pol; m_rehash_policy = pol;
...@@ -1362,9 +1467,9 @@ namespace tr1 ...@@ -1362,9 +1467,9 @@ namespace tr1
template<typename K, typename V, template<typename K, typename V,
typename A, typename Ex, typename Eq, typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP, typename H1, typename H2, typename H, typename RP,
bool c, bool m, bool u> bool c, bool ci, bool u>
typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, m, u>::iterator 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, m, u>:: hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
find(const key_type& k) find(const key_type& k)
{ {
typename hashtable::hash_code_t code = this->m_hash_code (k); typename hashtable::hash_code_t code = this->m_hash_code (k);
...@@ -1376,9 +1481,9 @@ namespace tr1 ...@@ -1376,9 +1481,9 @@ namespace tr1
template<typename K, typename V, template<typename K, typename V,
typename A, typename Ex, typename Eq, typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP, typename H1, typename H2, typename H, typename RP,
bool c, bool m, bool u> bool c, bool ci, bool u>
typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, m, u>::const_iterator 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, m, u>:: hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
find(const key_type& k) const find(const key_type& k) const
{ {
typename hashtable::hash_code_t code = this->m_hash_code (k); typename hashtable::hash_code_t code = this->m_hash_code (k);
...@@ -1390,9 +1495,9 @@ namespace tr1 ...@@ -1390,9 +1495,9 @@ namespace tr1
template<typename K, typename V, template<typename K, typename V,
typename A, typename Ex, typename Eq, typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP, typename H1, typename H2, typename H, typename RP,
bool c, bool m, bool u> bool c, bool ci, bool u>
typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, m, u>::size_type 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, m, u>:: hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
count(const key_type& k) const count(const key_type& k) const
{ {
typename hashtable::hash_code_t code = this->m_hash_code (k); typename hashtable::hash_code_t code = this->m_hash_code (k);
...@@ -1407,12 +1512,12 @@ namespace tr1 ...@@ -1407,12 +1512,12 @@ namespace tr1
template<typename K, typename V, template<typename K, typename V,
typename A, typename Ex, typename Eq, typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP, 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, 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, typename hashtable<K, V, A, Ex, Eq, H1,
H2, H, RP, c, m, u>::iterator> H2, H, RP, c, ci, u>::iterator>
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>::
equal_range(const key_type& k) equal_range(const key_type& k)
{ {
typename hashtable::hash_code_t code = this->m_hash_code (k); typename hashtable::hash_code_t code = this->m_hash_code (k);
...@@ -1440,12 +1545,12 @@ namespace tr1 ...@@ -1440,12 +1545,12 @@ namespace tr1
template<typename K, typename V, template<typename K, typename V,
typename A, typename Ex, typename Eq, typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP, 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, 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, typename hashtable<K, V, A, Ex, Eq, H1,
H2, H, RP, c, m, u>::const_iterator> H2, H, RP, c, ci, u>::const_iterator>
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>::
equal_range(const key_type& k) const equal_range(const key_type& k) const
{ {
typename hashtable::hash_code_t code = this->m_hash_code (k); typename hashtable::hash_code_t code = this->m_hash_code (k);
...@@ -1475,9 +1580,9 @@ namespace tr1 ...@@ -1475,9 +1580,9 @@ namespace tr1
template<typename K, typename V, template<typename K, typename V,
typename A, typename Ex, typename Eq, typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP, typename H1, typename H2, typename H, typename RP,
bool c, bool m, bool u> bool c, bool ci, bool u>
typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, m, u>::node* 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, m, u>:: hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
find_node(node* p, const key_type& k, find_node(node* p, const key_type& k,
typename hashtable::hash_code_t code) const typename hashtable::hash_code_t code) const
{ {
...@@ -1491,10 +1596,10 @@ namespace tr1 ...@@ -1491,10 +1596,10 @@ namespace tr1
template<typename K, typename V, template<typename K, typename V,
typename A, typename Ex, typename Eq, typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP, 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, std::pair<typename hashtable<K, V, A, Ex, Eq, H1,
H2, H, RP, c, m, u>::iterator, bool> H2, H, RP, c, ci, u>::iterator, bool>
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(const value_type& v, std::tr1::true_type) insert(const value_type& v, std::tr1::true_type)
{ {
const key_type& k = this->m_extract(v); const key_type& k = this->m_extract(v);
...@@ -1536,9 +1641,9 @@ namespace tr1 ...@@ -1536,9 +1641,9 @@ namespace tr1
template<typename K, typename V, template<typename K, typename V,
typename A, typename Ex, typename Eq, typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP, typename H1, typename H2, typename H, typename RP,
bool c, bool m, bool u> bool c, bool ci, bool u>
typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, m, u>::iterator 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, m, u>:: hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
insert(const value_type& v, std::tr1::false_type) insert(const value_type& v, std::tr1::false_type)
{ {
std::pair<bool, std::size_t> do_rehash std::pair<bool, std::size_t> do_rehash
...@@ -1571,10 +1676,10 @@ namespace tr1 ...@@ -1571,10 +1676,10 @@ namespace tr1
template<typename K, typename V, template<typename K, typename V,
typename A, typename Ex, typename Eq, typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP, typename H1, typename H2, typename H, typename RP,
bool c, bool m, bool u> bool c, bool ci, bool u>
template<typename InIter> template<typename InIter>
void 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) insert(InIter first, InIter last)
{ {
size_type n_elt = Internal::distance_fw (first, last); size_type n_elt = Internal::distance_fw (first, last);
...@@ -1587,43 +1692,40 @@ namespace tr1 ...@@ -1587,43 +1692,40 @@ namespace tr1
this->insert (*first); 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, template<typename K, typename V,
typename A, typename Ex, typename Eq, typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP, typename H1, typename H2, typename H, typename RP,
bool c, bool m, bool u> bool c, bool ci, bool u>
void 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, m, u>:: 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) erase(const_iterator i)
{ {
node* p = i.m_cur_node; const_iterator result = i;
node* cur = *i.m_cur_bucket; ++result;
if (cur == p) m_erase(i.m_cur_node, i.m_cur_bucket);
*i.m_cur_bucket = cur->m_next; return result;
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;
} }
template<typename K, typename V, template<typename K, typename V,
typename A, typename Ex, typename Eq, typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP, typename H1, typename H2, typename H, typename RP,
bool c, bool m, bool u> bool c, bool ci, bool u>
typename hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, m, u>::size_type 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, m, u>:: hashtable<K, V, A, Ex, Eq, H1, H2, H, RP, c, ci, u>::
erase(const key_type& k) erase(const key_type& k)
{ {
typename hashtable::hash_code_t code = this->m_hash_code (k); typename hashtable::hash_code_t code = this->m_hash_code (k);
...@@ -1649,29 +1751,38 @@ namespace tr1 ...@@ -1649,29 +1751,38 @@ namespace tr1
// ??? This could be optimized by taking advantage of the bucket // ??? This could be optimized by taking advantage of the bucket
// structure, but it's not clear that it's worth doing. It probably // 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. // wouldn't even be an optimization unless the load factor is large.
template <typename K, typename V, template<typename K, typename V,
typename A, typename Ex, typename Eq, typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP, typename H1, typename H2, typename H, typename RP,
bool c, bool m, bool u> bool c, bool ci, bool u>
void 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, m, u>:: 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) erase(const_iterator first, const_iterator last)
{ {
while (first != last) while (first != last)
{ first = this->erase(first);
const_iterator next = first; return last;
++next;
this->erase(first);
first = next;
}
} }
template<typename K, typename V, template<typename K, typename V,
typename A, typename Ex, typename Eq, typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP, typename H1, typename H2, typename H, typename RP,
bool c, bool m, bool u> bool c, bool ci, bool u>
void 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() clear()
{ {
m_deallocate_nodes(m_buckets, m_bucket_count); m_deallocate_nodes(m_buckets, m_bucket_count);
...@@ -1681,9 +1792,9 @@ namespace tr1 ...@@ -1681,9 +1792,9 @@ namespace tr1
template<typename K, typename V, template<typename K, typename V,
typename A, typename Ex, typename Eq, typename A, typename Ex, typename Eq,
typename H1, typename H2, typename H, typename RP, typename H1, typename H2, typename H, typename RP,
bool c, bool m, bool u> bool c, bool ci, bool u>
void 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) m_rehash(size_type N)
{ {
node** new_array = m_allocate_buckets (N); node** new_array = m_allocate_buckets (N);
...@@ -1714,7 +1825,32 @@ namespace tr1 ...@@ -1714,7 +1825,32 @@ namespace tr1
__throw_exception_again; __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 } // Namespace std::tr1
......
...@@ -59,7 +59,7 @@ namespace tr1 ...@@ -59,7 +59,7 @@ namespace tr1
Hash, Internal::mod_range_hashing, Hash, Internal::mod_range_hashing,
Internal::default_ranged_hash, Internal::default_ranged_hash,
Internal::prime_rehash_policy, Internal::prime_rehash_policy,
cache_hash_code, true, true> cache_hash_code, false, true>
{ {
typedef hashtable <Key, std::pair<const Key, T>, typedef hashtable <Key, std::pair<const Key, T>,
Alloc, Alloc,
...@@ -67,7 +67,7 @@ namespace tr1 ...@@ -67,7 +67,7 @@ namespace tr1
Hash, Internal::mod_range_hashing, Hash, Internal::mod_range_hashing,
Internal::default_ranged_hash, Internal::default_ranged_hash,
Internal::prime_rehash_policy, Internal::prime_rehash_policy,
cache_hash_code, true, true> cache_hash_code, false, true>
Base; Base;
public: public:
...@@ -110,7 +110,7 @@ namespace tr1 ...@@ -110,7 +110,7 @@ namespace tr1
Hash, Internal::mod_range_hashing, Hash, Internal::mod_range_hashing,
Internal::default_ranged_hash, Internal::default_ranged_hash,
Internal::prime_rehash_policy, Internal::prime_rehash_policy,
cache_hash_code, true, false> cache_hash_code, false, false>
{ {
typedef hashtable <Key, std::pair<const Key, T>, typedef hashtable <Key, std::pair<const Key, T>,
Alloc, Alloc,
...@@ -118,7 +118,7 @@ namespace tr1 ...@@ -118,7 +118,7 @@ namespace tr1
Hash, Internal::mod_range_hashing, Hash, Internal::mod_range_hashing,
Internal::default_ranged_hash, Internal::default_ranged_hash,
Internal::prime_rehash_policy, Internal::prime_rehash_policy,
cache_hash_code, true, false> cache_hash_code, false, false>
Base; Base;
public: public:
......
...@@ -57,14 +57,14 @@ namespace tr1 ...@@ -57,14 +57,14 @@ namespace tr1
Hash, Internal::mod_range_hashing, Hash, Internal::mod_range_hashing,
Internal::default_ranged_hash, Internal::default_ranged_hash,
Internal::prime_rehash_policy, Internal::prime_rehash_policy,
cache_hash_code, false, true> cache_hash_code, true, true>
{ {
typedef hashtable<Value, Value, Alloc, typedef hashtable<Value, Value, Alloc,
Internal::identity<Value>, Pred, Internal::identity<Value>, Pred,
Hash, Internal::mod_range_hashing, Hash, Internal::mod_range_hashing,
Internal::default_ranged_hash, Internal::default_ranged_hash,
Internal::prime_rehash_policy, Internal::prime_rehash_policy,
cache_hash_code, false, true> cache_hash_code, true, true>
Base; Base;
public: public:
...@@ -106,14 +106,14 @@ namespace tr1 ...@@ -106,14 +106,14 @@ namespace tr1
Hash, Internal::mod_range_hashing, Hash, Internal::mod_range_hashing,
Internal::default_ranged_hash, Internal::default_ranged_hash,
Internal::prime_rehash_policy, Internal::prime_rehash_policy,
cache_hash_code, false, false> cache_hash_code, true, false>
{ {
typedef hashtable<Value, Value, Alloc, typedef hashtable<Value, Value, Alloc,
Internal::identity<Value>, Pred, Internal::identity<Value>, Pred,
Hash, Internal::mod_range_hashing, Hash, Internal::mod_range_hashing,
Internal::default_ranged_hash, Internal::default_ranged_hash,
Internal::prime_rehash_policy, Internal::prime_rehash_policy,
cache_hash_code, false, false> cache_hash_code, true, false>
Base; Base;
public: public:
......
// 2005-10-08 Paolo Carlini <pcarlini@suse.de>
//
// Copyright (C) 2005 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
// 6.3.4.4 Class template unordered_map
#include <tr1/unordered_map>
#include <string>
#include <testsuite_hooks.h>
// libstdc++/24061
void test01()
{
bool test __attribute__((unused)) = true;
typedef std::tr1::unordered_map<std::string, int> Map;
typedef Map::iterator iterator;
typedef Map::const_iterator const_iterator;
typedef Map::value_type value_type;
Map m1;
m1.insert(value_type("all the love in the world", 1));
m1.insert(value_type("you know what you are?", 2));
m1.insert(value_type("the collector", 3));
m1.insert(value_type("the hand that feeds", 4));
m1.insert(value_type("love is not enough", 5));
m1.insert(value_type("every day is exactly the same", 6));
m1.insert(value_type("with teeth", 7));
m1.insert(value_type("only", 8));
m1.insert(value_type("getting smaller", 9));
m1.insert(value_type("sunspots", 10));
VERIFY( m1.size() == 10 );
iterator it1 = m1.begin();
++it1;
iterator it2 = it1;
++it2;
iterator it3 = m1.erase(it1);
VERIFY( m1.size() == 9 );
VERIFY( it3 == it2 );
VERIFY( *it3 == *it2 );
iterator it4 = m1.begin();
++it4;
++it4;
++it4;
iterator it5 = it4;
++it5;
++it5;
iterator it6 = m1.erase(it4, it5);
VERIFY( m1.size() == 7 );
VERIFY( it6 == it5 );
VERIFY( *it6 == *it5 );
const_iterator it7 = m1.begin();
++it7;
++it7;
++it7;
const_iterator it8 = it7;
++it8;
const_iterator it9 = m1.erase(it7);
VERIFY( m1.size() == 6 );
VERIFY( it9 == it8 );
VERIFY( *it9 == *it8 );
const_iterator it10 = m1.begin();
++it10;
const_iterator it11 = it10;
++it11;
++it11;
++it11;
++it11;
const_iterator it12 = m1.erase(it10, it11);
VERIFY( m1.size() == 2 );
VERIFY( it12 == it11 );
VERIFY( *it12 == *it11 );
VERIFY( ++it12 == m1.end() );
iterator it13 = m1.erase(m1.begin(), m1.end());
VERIFY( m1.size() == 0 );
VERIFY( it13 == it12 );
VERIFY( it13 == m1.begin() );
}
int main()
{
test01();
return 0;
}
// 2005-10-08 Paolo Carlini <pcarlini@suse.de>
//
// Copyright (C) 2005 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
// 6.3.4.6 Class template unordered_multimap
#include <tr1/unordered_map>
#include <string>
#include <testsuite_hooks.h>
// libstdc++/24061
void test01()
{
bool test __attribute__((unused)) = true;
typedef std::tr1::unordered_multimap<std::string, int> Mmap;
typedef Mmap::iterator iterator;
typedef Mmap::const_iterator const_iterator;
typedef Mmap::value_type value_type;
Mmap mm1;
mm1.insert(value_type("all the love in the world", 1));
mm1.insert(value_type("you know what you are?", 2));
mm1.insert(value_type("the collector", 3));
mm1.insert(value_type("the hand that feeds", 4));
mm1.insert(value_type("love is not enough", 5));
mm1.insert(value_type("every day is exactly the same", 6));
mm1.insert(value_type("with teeth", 7));
mm1.insert(value_type("only", 8));
mm1.insert(value_type("getting smaller", 9));
mm1.insert(value_type("sunspots", 10));
mm1.insert(value_type("you know what you are?", 5));
mm1.insert(value_type("the collector", 6));
mm1.insert(value_type("the hand that feeds", 7));
VERIFY( mm1.size() == 13 );
iterator it1 = mm1.begin();
++it1;
iterator it2 = it1;
++it2;
iterator it3 = mm1.erase(it1);
VERIFY( mm1.size() == 12 );
VERIFY( it3 == it2 );
VERIFY( *it3 == *it2 );
iterator it4 = mm1.begin();
++it4;
++it4;
++it4;
iterator it5 = it4;
++it5;
++it5;
iterator it6 = mm1.erase(it4, it5);
VERIFY( mm1.size() == 10 );
VERIFY( it6 == it5 );
VERIFY( *it6 == *it5 );
const_iterator it7 = mm1.begin();
++it7;
++it7;
++it7;
const_iterator it8 = it7;
++it8;
const_iterator it9 = mm1.erase(it7);
VERIFY( mm1.size() == 9 );
VERIFY( it9 == it8 );
VERIFY( *it9 == *it8 );
const_iterator it10 = mm1.begin();
++it10;
const_iterator it11 = it10;
++it11;
++it11;
++it11;
++it11;
const_iterator it12 = mm1.erase(it10, it11);
VERIFY( mm1.size() == 5 );
VERIFY( it12 == it11 );
VERIFY( *it12 == *it11 );
iterator it13 = mm1.erase(mm1.begin(), mm1.end());
VERIFY( mm1.size() == 0 );
VERIFY( it13 == mm1.end() );
VERIFY( it13 == mm1.begin() );
}
int main()
{
test01();
return 0;
}
// 2005-10-08 Paolo Carlini <pcarlini@suse.de>
//
// Copyright (C) 2005 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
// 6.3.4.5 Class template unordered_multiset
#include <tr1/unordered_set>
#include <string>
#include <testsuite_hooks.h>
// libstdc++/24061
void test01()
{
bool test __attribute__((unused)) = true;
typedef std::tr1::unordered_multiset<std::string> Mset;
typedef Mset::iterator iterator;
typedef Mset::const_iterator const_iterator;
Mset ms1;
ms1.insert("all the love in the world");
ms1.insert("you know what you are?");
ms1.insert("the collector");
ms1.insert("the hand that feeds");
ms1.insert("love is not enough");
ms1.insert("every day is exactly the same");
ms1.insert("with teeth");
ms1.insert("only");
ms1.insert("getting smaller");
ms1.insert("sunspots");
ms1.insert("the hand that feeds");
ms1.insert("love is not enough");
ms1.insert("every day is exactly the same");
VERIFY( ms1.size() == 13 );
iterator it1 = ms1.begin();
++it1;
iterator it2 = it1;
++it2;
iterator it3 = ms1.erase(it1);
VERIFY( ms1.size() == 12 );
VERIFY( it3 == it2 );
VERIFY( *it3 == *it2 );
iterator it4 = ms1.begin();
++it4;
++it4;
++it4;
iterator it5 = it4;
++it5;
++it5;
iterator it6 = ms1.erase(it4, it5);
VERIFY( ms1.size() == 10 );
VERIFY( it6 == it5 );
VERIFY( *it6 == *it5 );
const_iterator it7 = ms1.begin();
++it7;
++it7;
++it7;
const_iterator it8 = it7;
++it8;
const_iterator it9 = ms1.erase(it7);
VERIFY( ms1.size() == 9 );
VERIFY( it9 == it8 );
VERIFY( *it9 == *it8 );
const_iterator it10 = ms1.begin();
++it10;
const_iterator it11 = it10;
++it11;
++it11;
++it11;
++it11;
const_iterator it12 = ms1.erase(it10, it11);
VERIFY( ms1.size() == 5 );
VERIFY( it12 == it11 );
VERIFY( *it12 == *it11 );
iterator it13 = ms1.erase(ms1.begin(), ms1.end());
VERIFY( ms1.size() == 0 );
VERIFY( it13 == ms1.end() );
VERIFY( it13 == ms1.begin() );
}
int main()
{
test01();
return 0;
}
// 2005-10-08 Paolo Carlini <pcarlini@suse.de>
//
// Copyright (C) 2005 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
// 6.3.4.3 Class template unordered_set
#include <tr1/unordered_set>
#include <string>
#include <testsuite_hooks.h>
// libstdc++/24061
void test01()
{
bool test __attribute__((unused)) = true;
typedef std::tr1::unordered_set<std::string> Set;
typedef Set::iterator iterator;
typedef Set::const_iterator const_iterator;
Set s1;
s1.insert("all the love in the world");
s1.insert("you know what you are?");
s1.insert("the collector");
s1.insert("the hand that feeds");
s1.insert("love is not enough");
s1.insert("every day is exactly the same");
s1.insert("with teeth");
s1.insert("only");
s1.insert("getting smaller");
s1.insert("sunspots");
VERIFY( s1.size() == 10 );
iterator it1 = s1.begin();
++it1;
iterator it2 = it1;
++it2;
iterator it3 = s1.erase(it1);
VERIFY( s1.size() == 9 );
VERIFY( it3 == it2 );
VERIFY( *it3 == *it2 );
iterator it4 = s1.begin();
++it4;
++it4;
++it4;
iterator it5 = it4;
++it5;
++it5;
iterator it6 = s1.erase(it4, it5);
VERIFY( s1.size() == 7 );
VERIFY( it6 == it5 );
VERIFY( *it6 == *it5 );
const_iterator it7 = s1.begin();
++it7;
++it7;
++it7;
const_iterator it8 = it7;
++it8;
const_iterator it9 = s1.erase(it7);
VERIFY( s1.size() == 6 );
VERIFY( it9 == it8 );
VERIFY( *it9 == *it8 );
const_iterator it10 = s1.begin();
++it10;
const_iterator it11 = it10;
++it11;
++it11;
++it11;
++it11;
const_iterator it12 = s1.erase(it10, it11);
VERIFY( s1.size() == 2 );
VERIFY( it12 == it11 );
VERIFY( *it12 == *it11 );
VERIFY( ++it12 == s1.end() );
iterator it13 = s1.erase(s1.begin(), s1.end());
VERIFY( s1.size() == 0 );
VERIFY( it13 == s1.end() );
VERIFY( it13 == s1.begin() );
}
int main()
{
test01();
return 0;
}
// 2005-10-08 Paolo Carlini <pcarlini@suse.de>
//
// Copyright (C) 2005 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
// 6.3.4.4 Class template unordered_map
#include <tr1/unordered_map>
#include <string>
#include <testsuite_hooks.h>
// libstdc++/24061
void test01()
{
bool test __attribute__((unused)) = true;
typedef std::tr1::unordered_map<std::string, int> Map;
typedef Map::iterator iterator;
typedef Map::const_iterator const_iterator;
typedef Map::value_type value_type;
Map m1;
iterator it1 = m1.insert(m1.begin(),
value_type("all the love in the world", 1));
VERIFY( m1.size() == 1 );
VERIFY( *it1 == value_type("all the love in the world", 1) );
const_iterator cit1(it1);
const_iterator cit2 = m1.insert(cit1,
value_type("you know what you are?", 2));
VERIFY( m1.size() == 2 );
VERIFY( cit2 != cit1 );
VERIFY( *cit2 == value_type("you know what you are?", 2) );
iterator it2 = m1.insert(it1, value_type("all the love in the world", 3));
VERIFY( m1.size() == 2 );
VERIFY( it2 == it1 );
VERIFY( *it2 == value_type("all the love in the world", 1) );
}
int main()
{
test01();
return 0;
}
// 2005-10-08 Paolo Carlini <pcarlini@suse.de>
//
// Copyright (C) 2005 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
// 6.3.4.6 Class template unordered_multimap
#include <tr1/unordered_map>
#include <string>
#include <testsuite_hooks.h>
// libstdc++/24061
void test01()
{
bool test __attribute__((unused)) = true;
typedef std::tr1::unordered_multimap<std::string, int> Mmap;
typedef Mmap::iterator iterator;
typedef Mmap::const_iterator const_iterator;
typedef Mmap::value_type value_type;
Mmap mm1;
iterator it1 = mm1.insert(mm1.begin(),
value_type("all the love in the world", 1));
VERIFY( mm1.size() == 1 );
VERIFY( *it1 == value_type("all the love in the world", 1) );
const_iterator cit1(it1);
const_iterator cit2 = mm1.insert(cit1,
value_type("you know what you are?", 2));
VERIFY( mm1.size() == 2 );
VERIFY( cit2 != cit1 );
VERIFY( *cit2 == value_type("you know what you are?", 2) );
iterator it2 = mm1.insert(it1, value_type("all the love in the world", 3));
VERIFY( mm1.size() == 3 );
VERIFY( it2 != it1 );
VERIFY( *it2 == value_type("all the love in the world", 3) );
}
int main()
{
test01();
return 0;
}
// 2005-10-08 Paolo Carlini <pcarlini@suse.de>
//
// Copyright (C) 2005 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
// 6.3.4.5 Class template unordered_multiset
#include <tr1/unordered_set>
#include <string>
#include <testsuite_hooks.h>
// libstdc++/24061
void test01()
{
bool test __attribute__((unused)) = true;
typedef std::tr1::unordered_multiset<std::string> Mset;
typedef Mset::iterator iterator;
typedef Mset::const_iterator const_iterator;
Mset ms1;
iterator it1 = ms1.insert(ms1.begin(), "all the love in the world");
VERIFY( ms1.size() == 1 );
VERIFY( *it1 == "all the love in the world" );
const_iterator cit1(it1);
const_iterator cit2 = ms1.insert(cit1, "you know what you are?");
VERIFY( ms1.size() == 2 );
VERIFY( cit2 != cit1 );
VERIFY( *cit2 == "you know what you are?" );
iterator it2 = ms1.insert(it1, "all the love in the world");
VERIFY( ms1.size() == 3 );
VERIFY( it2 != it1 );
VERIFY( *it2 == "all the love in the world" );
}
int main()
{
test01();
return 0;
}
// 2005-10-08 Paolo Carlini <pcarlini@suse.de>
//
// Copyright (C) 2005 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
// 6.3.4.3 Class template unordered_set
#include <tr1/unordered_set>
#include <string>
#include <testsuite_hooks.h>
// libstdc++/24061
void test01()
{
bool test __attribute__((unused)) = true;
typedef std::tr1::unordered_set<std::string> Set;
typedef Set::iterator iterator;
typedef Set::const_iterator const_iterator;
Set s1;
iterator it1 = s1.insert(s1.begin(), "all the love in the world");
VERIFY( s1.size() == 1 );
VERIFY( *it1 == "all the love in the world" );
const_iterator cit1(it1);
const_iterator cit2 = s1.insert(cit1, "you know what you are?");
VERIFY( s1.size() == 2 );
VERIFY( cit2 != cit1 );
VERIFY( *cit2 == "you know what you are?" );
iterator it2 = s1.insert(it1, "all the love in the world");
VERIFY( s1.size() == 2 );
VERIFY( it2 == it1 );
VERIFY( *it2 == "all the love in the world" );
}
int main()
{
test01();
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment