Boost logo

Boost-Commit :

From: danieljames_at_[hidden]
Date: 2007-05-20 13:37:28


Author: danieljames
Date: 2007-05-20 13:37:27 EDT (Sun, 20 May 2007)
New Revision: 4146
URL: http://svn.boost.org/trac/boost/changeset/4146

Log:
It is currently proposed that insert, erase and rehash should be stable. Change insert(hint, value) so that it inserts at the end of a group of
equivalent keys (all the other functions were already stable).

Added:
   sandbox/unordered/libs/unordered/test/unordered/insert_stable_tests.cpp
Text files modified:
   sandbox/unordered/boost/unordered/detail/hash_table_impl.hpp | 9 ++++++++-
   sandbox/unordered/libs/unordered/doc/rationale.qbk | 7 +------
   sandbox/unordered/libs/unordered/test/unordered/Jamfile.v2 | 1 +
   3 files changed, 10 insertions(+), 7 deletions(-)

Modified: sandbox/unordered/boost/unordered/detail/hash_table_impl.hpp
==============================================================================
--- sandbox/unordered/boost/unordered/detail/hash_table_impl.hpp (original)
+++ sandbox/unordered/boost/unordered/detail/hash_table_impl.hpp 2007-05-20 13:37:27 EDT (Sun, 20 May 2007)
@@ -1561,6 +1561,13 @@
                     return insert(v);
                 }
                 else {
+ // Find the first node in the group - so that the node
+ // will be inserted at the end of the group.
+
+ local_iterator_base start(it.local_);
+ while(prev_in_group(start.node_)->next_ == start.node_)
+ start.node_ = prev_in_group(start.node_);
+
                     // Create the node before rehashing in case it throws an
                     // exception (need strong safety in such a case).
                     node_constructor a(this->allocators_);
@@ -1574,7 +1581,7 @@
                     // Nothing after this point can throw
 
                     link_ptr n = a.release();
- this->link_node(n, it.local_);
+ this->link_node(n, start);
 
                     return iterator_base(base, n);
                 }

Modified: sandbox/unordered/libs/unordered/doc/rationale.qbk
==============================================================================
--- sandbox/unordered/libs/unordered/doc/rationale.qbk (original)
+++ sandbox/unordered/libs/unordered/doc/rationale.qbk 2007-05-20 13:37:27 EDT (Sun, 20 May 2007)
@@ -118,12 +118,7 @@
 [h3 [@http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#518
     518. Are insert and erase stable for unordered_multiset and unordered_multimap?]]
 
-In this implementation, erase is stable. All inserts are stable, except for
-inserting with a hint, which has slightly surprising behaviour. If the hint
-points to the first element in the correct equal range it inserts at the end of
-the range, for all other elements in the range it inserts immediately before
-the element. I am very tempted to change insert with a hint to just ignore the
-hint completely.
+The current proposal is that insert and erase are stable - so they are here.
 
 [h3 [@http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#528
     528. TR1: issue 6.19 vs 6.3.4.3/2 (and 6.3.4.5/2)]]

Modified: sandbox/unordered/libs/unordered/test/unordered/Jamfile.v2
==============================================================================
--- sandbox/unordered/libs/unordered/test/unordered/Jamfile.v2 (original)
+++ sandbox/unordered/libs/unordered/test/unordered/Jamfile.v2 2007-05-20 13:37:27 EDT (Sun, 20 May 2007)
@@ -18,6 +18,7 @@
         [ run copy_tests.cpp ]
         [ run assign_tests.cpp ]
         [ run insert_tests.cpp ]
+ [ run insert_stable_tests.cpp ]
         [ run unnecessary_copy_tests.cpp ]
         [ run erase_tests.cpp ]
         [ run erase_equiv_tests.cpp ]

Added: sandbox/unordered/libs/unordered/test/unordered/insert_stable_tests.cpp
==============================================================================
--- (empty file)
+++ sandbox/unordered/libs/unordered/test/unordered/insert_stable_tests.cpp 2007-05-20 13:37:27 EDT (Sun, 20 May 2007)
@@ -0,0 +1,74 @@
+
+// Copyright 2007 Daniel James.
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/unordered_set.hpp>
+#include <boost/unordered_map.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#include <iostream>
+
+struct member {
+ int tag1_;
+ int tag2_;
+
+ member() : tag1_(0), tag2_(0) {}
+ member(int t1, int t2) : tag1_(t1), tag2_(t2) {}
+
+ friend bool operator==(member const& x, member const& y) {
+ return x.tag1_ == y.tag1_;
+ }
+
+ friend bool operator!=(member const& x, member const& y) {
+ return x.tag1_ != y.tag1_;
+ }
+};
+
+std::size_t hash_value(member const& x) {
+ return static_cast<std::size_t>(x.tag1_);
+}
+
+void stable_insert_test1() {
+ boost::unordered_multiset<member> x;
+
+ x.insert(member(1,1));
+ x.insert(member(1,2));
+ x.insert(member(1,3));
+
+ boost::unordered_multiset<member>::const_iterator it = x.begin(), end = x.end();
+ BOOST_TEST(it != end);
+ if(it != end) { BOOST_TEST(it->tag2_ == 1); ++it; }
+ BOOST_TEST(it != end);
+ if(it != end) { BOOST_TEST(it->tag2_ == 2); ++it; }
+ BOOST_TEST(it != end);
+ if(it != end) { BOOST_TEST(it->tag2_ == 3); ++it; }
+ BOOST_TEST(it == end);
+}
+
+void stable_insert_test2() {
+ boost::unordered_multimap<member, int> x;
+ typedef boost::unordered_multimap<member, int>::const_iterator iterator;
+
+ iterator it = x.insert(x.end(), std::make_pair(member(1,1), 1));
+ it = x.insert(it, std::make_pair(member(1,2), 2));
+ it = x.insert(it, std::make_pair(member(1,3), 3));
+
+ it = x.begin();
+ iterator end = x.end();
+ BOOST_TEST(it != end);
+ if(it != end) { BOOST_TEST(it->first.tag2_ == 1 && it->second == 1); ++it; }
+ BOOST_TEST(it != end);
+ if(it != end) { BOOST_TEST(it->first.tag2_ == 2 && it->second == 2); ++it; }
+ BOOST_TEST(it != end);
+ if(it != end) { BOOST_TEST(it->first.tag2_ == 3 && it->second == 3); ++it; }
+ BOOST_TEST(it == end);
+}
+
+int main()
+{
+ stable_insert_test1();
+ stable_insert_test2();
+
+ return boost::report_errors();
+}


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk