$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r53277 - in branches/release: . boost/unordered boost/unordered/detail libs/unordered/doc libs/unordered/test/helpers libs/unordered/test/objects libs/unordered/test/unordered
From: daniel_james_at_[hidden]
Date: 2009-05-26 05:57:00
Author: danieljames
Date: 2009-05-26 05:56:59 EDT (Tue, 26 May 2009)
New Revision: 53277
URL: http://svn.boost.org/trac/boost/changeset/53277
Log:
Rollback [52357] as it depends on macros that aren't in release.
Rolled back revisions 52393-52394,52397,52884-52885,53127,53255 via svnmerge from 
https://svn.boost.org/svn/boost/trunk
Properties modified: 
   branches/release/   (props changed)
Text files modified: 
   branches/release/boost/unordered/detail/config.hpp                        |     8                                         
   branches/release/boost/unordered/detail/hash_table.hpp                    |    27 -                                       
   branches/release/boost/unordered/detail/hash_table_impl.hpp               |   581 +++++++++++---------------------------- 
   branches/release/boost/unordered/unordered_map.hpp                        |   116 -------                                 
   branches/release/boost/unordered/unordered_set.hpp                        |   115 -------                                 
   branches/release/libs/unordered/doc/changes.qbk                           |    10                                         
   branches/release/libs/unordered/test/helpers/count.hpp                    |     7                                         
   branches/release/libs/unordered/test/objects/exception.hpp                |     2                                         
   branches/release/libs/unordered/test/objects/minimal.hpp                  |     2                                         
   branches/release/libs/unordered/test/objects/test.hpp                     |     2                                         
   branches/release/libs/unordered/test/unordered/compile_tests.hpp          |     8                                         
   branches/release/libs/unordered/test/unordered/unnecessary_copy_tests.cpp |    64 +--                                     
   12 files changed, 235 insertions(+), 707 deletions(-)
Modified: branches/release/boost/unordered/detail/config.hpp
==============================================================================
--- branches/release/boost/unordered/detail/config.hpp	(original)
+++ branches/release/boost/unordered/detail/config.hpp	2009-05-26 05:56:59 EDT (Tue, 26 May 2009)
@@ -19,12 +19,4 @@
 #  define BOOST_UNORDERED_NO_HAS_MOVE_ASSIGN
 #endif
 
-#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
-#   if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)
-        // STLport doesn't have std::forward.
-#   else
-#       define BOOST_UNORDERED_STD_FORWARD
-#   endif
-#endif
-
 #endif
Modified: branches/release/boost/unordered/detail/hash_table.hpp
==============================================================================
--- branches/release/boost/unordered/detail/hash_table.hpp	(original)
+++ branches/release/boost/unordered/detail/hash_table.hpp	2009-05-26 05:56:59 EDT (Tue, 26 May 2009)
@@ -12,11 +12,6 @@
 #endif
 
 #include <boost/config.hpp>
-#include <boost/unordered/detail/config.hpp>
-
-#if !defined(BOOST_UNORDERED_EMPLACE_LIMIT)
-#define BOOST_UNORDERED_EMPLACE_LIMIT 5
-#endif
 
 #include <cstddef>
 #include <boost/config/no_tr1/cmath.hpp>
@@ -33,12 +28,8 @@
 #include <boost/type_traits/is_same.hpp>
 #include <boost/type_traits/aligned_storage.hpp>
 #include <boost/type_traits/alignment_of.hpp>
-#include <boost/type_traits/remove_reference.hpp>
-#include <boost/type_traits/remove_const.hpp>
 #include <boost/mpl/if.hpp>
 #include <boost/mpl/and.hpp>
-#include <boost/mpl/or.hpp>
-#include <boost/mpl/not.hpp>
 #include <boost/detail/workaround.hpp>
 #include <boost/utility/swap.hpp>
 #include <boost/preprocessor/seq/size.hpp>
@@ -46,19 +37,11 @@
 
 #include <boost/mpl/aux_/config/eti.hpp>
 
-#if !(defined(BOOST_UNORDERED_STD_FORWARD))
-
-#include <boost/preprocessor/repetition/enum_params.hpp>
-#include <boost/preprocessor/repetition/enum_binary_params.hpp>
-#include <boost/preprocessor/repetition/repeat_from_to.hpp>
-
-#define BOOST_UNORDERED_TEMPLATE_ARGS(z, n) \
-    BOOST_PP_ENUM_PARAMS_Z(z, n, typename Arg)
-#define BOOST_UNORDERED_FUNCTION_PARAMS(z, n) \
-    BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, Arg, const& arg)
-#define BOOST_UNORDERED_CALL_PARAMS(z, n) \
-    BOOST_PP_ENUM_PARAMS_Z(z, n, arg)
-
+#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/mpl/not.hpp>
 #endif
 
 #if BOOST_WORKAROUND(__BORLANDC__, <= 0x0582)
Modified: branches/release/boost/unordered/detail/hash_table_impl.hpp
==============================================================================
--- branches/release/boost/unordered/detail/hash_table_impl.hpp	(original)
+++ branches/release/boost/unordered/detail/hash_table_impl.hpp	2009-05-26 05:56:59 EDT (Tue, 26 May 2009)
@@ -181,158 +181,55 @@
                     }
                 }
 
-                void construct_preamble()
-                {
-                    if(!node_) {
-                        node_constructed_ = false;
-                        value_constructed_ = false;
-
-                        node_ = allocators_.node_alloc_.allocate(1);
-                        allocators_.node_alloc_.construct(node_, node());
-                        node_constructed_ = true;
-                    }
-                    else {
-                        BOOST_ASSERT(node_constructed_ && value_constructed_);
-                        BOOST_UNORDERED_DESTRUCT(&node_->value(), value_type);
-                        value_constructed_ = false;
-                    }
-                }
-
-#if defined(BOOST_UNORDERED_STD_FORWARD)
+#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
                 template <typename... Args>
                 void construct(Args&&... args)
                 {
-                    construct_preamble();
-                    new(node_->address()) value_type(std::forward<Args>(args)...);
-                    value_constructed_ = true;
-                }
+                    BOOST_ASSERT(!node_);
+                    node_constructed_ = false;
+                    value_constructed_ = false;
 
-#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.
+                    node_ = allocators_.node_alloc_.allocate(1);
 
-                template <typename Arg>
-                void construct(Arg&& arg)
-                {
-                    construct_preamble();
-                    construct_impl(std::forward<Arg>(arg),
-                        (value_type const*) 0,
-                        (typename boost::remove_reference<Arg>::type const*) 0);
+                    allocators_.node_alloc_.construct(node_, node());
+                    node_constructed_ = true;
+
+                    new(node_->address()) value_type(std::forward<Args>(args)...);
                     value_constructed_ = true;
                 }
-
-                template <
-                    typename Arg,
-                    typename ValueType,
-                    typename Type>
-                void construct_impl(Arg&& arg, ValueType const*, Type const*)
+#else
+                template <typename V>
+                void construct(V const& v)
                 {
-                    new(node_->address()) value_type(std::forward<Arg>(arg));
-                }
+                    BOOST_ASSERT(!node_);
+                    node_constructed_ = false;
+                    value_constructed_ = false;
 
-                template <
-                    typename Arg,
-                    typename ValueFirst, typename ValueSecond,
-                    typename TypeFirst, typename TypeSecond>
-                void construct_impl(
-                    Arg&& arg,
-                    std::pair<ValueFirst, ValueSecond> const*,
-                    std::pair<TypeFirst, TypeSecond> const*)
-                {
-                    new(node_->address()) value_type(std::forward<Arg>(arg));
-                }
+                    node_ = allocators_.node_alloc_.allocate(1);
 
-                template <
-                    typename Arg,
-                    typename ValueFirst, typename ValueSecond,
-                    typename Type>
-                void construct_impl(
-                    Arg&& arg,
-                    std::pair<ValueFirst, ValueSecond> const*,
-                    Type const*)
-                {
-                    new(node_->address()) value_type(std::forward<Arg>(arg), ValueSecond());
-                }
-#endif
-                
-#else
+                    allocators_.node_alloc_.construct(node_, node());
+                    node_constructed_ = true;
 
-                void construct()
-                {
-                    construct_preamble();
-                    new(node_->address()) value_type;
+                    new(node_->address()) value_type(v);
                     value_constructed_ = true;
                 }
+#endif
 
-#define BOOST_UNORDERED_CONSTRUCT_IMPL(z, n, _)                                 \
-                template <                                                      \
-                    BOOST_UNORDERED_TEMPLATE_ARGS(z, n)                         \
-                >                                                               \
-                void construct(                                                 \
-                    BOOST_UNORDERED_FUNCTION_PARAMS(z, n)                       \
-                )                                                               \
-                {                                                               \
-                    construct_preamble();                                       \
-                    construct_impl(                                             \
-                        (value_type*) 0,                                        \
-                        BOOST_UNORDERED_CALL_PARAMS(z, n)                       \
-                    );                                                          \
-                    value_constructed_ = true;                                  \
-                }                                                               \
-                                                                                \
-                template <                                                      \
-                    typename T,                                                 \
-                    BOOST_UNORDERED_TEMPLATE_ARGS(z, n)                         \
-                >                                                               \
-                void construct_impl(                                            \
-                    T*,                                                         \
-                    BOOST_UNORDERED_FUNCTION_PARAMS(z, n)                       \
-                )                                                               \
-                {                                                               \
-                    new(node_->address()) value_type(                           \
-                        BOOST_UNORDERED_CALL_PARAMS(z, n)                       \
-                    );                                                          \
-                }                                                               \
-                                                                                \
-                                                                                
-#define BOOST_UNORDERED_CONSTRUCT_IMPL2(z, n, _)                                \
-                template <typename First, typename Second, typename Key,        \
-                    BOOST_UNORDERED_TEMPLATE_ARGS(z, n)                         \
-                >                                                               \
-                void construct_impl(                                            \
-                    std::pair<First, Second>*,                                  \
-                    Key const& k,                                               \
-                    BOOST_UNORDERED_FUNCTION_PARAMS(z, n)                       \
-                )                                                               \
-                {                                                               \
-                    new(node_->address()) value_type(k,                         \
-                        Second(                                                 \
-                        BOOST_UNORDERED_CALL_PARAMS(z, n)                       \
-                        )                                                       \
-                    );                                                          \
-                }
-
-                BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT,
-                    BOOST_UNORDERED_CONSTRUCT_IMPL, _)
-                BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT,
-                    BOOST_UNORDERED_CONSTRUCT_IMPL2, _)
-                
-                template <typename First, typename Second, typename T1, typename T2>
-                void construct_impl(std::pair<First, Second>*,
-                    std::pair<T1, T2> const& arg0)
+                template <typename K, typename M>
+                void construct_pair(K const& k, M*)
                 {
-                    new(node_->address()) value_type(arg0);
-                }
+                    BOOST_ASSERT(!node_);
+                    node_constructed_ = false;
+                    value_constructed_ = false;
 
-                template <typename First, typename Second, typename Key>
-                void construct_impl(std::pair<First, Second>*, Key const& k)
-                {
-                    new(node_->address()) value_type(First(k), Second());
-                }
+                    node_ = allocators_.node_alloc_.allocate(1);
 
-#undef BOOST_UNORDERED_CONSTRUCT_IMPL
+                    allocators_.node_alloc_.construct(node_, node());
+                    node_constructed_ = true;
 
-#endif
+                    new(node_->address()) value_type(k, M());
+                    value_constructed_ = true;
+                }
 
                 node_ptr get() const
                 {
@@ -1530,29 +1427,8 @@
             }
 
             // key extractors
-            //
-            // no throw
-            //
-            // 'extract_key' is called with the emplace parameters to return a
-            // key if available or 'no_key' is one isn't and will need to be
-            // constructed.
-
-            struct no_key {
-                no_key() {}
-                template <class T> no_key(T const&) {}
-            };
-
-
-            // If emplace is called with no arguments then there obviously
-            // isn't an available key.
 
-            static no_key extract_key()
-            {
-                return no_key();
-            }
-            
-            // Emplace or insert was called with the value type.
-            
+            // no throw
             static key_type const& extract_key(value_type const& v)
             {
                 return extract(v, (type_wrapper<value_type>*)0);
@@ -1569,67 +1445,40 @@
             {
                 return v.first;
             }
-            
-            // For maps, if emplace is called with just a key, then it's the value type
-            // with the second value default initialised.
-            
-            template <typename Arg>
-            static BOOST_DEDUCED_TYPENAME
-                boost::mpl::if_<boost::is_same<Arg, key_type>, key_type const&, no_key>::type
-                extract_key(Arg const& k)
+
+#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
+            struct no_key {};
+
+            template <typename Arg1, typename... Args>
+            static typename boost::enable_if<
+                boost::mpl::and_<
+                    boost::mpl::not_<boost::is_same<key_type, value_type> >,
+                    boost::is_same<Arg1, key_type>
+                >,
+                key_type>::type const& extract_key(Arg1 const& k, Args const&...)
             {
                 return k;
             }
 
-            // For a map, the argument might be a pair with the key as the first
-            // part and a convertible value as the second part.
-
             template <typename First, typename Second>
-            static BOOST_DEDUCED_TYPENAME
-                boost::mpl::if_<
-                    boost::mpl::and_<
-                        boost::mpl::not_<boost::is_same<key_type, value_type> >,
-                        boost::is_same<key_type,
-                            typename boost::remove_const<
-                                typename boost::remove_reference<First>::type
-                            >::type>
-                    >,
-                    key_type const&, no_key
-                >::type extract_key(std::pair<First, Second> const& v)
+            static typename boost::enable_if<
+                boost::mpl::and_<
+                    boost::mpl::not_<boost::is_same<key_type, value_type> >,
+                    boost::is_same<key_type,
+                        typename boost::remove_const<
+                            typename boost::remove_reference<First>::type
+                        >::type>
+                >,
+                key_type>::type const& extract_key(std::pair<First, Second> const& v)
             {
                 return v.first;
             }
 
-            // For maps if there is more than one argument, the key can be the first argument.
-
-#if defined(BOOST_UNORDERED_STD_FORWARD)
-            template <typename Arg, typename Arg1, typename... Args>
-            static BOOST_DEDUCED_TYPENAME
-                boost::mpl::if_<
-                    boost::mpl::and_<
-                        boost::mpl::not_<boost::is_same<value_type, key_type> >,
-                        boost::is_same<Arg, key_type>
-                    >,
-                    key_type const&, no_key
-                >::type extract_key(Arg const& k, Arg1 const&, Args const&...)
+            template <typename... Args>
+            static no_key extract_key(Args const&...)
             {
-                return k;
-            }
-
-#else
-            template <typename Arg, typename Arg1>
-            static BOOST_DEDUCED_TYPENAME
-                boost::mpl::if_<
-                    boost::mpl::and_<
-                        boost::mpl::not_<boost::is_same<value_type, key_type> >,
-                        boost::is_same<Arg, key_type>
-                    >,
-                    key_type const&, no_key
-                >::type extract_key(Arg const& k, Arg1 const&)
-            {
-                return k;
+                return no_key();
             }
-
 #endif
 
         public:
@@ -1733,78 +1582,72 @@
 
 #if BOOST_UNORDERED_EQUIVALENT_KEYS
 
-#if defined(BOOST_UNORDERED_STD_FORWARD)
+#if !(defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL))
+            // Insert (equivalent key containers)
 
-            // Emplace (equivalent key containers)
-            // (I'm using an overloaded emplace for both 'insert' and 'emplace')
+            // if hash function throws, basic exception safety
+            // strong otherwise
+            iterator_base insert(value_type const& v)
+            {
+                // 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(v);
+
+                return insert_impl(a);
+            }
+
+            // Insert (equivalent key containers)
 
             // if hash function throws, basic exception safety
             // strong otherwise
-            template <class... Args>
-            iterator_base emplace(Args&&... args)
+            iterator_base insert_hint(iterator_base const& it, value_type const& v)
             {
                 // 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(std::forward<Args>(args)...);
+                a.construct(v);
 
-                return emplace_impl(a);
+                return insert_hint_impl(it, a);
             }
 
-            // Emplace (equivalent key containers)
-            // (I'm using an overloaded emplace for both 'insert' and 'emplace')
+#else
+
+            // Insert (equivalent key containers)
+            // (I'm using an overloaded insert for both 'insert' and 'emplace')
 
             // if hash function throws, basic exception safety
             // strong otherwise
             template <class... Args>
-            iterator_base emplace_hint(iterator_base const& it, Args&&... args)
+            iterator_base insert(Args&&... args)
             {
                 // 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(std::forward<Args>(args)...);
 
-                return emplace_hint_impl(it, a);
+                return insert_impl(a);
             }
 
-#else
+            // Insert (equivalent key containers)
+            // (I'm using an overloaded insert for both 'insert' and 'emplace')
 
-#define BOOST_UNORDERED_INSERT_IMPL(z, n, _)                                        \
-            template <                                                              \
-               BOOST_UNORDERED_TEMPLATE_ARGS(z, n)                                  \
-            >                                                                       \
-            iterator_base emplace(                                                  \
-               BOOST_UNORDERED_FUNCTION_PARAMS(z, n)                                \
-            )                                                                       \
-            {                                                                       \
-                node_constructor a(data_.allocators_);                              \
-                a.construct(                                                        \
-                    BOOST_UNORDERED_CALL_PARAMS(z, n)                               \
-                );                                                                  \
-                return emplace_impl(a);                                             \
-            }                                                                       \
-                                                                                    \
-            template <                                                              \
-               BOOST_UNORDERED_TEMPLATE_ARGS(z, n)                                  \
-            >                                                                       \
-            iterator_base emplace_hint(iterator_base const& it,                     \
-               BOOST_UNORDERED_FUNCTION_PARAMS(z, n)                                \
-            )                                                                       \
-            {                                                                       \
-                node_constructor a(data_.allocators_);                              \
-                a.construct(                                                        \
-                    BOOST_UNORDERED_CALL_PARAMS(z, n)                               \
-                );                                                                  \
-                return emplace_hint_impl(it, a);                                    \
-            }
+            // if hash function throws, basic exception safety
+            // strong otherwise
+            template <class... Args>
+            iterator_base insert_hint(iterator_base const& it, Args&&... args)
+            {
+                // 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(std::forward<Args>(args)...);
 
-            BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT,
-                BOOST_UNORDERED_INSERT_IMPL, _)
+                return insert_hint_impl(it, a);
+            }
 
-#undef BOOST_UNORDERED_INSERT_IMPL
 #endif
 
-            iterator_base emplace_impl(node_constructor& a)
+            iterator_base insert_impl(node_constructor& a)
             {
                 key_type const& k = extract_key(a.get()->value());
                 size_type hash_value = hash_function()(k);
@@ -1825,17 +1668,17 @@
                 );
             }
 
-            iterator_base emplace_hint_impl(iterator_base const& it, node_constructor& a)
+            iterator_base insert_hint_impl(iterator_base const& it, node_constructor& a)
             {
                 // equal can throw, but with no effects
                 if (it == data_.end() || !equal(extract_key(a.get()->value()), *it)) {
-                    // Use the standard emplace if the iterator doesn't point
+                    // Use the standard insert if the iterator doesn't point
                     // to a matching key.
-                    return emplace_impl(a);
+                    return insert_impl(a);
                 }
                 else {
                     // Find the first node in the group - so that the node
-                    // will be added at the end of the group.
+                    // will be inserted at the end of the group.
 
                     link_ptr start(it.node_);
                     while(data_.prev_in_group(start)->next_ == start)
@@ -1864,7 +1707,7 @@
             {
                 size_type distance = unordered_detail::distance(i, j);
                 if(distance == 1) {
-                    emplace(*i);
+                    insert(*i);
                 }
                 else {
                     // Only require basic exception safety here
@@ -1894,7 +1737,7 @@
             {
                 // If only inserting 1 element, get the required
                 // safety since insert is only called once.
-                for (; i != j; ++i) emplace(*i);
+                for (; i != j; ++i) insert(*i);
             }
 
         public:
@@ -1930,7 +1773,7 @@
                     // 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.
@@ -1943,37 +1786,81 @@
                 }
             }
 
-#if defined(BOOST_UNORDERED_STD_FORWARD)
+#if !(defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL))
 
-            // Emplace (unique keys)
-            // (I'm using an overloaded emplace for both 'insert' and 'emplace')
+            // Insert (unique keys)
 
             // if hash function throws, basic exception safety
             // strong otherwise
-            template<typename... Args>
-            std::pair<iterator_base, bool> emplace(Args&&... args)
+            std::pair<iterator_base, bool> insert(value_type const& v)
             {
-                return emplace_impl(
-                    extract_key(std::forward<Args>(args)...),
-                    std::forward<Args>(args)...);
+                // No side effects in this initial code
+                key_type const& k = extract_key(v);
+                size_type hash_value = hash_function()(k);
+                bucket_ptr bucket = data_.bucket_ptr_from_hash(hash_value);
+                link_ptr pos = find_iterator(bucket, k);
+
+                if (BOOST_UNORDERED_BORLAND_BOOL(pos)) {
+                    // Found an existing key, return it (no throw).
+                    return std::pair<iterator_base, bool>(
+                        iterator_base(bucket, pos), false);
+
+                } else {
+                    // Doesn't already exist, add to bucket.
+                    // Side effects only in this block.
+
+                    // 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(v);
+
+                    // reserve has basic exception safety if the hash function
+                    // throws, strong otherwise.
+                    if(reserve_for_insert(size() + 1))
+                        bucket = data_.bucket_ptr_from_hash(hash_value);
+
+                    // Nothing after this point can throw.
+
+                    link_ptr n = data_.link_node_in_bucket(a, bucket);
+
+                    return std::pair<iterator_base, bool>(
+                        iterator_base(bucket, n), true);
+                }
             }
 
             // Insert (unique keys)
-            // (I'm using an overloaded emplace for both 'insert' and 'emplace')
-            // I'm just ignoring hints here for now.
+
+            // if hash function throws, basic exception safety
+            // strong otherwise
+            iterator_base insert_hint(iterator_base const& it, value_type const& v)
+            {
+                if(it != data_.end() && equal(extract_key(v), *it))
+                    return it;
+                else
+                    return insert(v).first;
+            }
+
+#else
+
+            // Insert (unique keys)
+            // (I'm using an overloaded insert for both 'insert' and 'emplace')
+            //
+            // TODO:
+            // For sets: create a local key without creating the node?
+            // For maps: use the first argument as the key.
 
             // if hash function throws, basic exception safety
             // strong otherwise
             template<typename... Args>
-            iterator_base emplace_hint(iterator_base const&, Args&&... args)
+            std::pair<iterator_base, bool> insert(Args&&... args)
             {
-                return emplace_impl(
+                return insert_impl(
                     extract_key(std::forward<Args>(args)...),
-                    std::forward<Args>(args)...).first;
+                    std::forward<Args>(args)...);
             }
 
             template<typename... Args>
-            std::pair<iterator_base, bool> emplace_impl(key_type const& k, Args&&... args)
+            std::pair<iterator_base, bool> insert_impl(key_type const& k, Args&&... args)
             {
                 // No side effects in this initial code
                 size_type hash_value = hash_function()(k);
@@ -2007,110 +1894,13 @@
             }
 
             template<typename... Args>
-            std::pair<iterator_base, bool> emplace_impl(no_key, Args&&... args)
+            std::pair<iterator_base, bool> insert_impl(no_key, Args&&... args)
             {
                 // Construct the node regardless - in order to get the key.
                 // It will be discarded if it isn't used
                 node_constructor a(data_.allocators_);
                 a.construct(std::forward<Args>(args)...);
-                return emplace_impl_with_node(a);
-            }
-#else
-            template <typename Arg0>
-            std::pair<iterator_base, bool> emplace(Arg0 const& arg0)
-            {
-                return emplace_impl(extract_key(arg0), arg0);
-            }
-
-            template <typename Arg0>
-            iterator_base emplace_hint(iterator_base const& it, Arg0 const& arg0)
-            {
-                return emplace_impl(extract_key(arg0), arg0).first;
-            }
-
-
-#define BOOST_UNORDERED_INSERT_IMPL(z, n, _)                                        \
-            template <                                                              \
-               BOOST_UNORDERED_TEMPLATE_ARGS(z, n)                                  \
-            >                                                                       \
-            std::pair<iterator_base, bool> emplace(                                 \
-               BOOST_UNORDERED_FUNCTION_PARAMS(z, n)                                \
-            )                                                                       \
-            {                                                                       \
-                return emplace_impl(                                                \
-                    extract_key(arg0, arg1),                                        \
-                    BOOST_UNORDERED_CALL_PARAMS(z, n)                               \
-                );                                                                  \
-            }                                                                       \
-                                                                                    \
-            template <                                                              \
-               BOOST_UNORDERED_TEMPLATE_ARGS(z, n)                                  \
-            >                                                                       \
-            iterator_base emplace_hint(iterator_base const& it,                     \
-               BOOST_UNORDERED_FUNCTION_PARAMS(z, n)                                \
-            )                                                                       \
-            {                                                                       \
-                return emplace_impl(                                                \
-                    extract_key(arg0, arg1),                                        \
-                    BOOST_UNORDERED_CALL_PARAMS(z, n)                               \
-                ).first;                                                            \
-            }                                                                       \
-            BOOST_UNORDERED_INSERT_IMPL2(z, n, _)
-
-#define BOOST_UNORDERED_INSERT_IMPL2(z, n, _)                                       \
-            template <                                                              \
-               BOOST_UNORDERED_TEMPLATE_ARGS(z, n)                                  \
-            >                                                                       \
-            std::pair<iterator_base, bool> emplace_impl(key_type const& k,          \
-               BOOST_UNORDERED_FUNCTION_PARAMS(z, n)                                \
-            )                                                                       \
-            {                                                                       \
-                size_type hash_value = hash_function()(k);                          \
-                bucket_ptr bucket = data_.bucket_ptr_from_hash(hash_value);         \
-                link_ptr pos = find_iterator(bucket, k);                            \
-                                                                                    \
-                if (BOOST_UNORDERED_BORLAND_BOOL(pos)) {                            \
-                    return std::pair<iterator_base, bool>(                          \
-                        iterator_base(bucket, pos), false);                         \
-                } else {                                                            \
-                    node_constructor a(data_.allocators_);                          \
-                    a.construct(                                                    \
-                        BOOST_UNORDERED_CALL_PARAMS(z, n)                           \
-                    );                                                              \
-                                                                                    \
-                    if(reserve_for_insert(size() + 1))                              \
-                        bucket = data_.bucket_ptr_from_hash(hash_value);            \
-                                                                                    \
-                    return std::pair<iterator_base, bool>(iterator_base(bucket,     \
-                        data_.link_node_in_bucket(a, bucket)), true);               \
-                }                                                                   \
-            }                                                                       \
-                                                                                    \
-            template <                                                              \
-               BOOST_UNORDERED_TEMPLATE_ARGS(z, n)                                  \
-            >                                                                       \
-            std::pair<iterator_base, bool> emplace_impl(no_key,                     \
-               BOOST_UNORDERED_FUNCTION_PARAMS(z, n)                                \
-            )                                                                       \
-            {                                                                       \
-                node_constructor a(data_.allocators_);                              \
-                a.construct(                                                        \
-                    BOOST_UNORDERED_CALL_PARAMS(z, n)                               \
-                );                                                                  \
-                return emplace_impl_with_node(a);                                   \
-            }
-
-            BOOST_UNORDERED_INSERT_IMPL2(1, 1, _)
 
-            BOOST_PP_REPEAT_FROM_TO(2, BOOST_UNORDERED_EMPLACE_LIMIT,
-                BOOST_UNORDERED_INSERT_IMPL, _)
-
-#undef BOOST_UNORDERED_INSERT_IMPL
-
-#endif
-
-            std::pair<iterator_base, bool> emplace_impl_with_node(node_constructor& a)
-            {
                 // No side effects in this initial code
                 key_type const& k = extract_key(a.get()->value());
                 size_type hash_value = hash_function()(k);
@@ -2134,6 +1924,19 @@
                 }
             }
 
+            // Insert (unique keys)
+            // (I'm using an overloaded insert for both 'insert' and 'emplace')
+
+            // if hash function throws, basic exception safety
+            // strong otherwise
+            template<typename... Args>
+            iterator_base insert_hint(iterator_base const&, Args&&... args)
+            {
+                // Life is complicated - just call the normal implementation.
+                return insert(std::forward<Args>(args)...).first;
+            }
+#endif
+
             // Insert from iterators (unique keys)
 
             template <typename I>
@@ -2161,13 +1964,6 @@
             template <typename InputIterator>
             void insert_range(InputIterator i, InputIterator j)
             {
-                if(i != j)
-                    return insert_range_impl(extract_key(*i), i, j);
-            }
-            
-            template <typename InputIterator>
-            void insert_range_impl(key_type const&, InputIterator i, InputIterator j)
-            {
                 node_constructor a(data_.allocators_);
 
                 for (; i != j; ++i) {
@@ -2196,36 +1992,6 @@
                     }
                 }
             }
-
-            template <typename InputIterator>
-            void insert_range_impl(no_key, InputIterator i, InputIterator j)
-            {
-                node_constructor a(data_.allocators_);
-
-                for (; i != j; ++i) {
-                    // No side effects in this initial code
-                    a.construct(*i);
-                    key_type const& k = extract_key(a.get()->value());
-                    size_type hash_value = hash_function()(extract_key(k));
-                    bucket_ptr bucket = data_.bucket_ptr_from_hash(hash_value);
-                    link_ptr pos = find_iterator(bucket, k);
-
-                    if (!BOOST_UNORDERED_BORLAND_BOOL(pos)) {
-                        // Doesn't already exist, add to bucket.
-                        // Side effects only in this block.
-
-                        // reserve has basic exception safety if the hash function
-                        // throws, strong otherwise.
-                        if(size() + 1 >= max_load_) {
-                            reserve_for_insert(size() + insert_size(i, j));
-                            bucket = data_.bucket_ptr_from_hash(hash_value);
-                        }
-
-                        // Nothing after this point can throw.
-                        data_.link_node_in_bucket(a, bucket);
-                    }
-                }
-            }
 #endif
         public:
 
@@ -2312,9 +2078,8 @@
                     key_type const& k) const
             {
                 link_ptr it = data_.begin(bucket);
-                while (BOOST_UNORDERED_BORLAND_BOOL(it) && !equal(k, data::get_value(it))) {
+                while (BOOST_UNORDERED_BORLAND_BOOL(it) && !equal(k, data::get_value(it)))
                     it = data::next_group(it);
-                }
 
                 return it;
             }
Modified: branches/release/boost/unordered/unordered_map.hpp
==============================================================================
--- branches/release/boost/unordered/unordered_map.hpp	(original)
+++ branches/release/boost/unordered/unordered_map.hpp	2009-05-26 05:56:59 EDT (Tue, 26 May 2009)
@@ -21,10 +21,6 @@
 #include <boost/unordered/detail/move.hpp>
 #endif
 
-#if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST)
-#include <initializer_list>
-#endif
-
 #if defined(BOOST_MSVC)
 #pragma warning(push)
 #if BOOST_MSVC >= 1400
@@ -139,7 +135,7 @@
 #endif
 #endif
 
-#if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST)
+#if !defined(BOOST_NO_INITIALIZER_LISTS)
         unordered_map(std::initializer_list<value_type> list,
                 size_type n = boost::unordered_detail::default_initial_bucket_count,
                 const hasher &hf = hasher(),
@@ -223,74 +219,30 @@
 
         // modifiers
 
-#if defined(BOOST_UNORDERED_STD_FORWARD)
+#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
         template <class... Args>
         std::pair<iterator, bool> emplace(Args&&... args)
         {
             return boost::unordered_detail::pair_cast<iterator, bool>(
-                base.emplace(std::forward<Args>(args)...));
+                base.insert(std::forward<Args>(args)...));
         }
 
         template <class... Args>
         iterator emplace_hint(const_iterator hint, Args&&... args)
         {
-            return iterator(base.emplace_hint(get(hint), std::forward<Args>(args)...));
-        }
-#else
-
-        std::pair<iterator, bool> emplace(value_type const& v = value_type())
-        {
-            return boost::unordered_detail::pair_cast<iterator, bool>(
-                base.emplace(v));
+            return iterator(base.insert_hint(get(hint), std::forward<Args>(args)...));
         }
-
-        iterator emplace_hint(const_iterator hint, value_type const& v = value_type())
-        {
-            return iterator(base.emplace_hint(get(hint), v));
-        }
-
-#define BOOST_UNORDERED_EMPLACE(z, n, _)                                        \
-            template <                                                          \
-                BOOST_UNORDERED_TEMPLATE_ARGS(z, n)                             \
-            >                                                                   \
-            std::pair<iterator, bool> emplace(                                  \
-                BOOST_UNORDERED_FUNCTION_PARAMS(z, n)                           \
-            )                                                                   \
-            {                                                                   \
-                return boost::unordered_detail::pair_cast<iterator, bool>(      \
-                    base.emplace(                                               \
-                        BOOST_UNORDERED_CALL_PARAMS(z, n)                       \
-                    ));                                                         \
-            }                                                                   \
-                                                                                \
-            template <                                                          \
-                BOOST_UNORDERED_TEMPLATE_ARGS(z, n)                             \
-            >                                                                   \
-            iterator emplace_hint(const_iterator hint,                          \
-                BOOST_UNORDERED_FUNCTION_PARAMS(z, n)                           \
-            )                                                                   \
-            {                                                                   \
-                return iterator(base.emplace_hint(get(hint),                    \
-                        BOOST_UNORDERED_CALL_PARAMS(z, n)                       \
-                ));                                                             \
-            }
-
-        BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT,
-            BOOST_UNORDERED_EMPLACE, _)
-
-#undef BOOST_UNORDERED_EMPLACE
-
 #endif
 
         std::pair<iterator, bool> insert(const value_type& obj)
         {
             return boost::unordered_detail::pair_cast<iterator, bool>(
-                    base.emplace(obj));
+                    base.insert(obj));
         }
 
         iterator insert(const_iterator hint, const value_type& obj)
         {
-            return iterator(base.emplace_hint(get(hint), obj));
+            return iterator(base.insert_hint(get(hint), obj));
         }
 
         template <class InputIterator>
@@ -589,7 +541,7 @@
 #endif
 #endif
 
-#if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST)
+#if !defined(BOOST_NO_INITIALIZER_LISTS)
         unordered_multimap(std::initializer_list<value_type> list,
                 size_type n = boost::unordered_detail::default_initial_bucket_count,
                 const hasher &hf = hasher(),
@@ -674,72 +626,28 @@
 
         // modifiers
 
-#if defined(BOOST_UNORDERED_STD_FORWARD)
+#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
         template <class... Args>
         iterator emplace(Args&&... args)
         {
-            return iterator(base.emplace(std::forward<Args>(args)...));
+            return iterator(base.insert(std::forward<Args>(args)...));
         }
 
         template <class... Args>
         iterator emplace_hint(const_iterator hint, Args&&... args)
         {
-            return iterator(base.emplace_hint(get(hint), std::forward<Args>(args)...));
+            return iterator(base.insert_hint(get(hint), std::forward<Args>(args)...));
         }
-#else
-
-        iterator emplace(value_type const& v = value_type())
-        {
-            return iterator(base.emplace(v));
-        }
-        
-        iterator emplace_hint(const_iterator hint, value_type const& v = value_type())
-        {
-            return iterator(base.emplace_hint(get(hint), v));
-        }
-
-
-#define BOOST_UNORDERED_EMPLACE(z, n, _)                                        \
-            template <                                                          \
-                BOOST_UNORDERED_TEMPLATE_ARGS(z, n)                             \
-            >                                                                   \
-            iterator emplace(                                                   \
-                BOOST_UNORDERED_FUNCTION_PARAMS(z, n)                           \
-            )                                                                   \
-            {                                                                   \
-                return iterator(                                                \
-                    base.emplace(                                               \
-                        BOOST_UNORDERED_CALL_PARAMS(z, n)                       \
-                    ));                                                         \
-            }                                                                   \
-                                                                                \
-            template <                                                          \
-                BOOST_UNORDERED_TEMPLATE_ARGS(z, n)                             \
-            >                                                                   \
-            iterator emplace_hint(const_iterator hint,                          \
-                BOOST_UNORDERED_FUNCTION_PARAMS(z, n)                           \
-            )                                                                   \
-            {                                                                   \
-                return iterator(base.emplace_hint(get(hint),                    \
-                        BOOST_UNORDERED_CALL_PARAMS(z, n)                       \
-                ));                                                             \
-            }
-
-        BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT,
-            BOOST_UNORDERED_EMPLACE, _)
-
-#undef BOOST_UNORDERED_EMPLACE
-
 #endif
 
         iterator insert(const value_type& obj)
         {
-            return iterator(base.emplace(obj));
+            return iterator(base.insert(obj));
         }
 
         iterator insert(const_iterator hint, const value_type& obj)
         {
-            return iterator(base.emplace_hint(get(hint), obj));
+            return iterator(base.insert_hint(get(hint), obj));
         }
 
         template <class InputIterator>
Modified: branches/release/boost/unordered/unordered_set.hpp
==============================================================================
--- branches/release/boost/unordered/unordered_set.hpp	(original)
+++ branches/release/boost/unordered/unordered_set.hpp	2009-05-26 05:56:59 EDT (Tue, 26 May 2009)
@@ -21,10 +21,6 @@
 #include <boost/unordered/detail/move.hpp>
 #endif
 
-#if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST)
-#include <initializer_list>
-#endif
-
 #if defined(BOOST_MSVC)
 #pragma warning(push)
 #if BOOST_MSVC >= 1400
@@ -137,7 +133,7 @@
 #endif
 #endif
 
-#if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST)
+#if !defined(BOOST_NO_INITIALIZER_LISTS)
         unordered_set(std::initializer_list<value_type> list,
                 size_type n = boost::unordered_detail::default_initial_bucket_count,
                 const hasher &hf = hasher(),
@@ -221,75 +217,31 @@
 
         // modifiers
 
-#if defined(BOOST_UNORDERED_STD_FORWARD)
+#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
         template <class... Args>
         std::pair<iterator, bool> emplace(Args&&... args)
         {
             return boost::unordered_detail::pair_cast<iterator, bool>(
-                base.emplace(std::forward<Args>(args)...));
+                base.insert(std::forward<Args>(args)...));
         }
 
         template <class... Args>
         iterator emplace_hint(const_iterator hint, Args&&... args)
         {
             return iterator(
-                base.emplace_hint(get(hint), std::forward<Args>(args)...));
-        }
-#else
-
-        std::pair<iterator, bool> emplace(value_type const& v = value_type())
-        {
-            return boost::unordered_detail::pair_cast<iterator, bool>(
-                base.emplace(v));
+                base.insert_hint(get(hint), std::forward<Args>(args)...));
         }
-
-        iterator emplace_hint(const_iterator hint, value_type const& v = value_type())
-        {
-            return iterator(base.emplace_hint(get(hint), v));
-        }
-
-#define BOOST_UNORDERED_EMPLACE(z, n, _)                                        \
-            template <                                                          \
-                BOOST_UNORDERED_TEMPLATE_ARGS(z, n)                             \
-            >                                                                   \
-            std::pair<iterator, bool> emplace(                                  \
-                BOOST_UNORDERED_FUNCTION_PARAMS(z, n)                           \
-            )                                                                   \
-            {                                                                   \
-                return boost::unordered_detail::pair_cast<iterator, bool>(      \
-                    base.emplace(                                               \
-                        BOOST_UNORDERED_CALL_PARAMS(z, n)                       \
-                    ));                                                         \
-            }                                                                   \
-                                                                                \
-            template <                                                          \
-                BOOST_UNORDERED_TEMPLATE_ARGS(z, n)                             \
-            >                                                                   \
-            iterator emplace_hint(const_iterator hint,                          \
-                BOOST_UNORDERED_FUNCTION_PARAMS(z, n)                           \
-            )                                                                   \
-            {                                                                   \
-                return iterator(base.emplace_hint(get(hint),                    \
-                        BOOST_UNORDERED_CALL_PARAMS(z, n)                       \
-                ));                                                             \
-            }
-
-        BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT,
-            BOOST_UNORDERED_EMPLACE, _)
-
-#undef BOOST_UNORDERED_EMPLACE
-
 #endif
 
         std::pair<iterator, bool> insert(const value_type& obj)
         {
             return boost::unordered_detail::pair_cast<iterator, bool>(
-                    base.emplace(obj));
+                    base.insert(obj));
         }
 
         iterator insert(const_iterator hint, const value_type& obj)
         {
-            return iterator(base.emplace_hint(get(hint), obj));
+            return iterator(base.insert_hint(get(hint), obj));
         }
 
         template <class InputIterator>
@@ -559,7 +511,7 @@
 #endif
 #endif
 
-#if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST)
+#if !defined(BOOST_NO_INITIALIZER_LISTS)
         unordered_multiset(std::initializer_list<value_type> list,
                 size_type n = boost::unordered_detail::default_initial_bucket_count,
                 const hasher &hf = hasher(),
@@ -643,71 +595,28 @@
 
         // modifiers
 
-#if defined(BOOST_UNORDERED_STD_FORWARD)
+#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
         template <class... Args>
         iterator emplace(Args&&... args)
         {
-            return iterator(base.emplace(std::forward<Args>(args)...));
+            return iterator(base.insert(std::forward<Args>(args)...));
         }
 
         template <class... Args>
         iterator emplace_hint(const_iterator hint, Args&&... args)
         {
-            return iterator(base.emplace_hint(get(hint), std::forward<Args>(args)...));
-        }
-#else
-
-        iterator emplace(value_type const& v = value_type())
-        {
-            return iterator(base.emplace(v));
-        }
-
-        iterator emplace_hint(const_iterator hint, value_type const& v = value_type())
-        {
-            return iterator(base.emplace_hint(get(hint), v));
+            return iterator(base.insert_hint(get(hint), std::forward<Args>(args)...));
         }
-
-#define BOOST_UNORDERED_EMPLACE(z, n, _)                                        \
-            template <                                                          \
-                BOOST_UNORDERED_TEMPLATE_ARGS(z, n)                             \
-            >                                                                   \
-            iterator emplace(                                                   \
-                BOOST_UNORDERED_FUNCTION_PARAMS(z, n)                           \
-            )                                                                   \
-            {                                                                   \
-                return iterator(                                                \
-                    base.emplace(                                               \
-                        BOOST_UNORDERED_CALL_PARAMS(z, n)                       \
-                    ));                                                         \
-            }                                                                   \
-                                                                                \
-            template <                                                          \
-                BOOST_UNORDERED_TEMPLATE_ARGS(z, n)                             \
-            >                                                                   \
-            iterator emplace_hint(const_iterator hint,                          \
-                BOOST_UNORDERED_FUNCTION_PARAMS(z, n)                           \
-            )                                                                   \
-            {                                                                   \
-                return iterator(base.emplace_hint(get(hint),                    \
-                        BOOST_UNORDERED_CALL_PARAMS(z, n)                       \
-                ));                                                             \
-            }
-
-        BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT,
-            BOOST_UNORDERED_EMPLACE, _)
-
-#undef BOOST_UNORDERED_EMPLACE
-
 #endif
 
         iterator insert(const value_type& obj)
         {
-            return iterator(base.emplace(obj));
+            return iterator(base.insert(obj));
         }
 
         iterator insert(const_iterator hint, const value_type& obj)
         {
-            return iterator(base.emplace_hint(get(hint), obj));
+            return iterator(base.insert_hint(get(hint), obj));
         }
 
         template <class InputIterator>
Modified: branches/release/libs/unordered/doc/changes.qbk
==============================================================================
--- branches/release/libs/unordered/doc/changes.qbk	(original)
+++ branches/release/libs/unordered/doc/changes.qbk	2009-05-26 05:56:59 EDT (Tue, 26 May 2009)
@@ -69,15 +69,5 @@
 * Some other minor internal changes to the implementation, tests and
   documentation.
 * Avoid an unnecessary copy in `operator[]`.
-* [@https://svn.boost.org/trac/boost/ticket/2975 Ticket 2975]: Fix length of
-  prime number list.
-
-[h2 Boost 1.40.0]
-
-* [@https://svn.boost.org/trac/boost/ticket/2975 Ticket 2975]:
-  Store the prime list as a preprocessor sequence - so that it will always get
-  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.
 
 [endsect]
Modified: branches/release/libs/unordered/test/helpers/count.hpp
==============================================================================
--- branches/release/libs/unordered/test/helpers/count.hpp	(original)
+++ branches/release/libs/unordered/test/helpers/count.hpp	2009-05-26 05:56:59 EDT (Tue, 26 May 2009)
@@ -6,8 +6,6 @@
 #if !defined(BOOST_UNORDERED_TEST_HELPERS_COUNT_HEAD)
 #define BOOST_UNORDERED_TEST_HELPERS_COUNT_HEAD
 
-#include <iostream>
-
 namespace test {
     struct object_count {
         int instances;
@@ -38,11 +36,6 @@
         bool operator!=(object_count const& x) const {
             return !(*this == x);
         }
-        
-        friend std::ostream& operator<<(std::ostream& out, object_count const& c) {
-            out<<"[instances: "<<c.instances<<", constructions: "<<c.constructions<<"]";
-            return out;
-        }
     };
 
     template <class T>
Modified: branches/release/libs/unordered/test/objects/exception.hpp
==============================================================================
--- branches/release/libs/unordered/test/objects/exception.hpp	(original)
+++ branches/release/libs/unordered/test/objects/exception.hpp	2009-05-26 05:56:59 EDT (Tue, 26 May 2009)
@@ -347,7 +347,7 @@
             detail::tracker.track_construct((void*) p, sizeof(T), tag_);
         }
 
-#if defined(BOOST_UNORDERED_STD_FORWARD)
+#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
         template<class... Args> void construct(pointer p, Args&&... args) {
             UNORDERED_SCOPE(allocator::construct(pointer, Args&&...)) {
                 UNORDERED_EPOINT("Mock allocator construct function.");
Modified: branches/release/libs/unordered/test/objects/minimal.hpp
==============================================================================
--- branches/release/libs/unordered/test/objects/minimal.hpp	(original)
+++ branches/release/libs/unordered/test/objects/minimal.hpp	2009-05-26 05:56:59 EDT (Tue, 26 May 2009)
@@ -229,7 +229,7 @@
 
         void construct(pointer p, T const& t) { new((void*)p.ptr_) T(t); }
 
-#if defined(BOOST_UNORDERED_STD_FORWARD)
+#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
         template<class... Args> void construct(pointer p, Args&&... args) {
             new((void*)p.ptr_) T(std::forward<Args>(args)...);
         }
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	2009-05-26 05:56:59 EDT (Tue, 26 May 2009)
@@ -218,7 +218,7 @@
             new(p) T(t);
         }
 
-#if defined(BOOST_UNORDERED_STD_FORWARD)
+#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
         template<class... Args> void construct(pointer p, Args&&... args) {
             detail::tracker.track_construct((void*) p, sizeof(T), tag_);
             new(p) T(std::forward<Args>(args)...);
Modified: branches/release/libs/unordered/test/unordered/compile_tests.hpp
==============================================================================
--- branches/release/libs/unordered/test/unordered/compile_tests.hpp	(original)
+++ branches/release/libs/unordered/test/unordered/compile_tests.hpp	2009-05-26 05:56:59 EDT (Tue, 26 May 2009)
@@ -151,12 +151,14 @@
 
     r.insert(std::pair<Key const, T>(k, v));
 
+#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
     Key k_lvalue(k);
     T v_lvalue(v);
 
     r.emplace(k, v);
     r.emplace(k_lvalue, v_lvalue);
     r.emplace(rvalue(k), rvalue(v));
+#endif
 }
 
 template <class X>
@@ -173,7 +175,9 @@
 {
     typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
     test::check_return_type<std::pair<iterator, bool> >::equals(r.insert(t));
+#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
     test::check_return_type<std::pair<iterator, bool> >::equals(r.emplace(t));
+#endif
 }
 
 template <class X, class T>
@@ -181,7 +185,9 @@
 {
     typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
     test::check_return_type<iterator>::equals(r.insert(t));
+#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
     test::check_return_type<iterator>::equals(r.emplace(t));
+#endif
 }
 
 template <class X, class Key, class T>
@@ -283,7 +289,9 @@
 
     const_iterator q = a.cbegin();
     test::check_return_type<iterator>::equals(a.insert(q, t));
+#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
     test::check_return_type<iterator>::equals(a.emplace_hint(q, t));
+#endif
 
     a.insert(i, j);
     test::check_return_type<size_type>::equals(a.erase(k));
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	2009-05-26 05:56:59 EDT (Tue, 26 May 2009)
@@ -68,22 +68,12 @@
 #define COPY_COUNT(n) \
     if(count_copies::copies != n) { \
         BOOST_ERROR("Wrong number of copies."); \
-        std::cerr<<"Number of copies: "<<count_copies::copies<<" expecting: "<<n<<std::endl; \
+        std::cerr<<"Number of copies: "<<count_copies::copies<<std::endl; \
     }
 #define MOVE_COUNT(n) \
     if(count_copies::moves != n) { \
         BOOST_ERROR("Wrong number of moves."); \
-        std::cerr<<"Number of moves: "<<count_copies::moves<<" expecting: "<<n<<std::endl; \
-    }
-#define COPY_COUNT_RANGE(a, b) \
-    if(count_copies::copies < a || count_copies::copies > b) { \
-        BOOST_ERROR("Wrong number of copies."); \
-        std::cerr<<"Number of copies: "<<count_copies::copies<<" expecting: ["<<a<<", "<<b<<"]"<<std::endl; \
-    }
-#define MOVE_COUNT_RANGE(a, b) \
-    if(count_copies::moves < a || count_copies::moves > b) { \
-        BOOST_ERROR("Wrong number of moves."); \
-        std::cerr<<"Number of moves: "<<count_copies::copies<<" expecting: ["<<a<<", "<<b<<"]"<<std::endl; \
+        std::cerr<<"Number of moves: "<<count_copies::moves<<std::endl; \
     }
 
 namespace unnecessary_copy_tests
@@ -109,6 +99,7 @@
     UNORDERED_TEST(unnecessary_copy_insert_test,
             ((set)(multiset)(map)(multimap)))
 
+#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
     template <class T>
     void unnecessary_copy_emplace_test(T*)
     {
@@ -126,19 +117,9 @@
         reset();
         T x;
         x.emplace(source<BOOST_DEDUCED_TYPENAME T::value_type>());
-#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
         COPY_COUNT(1);
-#else
-        COPY_COUNT(2);
-#endif
     }
 
-    UNORDERED_TEST(unnecessary_copy_emplace_test,
-            ((set)(multiset)(map)(multimap)))
-    UNORDERED_TEST(unnecessary_copy_emplace_rvalue_test,
-            ((set)(multiset)(map)(multimap)))
-
-#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
     template <class T>
     void unnecessary_copy_emplace_move_test(T*)
     {
@@ -150,11 +131,13 @@
         COPY_COUNT(1); MOVE_COUNT(1);
     }
 
+    UNORDERED_TEST(unnecessary_copy_emplace_test,
+            ((set)(multiset)(map)(multimap)))
+    UNORDERED_TEST(unnecessary_copy_emplace_rvalue_test,
+            ((set)(multiset)(map)(multimap)))
     UNORDERED_TEST(unnecessary_copy_emplace_move_test,
             ((set)(multiset)(map)(multimap)))
 
-#endif
-
     UNORDERED_AUTO_TEST(unnecessary_copy_emplace_set_test)
     {
         reset();
@@ -189,12 +172,10 @@
         x.emplace(source<count_copies>());
         COPY_COUNT(1); MOVE_COUNT(0);
 
-#if defined(BOOST_HAS_RVALUE_REFS)
         // No move should take place.
         reset();
         x.emplace(std::move(a));
         COPY_COUNT(0); MOVE_COUNT(0);
-#endif
 
         // Just in case a did get moved...
         count_copies b;
@@ -211,12 +192,8 @@
 
         // The container will have to create b copy in order to compare with
         // the existing element.
-        //
-        // Note to self: If copy_count == 0 it's an error not an optimization.
-        // TODO: Devise a better test.
 
         reset();
-
         x.emplace(b, b);
         COPY_COUNT(1); MOVE_COUNT(0);
     }
@@ -253,22 +230,24 @@
         x.emplace(source<std::pair<count_copies, count_copies> >());
         COPY_COUNT(2); MOVE_COUNT(0);
 
-        // TODO: This doesn't work on older versions of gcc.
-        //count_copies part;
-        std::pair<count_copies const, count_copies> b;
-        //reset();
-        //std::pair<count_copies const&, count_copies const&> a_ref(part, part);
-        //x.emplace(a_ref);
-        //COPY_COUNT(0); MOVE_COUNT(0);
+        count_copies part;
+        reset();
+        std::pair<count_copies const&, count_copies const&> a_ref(part, part);
+        x.emplace(a_ref);
+        COPY_COUNT(0); MOVE_COUNT(0);
 
-#if defined(BOOST_HAS_RVALUE_REFS)
         // No move should take place.
-        // (since a is already in the container)
         reset();
         x.emplace(std::move(a));
         COPY_COUNT(0); MOVE_COUNT(0);
-#endif
 
+        // Just in case a did get moved
+        std::pair<count_copies const, count_copies> b;
+
+        // This test requires a C++0x std::pair. Which gcc hasn't got yet.
+        //reset();
+        //x.emplace(b.first.tag_);
+        //COPY_COUNT(2); MOVE_COUNT(0);
 
         //
         // 2 arguments
@@ -288,9 +267,10 @@
         COPY_COUNT(1); MOVE_COUNT(0);
 
         reset();
-        x.emplace(count_copies(b.first.tag_), count_copies(b.second.tag_));
-        COPY_COUNT(2); MOVE_COUNT(0);        
+        x.emplace(b.first.tag_, b.second.tag_);
+        COPY_COUNT(2); MOVE_COUNT(0);
     }
+#endif
 }
 
 RUN_TESTS()