|
Boost-Commit : |
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()
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk