$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r74101 - in branches/release: boost/unordered boost/unordered/detail libs/unordered libs/unordered/test/helpers libs/unordered/test/objects libs/unordered/test/unordered
From: dnljms_at_[hidden]
Date: 2011-08-28 07:26:41
Author: danieljames
Date: 2011-08-28 07:26:38 EDT (Sun, 28 Aug 2011)
New Revision: 74101
URL: http://svn.boost.org/trac/boost/changeset/74101
Log:
Unordered: Merge from trunk.
Portability fixes, and fix some issues with constructing std::pair.
Added:
   branches/release/libs/unordered/test/unordered/allocator_traits.cpp
      - copied unchanged from r74100, /trunk/libs/unordered/test/unordered/allocator_traits.cpp
Properties modified: 
   branches/release/boost/unordered/   (props changed)
   branches/release/libs/unordered/   (props changed)
Text files modified: 
   branches/release/boost/unordered/detail/allocator_helpers.hpp             |   121 +++++++++++++++++-------------          
   branches/release/boost/unordered/detail/buckets.hpp                       |   154 ++++++++++++++++++++++++++++++++------- 
   branches/release/boost/unordered/detail/table.hpp                         |     8 +                                       
   branches/release/libs/unordered/test/helpers/memory.hpp                   |     9 +                                       
   branches/release/libs/unordered/test/objects/cxx11_allocator.hpp          |    17 +++-                                    
   branches/release/libs/unordered/test/objects/test.hpp                     |     4                                         
   branches/release/libs/unordered/test/unordered/Jamfile.v2                 |     1                                         
   branches/release/libs/unordered/test/unordered/insert_tests.cpp           |    79 ++++++++++++++++++++                    
   branches/release/libs/unordered/test/unordered/unnecessary_copy_tests.cpp |     5 +                                       
   9 files changed, 304 insertions(+), 94 deletions(-)
Modified: branches/release/boost/unordered/detail/allocator_helpers.hpp
==============================================================================
--- branches/release/boost/unordered/detail/allocator_helpers.hpp	(original)
+++ branches/release/boost/unordered/detail/allocator_helpers.hpp	2011-08-28 07:26:38 EDT (Sun, 28 Aug 2011)
@@ -5,8 +5,8 @@
 // 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)
 //
-// Written by Daniel James using some code from Pablo Halpern's
-// allocator traits implementation.
+// Allocator traits written by Daniel James based on Pablo Halpern's
+// implementation.
 
 #ifndef BOOST_UNORDERED_DETAIL_ALLOCATOR_UTILITIES_HPP_INCLUDED
 #define BOOST_UNORDERED_DETAIL_ALLOCATOR_UTILITIES_HPP_INCLUDED
@@ -18,6 +18,7 @@
 #include <boost/config.hpp>
 #include <boost/detail/select_type.hpp>
 #include <boost/utility/enable_if.hpp>
+#include <boost/preprocessor/cat.hpp>
 
 #if (defined(BOOST_NO_STD_ALLOCATOR) || defined(BOOST_DINKUMWARE_STDLIB)) \
     && !defined(__BORLANDC__)
@@ -81,38 +82,39 @@
     };
 #   endif
 
-    struct convertible_from_anything
-    {
-        template<typename T> convertible_from_anything(T const&);
-    };
+    template <typename T> T& make();
+    struct choice9 { typedef char (&type)[9]; };
+    struct choice8 : choice9 { typedef char (&type)[8]; };
+    struct choice7 : choice8 { typedef char (&type)[7]; };
+    struct choice6 : choice7 { typedef char (&type)[6]; };
+    struct choice5 : choice6 { typedef char (&type)[5]; };
+    struct choice4 : choice5 { typedef char (&type)[4]; };
+    struct choice3 : choice4 { typedef char (&type)[3]; };
+    struct choice2 : choice3 { typedef char (&type)[2]; };
+    struct choice1 : choice2 { typedef char (&type)[1]; };
+    choice1 choose();
 
-    typedef char (&no_type)[1];
-    typedef char (&yes_type)[2];
-
-    template <typename T> struct sfinae {
-        typedef yes_type type;
-    };
-
-    // Infrastructure for providing a default type for Tp::tname if absent.
     #define BOOST_DEFAULT_TYPE_TMPLT(tname)                                 \
         template <typename Tp, typename Default>                            \
         struct default_type_ ## tname {                                     \
-            template <typename T>                                           \
-            static BOOST_DEDUCED_TYPENAME sfinae<                           \
-                BOOST_DEDUCED_TYPENAME T::tname>::type test(int);           \
-            template <typename T>                                           \
-            static no_type test(long);                                      \
                                                                             \
-            enum { value = sizeof(test<Tp>(0)) == sizeof(yes_type) };       \
+            template <typename X>                                           \
+            static choice1::type test(choice1,                              \
+                BOOST_DEDUCED_TYPENAME X::tname* = 0);                      \
+                                                                            \
+            template <typename X>                                           \
+            static choice2::type test(choice2, void* = 0);                  \
                                                                             \
             struct DefaultWrap { typedef Default tname; };                  \
                                                                             \
+            enum { value = (1 == sizeof(test<Tp>(choose()))) };             \
+                                                                            \
             typedef BOOST_DEDUCED_TYPENAME                                  \
                 boost::detail::if_true<value>::                             \
                 BOOST_NESTED_TEMPLATE then<Tp, DefaultWrap>                 \
                 ::type::tname type;                                         \
         }
-    
+
     #define BOOST_DEFAULT_TYPE(T,tname, arg)                                \
         BOOST_DEDUCED_TYPENAME default_type_ ## tname<T, arg>::type
 
@@ -127,47 +129,62 @@
     BOOST_DEFAULT_TYPE_TMPLT(propagate_on_container_swap);
 
 #if !defined(BOOST_NO_SFINAE_EXPR) || BOOST_WORKAROUND(BOOST_MSVC, >= 1500)
-    // Specialization is only needed for Visual C++. Without it SFINAE doesn't
-    // kick in.
-    template <unsigned int>
-    struct expr_sfinae;
-    
-    template <>
-    struct expr_sfinae<sizeof(yes_type)> {
-        typedef yes_type type;
-    };
-    
+
+    template <typename T, unsigned int> struct expr_test;
+    template <typename T> struct expr_test<T, sizeof(char)> : T {};
+    template <typename U> static char for_expr_test(U const&);
+
+#define BOOST_UNORDERED_CHECK_EXPRESSION(count, result, expression)         \
+        template <typename U>                                               \
+        static typename expr_test<                                          \
+            BOOST_PP_CAT(choice, result),                                   \
+            sizeof(for_expr_test(((expression), 0)))>::type test(           \
+            BOOST_PP_CAT(choice, count))
+
+#define BOOST_UNORDERED_DEFAULT_EXPRESSION(count, result)                   \
+        template <typename U>                                               \
+        static BOOST_PP_CAT(choice, result)::type test(                     \
+            BOOST_PP_CAT(choice, count))
+
     template <typename T>
     struct has_select_on_container_copy_construction
     {
-        // This needs to be a template for Visual C++.
-        template <typename T2>
-        static yes_type to_yes_type(const T2&);
-
-        template <typename T2>
-        static typename expr_sfinae<sizeof(to_yes_type(
-            ((T2 const*)0)->select_on_container_copy_construction()
-        ))>::type check(T2*);
-
-        static no_type check(void*);
+        BOOST_UNORDERED_CHECK_EXPRESSION(1, 1, make<U const>().select_on_container_copy_construction());
+        BOOST_UNORDERED_DEFAULT_EXPRESSION(2, 2);
         
-        enum { value = sizeof(check((T*) 0)) == sizeof(yes_type) };
+        enum { value = sizeof(test<T>(choose())) == sizeof(choice1::type) };
     };
+
 #else
+
+   template <typename T> struct identity { typedef T type; };
+
+#define BOOST_UNORDERED_CHECK_MEMBER(count, result, name, member)           \
+                                                                            \
+    typedef typename identity<member>::type BOOST_PP_CAT(check, count);     \
+                                                                            \
+    template <BOOST_PP_CAT(check, count) e>                                 \
+    struct BOOST_PP_CAT(test, count) {                                      \
+        typedef void* type;                                                 \
+    };                                                                      \
+                                                                            \
+    template <class U> static BOOST_PP_CAT(choice, result)::type            \
+        test(BOOST_PP_CAT(choice, count),                                   \
+            typename BOOST_PP_CAT(test, count)<                             \
+                &U::name>::type = 0)
+
+#define BOOST_UNORDERED_DEFAULT_MEMBER(count, result)                       \
+    template <class U> static BOOST_PP_CAT(choice, result)::type            \
+        test(BOOST_PP_CAT(choice, count), void* = 0)
+
+
     template <typename T>
     struct has_select_on_container_copy_construction
     {
-        typedef T (T::*SelectFunc)() const;
-
-        template <SelectFunc e> struct sfinae { typedef yes_type type; };
-
-        template <class U>  
-        static typename sfinae<&U::select_on_container_copy_construction>::type
-            test(int);  
-        template <class U>  
-        static no_type test(...);  
+        BOOST_UNORDERED_CHECK_MEMBER(1, 1, select_on_container_copy_construction, T (T::*)() const);
+        BOOST_UNORDERED_DEFAULT_MEMBER(2, 2);
  
-        enum { value = sizeof(test<T>(1)) == sizeof(yes_type) };
+        enum { value = sizeof(test<T>(choose())) == sizeof(choice1::type) };
     };
 
 #endif
Modified: branches/release/boost/unordered/detail/buckets.hpp
==============================================================================
--- branches/release/boost/unordered/detail/buckets.hpp	(original)
+++ branches/release/boost/unordered/detail/buckets.hpp	2011-08-28 07:26:38 EDT (Sun, 28 Aug 2011)
@@ -517,44 +517,139 @@
     ////////////////////////////////////////////////////////////////////////////
     // Node Constructors
 
+    template <typename T, typename Arg1 = void>
+    struct emulated_pair_constructor
+    {
+        enum { value = false };
+    };
+    
+    template <typename A, typename B>
+    struct emulated_pair_constructor<std::pair<A, B>, void>
+    {
+        enum { value = true };
+    };
+    
+    template <typename A, typename B, typename Value>
+    struct emulated_pair_constructor<std::pair<A, B>, Value>
+    {
+        static choice1::type check(choice1, std::pair<A, B> const&);
+        static choice2::type check(choice2, A const&);
+    
+        enum { value = sizeof(check(choose(), make<Value>())) - 1 };
+    };
+
+    template <class T>
+    inline void construct_impl(void* address)
+    {
+        new(address) T();
+    }
+
 #if defined(BOOST_UNORDERED_STD_FORWARD_MOVE)
 
-    template <class T, class... Args>
-    inline void construct_impl(T*, void* address, Args&&... args)
+    template <class T, class Arg1>
+    inline void construct_impl(
+            typename boost::disable_if<emulated_pair_constructor<T, Arg1>,
+                void*>::type address,
+            Arg1&& a1)
+    {
+        new(address) T(std::forward<Arg1>(a1));
+    }
+
+    template <class T, class Arg1>
+    inline void construct_impl(
+            typename boost::enable_if<emulated_pair_constructor<T, Arg1>,
+                void*>::type address,
+            Arg1&& a1)
+    {
+        new(address) T(std::forward<Arg1>(a1), typename T::second_type());
+    }
+
+    template <class T, class Arg1, class Arg2>
+    inline void construct_impl(void* address, Arg1&& a1, Arg2&& a2)
     {
-        new(address) T(std::forward<Args>(args)...);
+        new(address) T(std::forward<Arg1>(a1), std::forward<Arg2>(a2));
+    }
+
+    template <class T, class Arg1, class Arg2, class... Args>
+    inline typename boost::disable_if<emulated_pair_constructor<T>, void>::type
+    construct_impl(void* address, Arg1&& arg1, Arg2&& arg2, Args&&... args)
+    {
+        new(address) T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2),
+            std::forward<Args>(args)...);
+    }
+
+    template <class T, class Arg1, class Arg2, class... Args>
+    inline typename boost::enable_if<emulated_pair_constructor<T>, void>::type
+    construct_impl(void* address, Arg1&& arg1, Arg2&& arg2, Args&&... args)
+    {
+        new(address) T(std::forward<Arg1>(arg1),
+            typename T::second_type(
+                std::forward<Arg2>(arg2), std::forward<Args>(args)...));
     }
 
 #else
 
-#define BOOST_UNORDERED_CONSTRUCT_IMPL(z, num_params, _)                       \
-    template <                                                                 \
-        class T,                                                               \
-        BOOST_UNORDERED_TEMPLATE_ARGS(z, num_params)                           \
-    >                                                                          \
-    inline void construct_impl(                                                \
-        T*, void* address,                                                     \
-        BOOST_UNORDERED_FUNCTION_PARAMS(z, num_params)                         \
-    )                                                                          \
-    {                                                                          \
-        new(address) T(                                                        \
-            BOOST_UNORDERED_CALL_PARAMS(z, num_params));                       \
-    }                                                                          \
-                                                                               \
-    template <class First, class Second, class Key,                            \
-        BOOST_UNORDERED_TEMPLATE_ARGS(z, num_params)                           \
-    >                                                                          \
-    inline void construct_impl(                                                \
-        std::pair<First, Second>*, void* address,                              \
-        Key const& k, BOOST_UNORDERED_FUNCTION_PARAMS(z, num_params))          \
-    {                                                                          \
-        new(address) std::pair<First, Second>(k,                               \
-            Second(BOOST_UNORDERED_CALL_PARAMS(z, num_params)));               \
+    template <class T, class Arg1>
+    inline BOOST_DEDUCED_TYPENAME boost::disable_if<emulated_pair_constructor<T, Arg1>, void>::type
+        construct_impl(void* address, BOOST_FWD_REF(Arg1) a1)
+    {
+        new(address) T(boost::forward<Arg1>(a1));
+    }
+
+    template <class T, class Arg1>
+    inline BOOST_DEDUCED_TYPENAME boost::enable_if<emulated_pair_constructor<T, Arg1>, void>::type
+        construct_impl(void* address, BOOST_FWD_REF(Arg1) a1)
+    {
+        new(address) T(
+            boost::forward<Arg1>(a1),
+            BOOST_DEDUCED_TYPENAME T::second_type()
+        );
     }
 
-    BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT,
+    template <class T, class Arg1, class Arg2>
+    inline void construct_impl(void* address,
+            BOOST_FWD_REF(Arg1) a1, BOOST_FWD_REF(Arg2) a2)
+    {
+        new(address) T(boost::forward<Arg1>(a1), boost::forward<Arg2>(a2));
+    }
+    
+#define BOOST_UNORDERED_CONSTRUCT_IMPL(z, num_params, _)                    \
+    template <                                                              \
+        class T,                                                            \
+        BOOST_UNORDERED_TEMPLATE_ARGS(z, num_params)                        \
+    >                                                                       \
+    inline void construct_impl(                                             \
+        BOOST_DEDUCED_TYPENAME                                              \
+        boost::disable_if<emulated_pair_constructor<T>, void*>::type        \
+        address,                                                            \
+        BOOST_UNORDERED_FUNCTION_PARAMS(z, num_params)                      \
+    )                                                                       \
+    {                                                                       \
+        new(address) T(                                                     \
+            BOOST_UNORDERED_CALL_PARAMS(z, num_params));                    \
+    }
+
+    BOOST_PP_REPEAT_FROM_TO(3, BOOST_UNORDERED_EMPLACE_LIMIT,
         BOOST_UNORDERED_CONSTRUCT_IMPL, _)
 
+#define BOOST_UNORDERED_CONSTRUCT_PAIR_IMPL(z, num_params, _)               \
+    template <class T, class Key,                                           \
+        BOOST_UNORDERED_TEMPLATE_ARGS(z, num_params)                        \
+    >                                                                       \
+    inline void construct_impl(                                             \
+        BOOST_DEDUCED_TYPENAME                                              \
+        boost::enable_if<emulated_pair_constructor<T>, void*>::type         \
+        address,                                                            \
+        Key const& k, BOOST_UNORDERED_FUNCTION_PARAMS(z, num_params))       \
+    {                                                                       \
+        new(address) T(k,                                                   \
+            BOOST_DEDUCED_TYPENAME                                          \
+            T::second_type(BOOST_UNORDERED_CALL_PARAMS(z, num_params)));    \
+    }
+
+    BOOST_PP_REPEAT_FROM_TO(2, BOOST_UNORDERED_EMPLACE_LIMIT,
+        BOOST_UNORDERED_CONSTRUCT_PAIR_IMPL, _)
+
 #undef BOOST_UNORDERED_CONSTRUCT_IMPL
 #endif
 
@@ -594,7 +689,7 @@
         void construct(Args&&... args)
         {
             construct_preamble();
-            construct_impl((value_type*) 0, node_->address(),
+            construct_impl<value_type>(node_->address(),
                 std::forward<Args>(args)...);
             value_constructed_ = true;
         }
@@ -609,8 +704,7 @@
         )                                                                      \
         {                                                                      \
             construct_preamble();                                              \
-            construct_impl(                                                    \
-                (value_type*) 0, node_->address(),                             \
+            construct_impl<value_type>(node_->address(),                       \
                 BOOST_UNORDERED_CALL_PARAMS(z, num_params)                     \
             );                                                                 \
             value_constructed_ = true;                                         \
Modified: branches/release/boost/unordered/detail/table.hpp
==============================================================================
--- branches/release/boost/unordered/detail/table.hpp	(original)
+++ branches/release/boost/unordered/detail/table.hpp	2011-08-28 07:26:38 EDT (Sun, 28 Aug 2011)
@@ -167,7 +167,9 @@
             //
             // Or from rehash post-condition:
             // count > size / mlf_
-            return next_prime(double_to_size_t(floor(size / (double) mlf_)) + 1);
+            return next_prime(double_to_size_t(floor(
+                static_cast<double>(size) /
+                static_cast<double>(mlf_))) + 1);
         }
 
         ////////////////////////////////////////////////////////////////////////
@@ -451,7 +453,9 @@
         else {
             // no throw:
             min_buckets = next_prime((std::max)(min_buckets,
-                    double_to_size_t(floor(this->size_ / (double) mlf_)) + 1));
+                double_to_size_t(floor(
+                    static_cast<double>(this->size_) /
+                    static_cast<double>(mlf_))) + 1));
             if(min_buckets != this->bucket_count_) {
                 this->rehash_impl(min_buckets);
                 this->max_load_ = calculate_max_load();
Modified: branches/release/libs/unordered/test/helpers/memory.hpp
==============================================================================
--- branches/release/libs/unordered/test/helpers/memory.hpp	(original)
+++ branches/release/libs/unordered/test/helpers/memory.hpp	2011-08-28 07:26:38 EDT (Sun, 28 Aug 2011)
@@ -194,8 +194,13 @@
         enum { value = false };
     };
 
-    template <typename Alloc>
-    int selected_count(Alloc const&)
+    struct convert_from_anything
+    {
+        template <typename T>
+        convert_from_anything(T const&) {}
+    };
+
+    int selected_count(convert_from_anything)
     {
         return 0;
     }
Modified: branches/release/libs/unordered/test/objects/cxx11_allocator.hpp
==============================================================================
--- branches/release/libs/unordered/test/objects/cxx11_allocator.hpp	(original)
+++ branches/release/libs/unordered/test/objects/cxx11_allocator.hpp	2011-08-28 07:26:38 EDT (Sun, 28 Aug 2011)
@@ -186,9 +186,14 @@
     };
 
     template <typename T, typename Flags = propagate_swap,
-        bool SelectCopy = Flags::is_select_on_copy ? true : false>
-    struct cxx11_allocator :
-        public cxx11_allocator_base<T>,
+        typename Enable = void>
+    struct cxx11_allocator;
+
+    template <typename T, typename Flags>
+    struct cxx11_allocator<
+        T, Flags,
+        typename boost::disable_if_c<Flags::is_select_on_copy>::type
+    > : public cxx11_allocator_base<T>,
         public swap_allocator_base<Flags>,
         public assign_allocator_base<Flags>,
         public move_allocator_base<Flags>,
@@ -228,8 +233,10 @@
     };
 
     template <typename T, typename Flags>
-    struct cxx11_allocator<T, Flags, true> : 
-        public cxx11_allocator_base<T>,
+    struct cxx11_allocator<
+        T, Flags,
+        typename boost::enable_if_c<Flags::is_select_on_copy>::type
+    > : public cxx11_allocator_base<T>,
         public swap_allocator_base<Flags>,
         public assign_allocator_base<Flags>,
         public move_allocator_base<Flags>,
Modified: branches/release/libs/unordered/test/objects/test.hpp
==============================================================================
--- branches/release/libs/unordered/test/objects/test.hpp	(original)
+++ branches/release/libs/unordered/test/objects/test.hpp	2011-08-28 07:26:38 EDT (Sun, 28 Aug 2011)
@@ -26,7 +26,7 @@
     object generate(object const*);
     implicitly_convertible generate(implicitly_convertible const*);
     
-    class object : globally_counted_object
+    class object : private globally_counted_object
     {
         friend class hash;
         friend class equal_to;
@@ -64,7 +64,7 @@
         }
     };
 
-    class implicitly_convertible : globally_counted_object
+    class implicitly_convertible : private globally_counted_object
     {
         int tag1_, tag2_;
     public:
Modified: branches/release/libs/unordered/test/unordered/Jamfile.v2
==============================================================================
--- branches/release/libs/unordered/test/unordered/Jamfile.v2	(original)
+++ branches/release/libs/unordered/test/unordered/Jamfile.v2	2011-08-28 07:26:38 EDT (Sun, 28 Aug 2011)
@@ -22,6 +22,7 @@
     :
         [ run fwd_set_test.cpp ]
         [ run fwd_map_test.cpp ]
+        [ run allocator_traits.cpp ]
         [ run compile_set.cpp ]
         [ run compile_map.cpp ]
         [ run link_test_1.cpp link_test_2.cpp ]
Modified: branches/release/libs/unordered/test/unordered/insert_tests.cpp
==============================================================================
--- branches/release/libs/unordered/test/unordered/insert_tests.cpp	(original)
+++ branches/release/libs/unordered/test/unordered/insert_tests.cpp	2011-08-28 07:26:38 EDT (Sun, 28 Aug 2011)
@@ -514,6 +514,85 @@
 
 #endif
 
+struct overloaded_constructor
+{
+    overloaded_constructor(int x1 = 1, int x2 = 2, int x3 = 3, int x4 = 4)
+      : x1(x1), x2(x2), x3(x3), x4(x4) {}
+
+    int x1, x2, x3, x4;
+    
+    bool operator==(overloaded_constructor const& rhs) const
+    {
+        return x1 == rhs.x1 && x2 == rhs.x2 && x3 == rhs.x3 && x4 == rhs.x4;
+    }
+    
+    friend std::size_t hash_value(overloaded_constructor const& x)
+    {
+        std::size_t hash = 0;
+        boost::hash_combine(hash, x.x1);
+        boost::hash_combine(hash, x.x2);
+        boost::hash_combine(hash, x.x3);
+        boost::hash_combine(hash, x.x4);
+        return hash;
+    }
+};
+
+// This will actually be deprecated pretty soon.
+
+UNORDERED_AUTO_TEST(map_emplace_test)
+{
+    boost::unordered_map<int, overloaded_constructor> x;
+
+    x.emplace();
+    BOOST_TEST(x.find(0) != x.end() &&
+        x.find(0)->second == overloaded_constructor());
+
+    x.emplace(1);
+    BOOST_TEST(x.find(1) != x.end() &&
+        x.find(1)->second == overloaded_constructor());
+
+    x.emplace(2, 3);
+    BOOST_TEST(x.find(2) != x.end() &&
+        x.find(2)->second == overloaded_constructor(3));
+
+    x.emplace(4, 5, 6);
+    BOOST_TEST(x.find(4) != x.end() &&
+        x.find(4)->second == overloaded_constructor(5, 6));
+
+    x.emplace(7, 8, 9, 10);
+    BOOST_TEST(x.find(7) != x.end() &&
+        x.find(7)->second == overloaded_constructor(8, 9, 10));
+}
+
+UNORDERED_AUTO_TEST(set_emplace_test)
+{
+    boost::unordered_set<overloaded_constructor> x;
+    overloaded_constructor check;
+
+    x.emplace();
+    BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check);
+
+    x.clear();
+    x.emplace(1);
+    check = overloaded_constructor(1);
+    BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check);
+
+    x.clear();
+    x.emplace(2, 3);
+    check = overloaded_constructor(2, 3);
+    BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check);
+
+    x.clear();
+    x.emplace(4, 5, 6);
+    check = overloaded_constructor(4, 5, 6);
+    BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check);
+
+    x.clear();
+    x.emplace(7, 8, 9, 10);
+    check = overloaded_constructor(7, 8, 9, 10);
+    BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check);
+}
+
 }
 
 RUN_TESTS()
Modified: branches/release/libs/unordered/test/unordered/unnecessary_copy_tests.cpp
==============================================================================
--- branches/release/libs/unordered/test/unordered/unnecessary_copy_tests.cpp	(original)
+++ branches/release/libs/unordered/test/unordered/unnecessary_copy_tests.cpp	2011-08-28 07:26:38 EDT (Sun, 28 Aug 2011)
@@ -341,7 +341,10 @@
         x.emplace(source<std::pair<count_copies, count_copies> >());
         COPY_COUNT(2); MOVE_COUNT(source_pair_cost);
 
-#if !defined(__GNUC__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2)
+#if (defined(__GNUC__) && __GNUC__ > 4) || \
+    (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ > 2) || \
+    (defined(BOOST_MSVC) && BOOST_MSVC >= 1600 ) || \
+    (!defined(__GNUC__) && !defined(BOOST_MSVC))
         count_copies part;
         reset();
         std::pair<count_copies const&, count_copies const&> a_ref(part, part);