$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r73798 - in trunk/libs/unordered/test: helpers objects unordered
From: dnljms_at_[hidden]
Date: 2011-08-15 16:23:31
Author: danieljames
Date: 2011-08-15 16:23:29 EDT (Mon, 15 Aug 2011)
New Revision: 73798
URL: http://svn.boost.org/trac/boost/changeset/73798
Log:
Unordered: Fix some portability issues in tests.
- Simplify mechanism for detecting traits of test allocators. There were
  some portability issues, but rather than fix them I've just gone for a
  simpler mechanism. Does mean that the relevant tests can't be run for
  other allocators.
- Fix a couple of unnecessary_copy_tests, whose results were the wrong
  way round.
- It appears that Visual C++ only implements RVO for implicitly defined
  copy constructors in debug mode, so adjust a move_test to account for
  the extra copies now that the copy constructors are explicitly
  defined.
Text files modified: 
   trunk/libs/unordered/test/helpers/memory.hpp                   |    13 ----                                    
   trunk/libs/unordered/test/objects/cxx11_allocator.hpp          |    95 ++++++++++++++++++++++----------------- 
   trunk/libs/unordered/test/objects/test.hpp                     |     7 ++                                      
   trunk/libs/unordered/test/unordered/assign_tests.cpp           |    15 +++++                                   
   trunk/libs/unordered/test/unordered/copy_tests.cpp             |    10 ++--                                    
   trunk/libs/unordered/test/unordered/move_tests.cpp             |    13 +++-                                    
   trunk/libs/unordered/test/unordered/swap_tests.cpp             |    21 +++++++-                                
   trunk/libs/unordered/test/unordered/unnecessary_copy_tests.cpp |     8 +-                                      
   8 files changed, 112 insertions(+), 70 deletions(-)
Modified: trunk/libs/unordered/test/helpers/memory.hpp
==============================================================================
--- trunk/libs/unordered/test/helpers/memory.hpp	(original)
+++ trunk/libs/unordered/test/helpers/memory.hpp	2011-08-15 16:23:29 EDT (Mon, 15 Aug 2011)
@@ -181,9 +181,9 @@
         }
     }
     
-    template <bool Value>
+    template <int Value>
     struct bool_type {
-        enum { value = Value };
+        enum { value = (Value ? true : false) };
     };
 
     struct true_type {
@@ -195,15 +195,6 @@
     };
 
     template <typename Alloc>
-    struct is_select_on_copy : false_type {};
-    template <typename Alloc>
-    struct is_propagate_on_swap : false_type {};
-    template <typename Alloc>
-    struct is_propagate_on_assign : false_type {};
-    template <typename Alloc>
-    struct is_propagate_on_move : false_type {};
-
-    template <typename Alloc>
     int selected_count(Alloc const&)
     {
         return 0;
Modified: trunk/libs/unordered/test/objects/cxx11_allocator.hpp
==============================================================================
--- trunk/libs/unordered/test/objects/cxx11_allocator.hpp	(original)
+++ trunk/libs/unordered/test/objects/cxx11_allocator.hpp	2011-08-15 16:23:29 EDT (Mon, 15 Aug 2011)
@@ -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
+        };
+    };
+    
+    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 <int Flag>
+    template <typename Flag>
     struct swap_allocator_base
     {
         struct propagate_on_container_swap {
-            enum { value = Flag != allocator_false }; };
+            enum { value = Flag::is_propagate_on_swap }; };
     };
 
-    template <int Flag>
+    template <typename Flag>
     struct assign_allocator_base
     {
         struct propagate_on_container_copy_assignment {
-            enum { value = Flag != allocator_false }; };
+            enum { value = Flag::is_propagate_on_assign }; };
     };
 
-    template <int Flag>
+    template <typename Flag>
     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 @@
         }
     };
 
-    template <typename T, allocator_flags Flags = propagate_swap,
-        bool SelectCopy = (Flags & select_copy) ? true : false>
+    template <typename T, typename Flags = propagate_swap,
+        bool SelectCopy = Flags::is_select_on_copy ? true : false>
     struct cxx11_allocator :
         public cxx11_allocator_base<T>,
-        public swap_allocator_base<Flags & propagate_swap>,
-        public assign_allocator_base<Flags & propagate_assign>,
-        public move_allocator_base<Flags & propagate_move>
+        public swap_allocator_base<Flags>,
+        public assign_allocator_base<Flags>,
+        public move_allocator_base<Flags>,
+        Flags
     {
         template <typename U> struct rebind {
             typedef cxx11_allocator<U, Flags> other;
@@ -202,12 +227,13 @@
         }
     };
 
-    template <typename T, allocator_flags Flags>
+    template <typename T, typename Flags>
     struct cxx11_allocator<T, Flags, true> : 
         public cxx11_allocator_base<T>,
-        public swap_allocator_base<Flags & propagate_swap>,
-        public assign_allocator_base<Flags & propagate_assign>,
-        public move_allocator_base<Flags & propagate_move>
+        public swap_allocator_base<Flags>,
+        public assign_allocator_base<Flags>,
+        public move_allocator_base<Flags>,
+        Flags
     {
         cxx11_allocator select_on_container_copy_construction() const
         {
@@ -249,7 +275,7 @@
         }
     };
 
-    template <typename T, allocator_flags Flags>
+    template <typename T, typename Flags>
     bool equivalent_impl(
             cxx11_allocator<T, Flags> const& x,
             cxx11_allocator<T, Flags> const& y,
@@ -258,20 +284,7 @@
         return x.tag_ == y.tag_;
     }
 
-    template <typename T, allocator_flags Flags>
-    struct is_select_on_copy<cxx11_allocator<T, Flags> >
-        : bool_type<(Flags & select_copy) ? true : false> {};
-    template <typename T, allocator_flags Flags>
-    struct is_propagate_on_swap<cxx11_allocator<T, Flags> >
-        : bool_type<(Flags & propagate_swap) ? true : false> {};
-    template <typename T, allocator_flags Flags>
-    struct is_propagate_on_assign<cxx11_allocator<T, Flags> >
-        : bool_type<(Flags & propagate_assign) ? true : false> {};
-    template <typename T, allocator_flags Flags>
-    struct is_propagate_on_move<cxx11_allocator<T, Flags> >
-        : bool_type<(Flags & propagate_move) ? true : false> {};
-
-    template <typename T, allocator_flags Flags>
+    template <typename T, typename Flags>
     int selected_count(cxx11_allocator<T, Flags> const& x)
     {
         return x.selected_;
Modified: trunk/libs/unordered/test/objects/test.hpp
==============================================================================
--- trunk/libs/unordered/test/objects/test.hpp	(original)
+++ trunk/libs/unordered/test/objects/test.hpp	2011-08-15 16:23:29 EDT (Mon, 15 Aug 2011)
@@ -284,6 +284,13 @@
         {
             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 <class T>
Modified: trunk/libs/unordered/test/unordered/assign_tests.cpp
==============================================================================
--- trunk/libs/unordered/test/unordered/assign_tests.cpp	(original)
+++ trunk/libs/unordered/test/unordered/assign_tests.cpp	2011-08-15 16:23:29 EDT (Mon, 15 Aug 2011)
@@ -99,7 +99,7 @@
         x2 = x1;
         BOOST_TEST(test::equivalent(x2.hash_function(), hf1));
         BOOST_TEST(test::equivalent(x2.key_eq(), eq1));
-        if (test::is_propagate_on_assign<allocator_type>::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 @@
 using test::default_generator;
 using test::generate_collisions;
 
+template <typename T>
+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)
Modified: trunk/libs/unordered/test/unordered/copy_tests.cpp
==============================================================================
--- trunk/libs/unordered/test/unordered/copy_tests.cpp	(original)
+++ trunk/libs/unordered/test/unordered/copy_tests.cpp	2011-08-15 16:23:29 EDT (Mon, 15 Aug 2011)
@@ -41,7 +41,7 @@
         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<allocator_type>::value ? 1 : 0));
+            (allocator_type::is_select_on_copy));
         test::check_equivalent_keys(y);
     }
 
@@ -55,7 +55,7 @@
         test::unordered_equivalence_tester<T> equivalent(x);
         BOOST_TEST(equivalent(y));
         BOOST_TEST(test::selected_count(y.get_allocator()) ==
-            (test::is_select_on_copy<allocator_type>::value ? 1 : 0));
+            (allocator_type::is_select_on_copy));
         test::check_equivalent_keys(y);
     }
 
@@ -75,7 +75,7 @@
         // 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<allocator_type>::value ? 1 : 0));
+            (allocator_type::is_select_on_copy));
         test::check_equivalent_keys(y);
     }
 }
@@ -104,7 +104,7 @@
         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<allocator_type>::value ? 1 : 0));
+            (allocator_type::is_select_on_copy));
         test::check_equivalent_keys(y);
     }
 
@@ -133,7 +133,7 @@
         BOOST_TEST(equivalent(y));
         test::check_equivalent_keys(y);
         BOOST_TEST(test::selected_count(y.get_allocator()) ==
-            (test::is_select_on_copy<allocator_type>::value ? 1 : 0));
+            (allocator_type::is_select_on_copy));
         BOOST_TEST(test::equivalent(y.get_allocator(), al));
     }
 
Modified: trunk/libs/unordered/test/unordered/move_tests.cpp
==============================================================================
--- trunk/libs/unordered/test/unordered/move_tests.cpp	(original)
+++ trunk/libs/unordered/test/unordered/move_tests.cpp	2011-08-15 16:23:29 EDT (Mon, 15 Aug 2011)
@@ -153,11 +153,16 @@
             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<T>::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<T>::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 @@
             test::check_container(y, v2);
             test::check_equivalent_keys(y);
             BOOST_TEST(y.max_load_factor() == 2.0);
-            if (test::is_propagate_on_move<allocator_type>::value) {
+            if (allocator_type::is_propagate_on_move) {
                 BOOST_TEST(test::equivalent(y.get_allocator(), al2));
             }
             else {
@@ -202,14 +207,14 @@
             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<allocator_type>::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<allocator_type>::value) {
+            if (allocator_type::is_propagate_on_move) {
                 BOOST_TEST(test::equivalent(y.get_allocator(), al2));
             }
             else {
Modified: trunk/libs/unordered/test/unordered/swap_tests.cpp
==============================================================================
--- trunk/libs/unordered/test/unordered/swap_tests.cpp	(original)
+++ trunk/libs/unordered/test/unordered/swap_tests.cpp	2011-08-15 16:23:29 EDT (Mon, 15 Aug 2011)
@@ -113,14 +113,14 @@
 
     {
         test::force_equal_allocator force_(
-            !test::is_propagate_on_swap<allocator_type>::value);
+            !allocator_type::is_propagate_on_swap);
         test::check_instances check_;
 
         test::random_values<X> 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<allocator_type>::value ||
+        if (allocator_type::is_propagate_on_swap ||
             x.get_allocator() == y.get_allocator())
         {
             swap_test_impl(x, y);
@@ -129,7 +129,7 @@
 
     {
         test::force_equal_allocator force_(
-            !test::is_propagate_on_swap<allocator_type>::value);
+            !allocator_type::is_propagate_on_swap);
         test::check_instances check_;
 
         test::random_values<X> vx(100, generator), vy(100, generator);
@@ -138,7 +138,7 @@
         X y(vy.begin(), vy.end(), 0, hasher(2), key_equal(2),
             allocator_type(2));
 
-        if (test::is_propagate_on_swap<allocator_type>::value ||
+        if (allocator_type::is_propagate_on_swap ||
             x.get_allocator() == y.get_allocator())
         {
             swap_test_impl(x, y);
@@ -194,6 +194,19 @@
         test::cxx11_allocator<test::object, test::no_propagate_swap> >*
     test_multimap_no_prop_swap;
 
+template <typename T>
+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)
Modified: trunk/libs/unordered/test/unordered/unnecessary_copy_tests.cpp
==============================================================================
--- trunk/libs/unordered/test/unordered/unnecessary_copy_tests.cpp	(original)
+++ trunk/libs/unordered/test/unordered/unnecessary_copy_tests.cpp	2011-08-15 16:23:29 EDT (Mon, 15 Aug 2011)
@@ -201,9 +201,9 @@
         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 @@
         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
 
         //