diff --git a/test/helpers/memory.hpp b/test/helpers/memory.hpp index 7ed3d046..102fd16e 100644 --- a/test/helpers/memory.hpp +++ b/test/helpers/memory.hpp @@ -181,9 +181,9 @@ namespace test } } - template + template struct bool_type { - enum { value = Value }; + enum { value = (Value ? true : false) }; }; struct true_type { @@ -194,15 +194,6 @@ namespace test enum { value = false }; }; - template - struct is_select_on_copy : false_type {}; - template - struct is_propagate_on_swap : false_type {}; - template - struct is_propagate_on_assign : false_type {}; - template - struct is_propagate_on_move : false_type {}; - template int selected_count(Alloc const&) { diff --git a/test/objects/cxx11_allocator.hpp b/test/objects/cxx11_allocator.hpp index 2971da44..f909b663 100644 --- a/test/objects/cxx11_allocator.hpp +++ b/test/objects/cxx11_allocator.hpp @@ -15,39 +15,63 @@ namespace test { - enum allocator_flags + struct allocator_false { - allocator_false = 0, - select_copy = 1, - propagate_swap = 2, - propagate_assign = 4, - propagate_move = 8, - allocator_flags_all = 15, - no_select_copy = allocator_flags_all - select_copy, - no_propagate_swap = allocator_flags_all - propagate_swap, - no_propagate_assign = allocator_flags_all - propagate_assign, - no_propagate_move = allocator_flags_all - propagate_move + enum { + is_select_on_copy = 0, + is_propagate_on_swap = 0, + is_propagate_on_assign = 0, + is_propagate_on_move = 0 + }; + }; + + struct allocator_flags_all + { + enum { + is_select_on_copy = 1, + is_propagate_on_swap = 1, + is_propagate_on_assign = 1, + is_propagate_on_move = 1 + }; }; - template + struct select_copy : allocator_false + { enum { is_select_on_copy = 1 }; }; + struct propagate_swap : allocator_false + { enum { is_propagate_on_swap = 1 }; }; + struct propagate_assign : allocator_false + { enum { is_propagate_on_assign = 1 }; }; + struct propagate_move : allocator_false + { enum { is_propagate_on_move = 1 }; }; + + struct no_select_copy : allocator_flags_all + { enum { is_select_on_copy = 0 }; }; + struct no_propagate_swap : allocator_flags_all + { enum { is_propagate_on_swap = 0 }; }; + struct no_propagate_assign : allocator_flags_all + { enum { is_propagate_on_assign = 0 }; }; + struct no_propagate_move : allocator_flags_all + { enum { is_propagate_on_move = 0 }; }; + + template struct swap_allocator_base { struct propagate_on_container_swap { - enum { value = Flag != allocator_false }; }; + enum { value = Flag::is_propagate_on_swap }; }; }; - template + template struct assign_allocator_base { struct propagate_on_container_copy_assignment { - enum { value = Flag != allocator_false }; }; + enum { value = Flag::is_propagate_on_assign }; }; }; - template + template struct move_allocator_base { struct propagate_on_container_move_assignment { - enum { value = Flag != allocator_false }; }; + enum { value = Flag::is_propagate_on_move }; }; }; namespace @@ -161,13 +185,14 @@ namespace test } }; - template + template struct cxx11_allocator : public cxx11_allocator_base, - public swap_allocator_base, - public assign_allocator_base, - public move_allocator_base + public swap_allocator_base, + public assign_allocator_base, + public move_allocator_base, + Flags { template struct rebind { typedef cxx11_allocator other; @@ -202,12 +227,13 @@ namespace test } }; - template + template struct cxx11_allocator : public cxx11_allocator_base, - public swap_allocator_base, - public assign_allocator_base, - public move_allocator_base + public swap_allocator_base, + public assign_allocator_base, + public move_allocator_base, + Flags { cxx11_allocator select_on_container_copy_construction() const { @@ -249,7 +275,7 @@ namespace test } }; - template + template bool equivalent_impl( cxx11_allocator const& x, cxx11_allocator const& y, @@ -258,20 +284,7 @@ namespace test return x.tag_ == y.tag_; } - template - struct is_select_on_copy > - : bool_type<(Flags & select_copy) ? true : false> {}; - template - struct is_propagate_on_swap > - : bool_type<(Flags & propagate_swap) ? true : false> {}; - template - struct is_propagate_on_assign > - : bool_type<(Flags & propagate_assign) ? true : false> {}; - template - struct is_propagate_on_move > - : bool_type<(Flags & propagate_move) ? true : false> {}; - - template + template int selected_count(cxx11_allocator const& x) { return x.selected_; diff --git a/test/objects/test.hpp b/test/objects/test.hpp index a2cf6c87..d1fe5c3b 100644 --- a/test/objects/test.hpp +++ b/test/objects/test.hpp @@ -284,6 +284,13 @@ namespace test { return tag_ != x.tag_; } + + enum { + is_select_on_copy = false, + is_propagate_on_swap = false, + is_propagate_on_assign = false, + is_propagate_on_move = false + }; }; template diff --git a/test/unordered/assign_tests.cpp b/test/unordered/assign_tests.cpp index f19b894f..2e0d71ad 100644 --- a/test/unordered/assign_tests.cpp +++ b/test/unordered/assign_tests.cpp @@ -99,7 +99,7 @@ void assign_tests2(T*, x2 = x1; BOOST_TEST(test::equivalent(x2.hash_function(), hf1)); BOOST_TEST(test::equivalent(x2.key_eq(), eq1)); - if (test::is_propagate_on_assign::value) { + if (allocator_type::is_propagate_on_assign) { BOOST_TEST(test::equivalent(x2.get_allocator(), al1)); BOOST_TEST(!test::equivalent(x2.get_allocator(), al2)); } @@ -161,6 +161,19 @@ boost::unordered_multimap +bool is_propagate(T*) +{ + return T::allocator_type::is_propagate_on_assign; +} + +UNORDERED_AUTO_TEST(check_traits) +{ + BOOST_TEST(!is_propagate(test_set)); + BOOST_TEST(is_propagate(test_set_prop_assign)); + BOOST_TEST(!is_propagate(test_set_no_prop_assign)); +} + UNORDERED_TEST(assign_tests1, ( (test_set)(test_multiset)(test_map)(test_multimap) (test_set_prop_assign)(test_multiset_prop_assign)(test_map_prop_assign)(test_multimap_prop_assign) diff --git a/test/unordered/copy_tests.cpp b/test/unordered/copy_tests.cpp index e0d4950e..0200a48e 100644 --- a/test/unordered/copy_tests.cpp +++ b/test/unordered/copy_tests.cpp @@ -41,7 +41,7 @@ void copy_construct_tests1(T*, BOOST_TEST(test::equivalent(y.get_allocator(), al)); BOOST_TEST(x.max_load_factor() == y.max_load_factor()); BOOST_TEST(test::selected_count(y.get_allocator()) == - (test::is_select_on_copy::value ? 1 : 0)); + (allocator_type::is_select_on_copy)); test::check_equivalent_keys(y); } @@ -55,7 +55,7 @@ void copy_construct_tests1(T*, test::unordered_equivalence_tester equivalent(x); BOOST_TEST(equivalent(y)); BOOST_TEST(test::selected_count(y.get_allocator()) == - (test::is_select_on_copy::value ? 1 : 0)); + (allocator_type::is_select_on_copy)); test::check_equivalent_keys(y); } @@ -75,7 +75,7 @@ void copy_construct_tests1(T*, // This isn't guaranteed: BOOST_TEST(y.load_factor() < y.max_load_factor()); BOOST_TEST(test::selected_count(y.get_allocator()) == - (test::is_select_on_copy::value ? 1 : 0)); + (allocator_type::is_select_on_copy)); test::check_equivalent_keys(y); } } @@ -104,7 +104,7 @@ void copy_construct_tests2(T* ptr, BOOST_TEST(test::equivalent(y.get_allocator(), al)); BOOST_TEST(x.max_load_factor() == y.max_load_factor()); BOOST_TEST(test::selected_count(y.get_allocator()) == - (test::is_select_on_copy::value ? 1 : 0)); + (allocator_type::is_select_on_copy)); test::check_equivalent_keys(y); } @@ -133,7 +133,7 @@ void copy_construct_tests2(T* ptr, BOOST_TEST(equivalent(y)); test::check_equivalent_keys(y); BOOST_TEST(test::selected_count(y.get_allocator()) == - (test::is_select_on_copy::value ? 1 : 0)); + (allocator_type::is_select_on_copy)); BOOST_TEST(test::equivalent(y.get_allocator(), al)); } diff --git a/test/unordered/move_tests.cpp b/test/unordered/move_tests.cpp index 479437dd..09f3edff 100644 --- a/test/unordered/move_tests.cpp +++ b/test/unordered/move_tests.cpp @@ -153,11 +153,16 @@ namespace move_tests T y(create(v, count, hf, eq, al, 1.0), al); #if !defined(BOOST_NO_RVALUE_REFERENCES) BOOST_TEST(count == test::global_object_count); -#else +#elif defined(BOOST_HAS_NRVO) BOOST_TEST( test::global_object_count.constructions - count.constructions <= (test::is_map::value ? 50 : 25)); BOOST_TEST(count.instances == test::global_object_count.instances); +#else + BOOST_TEST( + test::global_object_count.constructions - count.constructions <= + (test::is_map::value ? 100 : 50)); + BOOST_TEST(count.instances == test::global_object_count.instances); #endif test::check_container(y, v); BOOST_TEST(test::equivalent(y.hash_function(), hf)); @@ -188,7 +193,7 @@ namespace move_tests test::check_container(y, v2); test::check_equivalent_keys(y); BOOST_TEST(y.max_load_factor() == 2.0); - if (test::is_propagate_on_move::value) { + if (allocator_type::is_propagate_on_move) { BOOST_TEST(test::equivalent(y.get_allocator(), al2)); } else { @@ -202,14 +207,14 @@ namespace move_tests T y(0, hf, eq, al1); y = create(v, count, hf, eq, al2, 0.5); #if defined(BOOST_HAS_NRVO) - if (test::is_propagate_on_move::value) { + if (allocator_type::is_propagate_on_move) { BOOST_TEST(count == test::global_object_count); } #endif test::check_container(y, v); test::check_equivalent_keys(y); BOOST_TEST(y.max_load_factor() == 0.5); - if (test::is_propagate_on_move::value) { + if (allocator_type::is_propagate_on_move) { BOOST_TEST(test::equivalent(y.get_allocator(), al2)); } else { diff --git a/test/unordered/swap_tests.cpp b/test/unordered/swap_tests.cpp index a1aca83a..9769af7f 100644 --- a/test/unordered/swap_tests.cpp +++ b/test/unordered/swap_tests.cpp @@ -113,14 +113,14 @@ void swap_tests2(X* ptr = 0, { test::force_equal_allocator force_( - !test::is_propagate_on_swap::value); + !allocator_type::is_propagate_on_swap); test::check_instances check_; test::random_values vx(50, generator), vy(100, generator); X x(vx.begin(), vx.end(), 0, hasher(), key_equal(), allocator_type(1)); X y(vy.begin(), vy.end(), 0, hasher(), key_equal(), allocator_type(2)); - if (test::is_propagate_on_swap::value || + if (allocator_type::is_propagate_on_swap || x.get_allocator() == y.get_allocator()) { swap_test_impl(x, y); @@ -129,7 +129,7 @@ void swap_tests2(X* ptr = 0, { test::force_equal_allocator force_( - !test::is_propagate_on_swap::value); + !allocator_type::is_propagate_on_swap); test::check_instances check_; test::random_values vx(100, generator), vy(100, generator); @@ -138,7 +138,7 @@ void swap_tests2(X* ptr = 0, X y(vy.begin(), vy.end(), 0, hasher(2), key_equal(2), allocator_type(2)); - if (test::is_propagate_on_swap::value || + if (allocator_type::is_propagate_on_swap || x.get_allocator() == y.get_allocator()) { swap_test_impl(x, y); @@ -194,6 +194,19 @@ boost::unordered_multimap >* test_multimap_no_prop_swap; +template +bool is_propagate(T*) +{ + return T::allocator_type::is_propagate_on_swap; +} + +UNORDERED_AUTO_TEST(check_traits) +{ + BOOST_TEST(!is_propagate(test_set)); + BOOST_TEST(is_propagate(test_set_prop_swap)); + BOOST_TEST(!is_propagate(test_set_no_prop_swap)); +} + UNORDERED_TEST(swap_tests1, ( (test_set)(test_multiset)(test_map)(test_multimap) (test_set_prop_swap)(test_multiset_prop_swap)(test_map_prop_swap)(test_multimap_prop_swap) diff --git a/test/unordered/unnecessary_copy_tests.cpp b/test/unordered/unnecessary_copy_tests.cpp index 4b9ec9c7..4da803bc 100644 --- a/test/unordered/unnecessary_copy_tests.cpp +++ b/test/unordered/unnecessary_copy_tests.cpp @@ -201,9 +201,9 @@ namespace unnecessary_copy_tests COPY_COUNT(1); MOVE_COUNT(0); x.emplace(boost::move(a)); #if defined(BOOST_NO_RVALUE_REFERENCES) - COPY_COUNT(1); MOVE_COUNT(1); -#else COPY_COUNT(2); MOVE_COUNT(0); +#else + COPY_COUNT(1); MOVE_COUNT(1); #endif } @@ -227,11 +227,11 @@ namespace unnecessary_copy_tests reset(); x.emplace(); #if defined(BOOST_UNORDERED_STD_FORWARD_MOVE) + COPY_COUNT(1); MOVE_COUNT(0); +#else // TODO: I think that in this case the move could be delayed until // after checking for a collision, giving MOVE_COUNT(0). COPY_COUNT(1); MOVE_COUNT(1); -#else - COPY_COUNT(1); MOVE_COUNT(0); #endif //