mirror of
https://github.com/boostorg/unordered.git
synced 2025-07-30 03:17:15 +02:00
Implement full extract_key for compilers without SFINAE and variadic
templates. [SVN r52393]
This commit is contained in:
@ -28,20 +28,16 @@
|
|||||||
#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/not.hpp>
|
||||||
#include <boost/detail/workaround.hpp>
|
#include <boost/detail/workaround.hpp>
|
||||||
#include <boost/utility/swap.hpp>
|
#include <boost/utility/swap.hpp>
|
||||||
|
|
||||||
#include <boost/mpl/aux_/config/eti.hpp>
|
#include <boost/mpl/aux_/config/eti.hpp>
|
||||||
|
|
||||||
#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)
|
#if BOOST_WORKAROUND(__BORLANDC__, <= 0x0582)
|
||||||
#define BOOST_UNORDERED_BORLAND_BOOL(x) (bool)(x)
|
#define BOOST_UNORDERED_BORLAND_BOOL(x) (bool)(x)
|
||||||
#else
|
#else
|
||||||
|
@ -1428,7 +1428,18 @@ namespace boost {
|
|||||||
|
|
||||||
// key extractors
|
// key extractors
|
||||||
|
|
||||||
|
struct no_key {
|
||||||
|
no_key() {}
|
||||||
|
template <class T> no_key(T const&) {}
|
||||||
|
};
|
||||||
|
|
||||||
// no throw
|
// no throw
|
||||||
|
|
||||||
|
static no_key extract_key()
|
||||||
|
{
|
||||||
|
return no_key();
|
||||||
|
}
|
||||||
|
|
||||||
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);
|
||||||
@ -1445,40 +1456,46 @@ namespace boost {
|
|||||||
{
|
{
|
||||||
return v.first;
|
return v.first;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
|
template <typename Arg>
|
||||||
struct no_key {};
|
static BOOST_DEDUCED_TYPENAME
|
||||||
|
boost::mpl::if_<boost::is_same<Arg, key_type>, key_type const&, no_key>::type
|
||||||
template <typename Arg1, typename... Args>
|
extract_key(Arg const& k)
|
||||||
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;
|
return k;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename First, typename Second>
|
template <typename First, typename Second>
|
||||||
static typename boost::enable_if<
|
static BOOST_DEDUCED_TYPENAME
|
||||||
boost::mpl::and_<
|
boost::mpl::if_<
|
||||||
boost::mpl::not_<boost::is_same<key_type, value_type> >,
|
boost::mpl::and_<
|
||||||
boost::is_same<key_type,
|
boost::mpl::not_<boost::is_same<key_type, value_type> >,
|
||||||
typename boost::remove_const<
|
boost::is_same<key_type,
|
||||||
typename boost::remove_reference<First>::type
|
typename boost::remove_const<
|
||||||
>::type>
|
typename boost::remove_reference<First>::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;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... Args>
|
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
|
||||||
static no_key extract_key(Args const&...)
|
|
||||||
|
template <typename Arg, 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, Args const&...)
|
||||||
{
|
{
|
||||||
return no_key();
|
return k;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -1963,6 +1980,13 @@ 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_);
|
||||||
|
|
||||||
@ -1992,6 +2016,36 @@ 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:
|
||||||
|
|
||||||
|
@ -192,6 +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.
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
x.emplace(b, b);
|
x.emplace(b, b);
|
||||||
|
Reference in New Issue
Block a user