forked from boostorg/unordered
Support incomplete template parameters to unordered containers.
[SVN r57798]
This commit is contained in:
@ -15,9 +15,9 @@ namespace boost { namespace unordered_detail {
|
|||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
// Equality
|
// Equality
|
||||||
|
|
||||||
template <class H, class P, class A, class E>
|
template <class T>
|
||||||
bool hash_equivalent_table<H, P, A, E>
|
bool hash_equivalent_table<T>
|
||||||
::equals(hash_equivalent_table<H, P, A, E> const& other) const
|
::equals(hash_equivalent_table<T> const& other) const
|
||||||
{
|
{
|
||||||
if(this->size_ != other.size_) return false;
|
if(this->size_ != other.size_) return false;
|
||||||
if(!this->size_) return true;
|
if(!this->size_) return true;
|
||||||
@ -51,9 +51,9 @@ namespace boost { namespace unordered_detail {
|
|||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
// A convenience method for adding nodes.
|
// A convenience method for adding nodes.
|
||||||
|
|
||||||
template <class H, class P, class A, class E>
|
template <class T>
|
||||||
inline BOOST_DEDUCED_TYPENAME hash_equivalent_table<H, P, A, E>::node_ptr
|
inline BOOST_DEDUCED_TYPENAME hash_equivalent_table<T>::node_ptr
|
||||||
hash_equivalent_table<H, P, A, E>
|
hash_equivalent_table<T>
|
||||||
::add_node(node_constructor& a, bucket_ptr bucket, node_ptr pos)
|
::add_node(node_constructor& a, bucket_ptr bucket, node_ptr pos)
|
||||||
{
|
{
|
||||||
node_ptr n = a.release();
|
node_ptr n = a.release();
|
||||||
@ -72,10 +72,10 @@ namespace boost { namespace unordered_detail {
|
|||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
// Insert methods
|
// Insert methods
|
||||||
|
|
||||||
template <class H, class P, class A, class E>
|
template <class T>
|
||||||
inline BOOST_DEDUCED_TYPENAME
|
inline BOOST_DEDUCED_TYPENAME
|
||||||
hash_equivalent_table<H, P, A, E>::iterator_base
|
hash_equivalent_table<T>::iterator_base
|
||||||
hash_equivalent_table<H, P, A, E>::emplace_impl(node_constructor& a)
|
hash_equivalent_table<T>::emplace_impl(node_constructor& a)
|
||||||
{
|
{
|
||||||
key_type const& k = this->get_key(a.value());
|
key_type const& k = this->get_key(a.value());
|
||||||
std::size_t hash_value = this->hash_function()(k);
|
std::size_t hash_value = this->hash_function()(k);
|
||||||
@ -96,8 +96,8 @@ namespace boost { namespace unordered_detail {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class H, class P, class A, class E>
|
template <class T>
|
||||||
inline void hash_equivalent_table<H, P, A, E>
|
inline void hash_equivalent_table<T>
|
||||||
::emplace_impl_no_rehash(node_constructor& a)
|
::emplace_impl_no_rehash(node_constructor& a)
|
||||||
{
|
{
|
||||||
key_type const& k = this->get_key(a.value());
|
key_type const& k = this->get_key(a.value());
|
||||||
@ -112,10 +112,10 @@ namespace boost { namespace unordered_detail {
|
|||||||
|
|
||||||
// if hash function throws, basic exception safety
|
// if hash function throws, basic exception safety
|
||||||
// strong otherwise
|
// strong otherwise
|
||||||
template <class H, class P, class A, class E>
|
template <class T>
|
||||||
template <class... Args>
|
template <class... Args>
|
||||||
BOOST_DEDUCED_TYPENAME hash_equivalent_table<H, P, A, E>::iterator_base
|
BOOST_DEDUCED_TYPENAME hash_equivalent_table<T>::iterator_base
|
||||||
hash_equivalent_table<H, P, A, E>
|
hash_equivalent_table<T>
|
||||||
::emplace(Args&&... args)
|
::emplace(Args&&... args)
|
||||||
{
|
{
|
||||||
// Create the node before rehashing in case it throws an
|
// Create the node before rehashing in case it throws an
|
||||||
@ -129,10 +129,10 @@ namespace boost { namespace unordered_detail {
|
|||||||
#else
|
#else
|
||||||
|
|
||||||
#define BOOST_UNORDERED_INSERT_IMPL(z, num_params, _) \
|
#define BOOST_UNORDERED_INSERT_IMPL(z, num_params, _) \
|
||||||
template <class H, class P, class A, class E> \
|
template <class T> \
|
||||||
template <BOOST_UNORDERED_TEMPLATE_ARGS(z, num_params)> \
|
template <BOOST_UNORDERED_TEMPLATE_ARGS(z, num_params)> \
|
||||||
BOOST_DEDUCED_TYPENAME hash_equivalent_table<H, P, A, E>::iterator_base \
|
BOOST_DEDUCED_TYPENAME hash_equivalent_table<T>::iterator_base \
|
||||||
hash_equivalent_table<H, P, A, E> \
|
hash_equivalent_table<T> \
|
||||||
::emplace(BOOST_UNORDERED_FUNCTION_PARAMS(z, num_params)) \
|
::emplace(BOOST_UNORDERED_FUNCTION_PARAMS(z, num_params)) \
|
||||||
{ \
|
{ \
|
||||||
node_constructor a(*this); \
|
node_constructor a(*this); \
|
||||||
@ -151,9 +151,9 @@ namespace boost { namespace unordered_detail {
|
|||||||
|
|
||||||
// if hash function throws, or inserting > 1 element, basic exception safety
|
// if hash function throws, or inserting > 1 element, basic exception safety
|
||||||
// strong otherwise
|
// strong otherwise
|
||||||
template <class H, class P, class A, class E>
|
template <class T>
|
||||||
template <class I>
|
template <class I>
|
||||||
inline void hash_equivalent_table<H, P, A, E>
|
inline void hash_equivalent_table<T>
|
||||||
::insert_for_range(I i, I j, forward_traversal_tag)
|
::insert_for_range(I i, I j, forward_traversal_tag)
|
||||||
{
|
{
|
||||||
if(i == j) return;
|
if(i == j) return;
|
||||||
@ -182,9 +182,9 @@ namespace boost { namespace unordered_detail {
|
|||||||
|
|
||||||
// if hash function throws, or inserting > 1 element, basic exception safety
|
// if hash function throws, or inserting > 1 element, basic exception safety
|
||||||
// strong otherwise
|
// strong otherwise
|
||||||
template <class H, class P, class A, class E>
|
template <class T>
|
||||||
template <class I>
|
template <class I>
|
||||||
inline void hash_equivalent_table<H, P, A, E>
|
inline void hash_equivalent_table<T>
|
||||||
::insert_for_range(I i, I j, boost::incrementable_traversal_tag)
|
::insert_for_range(I i, I j, boost::incrementable_traversal_tag)
|
||||||
{
|
{
|
||||||
node_constructor a(*this);
|
node_constructor a(*this);
|
||||||
@ -196,9 +196,9 @@ namespace boost { namespace unordered_detail {
|
|||||||
|
|
||||||
// if hash function throws, or inserting > 1 element, basic exception safety
|
// if hash function throws, or inserting > 1 element, basic exception safety
|
||||||
// strong otherwise
|
// strong otherwise
|
||||||
template <class H, class P, class A, class E>
|
template <class T>
|
||||||
template <class I>
|
template <class I>
|
||||||
void hash_equivalent_table<H, P, A, E>::insert_range(I i, I j)
|
void hash_equivalent_table<T>::insert_range(I i, I j)
|
||||||
{
|
{
|
||||||
BOOST_DEDUCED_TYPENAME boost::iterator_traversal<I>::type
|
BOOST_DEDUCED_TYPENAME boost::iterator_traversal<I>::type
|
||||||
iterator_traversal_tag;
|
iterator_traversal_tag;
|
||||||
|
@ -28,128 +28,120 @@ namespace unordered_detail {
|
|||||||
template <class T> no_key(T const&) {}
|
template <class T> no_key(T const&) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <class ValueType>
|
||||||
struct set_extractor
|
struct set_extractor
|
||||||
{
|
{
|
||||||
template <class ValueType>
|
typedef ValueType value_type;
|
||||||
struct apply
|
typedef ValueType key_type;
|
||||||
|
|
||||||
|
static key_type const& extract(key_type const& v)
|
||||||
{
|
{
|
||||||
typedef ValueType value_type;
|
return v;
|
||||||
typedef ValueType key_type;
|
}
|
||||||
|
|
||||||
static key_type const& extract(key_type const& v)
|
static no_key extract()
|
||||||
{
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
static no_key extract()
|
|
||||||
{
|
|
||||||
return no_key();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(BOOST_UNORDERED_STD_FORWARD)
|
|
||||||
template <class... Args>
|
|
||||||
static no_key extract(Args const&...)
|
|
||||||
{
|
|
||||||
return no_key();
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
template <class Arg>
|
|
||||||
static no_key extract(Arg const&)
|
|
||||||
{
|
|
||||||
return no_key();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Arg>
|
|
||||||
static no_key extract(Arg const&, Arg const&)
|
|
||||||
{
|
|
||||||
return no_key();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static bool compare_mapped(value_type const&, value_type const&)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct map_extractor
|
|
||||||
{
|
|
||||||
template <class ValueType>
|
|
||||||
struct apply
|
|
||||||
{
|
{
|
||||||
typedef ValueType value_type;
|
return no_key();
|
||||||
typedef BOOST_DEDUCED_TYPENAME
|
}
|
||||||
remove_const<BOOST_DEDUCED_TYPENAME ValueType::first_type>::type
|
|
||||||
key_type;
|
|
||||||
|
|
||||||
static key_type const& extract(value_type const& v)
|
|
||||||
{
|
|
||||||
return v.first;
|
|
||||||
}
|
|
||||||
|
|
||||||
static key_type const& extract(key_type const& v)
|
|
||||||
{
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Second>
|
|
||||||
static key_type const& extract(std::pair<key_type, Second> const& v)
|
|
||||||
{
|
|
||||||
return v.first;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Second>
|
|
||||||
static key_type const& extract(
|
|
||||||
std::pair<key_type const, Second> const& v)
|
|
||||||
{
|
|
||||||
return v.first;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(BOOST_UNORDERED_STD_FORWARD)
|
#if defined(BOOST_UNORDERED_STD_FORWARD)
|
||||||
template <class Arg1, class... Args>
|
template <class... Args>
|
||||||
static key_type const& extract(key_type const& k,
|
static no_key extract(Args const&...)
|
||||||
Arg1 const&, Args const&...)
|
{
|
||||||
{
|
return no_key();
|
||||||
return k;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
template <class... Args>
|
|
||||||
static no_key extract(Args const&...)
|
|
||||||
{
|
|
||||||
return no_key();
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
template <class Arg1>
|
template <class Arg>
|
||||||
static key_type const& extract(key_type const& k, Arg1 const&)
|
static no_key extract(Arg const&)
|
||||||
{
|
{
|
||||||
return k;
|
return no_key();
|
||||||
}
|
}
|
||||||
|
|
||||||
static no_key extract()
|
template <class Arg>
|
||||||
{
|
static no_key extract(Arg const&, Arg const&)
|
||||||
return no_key();
|
{
|
||||||
}
|
return no_key();
|
||||||
|
}
|
||||||
template <class Arg>
|
|
||||||
static no_key extract(Arg const&)
|
|
||||||
{
|
|
||||||
return no_key();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Arg, class Arg1>
|
|
||||||
static no_key extract(Arg const&, Arg1 const&)
|
|
||||||
{
|
|
||||||
return no_key();
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static bool compare_mapped(value_type const& x, value_type const& y)
|
static bool compare_mapped(value_type const&, value_type const&)
|
||||||
{
|
{
|
||||||
return x.second == y.second;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <class Key, class ValueType>
|
||||||
|
struct map_extractor
|
||||||
|
{
|
||||||
|
typedef ValueType value_type;
|
||||||
|
typedef Key key_type;
|
||||||
|
|
||||||
|
static key_type const& extract(value_type const& v)
|
||||||
|
{
|
||||||
|
return v.first;
|
||||||
|
}
|
||||||
|
|
||||||
|
static key_type const& extract(key_type const& v)
|
||||||
|
{
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Second>
|
||||||
|
static key_type const& extract(std::pair<key_type, Second> const& v)
|
||||||
|
{
|
||||||
|
return v.first;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Second>
|
||||||
|
static key_type const& extract(
|
||||||
|
std::pair<key_type const, Second> const& v)
|
||||||
|
{
|
||||||
|
return v.first;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(BOOST_UNORDERED_STD_FORWARD)
|
||||||
|
template <class Arg1, class... Args>
|
||||||
|
static key_type const& extract(key_type const& k,
|
||||||
|
Arg1 const&, Args const&...)
|
||||||
|
{
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class... Args>
|
||||||
|
static no_key extract(Args const&...)
|
||||||
|
{
|
||||||
|
return no_key();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
template <class Arg1>
|
||||||
|
static key_type const& extract(key_type const& k, Arg1 const&)
|
||||||
|
{
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
|
||||||
|
static no_key extract()
|
||||||
|
{
|
||||||
|
return no_key();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Arg>
|
||||||
|
static no_key extract(Arg const&)
|
||||||
|
{
|
||||||
|
return no_key();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Arg, class Arg1>
|
||||||
|
static no_key extract(Arg const&, Arg1 const&)
|
||||||
|
{
|
||||||
|
return no_key();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static bool compare_mapped(value_type const& x, value_type const& y)
|
||||||
|
{
|
||||||
|
return x.second == y.second;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
@ -66,7 +66,9 @@ namespace boost { namespace unordered_detail {
|
|||||||
|
|
||||||
template <class Alloc, class Grouped>
|
template <class Alloc, class Grouped>
|
||||||
class hash_node_constructor;
|
class hash_node_constructor;
|
||||||
|
template <class ValueType>
|
||||||
struct set_extractor;
|
struct set_extractor;
|
||||||
|
template <class Key, class ValueType>
|
||||||
struct map_extractor;
|
struct map_extractor;
|
||||||
struct no_key;
|
struct no_key;
|
||||||
|
|
||||||
@ -208,9 +210,9 @@ namespace boost { namespace unordered_detail {
|
|||||||
typedef A value_allocator;
|
typedef A value_allocator;
|
||||||
typedef hash_bucket<A> bucket;
|
typedef hash_bucket<A> bucket;
|
||||||
typedef hash_node<A, G> node;
|
typedef hash_node<A, G> node;
|
||||||
typedef BOOST_DEDUCED_TYPENAME node::value_type value_type;
|
typedef BOOST_DEDUCED_TYPENAME A::value_type value_type;
|
||||||
typedef BOOST_DEDUCED_TYPENAME node::bucket_ptr bucket_ptr;
|
typedef BOOST_DEDUCED_TYPENAME bucket::bucket_ptr bucket_ptr;
|
||||||
typedef BOOST_DEDUCED_TYPENAME node::node_ptr node_ptr;
|
typedef BOOST_DEDUCED_TYPENAME bucket::node_ptr node_ptr;
|
||||||
|
|
||||||
bucket_ptr bucket_;
|
bucket_ptr bucket_;
|
||||||
node_ptr node_;
|
node_ptr node_;
|
||||||
@ -268,9 +270,9 @@ namespace boost { namespace unordered_detail {
|
|||||||
typedef BOOST_DEDUCED_TYPENAME A::value_type value_type;
|
typedef BOOST_DEDUCED_TYPENAME A::value_type value_type;
|
||||||
typedef BOOST_DEDUCED_TYPENAME iterator_base::node node;
|
typedef BOOST_DEDUCED_TYPENAME iterator_base::node node;
|
||||||
|
|
||||||
typedef BOOST_DEDUCED_TYPENAME node::bucket_allocator bucket_allocator;
|
typedef BOOST_DEDUCED_TYPENAME bucket::bucket_allocator bucket_allocator;
|
||||||
typedef BOOST_DEDUCED_TYPENAME node::bucket_ptr bucket_ptr;
|
typedef BOOST_DEDUCED_TYPENAME bucket::bucket_ptr bucket_ptr;
|
||||||
typedef BOOST_DEDUCED_TYPENAME node::node_ptr node_ptr;
|
typedef BOOST_DEDUCED_TYPENAME bucket::node_ptr node_ptr;
|
||||||
|
|
||||||
typedef BOOST_DEDUCED_TYPENAME rebind_wrap<value_allocator, node>::type
|
typedef BOOST_DEDUCED_TYPENAME rebind_wrap<value_allocator, node>::type
|
||||||
node_allocator;
|
node_allocator;
|
||||||
@ -424,33 +426,28 @@ namespace boost { namespace unordered_detail {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class H, class P, class A, class G, class E>
|
template <class T>
|
||||||
class hash_table :
|
class hash_table : public T::buckets, public T::buffered_functions
|
||||||
public hash_buckets<A, G>,
|
|
||||||
public hash_buffered_functions<H, P>
|
|
||||||
{
|
{
|
||||||
hash_table(hash_table const&);
|
hash_table(hash_table const&);
|
||||||
public:
|
public:
|
||||||
typedef H hasher;
|
typedef BOOST_DEDUCED_TYPENAME T::hasher hasher;
|
||||||
typedef P key_equal;
|
typedef BOOST_DEDUCED_TYPENAME T::key_equal key_equal;
|
||||||
typedef A value_allocator;
|
typedef BOOST_DEDUCED_TYPENAME T::value_allocator value_allocator;
|
||||||
typedef E key_extractor;
|
typedef BOOST_DEDUCED_TYPENAME T::key_type key_type;
|
||||||
typedef hash_buffered_functions<H, P> base;
|
typedef BOOST_DEDUCED_TYPENAME T::value_type value_type;
|
||||||
typedef hash_buckets<A, G> buckets;
|
typedef BOOST_DEDUCED_TYPENAME T::buffered_functions base;
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME T::buckets buckets;
|
||||||
typedef BOOST_DEDUCED_TYPENAME value_allocator::value_type value_type;
|
typedef BOOST_DEDUCED_TYPENAME T::extractor extractor;
|
||||||
typedef BOOST_DEDUCED_TYPENAME key_extractor::BOOST_NESTED_TEMPLATE
|
typedef BOOST_DEDUCED_TYPENAME T::node_constructor node_constructor;
|
||||||
apply<value_type> extractor;
|
|
||||||
typedef BOOST_DEDUCED_TYPENAME extractor::key_type key_type;
|
|
||||||
|
|
||||||
typedef BOOST_DEDUCED_TYPENAME buckets::node node;
|
typedef BOOST_DEDUCED_TYPENAME T::node node;
|
||||||
typedef BOOST_DEDUCED_TYPENAME buckets::bucket bucket;
|
typedef BOOST_DEDUCED_TYPENAME T::bucket bucket;
|
||||||
typedef BOOST_DEDUCED_TYPENAME buckets::node_ptr node_ptr;
|
typedef BOOST_DEDUCED_TYPENAME T::node_ptr node_ptr;
|
||||||
typedef BOOST_DEDUCED_TYPENAME buckets::bucket_ptr bucket_ptr;
|
typedef BOOST_DEDUCED_TYPENAME T::bucket_ptr bucket_ptr;
|
||||||
typedef BOOST_DEDUCED_TYPENAME buckets::iterator_base iterator_base;
|
typedef BOOST_DEDUCED_TYPENAME T::iterator_base iterator_base;
|
||||||
typedef BOOST_DEDUCED_TYPENAME buckets::node_allocator node_allocator;
|
typedef BOOST_DEDUCED_TYPENAME T::node_allocator node_allocator;
|
||||||
typedef hash_node_constructor<A, G> node_constructor;
|
typedef BOOST_DEDUCED_TYPENAME T::iterator_pair iterator_pair;
|
||||||
typedef std::pair<iterator_base, iterator_base> iterator_pair;
|
|
||||||
|
|
||||||
// Members
|
// Members
|
||||||
|
|
||||||
@ -563,27 +560,23 @@ namespace boost { namespace unordered_detail {
|
|||||||
node_constructor&, std::size_t);
|
node_constructor&, std::size_t);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class H, class P, class A, class E>
|
template <class T>
|
||||||
class hash_unique_table :
|
class hash_unique_table : public T::table
|
||||||
public hash_table<H, P, A, ungrouped, E>
|
|
||||||
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef H hasher;
|
typedef BOOST_DEDUCED_TYPENAME T::hasher hasher;
|
||||||
typedef P key_equal;
|
typedef BOOST_DEDUCED_TYPENAME T::key_equal key_equal;
|
||||||
typedef A value_allocator;
|
typedef BOOST_DEDUCED_TYPENAME T::value_allocator value_allocator;
|
||||||
typedef E key_extractor;
|
typedef BOOST_DEDUCED_TYPENAME T::key_type key_type;
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME T::value_type value_type;
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME T::table table;
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME T::node_constructor node_constructor;
|
||||||
|
|
||||||
typedef hash_table<H, P, A, ungrouped, E> table;
|
typedef BOOST_DEDUCED_TYPENAME T::node node;
|
||||||
typedef hash_node_constructor<A, ungrouped> node_constructor;
|
typedef BOOST_DEDUCED_TYPENAME T::node_ptr node_ptr;
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME T::bucket_ptr bucket_ptr;
|
||||||
typedef BOOST_DEDUCED_TYPENAME table::key_type key_type;
|
typedef BOOST_DEDUCED_TYPENAME T::iterator_base iterator_base;
|
||||||
typedef BOOST_DEDUCED_TYPENAME table::value_type value_type;
|
typedef BOOST_DEDUCED_TYPENAME T::extractor extractor;
|
||||||
typedef BOOST_DEDUCED_TYPENAME table::node node;
|
|
||||||
typedef BOOST_DEDUCED_TYPENAME table::node_ptr node_ptr;
|
|
||||||
typedef BOOST_DEDUCED_TYPENAME table::bucket_ptr bucket_ptr;
|
|
||||||
typedef BOOST_DEDUCED_TYPENAME table::iterator_base iterator_base;
|
|
||||||
typedef BOOST_DEDUCED_TYPENAME table::extractor extractor;
|
|
||||||
|
|
||||||
typedef std::pair<iterator_base, bool> emplace_return;
|
typedef std::pair<iterator_base, bool> emplace_return;
|
||||||
|
|
||||||
@ -657,27 +650,23 @@ namespace boost { namespace unordered_detail {
|
|||||||
void insert_range_impl(no_key, InputIt i, InputIt j);
|
void insert_range_impl(no_key, InputIt i, InputIt j);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class H, class P, class A, class E>
|
template <class T>
|
||||||
class hash_equivalent_table :
|
class hash_equivalent_table : public T::table
|
||||||
public hash_table<H, P, A, grouped, E>
|
|
||||||
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef H hasher;
|
typedef BOOST_DEDUCED_TYPENAME T::hasher hasher;
|
||||||
typedef P key_equal;
|
typedef BOOST_DEDUCED_TYPENAME T::key_equal key_equal;
|
||||||
typedef A value_allocator;
|
typedef BOOST_DEDUCED_TYPENAME T::value_allocator value_allocator;
|
||||||
typedef E key_extractor;
|
typedef BOOST_DEDUCED_TYPENAME T::key_type key_type;
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME T::value_type value_type;
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME T::table table;
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME T::node_constructor node_constructor;
|
||||||
|
|
||||||
typedef hash_table<H, P, A, grouped, E> table;
|
typedef BOOST_DEDUCED_TYPENAME T::node node;
|
||||||
typedef hash_node_constructor<A, grouped> node_constructor;
|
typedef BOOST_DEDUCED_TYPENAME T::node_ptr node_ptr;
|
||||||
typedef hash_iterator_base<A, grouped> iterator_base;
|
typedef BOOST_DEDUCED_TYPENAME T::bucket_ptr bucket_ptr;
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME T::iterator_base iterator_base;
|
||||||
typedef BOOST_DEDUCED_TYPENAME table::key_type key_type;
|
typedef BOOST_DEDUCED_TYPENAME T::extractor extractor;
|
||||||
typedef BOOST_DEDUCED_TYPENAME table::value_type value_type;
|
|
||||||
typedef BOOST_DEDUCED_TYPENAME table::node node;
|
|
||||||
typedef BOOST_DEDUCED_TYPENAME table::node_ptr node_ptr;
|
|
||||||
typedef BOOST_DEDUCED_TYPENAME table::bucket_ptr bucket_ptr;
|
|
||||||
typedef BOOST_DEDUCED_TYPENAME table::extractor extractor;
|
|
||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
@ -963,6 +952,80 @@ namespace boost { namespace unordered_detail {
|
|||||||
return base_ != x.base_;
|
return base_ != x.base_;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// types
|
||||||
|
|
||||||
|
template <class K, class V, class H, class P, class A, class E, class G>
|
||||||
|
struct types
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef K key_type;
|
||||||
|
typedef V value_type;
|
||||||
|
typedef H hasher;
|
||||||
|
typedef P key_equal;
|
||||||
|
typedef A value_allocator;
|
||||||
|
typedef E extractor;
|
||||||
|
typedef G group_type;
|
||||||
|
|
||||||
|
typedef hash_node_constructor<value_allocator, group_type> node_constructor;
|
||||||
|
typedef hash_buckets<value_allocator, group_type> buckets;
|
||||||
|
typedef hash_buffered_functions<hasher, key_equal> buffered_functions;
|
||||||
|
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME buckets::node node;
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME buckets::bucket bucket;
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME buckets::node_ptr node_ptr;
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME buckets::bucket_ptr bucket_ptr;
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME buckets::iterator_base iterator_base;
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME buckets::node_allocator node_allocator;
|
||||||
|
|
||||||
|
typedef std::pair<iterator_base, iterator_base> iterator_pair;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class H, class P, class A>
|
||||||
|
struct set : public types<
|
||||||
|
BOOST_DEDUCED_TYPENAME A::value_type,
|
||||||
|
BOOST_DEDUCED_TYPENAME A::value_type,
|
||||||
|
H, P, A,
|
||||||
|
set_extractor<BOOST_DEDUCED_TYPENAME A::value_type>,
|
||||||
|
ungrouped>
|
||||||
|
{
|
||||||
|
typedef hash_unique_table<set<H, P, A> > impl;
|
||||||
|
typedef hash_table<set<H, P, A> > table;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class H, class P, class A>
|
||||||
|
struct multiset : public types<
|
||||||
|
BOOST_DEDUCED_TYPENAME A::value_type,
|
||||||
|
BOOST_DEDUCED_TYPENAME A::value_type,
|
||||||
|
H, P, A,
|
||||||
|
set_extractor<BOOST_DEDUCED_TYPENAME A::value_type>,
|
||||||
|
grouped>
|
||||||
|
{
|
||||||
|
typedef hash_equivalent_table<multiset<H, P, A> > impl;
|
||||||
|
typedef hash_table<multiset<H, P, A> > table;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class K, class H, class P, class A>
|
||||||
|
struct map : public types<
|
||||||
|
K, BOOST_DEDUCED_TYPENAME A::value_type,
|
||||||
|
H, P, A,
|
||||||
|
map_extractor<K, BOOST_DEDUCED_TYPENAME A::value_type>,
|
||||||
|
ungrouped>
|
||||||
|
{
|
||||||
|
typedef hash_unique_table<map<K, H, P, A> > impl;
|
||||||
|
typedef hash_table<map<K, H, P, A> > table;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class K, class H, class P, class A>
|
||||||
|
struct multimap : public types<
|
||||||
|
K, BOOST_DEDUCED_TYPENAME A::value_type,
|
||||||
|
H, P, A,
|
||||||
|
map_extractor<K, BOOST_DEDUCED_TYPENAME A::value_type>,
|
||||||
|
grouped>
|
||||||
|
{
|
||||||
|
typedef hash_equivalent_table<multimap<K, H, P, A> > impl;
|
||||||
|
typedef hash_table<multimap<K, H, P, A> > table;
|
||||||
|
};
|
||||||
}}
|
}}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -21,17 +21,17 @@ namespace boost { namespace unordered_detail {
|
|||||||
// Helper methods
|
// Helper methods
|
||||||
|
|
||||||
// strong exception safety, no side effects
|
// strong exception safety, no side effects
|
||||||
template <class H, class P, class A, class G, class E>
|
template <class T>
|
||||||
inline bool hash_table<H, P, A, G, E>::equal(
|
inline bool hash_table<T>::equal(
|
||||||
key_type const& k, value_type const& v) const
|
key_type const& k, value_type const& v) const
|
||||||
{
|
{
|
||||||
return this->key_eq()(k, get_key(v));
|
return this->key_eq()(k, get_key(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
// strong exception safety, no side effects
|
// strong exception safety, no side effects
|
||||||
template <class H, class P, class A, class G, class E>
|
template <class T>
|
||||||
inline BOOST_DEDUCED_TYPENAME hash_table<H, P, A, G, E>::node_ptr
|
inline BOOST_DEDUCED_TYPENAME T::node_ptr
|
||||||
hash_table<H, P, A, G, E>::find_iterator(
|
hash_table<T>::find_iterator(
|
||||||
bucket_ptr bucket, key_type const& k) const
|
bucket_ptr bucket, key_type const& k) const
|
||||||
{
|
{
|
||||||
node_ptr it = bucket->next_;
|
node_ptr it = bucket->next_;
|
||||||
@ -46,17 +46,17 @@ namespace boost { namespace unordered_detail {
|
|||||||
|
|
||||||
// strong exception safety, no side effects
|
// strong exception safety, no side effects
|
||||||
// pre: this->buckets_
|
// pre: this->buckets_
|
||||||
template <class H, class P, class A, class G, class E>
|
template <class T>
|
||||||
inline BOOST_DEDUCED_TYPENAME hash_table<H, P, A, G, E>::node_ptr
|
inline BOOST_DEDUCED_TYPENAME T::node_ptr
|
||||||
hash_table<H, P, A, G, E>::find_iterator(key_type const& k) const
|
hash_table<T>::find_iterator(key_type const& k) const
|
||||||
{
|
{
|
||||||
return find_iterator(this->get_bucket(this->bucket_index(k)), k);
|
return find_iterator(this->get_bucket(this->bucket_index(k)), k);
|
||||||
}
|
}
|
||||||
|
|
||||||
// strong exception safety, no side effects
|
// strong exception safety, no side effects
|
||||||
template <class H, class P, class A, class G, class E>
|
template <class T>
|
||||||
inline BOOST_DEDUCED_TYPENAME hash_table<H, P, A, G, E>::node_ptr*
|
inline BOOST_DEDUCED_TYPENAME T::node_ptr*
|
||||||
hash_table<H, P, A, G, E>::find_for_erase(
|
hash_table<T>::find_for_erase(
|
||||||
bucket_ptr bucket, key_type const& k) const
|
bucket_ptr bucket, key_type const& k) const
|
||||||
{
|
{
|
||||||
node_ptr* it = &bucket->next_;
|
node_ptr* it = &bucket->next_;
|
||||||
@ -73,8 +73,8 @@ namespace boost { namespace unordered_detail {
|
|||||||
// Load methods
|
// Load methods
|
||||||
|
|
||||||
// no throw
|
// no throw
|
||||||
template <class H, class P, class A, class G, class E>
|
template <class T>
|
||||||
std::size_t hash_table<H, P, A, G, E>::max_size() const
|
std::size_t hash_table<T>::max_size() const
|
||||||
{
|
{
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@ -84,8 +84,8 @@ namespace boost { namespace unordered_detail {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// strong safety
|
// strong safety
|
||||||
template <class H, class P, class A, class G, class E>
|
template <class T>
|
||||||
inline std::size_t hash_table<H, P, A, G, E>::bucket_index(
|
inline std::size_t hash_table<T>::bucket_index(
|
||||||
key_type const& k) const
|
key_type const& k) const
|
||||||
{
|
{
|
||||||
// hash_function can throw:
|
// hash_function can throw:
|
||||||
@ -94,8 +94,8 @@ namespace boost { namespace unordered_detail {
|
|||||||
|
|
||||||
|
|
||||||
// no throw
|
// no throw
|
||||||
template <class H, class P, class A, class G, class E>
|
template <class T>
|
||||||
inline std::size_t hash_table<H, P, A, G, E>::calculate_max_load()
|
inline std::size_t hash_table<T>::calculate_max_load()
|
||||||
{
|
{
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@ -104,8 +104,8 @@ namespace boost { namespace unordered_detail {
|
|||||||
return double_to_size_t(ceil((double) mlf_ * this->bucket_count_));
|
return double_to_size_t(ceil((double) mlf_ * this->bucket_count_));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class H, class P, class A, class G, class E>
|
template <class T>
|
||||||
void hash_table<H, P, A, G, E>::max_load_factor(float z)
|
void hash_table<T>::max_load_factor(float z)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(z > 0);
|
BOOST_ASSERT(z > 0);
|
||||||
mlf_ = (std::max)(z, minimum_max_load_factor);
|
mlf_ = (std::max)(z, minimum_max_load_factor);
|
||||||
@ -113,8 +113,8 @@ namespace boost { namespace unordered_detail {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// no throw
|
// no throw
|
||||||
template <class H, class P, class A, class G, class E>
|
template <class T>
|
||||||
inline std::size_t hash_table<H, P, A, G, E>::min_buckets_for_size(
|
inline std::size_t hash_table<T>::min_buckets_for_size(
|
||||||
std::size_t size) const
|
std::size_t size) const
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(this->mlf_ != 0);
|
BOOST_ASSERT(this->mlf_ != 0);
|
||||||
@ -135,8 +135,8 @@ namespace boost { namespace unordered_detail {
|
|||||||
|
|
||||||
// init_buckets
|
// init_buckets
|
||||||
|
|
||||||
template <class H, class P, class A, class G, class E>
|
template <class T>
|
||||||
inline void hash_table<H, P, A, G, E>::init_buckets()
|
inline void hash_table<T>::init_buckets()
|
||||||
{
|
{
|
||||||
if (this->size_) {
|
if (this->size_) {
|
||||||
this->cached_begin_bucket_ = this->buckets_;
|
this->cached_begin_bucket_ = this->buckets_;
|
||||||
@ -153,8 +153,8 @@ namespace boost { namespace unordered_detail {
|
|||||||
//
|
//
|
||||||
// no throw
|
// no throw
|
||||||
|
|
||||||
template <class H, class P, class A, class G, class E>
|
template <class T>
|
||||||
inline void hash_table<H, P, A, G, E>::recompute_begin_bucket(bucket_ptr b)
|
inline void hash_table<T>::recompute_begin_bucket(bucket_ptr b)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(!(b < this->cached_begin_bucket_));
|
BOOST_ASSERT(!(b < this->cached_begin_bucket_));
|
||||||
|
|
||||||
@ -174,8 +174,8 @@ namespace boost { namespace unordered_detail {
|
|||||||
//
|
//
|
||||||
// no throw
|
// no throw
|
||||||
|
|
||||||
template <class H, class P, class A, class G, class E>
|
template <class T>
|
||||||
inline void hash_table<H, P, A, G, E>::recompute_begin_bucket(
|
inline void hash_table<T>::recompute_begin_bucket(
|
||||||
bucket_ptr b1, bucket_ptr b2)
|
bucket_ptr b1, bucket_ptr b2)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(!(b1 < this->cached_begin_bucket_) && !(b2 < b1));
|
BOOST_ASSERT(!(b1 < this->cached_begin_bucket_) && !(b2 < b1));
|
||||||
@ -186,8 +186,8 @@ namespace boost { namespace unordered_detail {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// no throw
|
// no throw
|
||||||
template <class H, class P, class A, class G, class E>
|
template <class T>
|
||||||
inline float hash_table<H, P, A, G, E>::load_factor() const
|
inline float hash_table<T>::load_factor() const
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(this->bucket_count_ != 0);
|
BOOST_ASSERT(this->bucket_count_ != 0);
|
||||||
return static_cast<float>(this->size_)
|
return static_cast<float>(this->size_)
|
||||||
@ -197,8 +197,8 @@ namespace boost { namespace unordered_detail {
|
|||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
template <class H, class P, class A, class G, class E>
|
template <class T>
|
||||||
hash_table<H, P, A, G, E>::hash_table(std::size_t num_buckets,
|
hash_table<T>::hash_table(std::size_t num_buckets,
|
||||||
hasher const& hf, key_equal const& eq, node_allocator const& a)
|
hasher const& hf, key_equal const& eq, node_allocator const& a)
|
||||||
: buckets(a, next_prime(num_buckets)),
|
: buckets(a, next_prime(num_buckets)),
|
||||||
base(hf, eq),
|
base(hf, eq),
|
||||||
@ -211,8 +211,8 @@ namespace boost { namespace unordered_detail {
|
|||||||
|
|
||||||
// Copy Construct with allocator
|
// Copy Construct with allocator
|
||||||
|
|
||||||
template <class H, class P, class A, class G, class E>
|
template <class T>
|
||||||
hash_table<H, P, A, G, E>::hash_table(hash_table const& x,
|
hash_table<T>::hash_table(hash_table const& x,
|
||||||
node_allocator const& a)
|
node_allocator const& a)
|
||||||
: buckets(a, x.min_buckets_for_size(x.size_)),
|
: buckets(a, x.min_buckets_for_size(x.size_)),
|
||||||
base(x),
|
base(x),
|
||||||
@ -229,8 +229,8 @@ namespace boost { namespace unordered_detail {
|
|||||||
|
|
||||||
// Move Construct
|
// Move Construct
|
||||||
|
|
||||||
template <class H, class P, class A, class G, class E>
|
template <class T>
|
||||||
hash_table<H, P, A, G, E>::hash_table(hash_table& x, move_tag)
|
hash_table<T>::hash_table(hash_table& x, move_tag)
|
||||||
: buckets(x.node_alloc(), x.bucket_count_),
|
: buckets(x.node_alloc(), x.bucket_count_),
|
||||||
base(x),
|
base(x),
|
||||||
size_(0),
|
size_(0),
|
||||||
@ -241,8 +241,8 @@ namespace boost { namespace unordered_detail {
|
|||||||
this->partial_swap(x);
|
this->partial_swap(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class H, class P, class A, class G, class E>
|
template <class T>
|
||||||
hash_table<H, P, A, G, E>::hash_table(hash_table& x,
|
hash_table<T>::hash_table(hash_table& x,
|
||||||
node_allocator const& a, move_tag)
|
node_allocator const& a, move_tag)
|
||||||
: buckets(a, x.bucket_count_),
|
: buckets(a, x.bucket_count_),
|
||||||
base(x),
|
base(x),
|
||||||
@ -261,8 +261,8 @@ namespace boost { namespace unordered_detail {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class H, class P, class A, class G, class E>
|
template <class T>
|
||||||
hash_table<H, P, A, G, E>& hash_table<H, P, A, G, K>::operator=(
|
hash_table<T>& hash_table<T>::operator=(
|
||||||
hash_table const& x)
|
hash_table const& x)
|
||||||
{
|
{
|
||||||
hash_table tmp(x, this->node_alloc());
|
hash_table tmp(x, this->node_alloc());
|
||||||
@ -280,8 +280,8 @@ namespace boost { namespace unordered_detail {
|
|||||||
// Can throw if hash or predicate object's copy constructor throws
|
// Can throw if hash or predicate object's copy constructor throws
|
||||||
// or if allocators are unequal.
|
// or if allocators are unequal.
|
||||||
|
|
||||||
template <class H, class P, class A, class G, class E>
|
template <class T>
|
||||||
inline void hash_table<H, P, A, G, E>::partial_swap(hash_table& x)
|
inline void hash_table<T>::partial_swap(hash_table& x)
|
||||||
{
|
{
|
||||||
this->buckets::swap(x); // No throw
|
this->buckets::swap(x); // No throw
|
||||||
std::swap(this->size_, x.size_);
|
std::swap(this->size_, x.size_);
|
||||||
@ -290,15 +290,15 @@ namespace boost { namespace unordered_detail {
|
|||||||
std::swap(this->max_load_, x.max_load_);
|
std::swap(this->max_load_, x.max_load_);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class H, class P, class A, class G, class E>
|
template <class T>
|
||||||
inline void hash_table<H, P, A, G, E>::fast_swap(hash_table& x)
|
inline void hash_table<T>::fast_swap(hash_table& x)
|
||||||
{
|
{
|
||||||
// These can throw, but they only affect the function objects
|
// These can throw, but they only affect the function objects
|
||||||
// that aren't in use so it is strongly exception safe, via.
|
// that aren't in use so it is strongly exception safe, via.
|
||||||
// double buffering.
|
// double buffering.
|
||||||
{
|
{
|
||||||
set_hash_functions<H, P> op1(*this, x);
|
set_hash_functions<hasher, key_equal> op1(*this, x);
|
||||||
set_hash_functions<H, P> op2(x, *this);
|
set_hash_functions<hasher, key_equal> op2(x, *this);
|
||||||
op1.commit();
|
op1.commit();
|
||||||
op2.commit();
|
op2.commit();
|
||||||
}
|
}
|
||||||
@ -309,8 +309,8 @@ namespace boost { namespace unordered_detail {
|
|||||||
std::swap(this->max_load_, x.max_load_);
|
std::swap(this->max_load_, x.max_load_);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class H, class P, class A, class G, class E>
|
template <class T>
|
||||||
inline void hash_table<H, P, A, G, E>::slow_swap(hash_table& x)
|
inline void hash_table<T>::slow_swap(hash_table& x)
|
||||||
{
|
{
|
||||||
if(this == &x) return;
|
if(this == &x) return;
|
||||||
|
|
||||||
@ -318,8 +318,8 @@ namespace boost { namespace unordered_detail {
|
|||||||
// These can throw, but they only affect the function objects
|
// These can throw, but they only affect the function objects
|
||||||
// that aren't in use so it is strongly exception safe, via.
|
// that aren't in use so it is strongly exception safe, via.
|
||||||
// double buffering.
|
// double buffering.
|
||||||
set_hash_functions<H, P> op1(*this, x);
|
set_hash_functions<hasher, key_equal> op1(*this, x);
|
||||||
set_hash_functions<H, P> op2(x, *this);
|
set_hash_functions<hasher, key_equal> op2(x, *this);
|
||||||
|
|
||||||
// Create new buckets in separate hash_buckets objects
|
// Create new buckets in separate hash_buckets objects
|
||||||
// which will clean up if anything throws an exception.
|
// which will clean up if anything throws an exception.
|
||||||
@ -345,8 +345,8 @@ namespace boost { namespace unordered_detail {
|
|||||||
if(x.buckets_) x.init_buckets();
|
if(x.buckets_) x.init_buckets();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class H, class P, class A, class G, class E>
|
template <class T>
|
||||||
void hash_table<H, P, A, G, E>::swap(hash_table& x)
|
void hash_table<T>::swap(hash_table& x)
|
||||||
{
|
{
|
||||||
if(this->node_alloc() == x.node_alloc()) {
|
if(this->node_alloc() == x.node_alloc()) {
|
||||||
if(this != &x) this->fast_swap(x);
|
if(this != &x) this->fast_swap(x);
|
||||||
@ -364,13 +364,13 @@ namespace boost { namespace unordered_detail {
|
|||||||
// Can throw if hash or predicate object's copy constructor throws
|
// Can throw if hash or predicate object's copy constructor throws
|
||||||
// or if allocators are unequal.
|
// or if allocators are unequal.
|
||||||
|
|
||||||
template <class H, class P, class A, class G, class E>
|
template <class T>
|
||||||
void hash_table<H, P, A, G, E>::move(hash_table& x)
|
void hash_table<T>::move(hash_table& x)
|
||||||
{
|
{
|
||||||
// This can throw, but it only affects the function objects
|
// This can throw, but it only affects the function objects
|
||||||
// that aren't in use so it is strongly exception safe, via.
|
// that aren't in use so it is strongly exception safe, via.
|
||||||
// double buffering.
|
// double buffering.
|
||||||
set_hash_functions<H, P> new_func_this(*this, x);
|
set_hash_functions<hasher, key_equal> new_func_this(*this, x);
|
||||||
|
|
||||||
if(this->node_alloc() == x.node_alloc()) {
|
if(this->node_alloc() == x.node_alloc()) {
|
||||||
this->buckets::move(x); // no throw
|
this->buckets::move(x); // no throw
|
||||||
@ -402,8 +402,8 @@ namespace boost { namespace unordered_detail {
|
|||||||
// Reserve & Rehash
|
// Reserve & Rehash
|
||||||
|
|
||||||
// basic exception safety
|
// basic exception safety
|
||||||
template <class H, class P, class A, class G, class E>
|
template <class T>
|
||||||
inline void hash_table<H, P, A, G, E>::create_for_insert(std::size_t size)
|
inline void hash_table<T>::create_for_insert(std::size_t size)
|
||||||
{
|
{
|
||||||
this->bucket_count_ = (std::max)(this->bucket_count_,
|
this->bucket_count_ = (std::max)(this->bucket_count_,
|
||||||
this->min_buckets_for_size(size));
|
this->min_buckets_for_size(size));
|
||||||
@ -412,8 +412,8 @@ namespace boost { namespace unordered_detail {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// basic exception safety
|
// basic exception safety
|
||||||
template <class H, class P, class A, class G, class E>
|
template <class T>
|
||||||
inline bool hash_table<H, P, A, G, E>::reserve_for_insert(std::size_t size)
|
inline bool hash_table<T>::reserve_for_insert(std::size_t size)
|
||||||
{
|
{
|
||||||
if(size >= max_load_) {
|
if(size >= max_load_) {
|
||||||
std::size_t num_buckets
|
std::size_t num_buckets
|
||||||
@ -431,8 +431,8 @@ namespace boost { namespace unordered_detail {
|
|||||||
// if hash function throws, basic exception safety
|
// if hash function throws, basic exception safety
|
||||||
// strong otherwise.
|
// strong otherwise.
|
||||||
|
|
||||||
template <class H, class P, class A, class G, class E>
|
template <class T>
|
||||||
inline void hash_table<H, P, A, G, E>::rehash(std::size_t min_buckets)
|
inline void hash_table<T>::rehash(std::size_t min_buckets)
|
||||||
{
|
{
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@ -451,8 +451,8 @@ namespace boost { namespace unordered_detail {
|
|||||||
// if hash function throws, basic exception safety
|
// if hash function throws, basic exception safety
|
||||||
// strong otherwise
|
// strong otherwise
|
||||||
|
|
||||||
template <class H, class P, class A, class G, class E>
|
template <class T>
|
||||||
void hash_table<H, P, A, G, E>
|
void hash_table<T>
|
||||||
::rehash_impl(std::size_t num_buckets)
|
::rehash_impl(std::size_t num_buckets)
|
||||||
{
|
{
|
||||||
hasher const& hf = this->hash_function();
|
hasher const& hf = this->hash_function();
|
||||||
@ -500,8 +500,8 @@ namespace boost { namespace unordered_detail {
|
|||||||
// basic excpetion safety. If an exception is thrown this will
|
// basic excpetion safety. If an exception is thrown this will
|
||||||
// leave dst partially filled.
|
// leave dst partially filled.
|
||||||
|
|
||||||
template <class H, class P, class A, class G, class E>
|
template <class T>
|
||||||
void hash_table<H, P, A, G, E>
|
void hash_table<T>
|
||||||
::copy_buckets_to(buckets& dst) const
|
::copy_buckets_to(buckets& dst) const
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(this->buckets_ && !dst.buckets_);
|
BOOST_ASSERT(this->buckets_ && !dst.buckets_);
|
||||||
@ -509,7 +509,7 @@ namespace boost { namespace unordered_detail {
|
|||||||
hasher const& hf = this->hash_function();
|
hasher const& hf = this->hash_function();
|
||||||
bucket_ptr end = this->get_bucket(this->bucket_count_);
|
bucket_ptr end = this->get_bucket(this->bucket_count_);
|
||||||
|
|
||||||
hash_node_constructor<A, G> a(dst);
|
node_constructor a(dst);
|
||||||
dst.create_buckets();
|
dst.create_buckets();
|
||||||
|
|
||||||
// no throw:
|
// no throw:
|
||||||
@ -544,8 +544,8 @@ namespace boost { namespace unordered_detail {
|
|||||||
//
|
//
|
||||||
// strong exception safety, no side effects
|
// strong exception safety, no side effects
|
||||||
|
|
||||||
template <class H, class P, class A, class G, class E>
|
template <class T>
|
||||||
std::size_t hash_table<H, P, A, G, E>::count(key_type const& k) const
|
std::size_t hash_table<T>::count(key_type const& k) const
|
||||||
{
|
{
|
||||||
if(!this->size_) return 0;
|
if(!this->size_) return 0;
|
||||||
node_ptr it = find_iterator(k); // throws, strong
|
node_ptr it = find_iterator(k); // throws, strong
|
||||||
@ -555,9 +555,9 @@ namespace boost { namespace unordered_detail {
|
|||||||
// find
|
// find
|
||||||
//
|
//
|
||||||
// strong exception safety, no side effects
|
// strong exception safety, no side effects
|
||||||
template <class H, class P, class A, class G, class E>
|
template <class T>
|
||||||
BOOST_DEDUCED_TYPENAME hash_table<H, P, A, G, E>::iterator_base
|
BOOST_DEDUCED_TYPENAME T::iterator_base
|
||||||
hash_table<H, P, A, G, E>::find(key_type const& k) const
|
hash_table<T>::find(key_type const& k) const
|
||||||
{
|
{
|
||||||
if(!this->size_) return this->end();
|
if(!this->size_) return this->end();
|
||||||
|
|
||||||
@ -570,9 +570,9 @@ namespace boost { namespace unordered_detail {
|
|||||||
return this->end();
|
return this->end();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class H, class P, class A, class G, class E>
|
template <class T>
|
||||||
BOOST_DEDUCED_TYPENAME A::value_type&
|
BOOST_DEDUCED_TYPENAME T::value_type&
|
||||||
hash_table<H, P, A, G, E>::at(key_type const& k) const
|
hash_table<T>::at(key_type const& k) const
|
||||||
{
|
{
|
||||||
if(!this->size_)
|
if(!this->size_)
|
||||||
throw std::out_of_range("Unable to find key in unordered_map.");
|
throw std::out_of_range("Unable to find key in unordered_map.");
|
||||||
@ -589,9 +589,9 @@ namespace boost { namespace unordered_detail {
|
|||||||
// equal_range
|
// equal_range
|
||||||
//
|
//
|
||||||
// strong exception safety, no side effects
|
// strong exception safety, no side effects
|
||||||
template <class H, class P, class A, class G, class E>
|
template <class T>
|
||||||
BOOST_DEDUCED_TYPENAME hash_table<H, P, A, G, E>::iterator_pair
|
BOOST_DEDUCED_TYPENAME T::iterator_pair
|
||||||
hash_table<H, P, A, G, E>::equal_range(key_type const& k) const
|
hash_table<T>::equal_range(key_type const& k) const
|
||||||
{
|
{
|
||||||
if(!this->size_)
|
if(!this->size_)
|
||||||
return iterator_pair(this->end(), this->end());
|
return iterator_pair(this->end(), this->end());
|
||||||
@ -612,8 +612,8 @@ namespace boost { namespace unordered_detail {
|
|||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
// Erase methods
|
// Erase methods
|
||||||
|
|
||||||
template <class H, class P, class A, class G, class E>
|
template <class T>
|
||||||
void hash_table<H, P, A, G, E>::clear()
|
void hash_table<T>::clear()
|
||||||
{
|
{
|
||||||
if(!this->size_) return;
|
if(!this->size_) return;
|
||||||
|
|
||||||
@ -626,8 +626,8 @@ namespace boost { namespace unordered_detail {
|
|||||||
this->cached_begin_bucket_ = end;
|
this->cached_begin_bucket_ = end;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class H, class P, class A, class G, class E>
|
template <class T>
|
||||||
inline std::size_t hash_table<H, P, A, G, E>::erase_group(
|
inline std::size_t hash_table<T>::erase_group(
|
||||||
node_ptr* it, bucket_ptr bucket)
|
node_ptr* it, bucket_ptr bucket)
|
||||||
{
|
{
|
||||||
node_ptr pos = *it;
|
node_ptr pos = *it;
|
||||||
@ -639,8 +639,8 @@ namespace boost { namespace unordered_detail {
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class H, class P, class A, class G, class E>
|
template <class T>
|
||||||
std::size_t hash_table<H, P, A, G, E>::erase_key(key_type const& k)
|
std::size_t hash_table<T>::erase_key(key_type const& k)
|
||||||
{
|
{
|
||||||
if(!this->size_) return 0;
|
if(!this->size_) return 0;
|
||||||
|
|
||||||
@ -653,9 +653,9 @@ namespace boost { namespace unordered_detail {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <class H, class P, class A, class G, class E>
|
template <class T>
|
||||||
BOOST_DEDUCED_TYPENAME hash_table<H, P, A, G, E>::iterator_base
|
BOOST_DEDUCED_TYPENAME T::iterator_base
|
||||||
hash_table<H, P, A, G, E>::erase(iterator_base r)
|
hash_table<T>::erase(iterator_base r)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(r.node_);
|
BOOST_ASSERT(r.node_);
|
||||||
iterator_base next = r;
|
iterator_base next = r;
|
||||||
@ -668,9 +668,9 @@ namespace boost { namespace unordered_detail {
|
|||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class H, class P, class A, class G, class E>
|
template <class T>
|
||||||
BOOST_DEDUCED_TYPENAME hash_table<H, P, A, G, E>::iterator_base
|
BOOST_DEDUCED_TYPENAME T::iterator_base
|
||||||
hash_table<H, P, A, G, E>::erase_range(
|
hash_table<T>::erase_range(
|
||||||
iterator_base r1, iterator_base r2)
|
iterator_base r1, iterator_base r2)
|
||||||
{
|
{
|
||||||
if(r1 != r2)
|
if(r1 != r2)
|
||||||
@ -713,9 +713,9 @@ namespace boost { namespace unordered_detail {
|
|||||||
return r2;
|
return r2;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class H, class P, class A, class G, class E>
|
template <class T>
|
||||||
BOOST_DEDUCED_TYPENAME hash_table<H, P, A, G, E>::iterator_base
|
BOOST_DEDUCED_TYPENAME hash_table<T>::iterator_base
|
||||||
hash_table<H, P, A, G, E>::emplace_empty_impl_with_node(
|
hash_table<T>::emplace_empty_impl_with_node(
|
||||||
node_constructor& a, std::size_t size)
|
node_constructor& a, std::size_t size)
|
||||||
{
|
{
|
||||||
key_type const& k = get_key(a.value());
|
key_type const& k = get_key(a.value());
|
||||||
|
@ -15,9 +15,9 @@ namespace boost { namespace unordered_detail {
|
|||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
// Equality
|
// Equality
|
||||||
|
|
||||||
template <class H, class P, class A, class E>
|
template <class T>
|
||||||
bool hash_unique_table<H, P, A, E>
|
bool hash_unique_table<T>
|
||||||
::equals(hash_unique_table<H, P, A, E> const& other) const
|
::equals(hash_unique_table<T> const& other) const
|
||||||
{
|
{
|
||||||
if(this->size_ != other.size_) return false;
|
if(this->size_ != other.size_) return false;
|
||||||
if(!this->size_) return true;
|
if(!this->size_) return true;
|
||||||
@ -43,9 +43,9 @@ namespace boost { namespace unordered_detail {
|
|||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
// A convenience method for adding nodes.
|
// A convenience method for adding nodes.
|
||||||
|
|
||||||
template <class H, class P, class A, class E>
|
template <class T>
|
||||||
inline BOOST_DEDUCED_TYPENAME hash_unique_table<H, P, A, E>::node_ptr
|
inline BOOST_DEDUCED_TYPENAME hash_unique_table<T>::node_ptr
|
||||||
hash_unique_table<H, P, A, E>::add_node(node_constructor& a,
|
hash_unique_table<T>::add_node(node_constructor& a,
|
||||||
bucket_ptr bucket)
|
bucket_ptr bucket)
|
||||||
{
|
{
|
||||||
node_ptr n = a.release();
|
node_ptr n = a.release();
|
||||||
@ -61,9 +61,9 @@ namespace boost { namespace unordered_detail {
|
|||||||
|
|
||||||
// if hash function throws, basic exception safety
|
// if hash function throws, basic exception safety
|
||||||
// strong otherwise
|
// strong otherwise
|
||||||
template <class H, class P, class A, class E>
|
template <class T>
|
||||||
BOOST_DEDUCED_TYPENAME hash_unique_table<H, P, A, E>::value_type&
|
BOOST_DEDUCED_TYPENAME hash_unique_table<T>::value_type&
|
||||||
hash_unique_table<H, P, A, E>::operator[](key_type const& k)
|
hash_unique_table<T>::operator[](key_type const& k)
|
||||||
{
|
{
|
||||||
typedef BOOST_DEDUCED_TYPENAME value_type::second_type mapped_type;
|
typedef BOOST_DEDUCED_TYPENAME value_type::second_type mapped_type;
|
||||||
|
|
||||||
@ -100,9 +100,9 @@ namespace boost { namespace unordered_detail {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class H, class P, class A, class E>
|
template <class T>
|
||||||
inline BOOST_DEDUCED_TYPENAME hash_unique_table<H, P, A, E>::emplace_return
|
inline BOOST_DEDUCED_TYPENAME hash_unique_table<T>::emplace_return
|
||||||
hash_unique_table<H, P, A, E>::emplace_impl_with_node(node_constructor& a)
|
hash_unique_table<T>::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 = this->get_key(a.value());
|
key_type const& k = this->get_key(a.value());
|
||||||
@ -129,10 +129,10 @@ namespace boost { namespace unordered_detail {
|
|||||||
|
|
||||||
#if defined(BOOST_UNORDERED_STD_FORWARD)
|
#if defined(BOOST_UNORDERED_STD_FORWARD)
|
||||||
|
|
||||||
template <class H, class P, class A, class E>
|
template <class T>
|
||||||
template<class... Args>
|
template<class... Args>
|
||||||
inline BOOST_DEDUCED_TYPENAME hash_unique_table<H, P, A, E>::emplace_return
|
inline BOOST_DEDUCED_TYPENAME hash_unique_table<T>::emplace_return
|
||||||
hash_unique_table<H, P, A, E>::emplace_impl(key_type const& k,
|
hash_unique_table<T>::emplace_impl(key_type const& k,
|
||||||
Args&&... args)
|
Args&&... args)
|
||||||
{
|
{
|
||||||
// No side effects in this initial code
|
// No side effects in this initial code
|
||||||
@ -166,10 +166,10 @@ namespace boost { namespace unordered_detail {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class H, class P, class A, class E>
|
template <class T>
|
||||||
template<class... Args>
|
template<class... Args>
|
||||||
inline BOOST_DEDUCED_TYPENAME hash_unique_table<H, P, A, E>::emplace_return
|
inline BOOST_DEDUCED_TYPENAME hash_unique_table<T>::emplace_return
|
||||||
hash_unique_table<H, P, A, E>::emplace_impl(no_key, Args&&... args)
|
hash_unique_table<T>::emplace_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
|
||||||
@ -178,10 +178,10 @@ namespace boost { namespace unordered_detail {
|
|||||||
return emplace_impl_with_node(a);
|
return emplace_impl_with_node(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class H, class P, class A, class E>
|
template <class T>
|
||||||
template<class... Args>
|
template<class... Args>
|
||||||
inline BOOST_DEDUCED_TYPENAME hash_unique_table<H, P, A, E>::emplace_return
|
inline BOOST_DEDUCED_TYPENAME hash_unique_table<T>::emplace_return
|
||||||
hash_unique_table<H, P, A, E>::emplace_empty_impl(Args&&... args)
|
hash_unique_table<T>::emplace_empty_impl(Args&&... args)
|
||||||
{
|
{
|
||||||
node_constructor a(*this);
|
node_constructor a(*this);
|
||||||
a.construct(std::forward<Args>(args)...);
|
a.construct(std::forward<Args>(args)...);
|
||||||
@ -191,11 +191,11 @@ namespace boost { namespace unordered_detail {
|
|||||||
#else
|
#else
|
||||||
|
|
||||||
#define BOOST_UNORDERED_INSERT_IMPL(z, num_params, _) \
|
#define BOOST_UNORDERED_INSERT_IMPL(z, num_params, _) \
|
||||||
template <class H, class P, class A, class E> \
|
template <class T> \
|
||||||
template <BOOST_UNORDERED_TEMPLATE_ARGS(z, num_params)> \
|
template <BOOST_UNORDERED_TEMPLATE_ARGS(z, num_params)> \
|
||||||
inline BOOST_DEDUCED_TYPENAME \
|
inline BOOST_DEDUCED_TYPENAME \
|
||||||
hash_unique_table<H, P, A, E>::emplace_return \
|
hash_unique_table<T>::emplace_return \
|
||||||
hash_unique_table<H, P, A, E>::emplace_impl( \
|
hash_unique_table<T>::emplace_impl( \
|
||||||
key_type const& k, \
|
key_type const& k, \
|
||||||
BOOST_UNORDERED_FUNCTION_PARAMS(z, num_params)) \
|
BOOST_UNORDERED_FUNCTION_PARAMS(z, num_params)) \
|
||||||
{ \
|
{ \
|
||||||
@ -218,11 +218,11 @@ namespace boost { namespace unordered_detail {
|
|||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
template <class H, class P, class A, class E> \
|
template <class T> \
|
||||||
template <BOOST_UNORDERED_TEMPLATE_ARGS(z, num_params)> \
|
template <BOOST_UNORDERED_TEMPLATE_ARGS(z, num_params)> \
|
||||||
inline BOOST_DEDUCED_TYPENAME \
|
inline BOOST_DEDUCED_TYPENAME \
|
||||||
hash_unique_table<H, P, A, E>::emplace_return \
|
hash_unique_table<T>::emplace_return \
|
||||||
hash_unique_table<H, P, A, E>:: \
|
hash_unique_table<T>:: \
|
||||||
emplace_impl(no_key, \
|
emplace_impl(no_key, \
|
||||||
BOOST_UNORDERED_FUNCTION_PARAMS(z, num_params)) \
|
BOOST_UNORDERED_FUNCTION_PARAMS(z, num_params)) \
|
||||||
{ \
|
{ \
|
||||||
@ -231,17 +231,17 @@ namespace boost { namespace unordered_detail {
|
|||||||
return emplace_impl_with_node(a); \
|
return emplace_impl_with_node(a); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
template <class H, class P, class A, class E> \
|
template <class T> \
|
||||||
template <BOOST_UNORDERED_TEMPLATE_ARGS(z, num_params)> \
|
template <BOOST_UNORDERED_TEMPLATE_ARGS(z, num_params)> \
|
||||||
inline BOOST_DEDUCED_TYPENAME \
|
inline BOOST_DEDUCED_TYPENAME \
|
||||||
hash_unique_table<H, P, A, E>::emplace_return \
|
hash_unique_table<T>::emplace_return \
|
||||||
hash_unique_table<H, P, A, E>:: \
|
hash_unique_table<T>:: \
|
||||||
emplace_empty_impl( \
|
emplace_empty_impl( \
|
||||||
BOOST_UNORDERED_FUNCTION_PARAMS(z, num_params)) \
|
BOOST_UNORDERED_FUNCTION_PARAMS(z, num_params)) \
|
||||||
{ \
|
{ \
|
||||||
node_constructor a(*this); \
|
node_constructor a(*this); \
|
||||||
a.construct(BOOST_UNORDERED_CALL_PARAMS(z, num_params)); \
|
a.construct(BOOST_UNORDERED_CALL_PARAMS(z, num_params)); \
|
||||||
return emplace_return(this->emplace_empty_impl_with_node(a, 1), true); \
|
return emplace_return(this->emplace_empty_impl_with_node(a, 1), true); \
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT,
|
BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT,
|
||||||
@ -259,10 +259,10 @@ namespace boost { namespace unordered_detail {
|
|||||||
// if hash function throws, basic exception safety
|
// if hash function throws, basic exception safety
|
||||||
// strong otherwise
|
// strong otherwise
|
||||||
|
|
||||||
template <class H, class P, class A, class E>
|
template <class T>
|
||||||
template<class... Args>
|
template<class... Args>
|
||||||
BOOST_DEDUCED_TYPENAME hash_unique_table<H, P, A, E>::emplace_return
|
BOOST_DEDUCED_TYPENAME hash_unique_table<T>::emplace_return
|
||||||
hash_unique_table<H, P, A, E>::emplace(Args&&... args)
|
hash_unique_table<T>::emplace(Args&&... args)
|
||||||
{
|
{
|
||||||
return this->size_ ?
|
return this->size_ ?
|
||||||
emplace_impl(
|
emplace_impl(
|
||||||
@ -273,10 +273,10 @@ namespace boost { namespace unordered_detail {
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
template <class H, class P, class A, class E>
|
template <class T>
|
||||||
template <class Arg0>
|
template <class Arg0>
|
||||||
BOOST_DEDUCED_TYPENAME hash_unique_table<H, P, A, E>::emplace_return
|
BOOST_DEDUCED_TYPENAME hash_unique_table<T>::emplace_return
|
||||||
hash_unique_table<H, P, A, E>::emplace(Arg0 const& arg0)
|
hash_unique_table<T>::emplace(Arg0 const& arg0)
|
||||||
{
|
{
|
||||||
return this->size_ ?
|
return this->size_ ?
|
||||||
emplace_impl(extractor::extract(arg0), arg0) :
|
emplace_impl(extractor::extract(arg0), arg0) :
|
||||||
@ -284,10 +284,10 @@ namespace boost { namespace unordered_detail {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define BOOST_UNORDERED_INSERT_IMPL(z, num_params, _) \
|
#define BOOST_UNORDERED_INSERT_IMPL(z, num_params, _) \
|
||||||
template <class H, class P, class A, class E> \
|
template <class T> \
|
||||||
template <BOOST_UNORDERED_TEMPLATE_ARGS(z, num_params)> \
|
template <BOOST_UNORDERED_TEMPLATE_ARGS(z, num_params)> \
|
||||||
BOOST_DEDUCED_TYPENAME hash_unique_table<H, P, A, E>::emplace_return \
|
BOOST_DEDUCED_TYPENAME hash_unique_table<T>::emplace_return \
|
||||||
hash_unique_table<H, P, A, E>::emplace( \
|
hash_unique_table<T>::emplace( \
|
||||||
BOOST_UNORDERED_FUNCTION_PARAMS(z, num_params)) \
|
BOOST_UNORDERED_FUNCTION_PARAMS(z, num_params)) \
|
||||||
{ \
|
{ \
|
||||||
return this->size_ ? \
|
return this->size_ ? \
|
||||||
@ -307,9 +307,9 @@ namespace boost { namespace unordered_detail {
|
|||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
// Insert range methods
|
// Insert range methods
|
||||||
|
|
||||||
template <class H, class P, class A, class E>
|
template <class T>
|
||||||
template <class InputIt>
|
template <class InputIt>
|
||||||
inline void hash_unique_table<H, P, A, E>::insert_range_impl(
|
inline void hash_unique_table<T>::insert_range_impl(
|
||||||
key_type const&, InputIt i, InputIt j)
|
key_type const&, InputIt i, InputIt j)
|
||||||
{
|
{
|
||||||
node_constructor a(*this);
|
node_constructor a(*this);
|
||||||
@ -352,9 +352,9 @@ namespace boost { namespace unordered_detail {
|
|||||||
} while(++i != j);
|
} while(++i != j);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class H, class P, class A, class E>
|
template <class T>
|
||||||
template <class InputIt>
|
template <class InputIt>
|
||||||
inline void hash_unique_table<H, P, A, E>::insert_range_impl(
|
inline void hash_unique_table<T>::insert_range_impl(
|
||||||
no_key, InputIt i, InputIt j)
|
no_key, InputIt i, InputIt j)
|
||||||
{
|
{
|
||||||
node_constructor a(*this);
|
node_constructor a(*this);
|
||||||
@ -375,9 +375,9 @@ namespace boost { namespace unordered_detail {
|
|||||||
|
|
||||||
// if hash function throws, or inserting > 1 element, basic exception safety
|
// if hash function throws, or inserting > 1 element, basic exception safety
|
||||||
// strong otherwise
|
// strong otherwise
|
||||||
template <class H, class P, class A, class E>
|
template <class T>
|
||||||
template <class InputIt>
|
template <class InputIt>
|
||||||
void hash_unique_table<H, P, A, E>::insert_range(InputIt i, InputIt j)
|
void hash_unique_table<T>::insert_range(InputIt i, InputIt j)
|
||||||
{
|
{
|
||||||
if(i != j)
|
if(i != j)
|
||||||
return insert_range_impl(extractor::extract(*i), i, j);
|
return insert_range_impl(extractor::extract(*i), i, j);
|
||||||
|
@ -58,10 +58,11 @@ namespace boost
|
|||||||
allocator_type, value_type>::type
|
allocator_type, value_type>::type
|
||||||
value_allocator;
|
value_allocator;
|
||||||
|
|
||||||
typedef boost::unordered_detail::hash_unique_table<Hash, Pred,
|
typedef boost::unordered_detail::map<Key, Hash, Pred,
|
||||||
value_allocator, boost::unordered_detail::map_extractor> table;
|
value_allocator> types;
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME types::impl table;
|
||||||
|
|
||||||
typedef BOOST_DEDUCED_TYPENAME table::iterator_base iterator_base;
|
typedef BOOST_DEDUCED_TYPENAME types::iterator_base iterator_base;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -96,7 +97,7 @@ namespace boost
|
|||||||
|
|
||||||
table table_;
|
table table_;
|
||||||
|
|
||||||
BOOST_DEDUCED_TYPENAME table::iterator_base const&
|
BOOST_DEDUCED_TYPENAME types::iterator_base const&
|
||||||
get(const_iterator const& it)
|
get(const_iterator const& it)
|
||||||
{
|
{
|
||||||
return boost::unordered_detail::iterator_access::get(it);
|
return boost::unordered_detail::iterator_access::get(it);
|
||||||
@ -553,14 +554,17 @@ namespace boost
|
|||||||
#if !BOOST_WORKAROUND(__BORLANDC__, < 0x0582)
|
#if !BOOST_WORKAROUND(__BORLANDC__, < 0x0582)
|
||||||
private:
|
private:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef BOOST_DEDUCED_TYPENAME
|
typedef BOOST_DEDUCED_TYPENAME
|
||||||
boost::unordered_detail::rebind_wrap<
|
boost::unordered_detail::rebind_wrap<
|
||||||
allocator_type, value_type>::type
|
allocator_type, value_type>::type
|
||||||
value_allocator;
|
value_allocator;
|
||||||
|
|
||||||
typedef boost::unordered_detail::hash_equivalent_table<Hash, Pred,
|
typedef boost::unordered_detail::multimap<Key, Hash, Pred,
|
||||||
value_allocator, boost::unordered_detail::map_extractor> table;
|
value_allocator> types;
|
||||||
typedef BOOST_DEDUCED_TYPENAME table::iterator_base iterator_base;
|
typedef BOOST_DEDUCED_TYPENAME types::impl table;
|
||||||
|
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME types::iterator_base iterator_base;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -595,7 +599,7 @@ namespace boost
|
|||||||
|
|
||||||
table table_;
|
table table_;
|
||||||
|
|
||||||
BOOST_DEDUCED_TYPENAME table::iterator_base const&
|
BOOST_DEDUCED_TYPENAME types::iterator_base const&
|
||||||
get(const_iterator const& it)
|
get(const_iterator const& it)
|
||||||
{
|
{
|
||||||
return boost::unordered_detail::iterator_access::get(it);
|
return boost::unordered_detail::iterator_access::get(it);
|
||||||
|
@ -58,9 +58,11 @@ namespace boost
|
|||||||
allocator_type, value_type>::type
|
allocator_type, value_type>::type
|
||||||
value_allocator;
|
value_allocator;
|
||||||
|
|
||||||
typedef boost::unordered_detail::hash_unique_table<Hash, Pred,
|
typedef boost::unordered_detail::set<Hash, Pred,
|
||||||
value_allocator, boost::unordered_detail::set_extractor> table;
|
value_allocator> types;
|
||||||
typedef BOOST_DEDUCED_TYPENAME table::iterator_base iterator_base;
|
typedef BOOST_DEDUCED_TYPENAME types::impl table;
|
||||||
|
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME types::iterator_base iterator_base;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -91,7 +93,7 @@ namespace boost
|
|||||||
|
|
||||||
table table_;
|
table table_;
|
||||||
|
|
||||||
BOOST_DEDUCED_TYPENAME table::iterator_base const&
|
BOOST_DEDUCED_TYPENAME types::iterator_base const&
|
||||||
get(const_iterator const& it)
|
get(const_iterator const& it)
|
||||||
{
|
{
|
||||||
return boost::unordered_detail::iterator_access::get(it);
|
return boost::unordered_detail::iterator_access::get(it);
|
||||||
@ -518,14 +520,17 @@ namespace boost
|
|||||||
#if !BOOST_WORKAROUND(__BORLANDC__, < 0x0582)
|
#if !BOOST_WORKAROUND(__BORLANDC__, < 0x0582)
|
||||||
private:
|
private:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef BOOST_DEDUCED_TYPENAME
|
typedef BOOST_DEDUCED_TYPENAME
|
||||||
boost::unordered_detail::rebind_wrap<
|
boost::unordered_detail::rebind_wrap<
|
||||||
allocator_type, value_type>::type
|
allocator_type, value_type>::type
|
||||||
value_allocator;
|
value_allocator;
|
||||||
|
|
||||||
typedef boost::unordered_detail::hash_equivalent_table<Hash, Pred,
|
typedef boost::unordered_detail::multiset<Hash, Pred,
|
||||||
value_allocator, boost::unordered_detail::set_extractor> table;
|
value_allocator> types;
|
||||||
typedef BOOST_DEDUCED_TYPENAME table::iterator_base iterator_base;
|
typedef BOOST_DEDUCED_TYPENAME types::impl table;
|
||||||
|
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME types::iterator_base iterator_base;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -556,7 +561,7 @@ namespace boost
|
|||||||
|
|
||||||
table table_;
|
table table_;
|
||||||
|
|
||||||
BOOST_DEDUCED_TYPENAME table::iterator_base const&
|
BOOST_DEDUCED_TYPENAME types::iterator_base const&
|
||||||
get(const_iterator const& it)
|
get(const_iterator const& it)
|
||||||
{
|
{
|
||||||
return boost::unordered_detail::iterator_access::get(it);
|
return boost::unordered_detail::iterator_access::get(it);
|
||||||
|
@ -58,8 +58,8 @@ namespace test
|
|||||||
return (std::numeric_limits<size_type>::max)();
|
return (std::numeric_limits<size_type>::max)();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(malloc_allocator const& x) const { return true; }
|
bool operator==(malloc_allocator const&) const { return true; }
|
||||||
bool operator!=(malloc_allocator const& x) const { return false; }
|
bool operator!=(malloc_allocator const&) const { return false; }
|
||||||
|
|
||||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||||
template <class T> void deallocate(T* p, size_type) {
|
template <class T> void deallocate(T* p, size_type) {
|
||||||
|
@ -25,6 +25,7 @@ test-suite unordered
|
|||||||
[ run compile_set.cpp ]
|
[ run compile_set.cpp ]
|
||||||
[ run compile_map.cpp ]
|
[ run compile_map.cpp ]
|
||||||
[ run link_test_1.cpp link_test_2.cpp ]
|
[ run link_test_1.cpp link_test_2.cpp ]
|
||||||
|
[ run incomplete_test.cpp ]
|
||||||
[ run simple_tests.cpp ]
|
[ run simple_tests.cpp ]
|
||||||
[ run equivalent_keys_tests.cpp ]
|
[ run equivalent_keys_tests.cpp ]
|
||||||
[ run constructor_tests.cpp ]
|
[ run constructor_tests.cpp ]
|
||||||
|
39
test/unordered/incomplete_test.cpp
Normal file
39
test/unordered/incomplete_test.cpp
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
|
||||||
|
// Copyright 2009 Daniel James.
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
#include <boost/unordered_map.hpp>
|
||||||
|
#include <boost/unordered_set.hpp>
|
||||||
|
|
||||||
|
namespace test
|
||||||
|
{
|
||||||
|
struct value;
|
||||||
|
struct hash;
|
||||||
|
struct equals;
|
||||||
|
template <class T>
|
||||||
|
struct malloc_allocator;
|
||||||
|
|
||||||
|
typedef boost::unordered_map<value, value, hash, equals, malloc_allocator<std::pair<value const, value> > > map;
|
||||||
|
typedef boost::unordered_multimap<value, value, hash, equals, malloc_allocator<std::pair<value const, value> > > multimap;
|
||||||
|
typedef boost::unordered_set<value, hash, equals, malloc_allocator<value> > set;
|
||||||
|
typedef boost::unordered_multiset<value, hash, equals, malloc_allocator<value> > multiset;
|
||||||
|
|
||||||
|
struct value {};
|
||||||
|
struct hash { std::size_t operator()(value const&) const { return 0; } };
|
||||||
|
struct equals { bool operator()(value const&, value const&) const { return true; } };
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "../helpers/allocator.hpp"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
test::map m1;
|
||||||
|
test::multimap m2;
|
||||||
|
test::set s1;
|
||||||
|
test::multiset s2;
|
||||||
|
|
||||||
|
m1[test::value()] = test::value();
|
||||||
|
m2.insert(std::make_pair(test::value(), test::value()));
|
||||||
|
s1.insert(test::value());
|
||||||
|
s2.insert(test::value());
|
||||||
|
}
|
Reference in New Issue
Block a user