From 1bc3ae3d9dba1912de9f5120cbbac3fd4f8ee906 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 26 Jul 2009 20:22:48 +0000 Subject: [PATCH] Merge unordered changes, including fixes for Boost.TR1. Merged revisions 55099-55100,55132,55138,55184-55185 via svnmerge from https://svn.boost.org/svn/boost/trunk ........ r55099 | danieljames | 2009-07-22 23:37:52 +0100 (Wed, 22 Jul 2009) | 1 line Fix the insert tests when there is a small number of buckets. ........ r55100 | danieljames | 2009-07-22 23:38:08 +0100 (Wed, 22 Jul 2009) | 1 line Adjust the unordered defaults so that emplace takes more parameters and less buckets are created by default. ........ r55132 | danieljames | 2009-07-23 18:53:59 +0100 (Thu, 23 Jul 2009) | 1 line Remove the emulation of single argument C++0x std::pair constructor. ........ r55138 | danieljames | 2009-07-23 23:17:20 +0100 (Thu, 23 Jul 2009) | 1 line Try to work around an odd Visual C++ 8 bug. ........ r55184 | danieljames | 2009-07-26 19:59:33 +0100 (Sun, 26 Jul 2009) | 1 line Some extra changelog notes. ........ r55185 | danieljames | 2009-07-26 20:00:40 +0100 (Sun, 26 Jul 2009) | 1 line Update the reference documentation to mention that emplace is now emulated. ........ [SVN r55189] --- doc/changes.qbk | 9 ++- doc/ref.xml | 32 +++++++--- include/boost/unordered/detail/hash_table.hpp | 4 +- .../unordered/detail/hash_table_impl.hpp | 64 +++---------------- include/boost/unordered/unordered_map.hpp | 26 ++++++-- include/boost/unordered/unordered_set.hpp | 24 +++++-- test/exception/insert_exception_tests.cpp | 2 +- test/helpers/input_iterator.hpp | 19 +++++- 8 files changed, 101 insertions(+), 79 deletions(-) diff --git a/doc/changes.qbk b/doc/changes.qbk index 956e0eae..418f1d90 100644 --- a/doc/changes.qbk +++ b/doc/changes.qbk @@ -79,8 +79,13 @@ First official release. the length right if it changes again in the future. * [@https://svn.boost.org/trac/boost/ticket/1978 Ticket 1978]: Implement `emplace` for all compilers. +* [@https://svn.boost.org/trac/boost/ticket/2908 Ticket 2908], + [@https://svn.boost.org/trac/boost/ticket/3096 Ticket 3096]: + Some workarounds for old versions of borland, including adding explicit + destructors to all containers. +* [@https://svn.boost.org/trac/boost/ticket/3082 Ticket 3082]: + Disable incorrect Visual C++ warnings. * Better configuration for C++0x features when the headers aren't available. -* [@https://svn.boost.org/trac/boost/ticket/2908 Ticket 2908]: - Add explicit destructors to all containers. +* Create less buckets by default. [endsect] diff --git a/doc/ref.xml b/doc/ref.xml index b1933659..2a3602dc 100644 --- a/doc/ref.xml +++ b/doc/ref.xml @@ -284,7 +284,9 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. Pointers and references to elements are never invalidated. - Only available on compilers with support for variadic template arguments and rvalue references. + If the compiler doesn't support variadic template arguments or rvalue + references, this is emulated for up to 10 arguments, with no support + for rvalue references or move semantics. @@ -313,7 +315,9 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same value. Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. Pointers and references to elements are never invalidated. - Only available on compilers with support for variadic template arguments and rvalue references. + If the compiler doesn't support variadic template arguments or rvalue + references, this is emulated for up to 10 arguments, with no support + for rvalue references or move semantics. @@ -1017,7 +1021,9 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. Pointers and references to elements are never invalidated. - Only available on compilers with support for variadic template arguments and rvalue references. + If the compiler doesn't support variadic template arguments or rvalue + references, this is emulated for up to 10 arguments, with no support + for rvalue references or move semantics. @@ -1046,7 +1052,9 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same value. Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. Pointers and references to elements are never invalidated. - Only available on compilers with support for variadic template arguments and rvalue references. + If the compiler doesn't support variadic template arguments or rvalue + references, this is emulated for up to 10 arguments, with no support + for rvalue references or move semantics. @@ -1762,7 +1770,9 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. Pointers and references to elements are never invalidated. - Only available on compilers with support for variadic template arguments and rvalue references. + If the compiler doesn't support variadic template arguments or rvalue + references, this is emulated for up to 10 arguments, with no support + for rvalue references or move semantics. @@ -1791,7 +1801,9 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. Pointers and references to elements are never invalidated. - Only available on compilers with support for variadic template arguments and rvalue references. + If the compiler doesn't support variadic template arguments or rvalue + references, this is emulated for up to 10 arguments, with no support + for rvalue references or move semantics. @@ -2544,7 +2556,9 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. Pointers and references to elements are never invalidated. - Only available on compilers with support for variadic template arguments and rvalue references. + If the compiler doesn't support variadic template arguments or rvalue + references, this is emulated for up to 10 arguments, with no support + for rvalue references or move semantics. @@ -2573,7 +2587,9 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. Pointers and references to elements are never invalidated. - Only available on compilers with support for variadic template arguments and rvalue references. + If the compiler doesn't support variadic template arguments or rvalue + references, this is emulated for up to 10 arguments, with no support + for rvalue references or move semantics. diff --git a/include/boost/unordered/detail/hash_table.hpp b/include/boost/unordered/detail/hash_table.hpp index 1609e955..2418b2a6 100644 --- a/include/boost/unordered/detail/hash_table.hpp +++ b/include/boost/unordered/detail/hash_table.hpp @@ -15,7 +15,7 @@ #include #if !defined(BOOST_UNORDERED_EMPLACE_LIMIT) -#define BOOST_UNORDERED_EMPLACE_LIMIT 5 +#define BOOST_UNORDERED_EMPLACE_LIMIT 10 #endif #include @@ -85,7 +85,7 @@ namespace boost { namespace unordered_detail { template struct type_wrapper {}; - static const std::size_t default_initial_bucket_count = 50; + static const std::size_t default_initial_bucket_count = 11; static const float minimum_max_load_factor = 1e-3f; inline std::size_t double_to_size_t(double f) diff --git a/include/boost/unordered/detail/hash_table_impl.hpp b/include/boost/unordered/detail/hash_table_impl.hpp index cee3e051..6bfe6580 100644 --- a/include/boost/unordered/detail/hash_table_impl.hpp +++ b/include/boost/unordered/detail/hash_table_impl.hpp @@ -206,55 +206,6 @@ namespace boost { new(node_->address()) value_type(std::forward(args)...); value_constructed_ = true; } - -#if defined(__GLIBCPP__) || defined(__GLIBCXX__) - // The GCC C++0x standard library implementation does not have - // a single argument pair constructor, so this works around that. - - template - void construct(Arg&& arg) - { - construct_preamble(); - construct_impl(std::forward(arg), - (value_type const*) 0, - (typename boost::remove_reference::type const*) 0); - value_constructed_ = true; - } - - template < - typename Arg, - typename ValueType, - typename Type> - void construct_impl(Arg&& arg, ValueType const*, Type const*) - { - new(node_->address()) value_type(std::forward(arg)); - } - - template < - typename Arg, - typename ValueFirst, typename ValueSecond, - typename TypeFirst, typename TypeSecond> - void construct_impl( - Arg&& arg, - std::pair const*, - std::pair const*) - { - new(node_->address()) value_type(std::forward(arg)); - } - - template < - typename Arg, - typename ValueFirst, typename ValueSecond, - typename Type> - void construct_impl( - Arg&& arg, - std::pair const*, - Type const*) - { - new(node_->address()) value_type(std::forward(arg), ValueSecond()); - } -#endif - #else #define BOOST_UNORDERED_CONSTRUCT_IMPL(z, n, _) \ @@ -316,15 +267,16 @@ namespace boost { new(node_->address()) value_type(arg0); } - template - void construct_impl(std::pair*, Key const& k) - { - new(node_->address()) value_type(First(k), Second()); - } - #undef BOOST_UNORDERED_CONSTRUCT_IMPL #endif + template + void construct_pair(K const& k, M*) + { + construct_preamble(); + new(node_->address()) value_type(k, M()); + value_constructed_ = true; + } node_ptr get() const { @@ -1922,7 +1874,7 @@ namespace boost { // Create the node before rehashing in case it throws an // exception (need strong safety in such a case). node_constructor a(data_.allocators_); - a.construct(k); + a.construct_pair(k, (mapped_type*) 0); // reserve has basic exception safety if the hash function // throws, strong otherwise. diff --git a/include/boost/unordered/unordered_map.hpp b/include/boost/unordered/unordered_map.hpp index d2793c56..b0658bad 100644 --- a/include/boost/unordered/unordered_map.hpp +++ b/include/boost/unordered/unordered_map.hpp @@ -105,8 +105,17 @@ namespace boost unordered_map(InputIterator f, InputIterator l, size_type n, const hasher &hf = hasher(), - const key_equal &eql = key_equal(), - const allocator_type &a = allocator_type()) + const key_equal &eql = key_equal()) + : base(f, l, n, hf, eql, allocator_type()) + { + } + + template + unordered_map(InputIterator f, InputIterator l, + size_type n, + const hasher &hf, + const key_equal &eql, + const allocator_type &a) : base(f, l, n, hf, eql, a) { } @@ -560,8 +569,17 @@ namespace boost unordered_multimap(InputIterator f, InputIterator l, size_type n, const hasher &hf = hasher(), - const key_equal &eql = key_equal(), - const allocator_type &a = allocator_type()) + const key_equal &eql = key_equal()) + : base(f, l, n, hf, eql, allocator_type()) + { + } + + template + unordered_multimap(InputIterator f, InputIterator l, + size_type n, + const hasher &hf, + const key_equal &eql, + const allocator_type &a) : base(f, l, n, hf, eql, a) { } diff --git a/include/boost/unordered/unordered_set.hpp b/include/boost/unordered/unordered_set.hpp index 07ed746b..aecb54b4 100644 --- a/include/boost/unordered/unordered_set.hpp +++ b/include/boost/unordered/unordered_set.hpp @@ -103,8 +103,16 @@ namespace boost template unordered_set(InputIterator f, InputIterator l, size_type n, const hasher &hf = hasher(), - const key_equal &eql = key_equal(), - const allocator_type &a = allocator_type()) + const key_equal &eql = key_equal()) + : base(f, l, n, hf, eql, allocator_type()) + { + } + + template + unordered_set(InputIterator f, InputIterator l, size_type n, + const hasher &hf, + const key_equal &eql, + const allocator_type &a) : base(f, l, n, hf, eql, a) { } @@ -530,8 +538,16 @@ namespace boost template unordered_multiset(InputIterator f, InputIterator l, size_type n, const hasher &hf = hasher(), - const key_equal &eql = key_equal(), - const allocator_type &a = allocator_type()) + const key_equal &eql = key_equal()) + : base(f, l, n, hf, eql, allocator_type()) + { + } + + template + unordered_multiset(InputIterator f, InputIterator l, size_type n, + const hasher &hf, + const key_equal &eql, + const allocator_type &a) : base(f, l, n, hf, eql, a) { } diff --git a/test/exception/insert_exception_tests.cpp b/test/exception/insert_exception_tests.cpp index c44d56ba..acb47b48 100644 --- a/test/exception/insert_exception_tests.cpp +++ b/test/exception/insert_exception_tests.cpp @@ -195,7 +195,7 @@ struct insert_test_rehash3 : public insert_test_base rehash_bucket_count = static_cast( ceil(original_bucket_count * (double) x.max_load_factor())) - 1; - size_type initial_elements = rehash_bucket_count - 5; + size_type initial_elements = rehash_bucket_count > 5 ? rehash_bucket_count - 5 : 1; BOOST_TEST(initial_elements < this->values.size()); x.insert(this->values.begin(), diff --git a/test/helpers/input_iterator.hpp b/test/helpers/input_iterator.hpp index ec864b7e..d81d9fec 100644 --- a/test/helpers/input_iterator.hpp +++ b/test/helpers/input_iterator.hpp @@ -6,19 +6,34 @@ #if !defined(BOOST_UNORDERED_TEST_HELPERS_INPUT_ITERATOR_HEADER) #define BOOST_UNORDERED_TEST_HELPERS_INPUT_ITERATOR_HEADER +#include #include namespace test { + template + struct proxy + { + typedef BOOST_DEDUCED_TYPENAME Iterator::value_type value_type; + + proxy(value_type const& v) : v_(v) {} + proxy(proxy const& x) : v_(x.v_) {} + operator value_type const&() const { return v_; } + + value_type v_; + }; + template struct input_iterator_adaptor : boost::iterator_adaptor< input_iterator_adaptor, Iterator, - boost::use_default, std::input_iterator_tag> + boost::use_default, std::input_iterator_tag, + proxy > { typedef boost::iterator_adaptor< input_iterator_adaptor, Iterator, - boost::use_default, std::input_iterator_tag> base; + boost::use_default, std::input_iterator_tag, + proxy > base; explicit input_iterator_adaptor(Iterator it = Iterator()) : base(it) {}