forked from boostorg/unordered
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 [SVN r53277]
This commit is contained in:
@ -69,15 +69,5 @@ First official release.
|
|||||||
* Some other minor internal changes to the implementation, tests and
|
* Some other minor internal changes to the implementation, tests and
|
||||||
documentation.
|
documentation.
|
||||||
* Avoid an unnecessary copy in `operator[]`.
|
* 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]
|
[endsect]
|
||||||
|
@ -19,12 +19,4 @@
|
|||||||
# define BOOST_UNORDERED_NO_HAS_MOVE_ASSIGN
|
# define BOOST_UNORDERED_NO_HAS_MOVE_ASSIGN
|
||||||
#endif
|
#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
|
#endif
|
||||||
|
@ -12,11 +12,6 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <boost/config.hpp>
|
#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 <cstddef>
|
||||||
#include <boost/config/no_tr1/cmath.hpp>
|
#include <boost/config/no_tr1/cmath.hpp>
|
||||||
@ -33,12 +28,8 @@
|
|||||||
#include <boost/type_traits/is_same.hpp>
|
#include <boost/type_traits/is_same.hpp>
|
||||||
#include <boost/type_traits/aligned_storage.hpp>
|
#include <boost/type_traits/aligned_storage.hpp>
|
||||||
#include <boost/type_traits/alignment_of.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/if.hpp>
|
||||||
#include <boost/mpl/and.hpp>
|
#include <boost/mpl/and.hpp>
|
||||||
#include <boost/mpl/or.hpp>
|
|
||||||
#include <boost/mpl/not.hpp>
|
|
||||||
#include <boost/detail/workaround.hpp>
|
#include <boost/detail/workaround.hpp>
|
||||||
#include <boost/utility/swap.hpp>
|
#include <boost/utility/swap.hpp>
|
||||||
#include <boost/preprocessor/seq/size.hpp>
|
#include <boost/preprocessor/seq/size.hpp>
|
||||||
@ -46,19 +37,11 @@
|
|||||||
|
|
||||||
#include <boost/mpl/aux_/config/eti.hpp>
|
#include <boost/mpl/aux_/config/eti.hpp>
|
||||||
|
|
||||||
#if !(defined(BOOST_UNORDERED_STD_FORWARD))
|
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
|
||||||
|
#include <boost/type_traits/remove_reference.hpp>
|
||||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
#include <boost/type_traits/remove_const.hpp>
|
||||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
#include <boost/utility/enable_if.hpp>
|
||||||
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
|
#include <boost/mpl/not.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)
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if BOOST_WORKAROUND(__BORLANDC__, <= 0x0582)
|
#if BOOST_WORKAROUND(__BORLANDC__, <= 0x0582)
|
||||||
|
@ -181,159 +181,56 @@ namespace boost {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void construct_preamble()
|
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
|
||||||
{
|
|
||||||
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)
|
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
void construct(Args&&... args)
|
void construct(Args&&... args)
|
||||||
{
|
{
|
||||||
construct_preamble();
|
BOOST_ASSERT(!node_);
|
||||||
|
node_constructed_ = false;
|
||||||
|
value_constructed_ = false;
|
||||||
|
|
||||||
|
node_ = allocators_.node_alloc_.allocate(1);
|
||||||
|
|
||||||
|
allocators_.node_alloc_.construct(node_, node());
|
||||||
|
node_constructed_ = true;
|
||||||
|
|
||||||
new(node_->address()) value_type(std::forward<Args>(args)...);
|
new(node_->address()) value_type(std::forward<Args>(args)...);
|
||||||
value_constructed_ = true;
|
value_constructed_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#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.
|
|
||||||
|
|
||||||
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);
|
|
||||||
value_constructed_ = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <
|
|
||||||
typename Arg,
|
|
||||||
typename ValueType,
|
|
||||||
typename Type>
|
|
||||||
void construct_impl(Arg&& arg, ValueType const*, Type const*)
|
|
||||||
{
|
|
||||||
new(node_->address()) value_type(std::forward<Arg>(arg));
|
|
||||||
}
|
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
#else
|
||||||
|
template <typename V>
|
||||||
void construct()
|
void construct(V const& v)
|
||||||
{
|
{
|
||||||
construct_preamble();
|
BOOST_ASSERT(!node_);
|
||||||
new(node_->address()) value_type;
|
node_constructed_ = false;
|
||||||
|
value_constructed_ = false;
|
||||||
|
|
||||||
|
node_ = allocators_.node_alloc_.allocate(1);
|
||||||
|
|
||||||
|
allocators_.node_alloc_.construct(node_, node());
|
||||||
|
node_constructed_ = true;
|
||||||
|
|
||||||
|
new(node_->address()) value_type(v);
|
||||||
value_constructed_ = true;
|
value_constructed_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#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)
|
|
||||||
{
|
|
||||||
new(node_->address()) value_type(arg0);
|
|
||||||
}
|
|
||||||
|
|
||||||
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());
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef BOOST_UNORDERED_CONSTRUCT_IMPL
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
template <typename K, typename M>
|
||||||
|
void construct_pair(K const& k, M*)
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(!node_);
|
||||||
|
node_constructed_ = false;
|
||||||
|
value_constructed_ = false;
|
||||||
|
|
||||||
|
node_ = allocators_.node_alloc_.allocate(1);
|
||||||
|
|
||||||
|
allocators_.node_alloc_.construct(node_, node());
|
||||||
|
node_constructed_ = true;
|
||||||
|
|
||||||
|
new(node_->address()) value_type(k, M());
|
||||||
|
value_constructed_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
node_ptr get() const
|
node_ptr get() const
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(node_);
|
BOOST_ASSERT(node_);
|
||||||
@ -1530,29 +1427,8 @@ namespace boost {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// key extractors
|
// key extractors
|
||||||
//
|
|
||||||
// no throw
|
// 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.
|
|
||||||
|
|
||||||
static key_type const& extract_key(value_type const& v)
|
static key_type const& extract_key(value_type const& v)
|
||||||
{
|
{
|
||||||
return extract(v, (type_wrapper<value_type>*)0);
|
return extract(v, (type_wrapper<value_type>*)0);
|
||||||
@ -1569,67 +1445,40 @@ namespace boost {
|
|||||||
{
|
{
|
||||||
return v.first;
|
return v.first;
|
||||||
}
|
}
|
||||||
|
|
||||||
// For maps, if emplace is called with just a key, then it's the value type
|
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
|
||||||
// with the second value default initialised.
|
struct no_key {};
|
||||||
|
|
||||||
template <typename Arg>
|
template <typename Arg1, typename... Args>
|
||||||
static BOOST_DEDUCED_TYPENAME
|
static typename boost::enable_if<
|
||||||
boost::mpl::if_<boost::is_same<Arg, key_type>, key_type const&, no_key>::type
|
boost::mpl::and_<
|
||||||
extract_key(Arg const& k)
|
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;
|
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>
|
template <typename First, typename Second>
|
||||||
static BOOST_DEDUCED_TYPENAME
|
static typename boost::enable_if<
|
||||||
boost::mpl::if_<
|
boost::mpl::and_<
|
||||||
boost::mpl::and_<
|
boost::mpl::not_<boost::is_same<key_type, value_type> >,
|
||||||
boost::mpl::not_<boost::is_same<key_type, value_type> >,
|
boost::is_same<key_type,
|
||||||
boost::is_same<key_type,
|
typename boost::remove_const<
|
||||||
typename boost::remove_const<
|
typename boost::remove_reference<First>::type
|
||||||
typename boost::remove_reference<First>::type
|
>::type>
|
||||||
>::type>
|
>,
|
||||||
>,
|
key_type>::type const& extract_key(std::pair<First, Second> const& v)
|
||||||
key_type const&, no_key
|
|
||||||
>::type extract_key(std::pair<First, Second> const& v)
|
|
||||||
{
|
{
|
||||||
return v.first;
|
return v.first;
|
||||||
}
|
}
|
||||||
|
|
||||||
// For maps if there is more than one argument, the key can be the first argument.
|
template <typename... Args>
|
||||||
|
static no_key extract_key(Args const&...)
|
||||||
#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&...)
|
|
||||||
{
|
{
|
||||||
return k;
|
return no_key();
|
||||||
}
|
}
|
||||||
|
|
||||||
#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;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -1733,78 +1582,72 @@ namespace boost {
|
|||||||
|
|
||||||
#if BOOST_UNORDERED_EQUIVALENT_KEYS
|
#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
|
// if hash function throws, basic exception safety
|
||||||
// strong otherwise
|
// strong otherwise
|
||||||
template <class... Args>
|
iterator_base insert(value_type const& v)
|
||||||
iterator_base emplace(Args&&... args)
|
|
||||||
{
|
{
|
||||||
// Create the node before rehashing in case it throws an
|
// Create the node before rehashing in case it throws an
|
||||||
// exception (need strong safety in such a case).
|
// exception (need strong safety in such a case).
|
||||||
node_constructor a(data_.allocators_);
|
node_constructor a(data_.allocators_);
|
||||||
a.construct(std::forward<Args>(args)...);
|
a.construct(v);
|
||||||
|
|
||||||
return emplace_impl(a);
|
return insert_impl(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emplace (equivalent key containers)
|
// Insert (equivalent key containers)
|
||||||
// (I'm using an overloaded emplace for both 'insert' and 'emplace')
|
|
||||||
|
|
||||||
// if hash function throws, basic exception safety
|
// if hash function throws, basic exception safety
|
||||||
// strong otherwise
|
// strong otherwise
|
||||||
template <class... Args>
|
iterator_base insert_hint(iterator_base const& it, value_type const& v)
|
||||||
iterator_base emplace_hint(iterator_base const& it, Args&&... args)
|
|
||||||
{
|
{
|
||||||
// Create the node before rehashing in case it throws an
|
// Create the node before rehashing in case it throws an
|
||||||
// exception (need strong safety in such a case).
|
// exception (need strong safety in such a case).
|
||||||
node_constructor a(data_.allocators_);
|
node_constructor a(data_.allocators_);
|
||||||
a.construct(std::forward<Args>(args)...);
|
a.construct(v);
|
||||||
|
|
||||||
return emplace_hint_impl(it, a);
|
return insert_hint_impl(it, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define BOOST_UNORDERED_INSERT_IMPL(z, n, _) \
|
// Insert (equivalent key containers)
|
||||||
template < \
|
// (I'm using an overloaded insert for both 'insert' and 'emplace')
|
||||||
BOOST_UNORDERED_TEMPLATE_ARGS(z, n) \
|
|
||||||
> \
|
// if hash function throws, basic exception safety
|
||||||
iterator_base emplace( \
|
// strong otherwise
|
||||||
BOOST_UNORDERED_FUNCTION_PARAMS(z, n) \
|
template <class... Args>
|
||||||
) \
|
iterator_base insert(Args&&... args)
|
||||||
{ \
|
{
|
||||||
node_constructor a(data_.allocators_); \
|
// Create the node before rehashing in case it throws an
|
||||||
a.construct( \
|
// exception (need strong safety in such a case).
|
||||||
BOOST_UNORDERED_CALL_PARAMS(z, n) \
|
node_constructor a(data_.allocators_);
|
||||||
); \
|
a.construct(std::forward<Args>(args)...);
|
||||||
return emplace_impl(a); \
|
|
||||||
} \
|
return insert_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); \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT,
|
// Insert (equivalent key containers)
|
||||||
BOOST_UNORDERED_INSERT_IMPL, _)
|
// (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 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)...);
|
||||||
|
|
||||||
|
return insert_hint_impl(it, a);
|
||||||
|
}
|
||||||
|
|
||||||
#undef BOOST_UNORDERED_INSERT_IMPL
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
iterator_base emplace_impl(node_constructor& a)
|
iterator_base insert_impl(node_constructor& a)
|
||||||
{
|
{
|
||||||
key_type const& k = extract_key(a.get()->value());
|
key_type const& k = extract_key(a.get()->value());
|
||||||
size_type hash_value = hash_function()(k);
|
size_type hash_value = hash_function()(k);
|
||||||
@ -1825,17 +1668,17 @@ namespace boost {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
// equal can throw, but with no effects
|
||||||
if (it == data_.end() || !equal(extract_key(a.get()->value()), *it)) {
|
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.
|
// to a matching key.
|
||||||
return emplace_impl(a);
|
return insert_impl(a);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Find the first node in the group - so that the node
|
// 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_);
|
link_ptr start(it.node_);
|
||||||
while(data_.prev_in_group(start)->next_ == start)
|
while(data_.prev_in_group(start)->next_ == start)
|
||||||
@ -1864,7 +1707,7 @@ namespace boost {
|
|||||||
{
|
{
|
||||||
size_type distance = unordered_detail::distance(i, j);
|
size_type distance = unordered_detail::distance(i, j);
|
||||||
if(distance == 1) {
|
if(distance == 1) {
|
||||||
emplace(*i);
|
insert(*i);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Only require basic exception safety here
|
// Only require basic exception safety here
|
||||||
@ -1894,7 +1737,7 @@ namespace boost {
|
|||||||
{
|
{
|
||||||
// If only inserting 1 element, get the required
|
// If only inserting 1 element, get the required
|
||||||
// safety since insert is only called once.
|
// safety since insert is only called once.
|
||||||
for (; i != j; ++i) emplace(*i);
|
for (; i != j; ++i) insert(*i);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -1930,7 +1773,7 @@ namespace boost {
|
|||||||
// Create the node before rehashing in case it throws an
|
// Create the node before rehashing in case it throws an
|
||||||
// exception (need strong safety in such a case).
|
// exception (need strong safety in such a case).
|
||||||
node_constructor a(data_.allocators_);
|
node_constructor a(data_.allocators_);
|
||||||
a.construct(k);
|
a.construct_pair(k, (mapped_type*) 0);
|
||||||
|
|
||||||
// reserve has basic exception safety if the hash function
|
// reserve has basic exception safety if the hash function
|
||||||
// throws, strong otherwise.
|
// throws, strong otherwise.
|
||||||
@ -1943,37 +1786,81 @@ namespace boost {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(BOOST_UNORDERED_STD_FORWARD)
|
#if !(defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL))
|
||||||
|
|
||||||
// Emplace (unique keys)
|
// Insert (unique keys)
|
||||||
// (I'm using an overloaded emplace for both 'insert' and 'emplace')
|
|
||||||
|
// if hash function throws, basic exception safety
|
||||||
|
// strong otherwise
|
||||||
|
std::pair<iterator_base, bool> insert(value_type const& v)
|
||||||
|
{
|
||||||
|
// 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)
|
||||||
|
|
||||||
|
// 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
|
// if hash function throws, basic exception safety
|
||||||
// strong otherwise
|
// strong otherwise
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
std::pair<iterator_base, bool> emplace(Args&&... args)
|
std::pair<iterator_base, bool> insert(Args&&... args)
|
||||||
{
|
{
|
||||||
return emplace_impl(
|
return insert_impl(
|
||||||
extract_key(std::forward<Args>(args)...),
|
extract_key(std::forward<Args>(args)...),
|
||||||
std::forward<Args>(args)...);
|
std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
iterator_base emplace_hint(iterator_base const&, Args&&... args)
|
std::pair<iterator_base, bool> insert_impl(key_type const& k, Args&&... args)
|
||||||
{
|
|
||||||
return emplace_impl(
|
|
||||||
extract_key(std::forward<Args>(args)...),
|
|
||||||
std::forward<Args>(args)...).first;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename... Args>
|
|
||||||
std::pair<iterator_base, bool> emplace_impl(key_type const& k, Args&&... args)
|
|
||||||
{
|
{
|
||||||
// No side effects in this initial code
|
// No side effects in this initial code
|
||||||
size_type hash_value = hash_function()(k);
|
size_type hash_value = hash_function()(k);
|
||||||
@ -2007,110 +1894,13 @@ namespace boost {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename... Args>
|
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.
|
// Construct the node regardless - in order to get the key.
|
||||||
// It will be discarded if it isn't used
|
// It will be discarded if it isn't used
|
||||||
node_constructor a(data_.allocators_);
|
node_constructor a(data_.allocators_);
|
||||||
a.construct(std::forward<Args>(args)...);
|
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
|
// No side effects in this initial code
|
||||||
key_type const& k = extract_key(a.get()->value());
|
key_type const& k = extract_key(a.get()->value());
|
||||||
size_type hash_value = hash_function()(k);
|
size_type hash_value = hash_function()(k);
|
||||||
@ -2134,6 +1924,19 @@ namespace boost {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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)
|
// Insert from iterators (unique keys)
|
||||||
|
|
||||||
template <typename I>
|
template <typename I>
|
||||||
@ -2160,13 +1963,6 @@ namespace boost {
|
|||||||
// strong otherwise
|
// strong otherwise
|
||||||
template <typename InputIterator>
|
template <typename InputIterator>
|
||||||
void insert_range(InputIterator i, InputIterator j)
|
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_);
|
node_constructor a(data_.allocators_);
|
||||||
|
|
||||||
@ -2196,36 +1992,6 @@ namespace boost {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
#endif
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -2312,9 +2078,8 @@ namespace boost {
|
|||||||
key_type const& k) const
|
key_type const& k) const
|
||||||
{
|
{
|
||||||
link_ptr it = data_.begin(bucket);
|
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);
|
it = data::next_group(it);
|
||||||
}
|
|
||||||
|
|
||||||
return it;
|
return it;
|
||||||
}
|
}
|
||||||
|
@ -21,10 +21,6 @@
|
|||||||
#include <boost/unordered/detail/move.hpp>
|
#include <boost/unordered/detail/move.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST)
|
|
||||||
#include <initializer_list>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(BOOST_MSVC)
|
#if defined(BOOST_MSVC)
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#if BOOST_MSVC >= 1400
|
#if BOOST_MSVC >= 1400
|
||||||
@ -139,7 +135,7 @@ namespace boost
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST)
|
#if !defined(BOOST_NO_INITIALIZER_LISTS)
|
||||||
unordered_map(std::initializer_list<value_type> list,
|
unordered_map(std::initializer_list<value_type> list,
|
||||||
size_type n = boost::unordered_detail::default_initial_bucket_count,
|
size_type n = boost::unordered_detail::default_initial_bucket_count,
|
||||||
const hasher &hf = hasher(),
|
const hasher &hf = hasher(),
|
||||||
@ -223,74 +219,30 @@ namespace boost
|
|||||||
|
|
||||||
// modifiers
|
// modifiers
|
||||||
|
|
||||||
#if defined(BOOST_UNORDERED_STD_FORWARD)
|
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
|
||||||
template <class... Args>
|
template <class... Args>
|
||||||
std::pair<iterator, bool> emplace(Args&&... args)
|
std::pair<iterator, bool> emplace(Args&&... args)
|
||||||
{
|
{
|
||||||
return boost::unordered_detail::pair_cast<iterator, bool>(
|
return boost::unordered_detail::pair_cast<iterator, bool>(
|
||||||
base.emplace(std::forward<Args>(args)...));
|
base.insert(std::forward<Args>(args)...));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class... Args>
|
template <class... Args>
|
||||||
iterator emplace_hint(const_iterator hint, Args&&... 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
|
|
||||||
|
|
||||||
std::pair<iterator, bool> emplace(value_type const& v = value_type())
|
|
||||||
{
|
|
||||||
return boost::unordered_detail::pair_cast<iterator, bool>(
|
|
||||||
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) \
|
|
||||||
> \
|
|
||||||
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
|
#endif
|
||||||
|
|
||||||
std::pair<iterator, bool> insert(const value_type& obj)
|
std::pair<iterator, bool> insert(const value_type& obj)
|
||||||
{
|
{
|
||||||
return boost::unordered_detail::pair_cast<iterator, bool>(
|
return boost::unordered_detail::pair_cast<iterator, bool>(
|
||||||
base.emplace(obj));
|
base.insert(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator insert(const_iterator hint, const value_type& 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>
|
template <class InputIterator>
|
||||||
@ -589,7 +541,7 @@ namespace boost
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST)
|
#if !defined(BOOST_NO_INITIALIZER_LISTS)
|
||||||
unordered_multimap(std::initializer_list<value_type> list,
|
unordered_multimap(std::initializer_list<value_type> list,
|
||||||
size_type n = boost::unordered_detail::default_initial_bucket_count,
|
size_type n = boost::unordered_detail::default_initial_bucket_count,
|
||||||
const hasher &hf = hasher(),
|
const hasher &hf = hasher(),
|
||||||
@ -674,72 +626,28 @@ namespace boost
|
|||||||
|
|
||||||
// modifiers
|
// modifiers
|
||||||
|
|
||||||
#if defined(BOOST_UNORDERED_STD_FORWARD)
|
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
|
||||||
template <class... Args>
|
template <class... Args>
|
||||||
iterator emplace(Args&&... args)
|
iterator emplace(Args&&... args)
|
||||||
{
|
{
|
||||||
return iterator(base.emplace(std::forward<Args>(args)...));
|
return iterator(base.insert(std::forward<Args>(args)...));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class... Args>
|
template <class... Args>
|
||||||
iterator emplace_hint(const_iterator hint, Args&&... 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
|
#endif
|
||||||
|
|
||||||
iterator insert(const value_type& obj)
|
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)
|
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>
|
template <class InputIterator>
|
||||||
|
@ -21,10 +21,6 @@
|
|||||||
#include <boost/unordered/detail/move.hpp>
|
#include <boost/unordered/detail/move.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST)
|
|
||||||
#include <initializer_list>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(BOOST_MSVC)
|
#if defined(BOOST_MSVC)
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#if BOOST_MSVC >= 1400
|
#if BOOST_MSVC >= 1400
|
||||||
@ -137,7 +133,7 @@ namespace boost
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST)
|
#if !defined(BOOST_NO_INITIALIZER_LISTS)
|
||||||
unordered_set(std::initializer_list<value_type> list,
|
unordered_set(std::initializer_list<value_type> list,
|
||||||
size_type n = boost::unordered_detail::default_initial_bucket_count,
|
size_type n = boost::unordered_detail::default_initial_bucket_count,
|
||||||
const hasher &hf = hasher(),
|
const hasher &hf = hasher(),
|
||||||
@ -221,75 +217,31 @@ namespace boost
|
|||||||
|
|
||||||
// modifiers
|
// modifiers
|
||||||
|
|
||||||
#if defined(BOOST_UNORDERED_STD_FORWARD)
|
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
|
||||||
template <class... Args>
|
template <class... Args>
|
||||||
std::pair<iterator, bool> emplace(Args&&... args)
|
std::pair<iterator, bool> emplace(Args&&... args)
|
||||||
{
|
{
|
||||||
return boost::unordered_detail::pair_cast<iterator, bool>(
|
return boost::unordered_detail::pair_cast<iterator, bool>(
|
||||||
base.emplace(std::forward<Args>(args)...));
|
base.insert(std::forward<Args>(args)...));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class... Args>
|
template <class... Args>
|
||||||
iterator emplace_hint(const_iterator hint, Args&&... args)
|
iterator emplace_hint(const_iterator hint, Args&&... args)
|
||||||
{
|
{
|
||||||
return iterator(
|
return iterator(
|
||||||
base.emplace_hint(get(hint), std::forward<Args>(args)...));
|
base.insert_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));
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
#endif
|
||||||
|
|
||||||
std::pair<iterator, bool> insert(const value_type& obj)
|
std::pair<iterator, bool> insert(const value_type& obj)
|
||||||
{
|
{
|
||||||
return boost::unordered_detail::pair_cast<iterator, bool>(
|
return boost::unordered_detail::pair_cast<iterator, bool>(
|
||||||
base.emplace(obj));
|
base.insert(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator insert(const_iterator hint, const value_type& 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>
|
template <class InputIterator>
|
||||||
@ -559,7 +511,7 @@ namespace boost
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST)
|
#if !defined(BOOST_NO_INITIALIZER_LISTS)
|
||||||
unordered_multiset(std::initializer_list<value_type> list,
|
unordered_multiset(std::initializer_list<value_type> list,
|
||||||
size_type n = boost::unordered_detail::default_initial_bucket_count,
|
size_type n = boost::unordered_detail::default_initial_bucket_count,
|
||||||
const hasher &hf = hasher(),
|
const hasher &hf = hasher(),
|
||||||
@ -643,71 +595,28 @@ namespace boost
|
|||||||
|
|
||||||
// modifiers
|
// modifiers
|
||||||
|
|
||||||
#if defined(BOOST_UNORDERED_STD_FORWARD)
|
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
|
||||||
template <class... Args>
|
template <class... Args>
|
||||||
iterator emplace(Args&&... args)
|
iterator emplace(Args&&... args)
|
||||||
{
|
{
|
||||||
return iterator(base.emplace(std::forward<Args>(args)...));
|
return iterator(base.insert(std::forward<Args>(args)...));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class... Args>
|
template <class... Args>
|
||||||
iterator emplace_hint(const_iterator hint, Args&&... 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
|
#endif
|
||||||
|
|
||||||
iterator insert(const value_type& obj)
|
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)
|
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>
|
template <class InputIterator>
|
||||||
|
@ -6,8 +6,6 @@
|
|||||||
#if !defined(BOOST_UNORDERED_TEST_HELPERS_COUNT_HEAD)
|
#if !defined(BOOST_UNORDERED_TEST_HELPERS_COUNT_HEAD)
|
||||||
#define BOOST_UNORDERED_TEST_HELPERS_COUNT_HEAD
|
#define BOOST_UNORDERED_TEST_HELPERS_COUNT_HEAD
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
namespace test {
|
namespace test {
|
||||||
struct object_count {
|
struct object_count {
|
||||||
int instances;
|
int instances;
|
||||||
@ -38,11 +36,6 @@ namespace test {
|
|||||||
bool operator!=(object_count const& x) const {
|
bool operator!=(object_count const& x) const {
|
||||||
return !(*this == x);
|
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>
|
template <class T>
|
||||||
|
@ -347,7 +347,7 @@ namespace exception
|
|||||||
detail::tracker.track_construct((void*) p, sizeof(T), tag_);
|
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) {
|
template<class... Args> void construct(pointer p, Args&&... args) {
|
||||||
UNORDERED_SCOPE(allocator::construct(pointer, Args&&...)) {
|
UNORDERED_SCOPE(allocator::construct(pointer, Args&&...)) {
|
||||||
UNORDERED_EPOINT("Mock allocator construct function.");
|
UNORDERED_EPOINT("Mock allocator construct function.");
|
||||||
|
@ -229,7 +229,7 @@ namespace minimal
|
|||||||
|
|
||||||
void construct(pointer p, T const& t) { new((void*)p.ptr_) T(t); }
|
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) {
|
template<class... Args> void construct(pointer p, Args&&... args) {
|
||||||
new((void*)p.ptr_) T(std::forward<Args>(args)...);
|
new((void*)p.ptr_) T(std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
@ -218,7 +218,7 @@ namespace test
|
|||||||
new(p) T(t);
|
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) {
|
template<class... Args> void construct(pointer p, Args&&... args) {
|
||||||
detail::tracker.track_construct((void*) p, sizeof(T), tag_);
|
detail::tracker.track_construct((void*) p, sizeof(T), tag_);
|
||||||
new(p) T(std::forward<Args>(args)...);
|
new(p) T(std::forward<Args>(args)...);
|
||||||
|
@ -151,12 +151,14 @@ void unordered_map_test(X& r, Key const& k, T const& v)
|
|||||||
|
|
||||||
r.insert(std::pair<Key const, T>(k, v));
|
r.insert(std::pair<Key const, T>(k, v));
|
||||||
|
|
||||||
|
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
|
||||||
Key k_lvalue(k);
|
Key k_lvalue(k);
|
||||||
T v_lvalue(v);
|
T v_lvalue(v);
|
||||||
|
|
||||||
r.emplace(k, v);
|
r.emplace(k, v);
|
||||||
r.emplace(k_lvalue, v_lvalue);
|
r.emplace(k_lvalue, v_lvalue);
|
||||||
r.emplace(rvalue(k), rvalue(v));
|
r.emplace(rvalue(k), rvalue(v));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class X>
|
template <class X>
|
||||||
@ -173,7 +175,9 @@ void unordered_unique_test(X& r, T const& t)
|
|||||||
{
|
{
|
||||||
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
|
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
|
||||||
test::check_return_type<std::pair<iterator, bool> >::equals(r.insert(t));
|
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));
|
test::check_return_type<std::pair<iterator, bool> >::equals(r.emplace(t));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class X, class T>
|
template <class X, class T>
|
||||||
@ -181,7 +185,9 @@ void unordered_equivalent_test(X& r, T const& t)
|
|||||||
{
|
{
|
||||||
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
|
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
|
||||||
test::check_return_type<iterator>::equals(r.insert(t));
|
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));
|
test::check_return_type<iterator>::equals(r.emplace(t));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class X, class Key, class T>
|
template <class X, class Key, class T>
|
||||||
@ -283,7 +289,9 @@ void unordered_test(X&, Key& k, T& t, Hash& hf, Pred& eq)
|
|||||||
|
|
||||||
const_iterator q = a.cbegin();
|
const_iterator q = a.cbegin();
|
||||||
test::check_return_type<iterator>::equals(a.insert(q, t));
|
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));
|
test::check_return_type<iterator>::equals(a.emplace_hint(q, t));
|
||||||
|
#endif
|
||||||
|
|
||||||
a.insert(i, j);
|
a.insert(i, j);
|
||||||
test::check_return_type<size_type>::equals(a.erase(k));
|
test::check_return_type<size_type>::equals(a.erase(k));
|
||||||
|
@ -68,22 +68,12 @@ namespace unnecessary_copy_tests
|
|||||||
#define COPY_COUNT(n) \
|
#define COPY_COUNT(n) \
|
||||||
if(count_copies::copies != n) { \
|
if(count_copies::copies != n) { \
|
||||||
BOOST_ERROR("Wrong number of copies."); \
|
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) \
|
#define MOVE_COUNT(n) \
|
||||||
if(count_copies::moves != n) { \
|
if(count_copies::moves != n) { \
|
||||||
BOOST_ERROR("Wrong number of moves."); \
|
BOOST_ERROR("Wrong number of moves."); \
|
||||||
std::cerr<<"Number of moves: "<<count_copies::moves<<" expecting: "<<n<<std::endl; \
|
std::cerr<<"Number of moves: "<<count_copies::moves<<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; \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace unnecessary_copy_tests
|
namespace unnecessary_copy_tests
|
||||||
@ -109,6 +99,7 @@ namespace unnecessary_copy_tests
|
|||||||
UNORDERED_TEST(unnecessary_copy_insert_test,
|
UNORDERED_TEST(unnecessary_copy_insert_test,
|
||||||
((set)(multiset)(map)(multimap)))
|
((set)(multiset)(map)(multimap)))
|
||||||
|
|
||||||
|
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
|
||||||
template <class T>
|
template <class T>
|
||||||
void unnecessary_copy_emplace_test(T*)
|
void unnecessary_copy_emplace_test(T*)
|
||||||
{
|
{
|
||||||
@ -126,19 +117,9 @@ namespace unnecessary_copy_tests
|
|||||||
reset();
|
reset();
|
||||||
T x;
|
T x;
|
||||||
x.emplace(source<BOOST_DEDUCED_TYPENAME T::value_type>());
|
x.emplace(source<BOOST_DEDUCED_TYPENAME T::value_type>());
|
||||||
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
|
|
||||||
COPY_COUNT(1);
|
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>
|
template <class T>
|
||||||
void unnecessary_copy_emplace_move_test(T*)
|
void unnecessary_copy_emplace_move_test(T*)
|
||||||
{
|
{
|
||||||
@ -150,11 +131,13 @@ namespace unnecessary_copy_tests
|
|||||||
COPY_COUNT(1); MOVE_COUNT(1);
|
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,
|
UNORDERED_TEST(unnecessary_copy_emplace_move_test,
|
||||||
((set)(multiset)(map)(multimap)))
|
((set)(multiset)(map)(multimap)))
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST(unnecessary_copy_emplace_set_test)
|
UNORDERED_AUTO_TEST(unnecessary_copy_emplace_set_test)
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
@ -189,12 +172,10 @@ namespace unnecessary_copy_tests
|
|||||||
x.emplace(source<count_copies>());
|
x.emplace(source<count_copies>());
|
||||||
COPY_COUNT(1); MOVE_COUNT(0);
|
COPY_COUNT(1); MOVE_COUNT(0);
|
||||||
|
|
||||||
#if defined(BOOST_HAS_RVALUE_REFS)
|
|
||||||
// No move should take place.
|
// No move should take place.
|
||||||
reset();
|
reset();
|
||||||
x.emplace(std::move(a));
|
x.emplace(std::move(a));
|
||||||
COPY_COUNT(0); MOVE_COUNT(0);
|
COPY_COUNT(0); MOVE_COUNT(0);
|
||||||
#endif
|
|
||||||
|
|
||||||
// Just in case a did get moved...
|
// Just in case a did get moved...
|
||||||
count_copies b;
|
count_copies b;
|
||||||
@ -211,12 +192,8 @@ namespace unnecessary_copy_tests
|
|||||||
|
|
||||||
// The container will have to create b copy in order to compare with
|
// The container will have to create b copy in order to compare with
|
||||||
// the existing element.
|
// the existing element.
|
||||||
//
|
|
||||||
// Note to self: If copy_count == 0 it's an error not an optimization.
|
|
||||||
// TODO: Devise a better test.
|
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
|
|
||||||
x.emplace(b, b);
|
x.emplace(b, b);
|
||||||
COPY_COUNT(1); MOVE_COUNT(0);
|
COPY_COUNT(1); MOVE_COUNT(0);
|
||||||
}
|
}
|
||||||
@ -253,22 +230,24 @@ namespace unnecessary_copy_tests
|
|||||||
x.emplace(source<std::pair<count_copies, count_copies> >());
|
x.emplace(source<std::pair<count_copies, count_copies> >());
|
||||||
COPY_COUNT(2); MOVE_COUNT(0);
|
COPY_COUNT(2); MOVE_COUNT(0);
|
||||||
|
|
||||||
// TODO: This doesn't work on older versions of gcc.
|
count_copies part;
|
||||||
//count_copies part;
|
reset();
|
||||||
std::pair<count_copies const, count_copies> b;
|
std::pair<count_copies const&, count_copies const&> a_ref(part, part);
|
||||||
//reset();
|
x.emplace(a_ref);
|
||||||
//std::pair<count_copies const&, count_copies const&> a_ref(part, part);
|
COPY_COUNT(0); MOVE_COUNT(0);
|
||||||
//x.emplace(a_ref);
|
|
||||||
//COPY_COUNT(0); MOVE_COUNT(0);
|
|
||||||
|
|
||||||
#if defined(BOOST_HAS_RVALUE_REFS)
|
|
||||||
// No move should take place.
|
// No move should take place.
|
||||||
// (since a is already in the container)
|
|
||||||
reset();
|
reset();
|
||||||
x.emplace(std::move(a));
|
x.emplace(std::move(a));
|
||||||
COPY_COUNT(0); MOVE_COUNT(0);
|
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
|
// 2 arguments
|
||||||
@ -288,9 +267,10 @@ namespace unnecessary_copy_tests
|
|||||||
COPY_COUNT(1); MOVE_COUNT(0);
|
COPY_COUNT(1); MOVE_COUNT(0);
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
x.emplace(count_copies(b.first.tag_), count_copies(b.second.tag_));
|
x.emplace(b.first.tag_, b.second.tag_);
|
||||||
COPY_COUNT(2); MOVE_COUNT(0);
|
COPY_COUNT(2); MOVE_COUNT(0);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
RUN_TESTS()
|
RUN_TESTS()
|
||||||
|
Reference in New Issue
Block a user