From ff91c72eec257de4725392388a144ddf95c2ec42 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Mon, 12 Jun 2006 23:30:46 +0000 Subject: [PATCH] Improved support for Visual C++. [SVN r2985] --- include/boost/unordered/detail/hash_table.hpp | 4 +-- .../unordered/detail/hash_table_impl.hpp | 2 +- test/container/link_test_1.cpp | 2 ++ test/container/simple_tests.cpp | 2 +- test/helpers/equivalent.hpp | 21 ++++++------ test/helpers/generators.hpp | 23 ++++++++++++- test/helpers/helpers.hpp | 31 ++++++++++++------ test/helpers/invariants.hpp | 5 ++- test/helpers/tracker.hpp | 31 +++++++++++++----- test/objects/test.hpp | 20 +++++++++--- test/unordered/assign_tests.cpp | 6 ++-- test/unordered/bucket_tests.cpp | 2 +- test/unordered/compile_tests.cpp | 2 +- test/unordered/constructor_tests.cpp | 26 +++++++-------- test/unordered/find_tests.cpp | 32 ++++++++++--------- test/unordered/insert_tests.cpp | 11 ++++--- test/unordered/load_factor_tests.cpp | 6 ++-- test/unordered/rehash_tests.cpp | 2 +- test/unordered/swap_tests.cpp | 7 ++-- 19 files changed, 154 insertions(+), 81 deletions(-) diff --git a/include/boost/unordered/detail/hash_table.hpp b/include/boost/unordered/detail/hash_table.hpp index 59c7f072..5a2423d5 100644 --- a/include/boost/unordered/detail/hash_table.hpp +++ b/include/boost/unordered/detail/hash_table.hpp @@ -51,7 +51,7 @@ #endif #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) -#define BOOST_HASH_MSVC_RESET_PTR(x) unordered_detail::reset(node_pointer_) +#define BOOST_HASH_MSVC_RESET_PTR(x) unordered_detail::reset(x) #else #define BOOST_HASH_MSVC_RESET_PTR(x) #endif @@ -61,7 +61,7 @@ namespace boost { template struct type_wrapper {}; const static std::size_t default_initial_bucket_count = 50; - const static float minimum_max_load_factor = 1e-3; + const static float minimum_max_load_factor = 1e-3f; inline std::size_t next_prime(std::size_t n); template diff --git a/include/boost/unordered/detail/hash_table_impl.hpp b/include/boost/unordered/detail/hash_table_impl.hpp index 8388165d..4eee2693 100644 --- a/include/boost/unordered/detail/hash_table_impl.hpp +++ b/include/boost/unordered/detail/hash_table_impl.hpp @@ -1811,7 +1811,7 @@ namespace boost { // Create the node before rehashing in case it throws an // exception (need strong safety in such a case). node_constructor a(this->node_alloc_, this->bucket_alloc_); - value_type const& v(*i); + value_type const& v = *i; a.construct(v); // reserve has basic exception safety if the hash function diff --git a/test/container/link_test_1.cpp b/test/container/link_test_1.cpp index 82e1994a..73efe2b4 100644 --- a/test/container/link_test_1.cpp +++ b/test/container/link_test_1.cpp @@ -19,4 +19,6 @@ int main() boost::unordered_multimap x4; foo(x1, x2, x3, x4); + + return 0; } diff --git a/test/container/simple_tests.cpp b/test/container/simple_tests.cpp index 94c9f79a..c4a7bbd0 100644 --- a/test/container/simple_tests.cpp +++ b/test/container/simple_tests.cpp @@ -58,7 +58,7 @@ void simple_test(X const& a) { X u; - X& r(u); + X& r = u; // TODO: I can't actually see a requirement for that assignment // returns a reference to itself (just that it returns a reference). BOOST_TEST(&(r = r) == &r); diff --git a/test/helpers/equivalent.hpp b/test/helpers/equivalent.hpp index cd9033b2..924c79f6 100644 --- a/test/helpers/equivalent.hpp +++ b/test/helpers/equivalent.hpp @@ -14,32 +14,35 @@ namespace test { + struct base_type {} base; + struct derived_type : base_type {} derived; + template - bool equivalent_impl(T1 const& x, T2 const& y) { + bool equivalent_impl(T1 const& x, T2 const& y, base_type) { return x == y; } template - bool equivalent_impl(boost::hash const&, boost::hash const&) { + bool equivalent_impl(boost::hash const&, boost::hash const&, derived_type) { return true; } template - bool equivalent_impl(std::equal_to const&, std::equal_to const&) { + bool equivalent_impl(std::equal_to const&, std::equal_to const&, derived_type) { return true; } template bool equivalent_impl(std::pair const& x1, - std::pair const& x2) { - return equivalent_impl(x1.first, x2.first) && - equivalent_impl(x1.second, x2.second); + std::pair const& x2, derived_type) { + return equivalent_impl(x1.first, x2.first, derived) && + equivalent_impl(x1.second, x2.second, derived); } struct equivalent_type { template bool operator()(T1 const& x, T2 const& y) { - return equivalent_impl(x, y); + return equivalent_impl(x, y, derived); } }; @@ -74,8 +77,8 @@ namespace test bool operator()(Container const& x) const { if(!((size_ == x.size()) && - (test::equivalent_impl(hasher_, x.hash_function())) && - (test::equivalent_impl(key_equal_, x.key_eq())) && + (test::equivalent(hasher_, x.hash_function())) && + (test::equivalent(key_equal_, x.key_eq())) && (max_load_factor_ == x.max_load_factor()) && (values_.size() == x.size()))) return false; diff --git a/test/helpers/generators.hpp b/test/helpers/generators.hpp index 6e2c1af7..93c93950 100644 --- a/test/helpers/generators.hpp +++ b/test/helpers/generators.hpp @@ -11,18 +11,24 @@ #include #include +#if 0 #include #include #include #include #include +#else +#include +#endif #include "./fwd.hpp" namespace test { +#if 0 typedef boost::hellekalek1995 integer_generator_type; typedef boost::lagged_fibonacci607 real_generator_type; +#endif template struct generator @@ -36,20 +42,30 @@ namespace test inline int generate(int const*) { +#if 0 integer_generator_type gen; boost::uniform_int<> dist(0, 1000); static boost::variate_generator > vg(gen, dist); return vg(); +#else + using namespace std; + return rand(); +#endif } inline char generate(char const*) { +#if 0 integer_generator_type gen; - boost::uniform_int dist(32, 128); + boost::uniform_int dist(32, 127); static boost::variate_generator > vg(gen, dist); return vg(); +#else + using namespace std; + return rand() % (128 - 32) + 32; +#endif } inline std::string generate(std::string const*) @@ -74,11 +90,16 @@ namespace test float generate(float const*) { +#if 0 real_generator_type gen; boost::uniform_real dist; static boost::variate_generator > vg(gen, dist); return vg(); +#else + using namespace std; + return (double) rand() / (double) RAND_MAX; +#endif } template std::pair generate( diff --git a/test/helpers/helpers.hpp b/test/helpers/helpers.hpp index fa219cda..875a78a2 100644 --- a/test/helpers/helpers.hpp +++ b/test/helpers/helpers.hpp @@ -9,21 +9,32 @@ namespace test { template - inline typename Container::key_type get_key(typename Container::key_type const& x) + struct get_key_impl { - return x; - } + typedef typename Container::key_type key_type; - template - inline typename Container::key_type get_key(std::pair const& x) - { - return x.first; - } + static key_type get_key(key_type const& x) + { + return x; + } + template + static key_type get_key(std::pair const& x, char = 0) + { + return x.first; + } + + template + static key_type get_key(std::pair const& x, unsigned char = 0) + { + return x.first; + } + }; + template - inline typename Container::key_type get_key(std::pair const& x) + inline typename Container::key_type get_key(T const& x) { - return x.first; + return get_key_impl::get_key(x); } } diff --git a/test/helpers/invariants.hpp b/test/helpers/invariants.hpp index 20afe3d5..b6c6842c 100644 --- a/test/helpers/invariants.hpp +++ b/test/helpers/invariants.hpp @@ -10,6 +10,7 @@ #define BOOST_UNORDERED_TEST_HELPERS_INVARIANT_HEADER #include +#include #include "./metafunctions.hpp" #include "./helpers.hpp" @@ -80,7 +81,9 @@ namespace test // Finally, check that size matches up. if(x1.size() != size) BOOST_ERROR("x1.size() doesn't match actual size."); - if(static_cast(size) / static_cast(x1.bucket_count()) != x1.load_factor()) + float load_factor = static_cast(size) / static_cast(x1.bucket_count()); + using namespace std; + if(fabs(x1.load_factor() - load_factor) > x1.load_factor() / 64) BOOST_ERROR("x1.load_factor() doesn't match actual load_factor."); } } diff --git a/test/helpers/tracker.hpp b/test/helpers/tracker.hpp index a70fffcb..ba7376e5 100644 --- a/test/helpers/tracker.hpp +++ b/test/helpers/tracker.hpp @@ -16,6 +16,8 @@ #include #include #include +#include +#include #include "../objects/fwd.hpp" #include "./metafunctions.hpp" #include "./helpers.hpp" @@ -24,15 +26,19 @@ namespace test { template - struct equals_to_compare + struct equals_to_compare2 + : public boost::mpl::identity > { - typedef std::less type; }; - template <> - struct equals_to_compare + template + struct equals_to_compare + : public boost::mpl::eval_if< + boost::is_same, + boost::mpl::identity, + equals_to_compare2 + > { - typedef test::less type; }; template @@ -121,13 +127,22 @@ namespace test (typename non_const_value_type::type*) 0 ); } + + template + void insert_range(It begin, It end) { + while(begin != end) { + this->insert(*begin); + ++begin; + } + } }; template typename equals_to_compare::type create_compare( - Equals equals) + Equals const& equals) { - return typename equals_to_compare::type(); + typename equals_to_compare::type x; + return x; } template @@ -140,7 +155,7 @@ namespace test void check_container(X1 const& container, X2 const& values) { ordered tracker = create_ordered(container); - tracker.insert(values.begin(), values.end()); + tracker.insert_range(values.begin(), values.end()); tracker.compare(container); } } diff --git a/test/objects/test.hpp b/test/objects/test.hpp index 4b55fa10..6fda7bbb 100644 --- a/test/objects/test.hpp +++ b/test/objects/test.hpp @@ -47,7 +47,7 @@ namespace test friend object generate(object const*) { - int* x; + int* x = 0; return object(generate(x), generate(x)); } @@ -339,10 +339,7 @@ namespace test return (std::numeric_limits::max)(); } - friend bool operator==(allocator const& x, allocator const& y) - { - return x.tag_ == y.tag_; - } + friend bool operator==(allocator const& x, allocator const& y); friend bool operator!=(allocator const& x, allocator const& y) { @@ -351,4 +348,17 @@ namespace test }; } +#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) +namespace test +{ +#endif + template + bool operator==(test::allocator const& x, test::allocator const& y) + { + return x.tag_ == y.tag_; + } +#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) +} +#endif + #endif diff --git a/test/unordered/assign_tests.cpp b/test/unordered/assign_tests.cpp index b7053b97..3915b81c 100644 --- a/test/unordered/assign_tests.cpp +++ b/test/unordered/assign_tests.cpp @@ -34,7 +34,7 @@ void assign_tests1(T* = 0) T x(v.begin(), v.end()); test::ordered tracker = test::create_ordered(x); - tracker.insert(v.begin(), v.end()); + tracker.insert_range(v.begin(), v.end()); x = x; tracker.compare(x); @@ -68,7 +68,7 @@ void assign_tests2(T* = 0) x2 = x1; BOOST_TEST(test::equivalent(x2.hash_function(), hf1)); BOOST_TEST(test::equivalent(x2.key_eq(), eq1)); - check_container(x2, v); + test::check_container(x2, v); } std::cerr<<"assign_tests2.2\n"; @@ -81,7 +81,7 @@ void assign_tests2(T* = 0) BOOST_TEST(test::equivalent(x2.hash_function(), hf1)); BOOST_TEST(test::equivalent(x2.key_eq(), eq1)); BOOST_TEST(test::equivalent(x2.get_allocator(), al2)); - check_container(x2, v1); + test::check_container(x2, v1); } } diff --git a/test/unordered/bucket_tests.cpp b/test/unordered/bucket_tests.cpp index b4b78041..ba42769d 100644 --- a/test/unordered/bucket_tests.cpp +++ b/test/unordered/bucket_tests.cpp @@ -39,7 +39,7 @@ void bucket_tests(X* = 0) for(size_type i = 0; i < x.bucket_count(); ++i) { BOOST_TEST(x.bucket_size(i) == (size_type) std::distance(x.begin(i), x.end(i))); - X const& x_ref(x); + X const& x_ref = x; BOOST_TEST(x.bucket_size(i) == (size_type) std::distance(x_ref.begin(i), x_ref.end(i))); } } diff --git a/test/unordered/compile_tests.cpp b/test/unordered/compile_tests.cpp index ccc90b0c..b9e9c3ad 100644 --- a/test/unordered/compile_tests.cpp +++ b/test/unordered/compile_tests.cpp @@ -106,7 +106,7 @@ void unordered_test(X& ref, Key& k, T& t, Hash& hf, Pred& eq) X(10); X a3(10); X(); - X a4(); + X a4; typename X::value_type* i = 0; typename X::value_type* j = 0; diff --git a/test/unordered/constructor_tests.cpp b/test/unordered/constructor_tests.cpp index c8d58dd3..082d4d5f 100644 --- a/test/unordered/constructor_tests.cpp +++ b/test/unordered/constructor_tests.cpp @@ -67,7 +67,7 @@ void constructor_tests1(T* = 0) BOOST_TEST(test::equivalent(x.hash_function(), hf)); BOOST_TEST(test::equivalent(x.key_eq(), eq)); BOOST_TEST(test::equivalent(x.get_allocator(), al)); - check_container(x, v); + test::check_container(x, v); } std::cerr<<"Construct 6\n"; @@ -78,7 +78,7 @@ void constructor_tests1(T* = 0) BOOST_TEST(test::equivalent(x.hash_function(), hf)); BOOST_TEST(test::equivalent(x.key_eq(), eq)); BOOST_TEST(test::equivalent(x.get_allocator(), al)); - check_container(x, v); + test::check_container(x, v); } std::cerr<<"Construct 7\n"; @@ -89,7 +89,7 @@ void constructor_tests1(T* = 0) BOOST_TEST(test::equivalent(x.hash_function(), hf)); BOOST_TEST(test::equivalent(x.key_eq(), eq)); BOOST_TEST(test::equivalent(x.get_allocator(), al)); - check_container(x, v); + test::check_container(x, v); } std::cerr<<"Construct 8\n"; @@ -99,7 +99,7 @@ void constructor_tests1(T* = 0) BOOST_TEST(test::equivalent(x.hash_function(), hf)); BOOST_TEST(test::equivalent(x.key_eq(), eq)); BOOST_TEST(test::equivalent(x.get_allocator(), al)); - check_container(x, v); + test::check_container(x, v); } std::cerr<<"Construct 9\n"; @@ -120,7 +120,7 @@ void constructor_tests1(T* = 0) BOOST_TEST(test::equivalent(x.hash_function(), hf)); BOOST_TEST(test::equivalent(x.key_eq(), eq)); BOOST_TEST(test::equivalent(x.get_allocator(), al)); - check_container(x, v); + test::check_container(x, v); } } @@ -163,7 +163,7 @@ void constructor_tests2(T* = 0) BOOST_TEST(test::equivalent(x.hash_function(), hf1)); BOOST_TEST(test::equivalent(x.key_eq(), eq1)); BOOST_TEST(test::equivalent(x.get_allocator(), al)); - check_container(x, v); + test::check_container(x, v); } std::cerr<<"Construct 4\n"; @@ -174,7 +174,7 @@ void constructor_tests2(T* = 0) BOOST_TEST(test::equivalent(x.hash_function(), hf1)); BOOST_TEST(test::equivalent(x.key_eq(), eq)); BOOST_TEST(test::equivalent(x.get_allocator(), al)); - check_container(x, v); + test::check_container(x, v); } @@ -183,8 +183,8 @@ void constructor_tests2(T* = 0) test::random_values v(100); T x(v.begin(), v.end(), 0, hf, eq, al1); T y(x.begin(), x.end(), 0, hf1, eq1, al2); - check_container(x, v); - check_container(y, x); + test::check_container(x, v); + test::check_container(y, x); } std::cerr<<"Construct 6\n"; @@ -192,8 +192,8 @@ void constructor_tests2(T* = 0) test::random_values v(100); T x(v.begin(), v.end(), 0, hf1, eq1); T y(x.begin(), x.end(), 0, hf, eq); - check_container(x, v); - check_container(y, x); + test::check_container(x, v); + test::check_container(y, x); } std::cerr<<"Construct 7\n"; @@ -201,8 +201,8 @@ void constructor_tests2(T* = 0) test::random_values v(100); T x(v.begin(), v.end(), 0, hf1, eq1); T y(x.begin(), x.end(), 0, hf2, eq2); - check_container(x, v); - check_container(y, x); + test::check_container(x, v); + test::check_container(y, x); } } diff --git a/test/unordered/find_tests.cpp b/test/unordered/find_tests.cpp index 89b53870..6b00435e 100644 --- a/test/unordered/find_tests.cpp +++ b/test/unordered/find_tests.cpp @@ -14,18 +14,20 @@ template void find_tests1(X*) { + typedef typename X::iterator iterator; + { test::random_values v(500); X x(v.begin(), v.end()); X const& x_const = x; test::ordered tracker = test::create_ordered(x); - tracker.insert(v.begin(), v.end()); + tracker.insert_range(v.begin(), v.end()); - for(typename test::ordered::const_iterator it = - tracker.begin(); it != tracker.end(); ++it) + for(typename test::ordered::const_iterator it1 = + tracker.begin(); it1 != tracker.end(); ++it1) { - typename X::key_type key = test::get_key(*it); - typename X::iterator pos = x.find(key); + typename X::key_type key = test::get_key(*it1); + iterator pos = x.find(key); typename X::const_iterator const_pos = x_const.find(key); BOOST_TEST(pos != x.end() && x.key_eq()(key, test::get_key(*pos))); @@ -43,17 +45,16 @@ void find_tests1(X*) } test::random_values v2(500); - for(typename test::random_values::const_iterator it = - v2.begin(); it != v2.end(); ++it) + for(typename test::random_values::const_iterator it2 = + v2.begin(); it2 != v2.end(); ++it2) { - typename X::key_type key = test::get_key(*it); + typename X::key_type key = test::get_key(*it2); if(tracker.find(test::get_key(key)) == tracker.end()) { BOOST_TEST(x.find(key) == x.end()); BOOST_TEST(x_const.find(key) == x_const.end()); BOOST_TEST(x.count(key) == 0); - std::pair range = x.equal_range(key); + std::pair range = x.equal_range(key); BOOST_TEST(range.first == range.second); } } @@ -63,14 +64,13 @@ void find_tests1(X*) X x; test::random_values v2(5); - for(typename test::random_values::const_iterator it = - v2.begin(); it != v2.end(); ++it) + for(typename test::random_values::const_iterator it3 = + v2.begin(); it3 != v2.end(); ++it3) { - typename X::key_type key = test::get_key(*it); + typename X::key_type key = test::get_key(*it3); BOOST_TEST(x.find(key) == x.end()); BOOST_TEST(x.count(key) == 0); - std::pair range = x.equal_range(key); + std::pair range = x.equal_range(key); BOOST_TEST(range.first == range.second); } } @@ -87,4 +87,6 @@ int main() find_tests1((boost::unordered_multiset >*) 0); find_tests1((boost::unordered_map >*) 0); find_tests1((boost::unordered_multimap >*) 0); + + return 0; } diff --git a/test/unordered/insert_tests.cpp b/test/unordered/insert_tests.cpp index 1d3be884..20e60643 100644 --- a/test/unordered/insert_tests.cpp +++ b/test/unordered/insert_tests.cpp @@ -18,6 +18,10 @@ template void unique_insert_tests1(X* = 0) { + typedef typename X::iterator iterator; + typedef test::ordered ordered; + typedef typename test::ordered::iterator ordered_iterator; + std::cerr<<"insert(value) tests for containers with unique keys.\n"; X x; @@ -30,9 +34,8 @@ void unique_insert_tests1(X* = 0) typename X::size_type old_bucket_count = x.bucket_count(); float b = x.max_load_factor(); - std::pair r1 = x.insert(*it); - std::pair::iterator, bool> r2 - = tracker.insert(*it); + std::pair r1 = x.insert(*it); + std::pair r2 = tracker.insert(*it); BOOST_TEST(r1.second == r2.second); BOOST_TEST(*r1.first == *r2.first); @@ -192,7 +195,7 @@ void insert_tests2(X* = 0) test::random_values v(1000); x.insert(v.begin(), v.end()); - check_container(x, v); + test::check_container(x, v); test::check_equivalent_keys(x); } diff --git a/test/unordered/load_factor_tests.cpp b/test/unordered/load_factor_tests.cpp index 973c8abf..677b4659 100644 --- a/test/unordered/load_factor_tests.cpp +++ b/test/unordered/load_factor_tests.cpp @@ -46,9 +46,9 @@ void insert_test(X*, float mlf) template void load_factor_insert_tests(X* ptr = 0) { - insert_test(ptr, 1.0); - insert_test(ptr, 0.1); - insert_test(ptr, 100); + insert_test(ptr, 1.0f); + insert_test(ptr, 0.1f); + insert_test(ptr, 100.0f); insert_test(ptr, (std::numeric_limits::min)()); diff --git a/test/unordered/rehash_tests.cpp b/test/unordered/rehash_tests.cpp index 9892be90..516e1cd7 100644 --- a/test/unordered/rehash_tests.cpp +++ b/test/unordered/rehash_tests.cpp @@ -32,7 +32,7 @@ void rehash_test1(X* = 0) { test::random_values v(1000); test::ordered tracker; - tracker.insert(v.begin(), v.end()); + tracker.insert_range(v.begin(), v.end()); X x(v.begin(), v.end()); x.rehash(0); BOOST_TEST(postcondition(x, 0)); diff --git a/test/unordered/swap_tests.cpp b/test/unordered/swap_tests.cpp index 7b074283..f9dcddb3 100644 --- a/test/unordered/swap_tests.cpp +++ b/test/unordered/swap_tests.cpp @@ -3,6 +3,9 @@ // subject to 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 +#include +#include #include #include #include @@ -16,8 +19,8 @@ void swap_test_impl(X& x1, X& x2) { test::ordered tracker1 = test::create_ordered(x1); test::ordered tracker2 = test::create_ordered(x2); - tracker1.insert(x1.begin(), x1.end()); - tracker2.insert(x2.begin(), x2.end()); + tracker1.insert_range(x1.begin(), x1.end()); + tracker2.insert_range(x2.begin(), x2.end()); x1.swap(x2); tracker1.compare(x2); tracker2.compare(x1);