diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 82e45c6800a0..653b0de58df4 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,32 @@ +2005-10-09 Paolo Carlini + + 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 Merge from csl-arm-branch: diff --git a/libstdc++-v3/include/tr1/hashtable b/libstdc++-v3/include/tr1/hashtable index 240c471b5208..36e33b0f418f 100644 --- a/libstdc++-v3/include/tr1/hashtable +++ b/libstdc++-v3/include/tr1/hashtable @@ -157,23 +157,22 @@ namespace Internal const node_iterator_base& y) { return x.m_cur != y.m_cur; } - template + template struct node_iterator : public node_iterator_base { - typedef Value value_type; - typedef typename IF::type pointer; - typedef typename IF::type reference; - typedef std::ptrdiff_t difference_type; - typedef std::forward_iterator_tag iterator_category; + typedef Value value_type; + typedef typename IF::type + pointer; + typedef typename IF::type + reference; + typedef std::ptrdiff_t difference_type; + typedef std::forward_iterator_tag iterator_category; explicit node_iterator(hash_node* p = 0) : node_iterator_base(p) { } - node_iterator(const node_iterator& x) - : node_iterator_base(x.m_cur) { } - reference operator*() const { return this->m_cur->m_v; } @@ -198,6 +197,48 @@ namespace Internal } }; + template + struct node_const_iterator + : public node_iterator_base + { + 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* p = 0) + : node_iterator_base(p) { } + + node_const_iterator(const node_iterator& x) + : node_iterator_base(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 struct hashtable_iterator_base { @@ -248,15 +289,17 @@ namespace Internal const hashtable_iterator_base& y) { return x.m_cur_node != y.m_cur_node; } - template + template struct hashtable_iterator : public hashtable_iterator_base { - typedef Value value_type; - typedef typename IF::type pointer; - typedef typename IF::type reference; - typedef std::ptrdiff_t difference_type; - typedef std::forward_iterator_tag iterator_category; + typedef Value value_type; + typedef typename IF::type + pointer; + typedef typename IF::type + reference; + typedef std::ptrdiff_t difference_type; + typedef std::forward_iterator_tag iterator_category; hashtable_iterator(hash_node* p, hash_node** b) @@ -266,9 +309,6 @@ namespace Internal hashtable_iterator(hash_node** b) : hashtable_iterator_base(*b, b) { } - hashtable_iterator(const hashtable_iterator& x) - : hashtable_iterator_base(x.m_cur_node, x.m_cur_bucket) { } - reference operator*() const { return this->m_cur_node->m_v; } @@ -292,6 +332,50 @@ namespace Internal return tmp; } }; + template + struct hashtable_const_iterator + : public hashtable_iterator_base + { + 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* p, + hash_node** b) + : hashtable_iterator_base(p, b) { } + + explicit + hashtable_const_iterator(hash_node** b) + : hashtable_iterator_base(*b, b) { } + + hashtable_const_iterator(const hashtable_iterator& x) + : hashtable_iterator_base(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 // ---------------------------------------------------------------------- @@ -843,10 +927,9 @@ namespace tr1 // 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 @@ -859,20 +942,20 @@ namespace tr1 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 >, public Internal::hash_code_base, public Internal::map_base > { public: @@ -887,16 +970,18 @@ namespace tr1 typedef typename Allocator::reference reference; typedef typename Allocator::const_reference const_reference; - typedef Internal::node_iterator local_iterator; - typedef Internal::node_iterator + typedef Internal::node_const_iterator const_local_iterator; - typedef Internal::hashtable_iterator iterator; - typedef Internal::hashtable_iterator + typedef Internal::hashtable_const_iterator const_iterator; private: @@ -1068,6 +1153,12 @@ namespace tr1 std::pair, iterator>::type Insert_Return_Type; + typedef typename Internal::IF, + Internal::identity + >::type + Insert_Conv_Type; + node* find_node(node* p, const key_type& k, typename hashtable::hash_code_t c) const; @@ -1085,34 +1176,48 @@ namespace tr1 return this->insert(v, std::tr1::integral_constant()); } - - 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 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); }; //---------------------------------------------------------------------- @@ -1121,9 +1226,9 @@ namespace tr1 template - typename hashtable::node* - hashtable:: + bool c, bool ci, bool u> + typename hashtable::node* + hashtable:: m_allocate_node(const value_type& v) { node* n = m_node_allocator.allocate(1); @@ -1143,9 +1248,9 @@ namespace tr1 template + bool c, bool ci, bool u> void - hashtable:: + hashtable:: m_deallocate_node(node* n) { get_allocator().destroy(&n->m_v); @@ -1155,9 +1260,9 @@ namespace tr1 template + bool c, bool ci, bool u> void - hashtable:: + hashtable:: m_deallocate_nodes(node** array, size_type n) { for (size_type i = 0; i < n; ++i) @@ -1176,9 +1281,9 @@ namespace tr1 template - typename hashtable::node** - hashtable:: + bool c, bool ci, bool u> + typename hashtable::node** + hashtable:: m_allocate_buckets(size_type n) { bucket_allocator_t alloc(m_node_allocator); @@ -1194,9 +1299,9 @@ namespace tr1 template + bool c, bool ci, bool u> void - hashtable:: + hashtable:: m_deallocate_buckets(node** p, size_type n) { bucket_allocator_t alloc(m_node_allocator); @@ -1206,8 +1311,8 @@ namespace tr1 template - hashtable:: + bool c, bool ci, bool u> + hashtable:: hashtable(size_type bucket_hint, const H1& h1, const H2& h2, const H& h, const Eq& eq, const Ex& exk, @@ -1227,9 +1332,9 @@ namespace tr1 template + bool c, bool ci, bool u> template - hashtable:: + hashtable:: hashtable(InIter f, InIter l, size_type bucket_hint, const H1& h1, const H2& h2, const H& h, @@ -1265,8 +1370,8 @@ namespace tr1 template - hashtable:: + bool c, bool ci, bool u> + hashtable:: hashtable(const hashtable& ht) : Internal::rehash_base(ht), Internal::hash_code_base(ht), @@ -1303,9 +1408,9 @@ namespace tr1 template - hashtable& - hashtable:: + bool c, bool ci, bool u> + hashtable& + hashtable:: operator=(const hashtable& ht) { hashtable tmp(ht); @@ -1316,8 +1421,8 @@ namespace tr1 template - hashtable:: + bool c, bool ci, bool u> + hashtable:: ~hashtable() { clear(); @@ -1327,9 +1432,9 @@ namespace tr1 template + bool c, bool ci, bool u> void - hashtable:: + hashtable:: swap(hashtable& x) { // The only base class with member variables is hash_code_base. We @@ -1348,9 +1453,9 @@ namespace tr1 template + bool c, bool ci, bool u> void - hashtable:: + hashtable:: rehash_policy(const RP& pol) { m_rehash_policy = pol; @@ -1362,9 +1467,9 @@ namespace tr1 template - typename hashtable::iterator - hashtable:: + bool c, bool ci, bool u> + typename hashtable::iterator + hashtable:: find(const key_type& k) { typename hashtable::hash_code_t code = this->m_hash_code (k); @@ -1376,9 +1481,9 @@ namespace tr1 template - typename hashtable::const_iterator - hashtable:: + bool c, bool ci, bool u> + typename hashtable::const_iterator + hashtable:: find(const key_type& k) const { typename hashtable::hash_code_t code = this->m_hash_code (k); @@ -1390,9 +1495,9 @@ namespace tr1 template - typename hashtable::size_type - hashtable:: + bool c, bool ci, bool u> + typename hashtable::size_type + hashtable:: count(const key_type& k) const { typename hashtable::hash_code_t code = this->m_hash_code (k); @@ -1407,12 +1512,12 @@ namespace tr1 template + bool c, bool ci, bool u> std::pair::iterator, + H2, H, RP, c, ci, u>::iterator, typename hashtable::iterator> - hashtable:: + H2, H, RP, c, ci, u>::iterator> + hashtable:: equal_range(const key_type& k) { typename hashtable::hash_code_t code = this->m_hash_code (k); @@ -1440,12 +1545,12 @@ namespace tr1 template + bool c, bool ci, bool u> std::pair::const_iterator, + H2, H, RP, c, ci, u>::const_iterator, typename hashtable::const_iterator> - hashtable:: + H2, H, RP, c, ci, u>::const_iterator> + hashtable:: equal_range(const key_type& k) const { typename hashtable::hash_code_t code = this->m_hash_code (k); @@ -1475,9 +1580,9 @@ namespace tr1 template - typename hashtable::node* - hashtable:: + bool c, bool ci, bool u> + typename hashtable::node* + hashtable:: find_node(node* p, const key_type& k, typename hashtable::hash_code_t code) const { @@ -1491,10 +1596,10 @@ namespace tr1 template + bool c, bool ci, bool u> std::pair::iterator, bool> - hashtable:: + H2, H, RP, c, ci, u>::iterator, bool> + hashtable:: insert(const value_type& v, std::tr1::true_type) { const key_type& k = this->m_extract(v); @@ -1536,9 +1641,9 @@ namespace tr1 template - typename hashtable::iterator - hashtable:: + bool c, bool ci, bool u> + typename hashtable::iterator + hashtable:: insert(const value_type& v, std::tr1::false_type) { std::pair do_rehash @@ -1571,10 +1676,10 @@ namespace tr1 template + bool c, bool ci, bool u> template void - hashtable:: + hashtable:: insert(InIter first, InIter last) { size_type n_elt = Internal::distance_fw (first, last); @@ -1587,43 +1692,40 @@ namespace tr1 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 - void - hashtable:: + bool c, bool ci, bool u> + typename hashtable::iterator + hashtable:: + erase(iterator i) + { + iterator result = i; + ++result; + m_erase(i.m_cur_node, i.m_cur_bucket); + return result; + } + + template + typename hashtable::const_iterator + hashtable:: 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 hashtable::size_type - hashtable:: + bool c, bool ci, bool u> + typename hashtable::size_type + hashtable:: erase(const key_type& k) { typename hashtable::hash_code_t code = this->m_hash_code (k); @@ -1649,29 +1751,38 @@ namespace tr1 // ??? 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 - void - hashtable:: + template + typename hashtable::iterator + hashtable:: + erase(iterator first, iterator last) + { + while (first != last) + first = this->erase(first); + return last; + } + + template + typename hashtable::const_iterator + hashtable:: 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 + bool c, bool ci, bool u> void - hashtable:: + hashtable:: clear() { m_deallocate_nodes(m_buckets, m_bucket_count); @@ -1681,9 +1792,9 @@ namespace tr1 template + bool c, bool ci, bool u> void - hashtable:: + hashtable:: m_rehash(size_type N) { node** new_array = m_allocate_buckets (N); @@ -1714,7 +1825,32 @@ namespace tr1 __throw_exception_again; } } - + + template + void + hashtable:: + 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 diff --git a/libstdc++-v3/include/tr1/unordered_map b/libstdc++-v3/include/tr1/unordered_map index 8568687df043..2f789c80e8f5 100644 --- a/libstdc++-v3/include/tr1/unordered_map +++ b/libstdc++-v3/include/tr1/unordered_map @@ -59,7 +59,7 @@ namespace tr1 Hash, Internal::mod_range_hashing, Internal::default_ranged_hash, Internal::prime_rehash_policy, - cache_hash_code, true, true> + cache_hash_code, false, true> { typedef hashtable , Alloc, @@ -67,7 +67,7 @@ namespace tr1 Hash, Internal::mod_range_hashing, Internal::default_ranged_hash, Internal::prime_rehash_policy, - cache_hash_code, true, true> + cache_hash_code, false, true> Base; public: @@ -110,7 +110,7 @@ namespace tr1 Hash, Internal::mod_range_hashing, Internal::default_ranged_hash, Internal::prime_rehash_policy, - cache_hash_code, true, false> + cache_hash_code, false, false> { typedef hashtable , Alloc, @@ -118,7 +118,7 @@ namespace tr1 Hash, Internal::mod_range_hashing, Internal::default_ranged_hash, Internal::prime_rehash_policy, - cache_hash_code, true, false> + cache_hash_code, false, false> Base; public: diff --git a/libstdc++-v3/include/tr1/unordered_set b/libstdc++-v3/include/tr1/unordered_set index 63f431f48e64..6a4881a3d1d9 100644 --- a/libstdc++-v3/include/tr1/unordered_set +++ b/libstdc++-v3/include/tr1/unordered_set @@ -57,14 +57,14 @@ namespace tr1 Hash, Internal::mod_range_hashing, Internal::default_ranged_hash, Internal::prime_rehash_policy, - cache_hash_code, false, true> + cache_hash_code, true, true> { typedef hashtable, Pred, Hash, Internal::mod_range_hashing, Internal::default_ranged_hash, Internal::prime_rehash_policy, - cache_hash_code, false, true> + cache_hash_code, true, true> Base; public: @@ -106,14 +106,14 @@ namespace tr1 Hash, Internal::mod_range_hashing, Internal::default_ranged_hash, Internal::prime_rehash_policy, - cache_hash_code, false, false> + cache_hash_code, true, false> { typedef hashtable, Pred, Hash, Internal::mod_range_hashing, Internal::default_ranged_hash, Internal::prime_rehash_policy, - cache_hash_code, false, false> + cache_hash_code, true, false> Base; public: diff --git a/libstdc++-v3/testsuite/tr1/6_containers/unordered/erase/24061-map.cc b/libstdc++-v3/testsuite/tr1/6_containers/unordered/erase/24061-map.cc new file mode 100644 index 000000000000..9289b65859cd --- /dev/null +++ b/libstdc++-v3/testsuite/tr1/6_containers/unordered/erase/24061-map.cc @@ -0,0 +1,106 @@ +// 2005-10-08 Paolo Carlini +// +// 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 +#include +#include + +// libstdc++/24061 +void test01() +{ + bool test __attribute__((unused)) = true; + + typedef std::tr1::unordered_map 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; +} diff --git a/libstdc++-v3/testsuite/tr1/6_containers/unordered/erase/24061-multimap.cc b/libstdc++-v3/testsuite/tr1/6_containers/unordered/erase/24061-multimap.cc new file mode 100644 index 000000000000..b9980b73136f --- /dev/null +++ b/libstdc++-v3/testsuite/tr1/6_containers/unordered/erase/24061-multimap.cc @@ -0,0 +1,109 @@ +// 2005-10-08 Paolo Carlini +// +// 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 +#include +#include + +// libstdc++/24061 +void test01() +{ + bool test __attribute__((unused)) = true; + + typedef std::tr1::unordered_multimap 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; +} diff --git a/libstdc++-v3/testsuite/tr1/6_containers/unordered/erase/24061-multiset.cc b/libstdc++-v3/testsuite/tr1/6_containers/unordered/erase/24061-multiset.cc new file mode 100644 index 000000000000..a00beab49435 --- /dev/null +++ b/libstdc++-v3/testsuite/tr1/6_containers/unordered/erase/24061-multiset.cc @@ -0,0 +1,108 @@ +// 2005-10-08 Paolo Carlini +// +// 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 +#include +#include + +// libstdc++/24061 +void test01() +{ + bool test __attribute__((unused)) = true; + + typedef std::tr1::unordered_multiset 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; +} diff --git a/libstdc++-v3/testsuite/tr1/6_containers/unordered/erase/24061-set.cc b/libstdc++-v3/testsuite/tr1/6_containers/unordered/erase/24061-set.cc new file mode 100644 index 000000000000..202a21d1dddb --- /dev/null +++ b/libstdc++-v3/testsuite/tr1/6_containers/unordered/erase/24061-set.cc @@ -0,0 +1,105 @@ +// 2005-10-08 Paolo Carlini +// +// 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 +#include +#include + +// libstdc++/24061 +void test01() +{ + bool test __attribute__((unused)) = true; + + typedef std::tr1::unordered_set 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; +} diff --git a/libstdc++-v3/testsuite/tr1/6_containers/unordered/insert/24061-map.cc b/libstdc++-v3/testsuite/tr1/6_containers/unordered/insert/24061-map.cc new file mode 100644 index 000000000000..8e290afd7f75 --- /dev/null +++ b/libstdc++-v3/testsuite/tr1/6_containers/unordered/insert/24061-map.cc @@ -0,0 +1,61 @@ +// 2005-10-08 Paolo Carlini +// +// 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 +#include +#include + +// libstdc++/24061 +void test01() +{ + bool test __attribute__((unused)) = true; + + typedef std::tr1::unordered_map 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; +} diff --git a/libstdc++-v3/testsuite/tr1/6_containers/unordered/insert/24061-multimap.cc b/libstdc++-v3/testsuite/tr1/6_containers/unordered/insert/24061-multimap.cc new file mode 100644 index 000000000000..a744c8bb3811 --- /dev/null +++ b/libstdc++-v3/testsuite/tr1/6_containers/unordered/insert/24061-multimap.cc @@ -0,0 +1,61 @@ +// 2005-10-08 Paolo Carlini +// +// 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 +#include +#include + +// libstdc++/24061 +void test01() +{ + bool test __attribute__((unused)) = true; + + typedef std::tr1::unordered_multimap 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; +} diff --git a/libstdc++-v3/testsuite/tr1/6_containers/unordered/insert/24061-multiset.cc b/libstdc++-v3/testsuite/tr1/6_containers/unordered/insert/24061-multiset.cc new file mode 100644 index 000000000000..9467f418ef39 --- /dev/null +++ b/libstdc++-v3/testsuite/tr1/6_containers/unordered/insert/24061-multiset.cc @@ -0,0 +1,58 @@ +// 2005-10-08 Paolo Carlini +// +// 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 +#include +#include + +// libstdc++/24061 +void test01() +{ + bool test __attribute__((unused)) = true; + + typedef std::tr1::unordered_multiset 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; +} diff --git a/libstdc++-v3/testsuite/tr1/6_containers/unordered/insert/24061-set.cc b/libstdc++-v3/testsuite/tr1/6_containers/unordered/insert/24061-set.cc new file mode 100644 index 000000000000..c7d670c9f491 --- /dev/null +++ b/libstdc++-v3/testsuite/tr1/6_containers/unordered/insert/24061-set.cc @@ -0,0 +1,58 @@ +// 2005-10-08 Paolo Carlini +// +// 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 +#include +#include + +// libstdc++/24061 +void test01() +{ + bool test __attribute__((unused)) = true; + + typedef std::tr1::unordered_set 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; +}