forked from boostorg/unordered
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f409496e68 |
+5
-11
@@ -3,14 +3,16 @@
|
||||
# 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)
|
||||
|
||||
using boostbook ;
|
||||
using quickbook ;
|
||||
|
||||
path-constant images_location : ../ ;
|
||||
path-constant admonishment_location : ../../../../doc/src/images ;
|
||||
|
||||
xml unordered : unordered.qbk ;
|
||||
boostbook standalone : unordered :
|
||||
<xsl:param>html.stylesheet=../../../../doc/html/boostbook.css
|
||||
<xsl:param>boost.root=../../../..
|
||||
<xsl:param>boost.libraries=../../../libraries.htm
|
||||
<xsl:param>navig.graphics=1
|
||||
|
||||
<xsl:param>chunk.first.sections=1
|
||||
<xsl:param>chunk.section.depth=2
|
||||
<xsl:param>generate.section.toc.level=2
|
||||
@@ -21,15 +23,7 @@ boostbook standalone : unordered :
|
||||
<xsl:param>boost.compact.function=0
|
||||
<xsl:param>boost.compact.enum=0
|
||||
|
||||
# HTML Options:
|
||||
|
||||
<format>html:<xsl:param>boost.root=../../../..
|
||||
<format>html:<xsl:param>img.src.path=../../../../doc/html/
|
||||
<format>xhtml:<xsl:param>boost.root=../../../..
|
||||
<format>xhtml:<xsl:param>img.src.path=../../../../doc/html/
|
||||
|
||||
# PDF Options:
|
||||
|
||||
# TOC Generation: this is needed for FOP-0.9 and later:
|
||||
<xsl:param>fop1.extensions=0
|
||||
<format>pdf:<xsl:param>xep.extensions=1
|
||||
|
||||
@@ -117,21 +117,4 @@ First official release.
|
||||
Add missing `std` qualifier to `ptrdiff_t`.
|
||||
* Some code formatting changes to fit almost all lines into 80 characters.
|
||||
|
||||
[h2 Boost 1.43.0]
|
||||
|
||||
* [@http://svn.boost.org/trac/boost/ticket/3966 Ticket 3966]:
|
||||
`erase_return_void` is now `quick_erase`, which is the
|
||||
[@http://home.roadrunner.com/~hinnant/issue_review/lwg-active.html#579
|
||||
current forerunner for resolving the slow erase by iterator], although
|
||||
there's a strong possibility that this may change in the future. The old
|
||||
method name remains for backwards compatibility but is considered deprecated
|
||||
and will be removed in a future release.
|
||||
* Use Boost.Exception.
|
||||
* Stop using deprecated `BOOST_HAS_*` macros.
|
||||
|
||||
[h2 Boost 1.45.0]
|
||||
|
||||
* Fix a bug when inserting into an `unordered_map` or `unordered_set` using
|
||||
iterators which returns `value_type` by copy.
|
||||
|
||||
[endsect]
|
||||
|
||||
+24
-120
@@ -464,8 +464,8 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
When the number of elements is a lot smaller than the number of buckets
|
||||
this function can be very inefficient as it has to search through empty
|
||||
buckets for the next element, in order to return the iterator.
|
||||
The method <methodname>quick_erase</methodname> is faster, but has yet
|
||||
to be standardized.
|
||||
As a temporary workaround, the container has the method
|
||||
<methodname>erase_return_void</methodname> which will be faster.
|
||||
</para>
|
||||
</notes>
|
||||
</method>
|
||||
@@ -503,30 +503,6 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<para>In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations.</para>
|
||||
</throws>
|
||||
</method>
|
||||
<method name="quick_erase">
|
||||
<parameter name="position">
|
||||
<paramtype>const_iterator</paramtype>
|
||||
</parameter>
|
||||
<type>void</type>
|
||||
<description>
|
||||
<para>Erase the element pointed to by <code>position</code>.</para>
|
||||
</description>
|
||||
<throws>
|
||||
<para>Only throws an exception if it is thrown by <code>hasher</code> or <code>key_equal</code>.</para>
|
||||
<para>In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations.</para>
|
||||
</throws>
|
||||
<notes>
|
||||
<para>
|
||||
This method is faster than <methodname>erase</methodname> as
|
||||
it doesn't have to find the next element in the container -
|
||||
a potentially costly operation.
|
||||
</para>
|
||||
<para>
|
||||
As it hasn't been standardized, it's likely that this may
|
||||
change in the future.
|
||||
</para>
|
||||
</notes>
|
||||
</method>
|
||||
<method name="erase_return_void">
|
||||
<parameter name="position">
|
||||
<paramtype>const_iterator</paramtype>
|
||||
@@ -541,10 +517,10 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</throws>
|
||||
<notes>
|
||||
<para>
|
||||
This method is now deprecated, use
|
||||
<methodname>quick_return</methodname> instead. Although be
|
||||
warned that as that isn't standardized yet, it could also
|
||||
change.
|
||||
This is a temporary workaround for the inefficient
|
||||
<methodname>erase</methodname> method. Hopefully, in a future
|
||||
version the signature of <methodname>erase</methodname> will
|
||||
be changed and this will be deprecated.
|
||||
</para>
|
||||
</notes>
|
||||
</method>
|
||||
@@ -1351,8 +1327,8 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
When the number of elements is a lot smaller than the number of buckets
|
||||
this function can be very inefficient as it has to search through empty
|
||||
buckets for the next element, in order to return the iterator.
|
||||
The method <methodname>quick_erase</methodname> is faster, but has yet
|
||||
to be standardized.
|
||||
As a temporary workaround, the container has the method
|
||||
<methodname>erase_return_void</methodname> which will be faster.
|
||||
</para>
|
||||
</notes>
|
||||
</method>
|
||||
@@ -1390,30 +1366,6 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<para>In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations.</para>
|
||||
</throws>
|
||||
</method>
|
||||
<method name="quick_erase">
|
||||
<parameter name="position">
|
||||
<paramtype>const_iterator</paramtype>
|
||||
</parameter>
|
||||
<type>void</type>
|
||||
<description>
|
||||
<para>Erase the element pointed to by <code>position</code>.</para>
|
||||
</description>
|
||||
<throws>
|
||||
<para>Only throws an exception if it is thrown by <code>hasher</code> or <code>key_equal</code>.</para>
|
||||
<para>In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations.</para>
|
||||
</throws>
|
||||
<notes>
|
||||
<para>
|
||||
This method is faster than <methodname>erase</methodname> as
|
||||
it doesn't have to find the next element in the container -
|
||||
a potentially costly operation.
|
||||
</para>
|
||||
<para>
|
||||
As it hasn't been standardized, it's likely that this may
|
||||
change in the future.
|
||||
</para>
|
||||
</notes>
|
||||
</method>
|
||||
<method name="erase_return_void">
|
||||
<parameter name="position">
|
||||
<paramtype>const_iterator</paramtype>
|
||||
@@ -1428,10 +1380,10 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</throws>
|
||||
<notes>
|
||||
<para>
|
||||
This method is now deprecated, use
|
||||
<methodname>quick_return</methodname> instead. Although be
|
||||
warned that as that isn't standardized yet, it could also
|
||||
change.
|
||||
This is a temporary workaround for the inefficient
|
||||
<methodname>erase</methodname> method. Hopefully, in a future
|
||||
version the signature of <methodname>erase</methodname> will
|
||||
be changed and this will be deprecated.
|
||||
</para>
|
||||
</notes>
|
||||
</method>
|
||||
@@ -2252,8 +2204,8 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
When the number of elements is a lot smaller than the number of buckets
|
||||
this function can be very inefficient as it has to search through empty
|
||||
buckets for the next element, in order to return the iterator.
|
||||
The method <methodname>quick_erase</methodname> is faster, but has yet
|
||||
to be standardized.
|
||||
As a temporary workaround, the container has the method
|
||||
<methodname>erase_return_void</methodname> which will be faster.
|
||||
</para>
|
||||
</notes>
|
||||
</method>
|
||||
@@ -2291,30 +2243,6 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<para>In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations.</para>
|
||||
</throws>
|
||||
</method>
|
||||
<method name="quick_erase">
|
||||
<parameter name="position">
|
||||
<paramtype>const_iterator</paramtype>
|
||||
</parameter>
|
||||
<type>void</type>
|
||||
<description>
|
||||
<para>Erase the element pointed to by <code>position</code>.</para>
|
||||
</description>
|
||||
<throws>
|
||||
<para>Only throws an exception if it is thrown by <code>hasher</code> or <code>key_equal</code>.</para>
|
||||
<para>In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations.</para>
|
||||
</throws>
|
||||
<notes>
|
||||
<para>
|
||||
This method is faster than <methodname>erase</methodname> as
|
||||
it doesn't have to find the next element in the container -
|
||||
a potentially costly operation.
|
||||
</para>
|
||||
<para>
|
||||
As it hasn't been standardized, it's likely that this may
|
||||
change in the future.
|
||||
</para>
|
||||
</notes>
|
||||
</method>
|
||||
<method name="erase_return_void">
|
||||
<parameter name="position">
|
||||
<paramtype>const_iterator</paramtype>
|
||||
@@ -2329,10 +2257,10 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</throws>
|
||||
<notes>
|
||||
<para>
|
||||
This method is now deprecated, use
|
||||
<methodname>quick_return</methodname> instead. Although be
|
||||
warned that as that isn't standardized yet, it could also
|
||||
change.
|
||||
This is a temporary workaround for the inefficient
|
||||
<methodname>erase</methodname> method. Hopefully, in a future
|
||||
version the signature of <methodname>erase</methodname> will
|
||||
be changed and this will be deprecated.
|
||||
</para>
|
||||
</notes>
|
||||
</method>
|
||||
@@ -3188,8 +3116,8 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
When the number of elements is a lot smaller than the number of buckets
|
||||
this function can be very inefficient as it has to search through empty
|
||||
buckets for the next element, in order to return the iterator.
|
||||
The method <methodname>quick_erase</methodname> is faster, but has yet
|
||||
to be standardized.
|
||||
As a temporary workaround, the container has the method
|
||||
<methodname>erase_return_void</methodname> which will be faster.
|
||||
</para>
|
||||
</notes>
|
||||
</method>
|
||||
@@ -3227,30 +3155,6 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<para>In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations.</para>
|
||||
</throws>
|
||||
</method>
|
||||
<method name="quick_erase">
|
||||
<parameter name="position">
|
||||
<paramtype>const_iterator</paramtype>
|
||||
</parameter>
|
||||
<type>void</type>
|
||||
<description>
|
||||
<para>Erase the element pointed to by <code>position</code>.</para>
|
||||
</description>
|
||||
<throws>
|
||||
<para>Only throws an exception if it is thrown by <code>hasher</code> or <code>key_equal</code>.</para>
|
||||
<para>In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations.</para>
|
||||
</throws>
|
||||
<notes>
|
||||
<para>
|
||||
This method is faster than <methodname>erase</methodname> as
|
||||
it doesn't have to find the next element in the container -
|
||||
a potentially costly operation.
|
||||
</para>
|
||||
<para>
|
||||
As it hasn't been standardized, it's likely that this may
|
||||
change in the future.
|
||||
</para>
|
||||
</notes>
|
||||
</method>
|
||||
<method name="erase_return_void">
|
||||
<parameter name="position">
|
||||
<paramtype>const_iterator</paramtype>
|
||||
@@ -3265,10 +3169,10 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</throws>
|
||||
<notes>
|
||||
<para>
|
||||
This method is now deprecated, use
|
||||
<methodname>quick_return</methodname> instead. Although be
|
||||
warned that as that isn't standardized yet, it could also
|
||||
change.
|
||||
This is a temporary workaround for the inefficient
|
||||
<methodname>erase</methodname> method. Hopefully, in a future
|
||||
version the signature of <methodname>erase</methodname> will
|
||||
be changed and this will be deprecated.
|
||||
</para>
|
||||
</notes>
|
||||
</method>
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@
|
||||
[license
|
||||
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])
|
||||
[@http://www.boost.org/LICENSE_1_0.txt]
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace boost { namespace unordered_detail {
|
||||
inline void hash_buckets<A, G>::delete_node(node_ptr b)
|
||||
{
|
||||
node* raw_ptr = static_cast<node*>(&*b);
|
||||
boost::unordered_detail::destroy(raw_ptr->value_ptr());
|
||||
boost::unordered_detail::destroy(&raw_ptr->value());
|
||||
real_node_ptr n(node_alloc().address(*raw_ptr));
|
||||
node_alloc().destroy(n);
|
||||
node_alloc().deallocate(n, 1);
|
||||
|
||||
@@ -12,101 +12,6 @@
|
||||
|
||||
namespace boost { namespace unordered_detail {
|
||||
|
||||
template <class T>
|
||||
class hash_equivalent_table : public T::table
|
||||
{
|
||||
public:
|
||||
typedef BOOST_DEDUCED_TYPENAME T::hasher hasher;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::key_equal key_equal;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::value_allocator value_allocator;
|
||||
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 BOOST_DEDUCED_TYPENAME T::node node;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::node_ptr node_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::bucket_ptr bucket_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::iterator_base iterator_base;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::extractor extractor;
|
||||
|
||||
// Constructors
|
||||
|
||||
hash_equivalent_table(std::size_t n,
|
||||
hasher const& hf, key_equal const& eq, value_allocator const& a)
|
||||
: table(n, hf, eq, a) {}
|
||||
hash_equivalent_table(hash_equivalent_table const& x)
|
||||
: table(x, x.node_alloc()) {}
|
||||
hash_equivalent_table(hash_equivalent_table const& x,
|
||||
value_allocator const& a)
|
||||
: table(x, a) {}
|
||||
hash_equivalent_table(hash_equivalent_table& x, move_tag m)
|
||||
: table(x, m) {}
|
||||
hash_equivalent_table(hash_equivalent_table& x,
|
||||
value_allocator const& a, move_tag m)
|
||||
: table(x, a, m) {}
|
||||
~hash_equivalent_table() {}
|
||||
|
||||
// Insert methods
|
||||
|
||||
iterator_base emplace_impl(node_constructor& a);
|
||||
void emplace_impl_no_rehash(node_constructor& a);
|
||||
|
||||
// equals
|
||||
|
||||
bool equals(hash_equivalent_table const&) const;
|
||||
|
||||
inline node_ptr add_node(node_constructor& a,
|
||||
bucket_ptr bucket, node_ptr pos);
|
||||
|
||||
#if defined(BOOST_UNORDERED_STD_FORWARD)
|
||||
|
||||
template <class... Args>
|
||||
iterator_base emplace(Args&&... args);
|
||||
|
||||
#else
|
||||
|
||||
#define BOOST_UNORDERED_INSERT_IMPL(z, n, _) \
|
||||
template <BOOST_UNORDERED_TEMPLATE_ARGS(z, n)> \
|
||||
iterator_base emplace(BOOST_UNORDERED_FUNCTION_PARAMS(z, n));
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT,
|
||||
BOOST_UNORDERED_INSERT_IMPL, _)
|
||||
|
||||
#undef BOOST_UNORDERED_INSERT_IMPL
|
||||
#endif
|
||||
|
||||
template <class I>
|
||||
void insert_for_range(I i, I j, forward_traversal_tag);
|
||||
template <class I>
|
||||
void insert_for_range(I i, I j, boost::incrementable_traversal_tag);
|
||||
template <class I>
|
||||
void insert_range(I i, I j);
|
||||
};
|
||||
|
||||
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 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;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Equality
|
||||
|
||||
|
||||
@@ -21,17 +21,17 @@
|
||||
|
||||
// This header defines most of the classes used to implement the unordered
|
||||
// containers. It doesn't include the insert methods as they require a lot
|
||||
// of preprocessor metaprogramming - they are in unique.hpp and equivalent.hpp.
|
||||
// of preprocessor metaprogramming - they are in insert.hpp
|
||||
|
||||
// Template parameters:
|
||||
//
|
||||
// H = Hash Function
|
||||
// P = Predicate
|
||||
// A = Value Allocator
|
||||
// G = Bucket group policy, 'grouped' or 'ungrouped'
|
||||
// G = Grouped/Ungrouped
|
||||
// E = Key Extractor
|
||||
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_NO_VARIADIC_TEMPLATES)
|
||||
#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
|
||||
@@ -64,8 +64,6 @@ namespace boost { namespace unordered_detail {
|
||||
static const std::size_t default_bucket_count = 11;
|
||||
struct move_tag {};
|
||||
|
||||
template <class T> class hash_unique_table;
|
||||
template <class T> class hash_equivalent_table;
|
||||
template <class Alloc, class Grouped>
|
||||
class hash_node_constructor;
|
||||
template <class ValueType>
|
||||
@@ -90,37 +88,7 @@ namespace boost { namespace unordered_detail {
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// This section implements buckets and nodes. Here's a rough
|
||||
// inheritance diagram, to show how they pull together.
|
||||
//
|
||||
// For unordered_set/unordered_map:
|
||||
//
|
||||
// hash_bucket<A>
|
||||
// |
|
||||
// ungrouped_node_base<A> value_base<A::value_type>
|
||||
// | |
|
||||
// +--------------+-------------+
|
||||
// |
|
||||
// hash_node<A, ungrouped>
|
||||
//
|
||||
// For unordered_multiset/unordered_multimap:
|
||||
//
|
||||
// hash_bucket<A>
|
||||
// |
|
||||
// grouped_node_base<A> value_base<A::value_type>
|
||||
// | |
|
||||
// +--------------+-------------+
|
||||
// |
|
||||
// hash_node<A, grouped>
|
||||
|
||||
// hash_bucket
|
||||
//
|
||||
// hash_bucket is used for both the buckets and as a base class for
|
||||
// nodes. By using 'bucket_ptr' for 'node_ptr', 'next_' can point
|
||||
// to either a bucket or a node. This is used later to implement a
|
||||
// sentinel at the end of the bucket array.
|
||||
|
||||
template <class A>
|
||||
class hash_bucket
|
||||
@@ -139,16 +107,6 @@ namespace boost { namespace unordered_detail {
|
||||
hash_bucket() : next_() {}
|
||||
};
|
||||
|
||||
// In containers with equivalent keys (unordered_multimap and
|
||||
// unordered_multiset) equivalent nodes are grouped together, in
|
||||
// containers with unique keys (unordered_map and unordered_set)
|
||||
// individual nodes are treated as groups of one. The following two
|
||||
// classes implement the data structure.
|
||||
|
||||
// This is used for containers with unique keys. There are no groups
|
||||
// so it doesn't add any extra members, and just treats individual
|
||||
// nodes as groups of one.
|
||||
|
||||
template <class A>
|
||||
struct ungrouped_node_base : hash_bucket<A> {
|
||||
typedef hash_bucket<A> bucket;
|
||||
@@ -165,10 +123,6 @@ namespace boost { namespace unordered_detail {
|
||||
static void unlink_nodes(bucket& b, node_ptr end);
|
||||
};
|
||||
|
||||
// This is used for containers with equivalent keys. It implements a
|
||||
// circular list running in the opposite direction to the linked
|
||||
// list through the nodes.
|
||||
|
||||
template <class A>
|
||||
struct grouped_node_base : hash_bucket<A>
|
||||
{
|
||||
@@ -195,10 +149,6 @@ namespace boost { namespace unordered_detail {
|
||||
}
|
||||
};
|
||||
|
||||
// These two classes implement an easy way to pass around the node
|
||||
// group policy classes without the messy template parameters.
|
||||
// Whenever you see the template parameter 'G' it's one of these.
|
||||
|
||||
struct ungrouped
|
||||
{
|
||||
template <class A>
|
||||
@@ -215,8 +165,6 @@ namespace boost { namespace unordered_detail {
|
||||
};
|
||||
};
|
||||
|
||||
// The space used to store values in a node.
|
||||
|
||||
template <class ValueType>
|
||||
struct value_base
|
||||
{
|
||||
@@ -231,9 +179,6 @@ namespace boost { namespace unordered_detail {
|
||||
value_type& value() {
|
||||
return *(ValueType*) this;
|
||||
}
|
||||
value_type* value_ptr() {
|
||||
return (ValueType*) this;
|
||||
}
|
||||
private:
|
||||
value_base& operator=(value_base const&);
|
||||
};
|
||||
@@ -252,20 +197,11 @@ namespace boost { namespace unordered_detail {
|
||||
static value_type& get_value(node_ptr p) {
|
||||
return static_cast<hash_node&>(*p).value();
|
||||
}
|
||||
static value_type* get_value_ptr(node_ptr p) {
|
||||
return static_cast<hash_node&>(*p).value_ptr();
|
||||
}
|
||||
private:
|
||||
hash_node& operator=(hash_node const&);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Iterator Base
|
||||
//
|
||||
// This is the iterator used internally, the external iterators are
|
||||
// provided by lightweight wrappers (hash_iterator and
|
||||
// hast_const_iterator) which provide the full iterator interface.
|
||||
|
||||
template <class A, class G>
|
||||
class hash_iterator_base
|
||||
@@ -310,24 +246,12 @@ namespace boost { namespace unordered_detail {
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Now the main data structure:
|
||||
//
|
||||
// hash_buckets<A, G> hash_buffered_functions<H, P>
|
||||
// | |
|
||||
// +-------------+--------------+
|
||||
// |
|
||||
// hash_table<T>
|
||||
//
|
||||
// T is a class which contains typedefs for all the types we need.
|
||||
|
||||
// hash_buckets
|
||||
//
|
||||
// This is responsible for allocating and deallocating buckets and nodes.
|
||||
//
|
||||
// Notes:
|
||||
// 1. For the sake exception safety the consturctors don't allocate
|
||||
// 1. For the sake exception safety the allocators themselves don't allocate
|
||||
// anything.
|
||||
// 2. It's the callers responsibility to allocate the buckets before calling
|
||||
// any of the methods (other than getters and setters).
|
||||
@@ -401,17 +325,6 @@ namespace boost { namespace unordered_detail {
|
||||
std::size_t delete_to_bucket_end(node_ptr begin);
|
||||
};
|
||||
|
||||
// Assigning and swapping the equality and hash function objects
|
||||
// needs strong exception safety. To implement that normally we'd
|
||||
// require one of them to be known to not throw and the other to
|
||||
// guarantee strong exception safety. Unfortunately they both only
|
||||
// have basic exception safety. So to acheive strong exception
|
||||
// safety we have storage space for two copies, and assign the new
|
||||
// copies to the unused space. Then switch to using that to use
|
||||
// them. This is implemented in 'set_hash_functions' which
|
||||
// atomically assigns the new function objects in a strongly
|
||||
// exception safe manner.
|
||||
|
||||
template <class H, class P> class set_hash_functions;
|
||||
|
||||
template <class H, class P>
|
||||
@@ -514,12 +427,6 @@ namespace boost { namespace unordered_detail {
|
||||
}
|
||||
};
|
||||
|
||||
// This implements almost all of the required functionality, apart
|
||||
// from some things that are specific to containers with unique and
|
||||
// equivalent keys which is implemented in hash_unique_table and
|
||||
// hash_equivalent_table. See unique.hpp and equivalent.hpp for
|
||||
// their declaration and implementation.
|
||||
|
||||
template <class T>
|
||||
class hash_table : public T::buckets, public T::buffered_functions
|
||||
{
|
||||
@@ -660,12 +567,169 @@ namespace boost { namespace unordered_detail {
|
||||
node_constructor&, std::size_t);
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Iterators
|
||||
template <class T>
|
||||
class hash_unique_table : public T::table
|
||||
{
|
||||
public:
|
||||
typedef BOOST_DEDUCED_TYPENAME T::hasher hasher;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::key_equal key_equal;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::value_allocator value_allocator;
|
||||
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;
|
||||
|
||||
// iterator_access is used to access the internal iterator without
|
||||
// making it publicly available.
|
||||
typedef BOOST_DEDUCED_TYPENAME T::node node;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::node_ptr node_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::bucket_ptr bucket_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::iterator_base iterator_base;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::extractor extractor;
|
||||
|
||||
typedef std::pair<iterator_base, bool> emplace_return;
|
||||
|
||||
// Constructors
|
||||
|
||||
hash_unique_table(std::size_t n, hasher const& hf, key_equal const& eq,
|
||||
value_allocator const& a)
|
||||
: table(n, hf, eq, a) {}
|
||||
hash_unique_table(hash_unique_table const& x)
|
||||
: table(x, x.node_alloc()) {}
|
||||
hash_unique_table(hash_unique_table const& x, value_allocator const& a)
|
||||
: table(x, a) {}
|
||||
hash_unique_table(hash_unique_table& x, move_tag m)
|
||||
: table(x, m) {}
|
||||
hash_unique_table(hash_unique_table& x, value_allocator const& a,
|
||||
move_tag m)
|
||||
: table(x, a, m) {}
|
||||
~hash_unique_table() {}
|
||||
|
||||
// Insert methods
|
||||
|
||||
emplace_return emplace_impl_with_node(node_constructor& a);
|
||||
value_type& operator[](key_type const& k);
|
||||
|
||||
// equals
|
||||
|
||||
bool equals(hash_unique_table const&) const;
|
||||
|
||||
node_ptr add_node(node_constructor& a, bucket_ptr bucket);
|
||||
|
||||
#if defined(BOOST_UNORDERED_STD_FORWARD)
|
||||
|
||||
template<class... Args>
|
||||
emplace_return emplace(Args&&... args);
|
||||
template<class... Args>
|
||||
emplace_return emplace_impl(key_type const& k, Args&&... args);
|
||||
template<class... Args>
|
||||
emplace_return emplace_impl(no_key, Args&&... args);
|
||||
template<class... Args>
|
||||
emplace_return emplace_empty_impl(Args&&... args);
|
||||
#else
|
||||
|
||||
#define BOOST_UNORDERED_INSERT_IMPL(z, n, _) \
|
||||
template <BOOST_UNORDERED_TEMPLATE_ARGS(z, n)> \
|
||||
emplace_return emplace( \
|
||||
BOOST_UNORDERED_FUNCTION_PARAMS(z, n)); \
|
||||
template <BOOST_UNORDERED_TEMPLATE_ARGS(z, n)> \
|
||||
emplace_return emplace_impl(key_type const& k, \
|
||||
BOOST_UNORDERED_FUNCTION_PARAMS(z, n)); \
|
||||
template <BOOST_UNORDERED_TEMPLATE_ARGS(z, n)> \
|
||||
emplace_return emplace_impl(no_key, \
|
||||
BOOST_UNORDERED_FUNCTION_PARAMS(z, n)); \
|
||||
template <BOOST_UNORDERED_TEMPLATE_ARGS(z, n)> \
|
||||
emplace_return emplace_empty_impl( \
|
||||
BOOST_UNORDERED_FUNCTION_PARAMS(z, n));
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT,
|
||||
BOOST_UNORDERED_INSERT_IMPL, _)
|
||||
|
||||
#undef BOOST_UNORDERED_INSERT_IMPL
|
||||
|
||||
#endif
|
||||
|
||||
// if hash function throws, or inserting > 1 element, basic exception
|
||||
// safety strong otherwise
|
||||
template <class InputIt>
|
||||
void insert_range(InputIt i, InputIt j);
|
||||
template <class InputIt>
|
||||
void insert_range_impl(key_type const&, InputIt i, InputIt j);
|
||||
template <class InputIt>
|
||||
void insert_range_impl(no_key, InputIt i, InputIt j);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class hash_equivalent_table : public T::table
|
||||
{
|
||||
public:
|
||||
typedef BOOST_DEDUCED_TYPENAME T::hasher hasher;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::key_equal key_equal;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::value_allocator value_allocator;
|
||||
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 BOOST_DEDUCED_TYPENAME T::node node;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::node_ptr node_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::bucket_ptr bucket_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::iterator_base iterator_base;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::extractor extractor;
|
||||
|
||||
// Constructors
|
||||
|
||||
hash_equivalent_table(std::size_t n,
|
||||
hasher const& hf, key_equal const& eq, value_allocator const& a)
|
||||
: table(n, hf, eq, a) {}
|
||||
hash_equivalent_table(hash_equivalent_table const& x)
|
||||
: table(x, x.node_alloc()) {}
|
||||
hash_equivalent_table(hash_equivalent_table const& x,
|
||||
value_allocator const& a)
|
||||
: table(x, a) {}
|
||||
hash_equivalent_table(hash_equivalent_table& x, move_tag m)
|
||||
: table(x, m) {}
|
||||
hash_equivalent_table(hash_equivalent_table& x,
|
||||
value_allocator const& a, move_tag m)
|
||||
: table(x, a, m) {}
|
||||
~hash_equivalent_table() {}
|
||||
|
||||
// Insert methods
|
||||
|
||||
iterator_base emplace_impl(node_constructor& a);
|
||||
void emplace_impl_no_rehash(node_constructor& a);
|
||||
|
||||
// equals
|
||||
|
||||
bool equals(hash_equivalent_table const&) const;
|
||||
|
||||
inline node_ptr add_node(node_constructor& a,
|
||||
bucket_ptr bucket, node_ptr pos);
|
||||
|
||||
#if defined(BOOST_UNORDERED_STD_FORWARD)
|
||||
|
||||
template <class... Args>
|
||||
iterator_base emplace(Args&&... args);
|
||||
|
||||
#else
|
||||
|
||||
#define BOOST_UNORDERED_INSERT_IMPL(z, n, _) \
|
||||
template <BOOST_UNORDERED_TEMPLATE_ARGS(z, n)> \
|
||||
iterator_base emplace(BOOST_UNORDERED_FUNCTION_PARAMS(z, n));
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT,
|
||||
BOOST_UNORDERED_INSERT_IMPL, _)
|
||||
|
||||
#undef BOOST_UNORDERED_INSERT_IMPL
|
||||
#endif
|
||||
|
||||
template <class I>
|
||||
void insert_for_range(I i, I j, forward_traversal_tag);
|
||||
template <class I>
|
||||
void insert_for_range(I i, I j, boost::incrementable_traversal_tag);
|
||||
template <class I>
|
||||
void insert_range(I i, I j);
|
||||
};
|
||||
|
||||
// Iterator Access
|
||||
|
||||
class iterator_access
|
||||
{
|
||||
@@ -678,6 +742,8 @@ namespace boost { namespace unordered_detail {
|
||||
}
|
||||
};
|
||||
|
||||
// Iterators
|
||||
|
||||
template <class A, class G> class hash_iterator;
|
||||
template <class A, class G> class hash_const_iterator;
|
||||
template <class A, class G> class hash_local_iterator;
|
||||
@@ -715,7 +781,7 @@ namespace boost { namespace unordered_detail {
|
||||
return node::get_value(ptr_);
|
||||
}
|
||||
value_type* operator->() const {
|
||||
return node::get_value_ptr(ptr_);
|
||||
return &node::get_value(ptr_);
|
||||
}
|
||||
hash_local_iterator& operator++() {
|
||||
ptr_ = ptr_->next_; return *this;
|
||||
@@ -765,7 +831,7 @@ namespace boost { namespace unordered_detail {
|
||||
return node::get_value(ptr_);
|
||||
}
|
||||
value_type const* operator->() const {
|
||||
return node::get_value_ptr(ptr_);
|
||||
return &node::get_value(ptr_);
|
||||
}
|
||||
hash_const_local_iterator& operator++() {
|
||||
ptr_ = ptr_->next_; return *this;
|
||||
@@ -787,7 +853,7 @@ namespace boost { namespace unordered_detail {
|
||||
}
|
||||
};
|
||||
|
||||
// Iterators
|
||||
// iterators
|
||||
//
|
||||
// all no throw
|
||||
|
||||
@@ -894,12 +960,7 @@ namespace boost { namespace unordered_detail {
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// types
|
||||
//
|
||||
// This is used to convieniently pass around a container's typedefs
|
||||
// without having 7 template parameters.
|
||||
|
||||
template <class K, class V, class H, class P, class A, class E, class G>
|
||||
struct types
|
||||
@@ -927,6 +988,52 @@ namespace boost { namespace unordered_detail {
|
||||
|
||||
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
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include <algorithm>
|
||||
#include <boost/config/no_tr1/cmath.hpp>
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
#include <boost/unordered/detail/buckets.hpp>
|
||||
|
||||
@@ -609,15 +608,15 @@ namespace boost { namespace unordered_detail {
|
||||
hash_table<T>::at(key_type const& k) const
|
||||
{
|
||||
if(!this->size_)
|
||||
boost::throw_exception(std::out_of_range("Unable to find key in unordered_map."));
|
||||
throw std::out_of_range("Unable to find key in unordered_map.");
|
||||
|
||||
bucket_ptr bucket = this->get_bucket(this->bucket_index(k));
|
||||
node_ptr it = find_iterator(bucket, k);
|
||||
|
||||
if (!it)
|
||||
boost::throw_exception(std::out_of_range("Unable to find key in unordered_map."));
|
||||
|
||||
return node::get_value(it);
|
||||
if (BOOST_UNORDERED_BORLAND_BOOL(it))
|
||||
return node::get_value(it);
|
||||
else
|
||||
throw std::out_of_range("Unable to find key in unordered_map.");
|
||||
}
|
||||
|
||||
// equal_range
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
// Copyright (C) 2003-2004 Jeremy B. Maitin-Shepard.
|
||||
// Copyright (C) 2005-2010 Daniel James
|
||||
// Copyright (C) 2005-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)
|
||||
|
||||
@@ -12,121 +12,6 @@
|
||||
|
||||
namespace boost { namespace unordered_detail {
|
||||
|
||||
template <class T>
|
||||
class hash_unique_table : public T::table
|
||||
{
|
||||
public:
|
||||
typedef BOOST_DEDUCED_TYPENAME T::hasher hasher;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::key_equal key_equal;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::value_allocator value_allocator;
|
||||
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 BOOST_DEDUCED_TYPENAME T::node node;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::node_ptr node_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::bucket_ptr bucket_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::iterator_base iterator_base;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::extractor extractor;
|
||||
|
||||
typedef std::pair<iterator_base, bool> emplace_return;
|
||||
|
||||
// Constructors
|
||||
|
||||
hash_unique_table(std::size_t n, hasher const& hf, key_equal const& eq,
|
||||
value_allocator const& a)
|
||||
: table(n, hf, eq, a) {}
|
||||
hash_unique_table(hash_unique_table const& x)
|
||||
: table(x, x.node_alloc()) {}
|
||||
hash_unique_table(hash_unique_table const& x, value_allocator const& a)
|
||||
: table(x, a) {}
|
||||
hash_unique_table(hash_unique_table& x, move_tag m)
|
||||
: table(x, m) {}
|
||||
hash_unique_table(hash_unique_table& x, value_allocator const& a,
|
||||
move_tag m)
|
||||
: table(x, a, m) {}
|
||||
~hash_unique_table() {}
|
||||
|
||||
// Insert methods
|
||||
|
||||
emplace_return emplace_impl_with_node(node_constructor& a);
|
||||
value_type& operator[](key_type const& k);
|
||||
|
||||
// equals
|
||||
|
||||
bool equals(hash_unique_table const&) const;
|
||||
|
||||
node_ptr add_node(node_constructor& a, bucket_ptr bucket);
|
||||
|
||||
#if defined(BOOST_UNORDERED_STD_FORWARD)
|
||||
|
||||
template<class... Args>
|
||||
emplace_return emplace(Args&&... args);
|
||||
template<class... Args>
|
||||
emplace_return emplace_impl(key_type const& k, Args&&... args);
|
||||
template<class... Args>
|
||||
emplace_return emplace_impl(no_key, Args&&... args);
|
||||
template<class... Args>
|
||||
emplace_return emplace_empty_impl(Args&&... args);
|
||||
#else
|
||||
|
||||
#define BOOST_UNORDERED_INSERT_IMPL(z, n, _) \
|
||||
template <BOOST_UNORDERED_TEMPLATE_ARGS(z, n)> \
|
||||
emplace_return emplace( \
|
||||
BOOST_UNORDERED_FUNCTION_PARAMS(z, n)); \
|
||||
template <BOOST_UNORDERED_TEMPLATE_ARGS(z, n)> \
|
||||
emplace_return emplace_impl(key_type const& k, \
|
||||
BOOST_UNORDERED_FUNCTION_PARAMS(z, n)); \
|
||||
template <BOOST_UNORDERED_TEMPLATE_ARGS(z, n)> \
|
||||
emplace_return emplace_impl(no_key, \
|
||||
BOOST_UNORDERED_FUNCTION_PARAMS(z, n)); \
|
||||
template <BOOST_UNORDERED_TEMPLATE_ARGS(z, n)> \
|
||||
emplace_return emplace_empty_impl( \
|
||||
BOOST_UNORDERED_FUNCTION_PARAMS(z, n));
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT,
|
||||
BOOST_UNORDERED_INSERT_IMPL, _)
|
||||
|
||||
#undef BOOST_UNORDERED_INSERT_IMPL
|
||||
|
||||
#endif
|
||||
|
||||
// if hash function throws, or inserting > 1 element, basic exception
|
||||
// safety strong otherwise
|
||||
template <class InputIt>
|
||||
void insert_range(InputIt i, InputIt j);
|
||||
template <class InputIt>
|
||||
void insert_range_impl(key_type const&, InputIt i, InputIt j);
|
||||
template <class InputIt>
|
||||
void insert_range_impl2(node_constructor&, key_type const&, InputIt i, InputIt j);
|
||||
template <class InputIt>
|
||||
void insert_range_impl(no_key, InputIt i, InputIt j);
|
||||
};
|
||||
|
||||
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 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;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Equality
|
||||
|
||||
@@ -422,36 +307,6 @@ namespace boost { namespace unordered_detail {
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Insert range methods
|
||||
|
||||
template <class T>
|
||||
template <class InputIt>
|
||||
inline void hash_unique_table<T>::insert_range_impl2(
|
||||
node_constructor& a, key_type const& k, InputIt i, InputIt j)
|
||||
{
|
||||
// No side effects in this initial code
|
||||
std::size_t hash_value = this->hash_function()(k);
|
||||
bucket_ptr bucket = this->bucket_ptr_from_hash(hash_value);
|
||||
node_ptr pos = this->find_iterator(bucket, k);
|
||||
|
||||
if (!BOOST_UNORDERED_BORLAND_BOOL(pos)) {
|
||||
// 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).
|
||||
a.construct(*i);
|
||||
|
||||
// reserve has basic exception safety if the hash function
|
||||
// throws, strong otherwise.
|
||||
if(this->size_ + 1 >= this->max_load_) {
|
||||
this->reserve_for_insert(this->size_ + insert_size(i, j));
|
||||
bucket = this->bucket_ptr_from_hash(hash_value);
|
||||
}
|
||||
|
||||
// Nothing after this point can throw.
|
||||
add_node(a, bucket);
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
template <class InputIt>
|
||||
inline void hash_unique_table<T>::insert_range_impl(
|
||||
@@ -467,14 +322,33 @@ namespace boost { namespace unordered_detail {
|
||||
}
|
||||
|
||||
do {
|
||||
// No side effects in this initial code
|
||||
// Note: can't use get_key as '*i' might not be value_type - it
|
||||
// could be a pair with first_types as key_type without const or a
|
||||
// different second_type.
|
||||
//
|
||||
// TODO: Might be worth storing the value_type instead of the key
|
||||
// here. Could be more efficient if '*i' is expensive. Could be
|
||||
// less efficient if copying the full value_type is expensive.
|
||||
insert_range_impl2(a, extractor::extract(*i), i, j);
|
||||
key_type const& k = extractor::extract(*i);
|
||||
std::size_t hash_value = this->hash_function()(k);
|
||||
bucket_ptr bucket = this->bucket_ptr_from_hash(hash_value);
|
||||
node_ptr pos = this->find_iterator(bucket, k);
|
||||
|
||||
if (!BOOST_UNORDERED_BORLAND_BOOL(pos)) {
|
||||
// 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).
|
||||
a.construct(*i);
|
||||
|
||||
// reserve has basic exception safety if the hash function
|
||||
// throws, strong otherwise.
|
||||
if(this->size_ + 1 >= this->max_load_) {
|
||||
this->reserve_for_insert(this->size_ + insert_size(i, j));
|
||||
bucket = this->bucket_ptr_from_hash(hash_value);
|
||||
}
|
||||
|
||||
// Nothing after this point can throw.
|
||||
add_node(a, bucket);
|
||||
}
|
||||
} while(++i != j);
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,12 @@ namespace boost { namespace unordered_detail {
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// primes
|
||||
|
||||
template<class T> struct prime_list_template
|
||||
{
|
||||
static std::size_t const value[];
|
||||
static std::ptrdiff_t const length;
|
||||
};
|
||||
|
||||
#define BOOST_UNORDERED_PRIMES \
|
||||
(5ul)(11ul)(17ul)(29ul)(37ul)(53ul)(67ul)(79ul) \
|
||||
(97ul)(131ul)(193ul)(257ul)(389ul)(521ul)(769ul) \
|
||||
@@ -41,28 +47,14 @@ namespace boost { namespace unordered_detail {
|
||||
(50331653ul)(100663319ul)(201326611ul)(402653189ul)(805306457ul) \
|
||||
(1610612741ul)(3221225473ul)(4294967291ul)
|
||||
|
||||
template<class T> struct prime_list_template
|
||||
{
|
||||
static std::size_t const value[];
|
||||
|
||||
#if !defined(SUNPRO_CC)
|
||||
static std::ptrdiff_t const length;
|
||||
#else
|
||||
static std::ptrdiff_t const length
|
||||
= BOOST_PP_SEQ_SIZE(BOOST_UNORDERED_PRIMES);
|
||||
#endif
|
||||
};
|
||||
|
||||
template<class T>
|
||||
std::size_t const prime_list_template<T>::value[] = {
|
||||
BOOST_PP_SEQ_ENUM(BOOST_UNORDERED_PRIMES)
|
||||
};
|
||||
|
||||
#if !defined(SUNPRO_CC)
|
||||
template<class T>
|
||||
std::ptrdiff_t const prime_list_template<T>::length
|
||||
= BOOST_PP_SEQ_SIZE(BOOST_UNORDERED_PRIMES);
|
||||
#endif
|
||||
|
||||
#undef BOOST_UNORDERED_PRIMES
|
||||
|
||||
@@ -299,7 +291,7 @@ namespace boost { namespace unordered_detail {
|
||||
#if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613))
|
||||
struct dummy { hash_node<Alloc, Grouped> x; };
|
||||
#endif
|
||||
boost::unordered_detail::destroy(node_->value_ptr());
|
||||
boost::unordered_detail::destroy(&node_->value());
|
||||
}
|
||||
|
||||
if (node_constructed_)
|
||||
@@ -322,7 +314,7 @@ namespace boost { namespace unordered_detail {
|
||||
}
|
||||
else {
|
||||
BOOST_ASSERT(node_constructed_ && value_constructed_);
|
||||
boost::unordered_detail::destroy(node_->value_ptr());
|
||||
boost::unordered_detail::destroy(&node_->value());
|
||||
value_constructed_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include <boost/unordered/detail/equivalent.hpp>
|
||||
#include <boost/unordered/detail/unique.hpp>
|
||||
|
||||
#if defined(BOOST_NO_RVALUE_REFERENCES)
|
||||
#if !defined(BOOST_HAS_RVALUE_REFS)
|
||||
#include <boost/unordered/detail/move.hpp>
|
||||
#endif
|
||||
|
||||
@@ -159,12 +159,7 @@ namespace boost
|
||||
|
||||
~unordered_map() {}
|
||||
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES)
|
||||
unordered_map(unordered_map const& other)
|
||||
: table_(other.table_)
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(BOOST_HAS_RVALUE_REFS)
|
||||
unordered_map(unordered_map&& other)
|
||||
: table_(other.table_, boost::unordered_detail::move_tag())
|
||||
{
|
||||
@@ -175,12 +170,6 @@ namespace boost
|
||||
{
|
||||
}
|
||||
|
||||
unordered_map& operator=(unordered_map const& x)
|
||||
{
|
||||
table_ = x.table_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
unordered_map& operator=(unordered_map&& x)
|
||||
{
|
||||
table_.move(x.table_);
|
||||
@@ -380,11 +369,6 @@ namespace boost
|
||||
return iterator(table_.erase_range(get(first), get(last)));
|
||||
}
|
||||
|
||||
void quick_erase(const_iterator position)
|
||||
{
|
||||
table_.erase(get(position));
|
||||
}
|
||||
|
||||
void erase_return_void(const_iterator position)
|
||||
{
|
||||
table_.erase(get(position));
|
||||
@@ -715,12 +699,7 @@ namespace boost
|
||||
|
||||
~unordered_multimap() {}
|
||||
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES)
|
||||
unordered_multimap(unordered_multimap const& other)
|
||||
: table_(other.table_)
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(BOOST_HAS_RVALUE_REFS)
|
||||
unordered_multimap(unordered_multimap&& other)
|
||||
: table_(other.table_, boost::unordered_detail::move_tag())
|
||||
{
|
||||
@@ -731,12 +710,6 @@ namespace boost
|
||||
{
|
||||
}
|
||||
|
||||
unordered_multimap& operator=(unordered_multimap const& x)
|
||||
{
|
||||
table_ = x.table_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
unordered_multimap& operator=(unordered_multimap&& x)
|
||||
{
|
||||
table_.move(x.table_);
|
||||
@@ -934,11 +907,6 @@ namespace boost
|
||||
return iterator(table_.erase_range(get(first), get(last)));
|
||||
}
|
||||
|
||||
void quick_erase(const_iterator position)
|
||||
{
|
||||
table_.erase(get(position));
|
||||
}
|
||||
|
||||
void erase_return_void(const_iterator position)
|
||||
{
|
||||
table_.erase(get(position));
|
||||
|
||||
@@ -24,13 +24,13 @@ namespace boost
|
||||
class A = std::allocator<std::pair<const K, T> > >
|
||||
class unordered_map;
|
||||
template <class K, class T, class H, class P, class A>
|
||||
inline bool operator==(unordered_map<K, T, H, P, A> const&,
|
||||
bool operator==(unordered_map<K, T, H, P, A> const&,
|
||||
unordered_map<K, T, H, P, A> const&);
|
||||
template <class K, class T, class H, class P, class A>
|
||||
inline bool operator!=(unordered_map<K, T, H, P, A> const&,
|
||||
bool operator!=(unordered_map<K, T, H, P, A> const&,
|
||||
unordered_map<K, T, H, P, A> const&);
|
||||
template <class K, class T, class H, class P, class A>
|
||||
inline void swap(unordered_map<K, T, H, P, A>&,
|
||||
void swap(unordered_map<K, T, H, P, A>&,
|
||||
unordered_map<K, T, H, P, A>&);
|
||||
|
||||
template <class K,
|
||||
@@ -40,13 +40,13 @@ namespace boost
|
||||
class A = std::allocator<std::pair<const K, T> > >
|
||||
class unordered_multimap;
|
||||
template <class K, class T, class H, class P, class A>
|
||||
inline bool operator==(unordered_multimap<K, T, H, P, A> const&,
|
||||
bool operator==(unordered_multimap<K, T, H, P, A> const&,
|
||||
unordered_multimap<K, T, H, P, A> const&);
|
||||
template <class K, class T, class H, class P, class A>
|
||||
inline bool operator!=(unordered_multimap<K, T, H, P, A> const&,
|
||||
bool operator!=(unordered_multimap<K, T, H, P, A> const&,
|
||||
unordered_multimap<K, T, H, P, A> const&);
|
||||
template <class K, class T, class H, class P, class A>
|
||||
inline void swap(unordered_multimap<K, T, H, P, A>&,
|
||||
void swap(unordered_multimap<K, T, H, P, A>&,
|
||||
unordered_multimap<K, T, H, P, A>&);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include <boost/unordered/detail/equivalent.hpp>
|
||||
#include <boost/unordered/detail/unique.hpp>
|
||||
|
||||
#if defined(BOOST_NO_RVALUE_REFERENCES)
|
||||
#if !defined(BOOST_HAS_RVALUE_REFS)
|
||||
#include <boost/unordered/detail/move.hpp>
|
||||
#endif
|
||||
|
||||
@@ -153,12 +153,7 @@ namespace boost
|
||||
|
||||
~unordered_set() {}
|
||||
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES)
|
||||
unordered_set(unordered_set const& other)
|
||||
: table_(other.table_)
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(BOOST_HAS_RVALUE_REFS)
|
||||
unordered_set(unordered_set&& other)
|
||||
: table_(other.table_, boost::unordered_detail::move_tag())
|
||||
{
|
||||
@@ -169,12 +164,6 @@ namespace boost
|
||||
{
|
||||
}
|
||||
|
||||
unordered_set& operator=(unordered_set const& x)
|
||||
{
|
||||
table_ = x.table_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
unordered_set& operator=(unordered_set&& x)
|
||||
{
|
||||
table_.move(x.table_);
|
||||
@@ -372,11 +361,6 @@ namespace boost
|
||||
return iterator(table_.erase_range(get(first), get(last)));
|
||||
}
|
||||
|
||||
void quick_erase(const_iterator position)
|
||||
{
|
||||
table_.erase(get(position));
|
||||
}
|
||||
|
||||
void erase_return_void(const_iterator position)
|
||||
{
|
||||
table_.erase(get(position));
|
||||
@@ -661,12 +645,7 @@ namespace boost
|
||||
|
||||
~unordered_multiset() {}
|
||||
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES)
|
||||
unordered_multiset(unordered_multiset const& other)
|
||||
: table_(other.table_)
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(BOOST_HAS_RVALUE_REFS)
|
||||
unordered_multiset(unordered_multiset&& other)
|
||||
: table_(other.table_, boost::unordered_detail::move_tag())
|
||||
{
|
||||
@@ -677,12 +656,6 @@ namespace boost
|
||||
{
|
||||
}
|
||||
|
||||
unordered_multiset& operator=(unordered_multiset const& x)
|
||||
{
|
||||
table_ = x.table_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
unordered_multiset& operator=(unordered_multiset&& x)
|
||||
{
|
||||
table_.move(x.table_);
|
||||
@@ -876,11 +849,6 @@ namespace boost
|
||||
return iterator(table_.erase_range(get(first), get(last)));
|
||||
}
|
||||
|
||||
void quick_erase(const_iterator position)
|
||||
{
|
||||
table_.erase(get(position));
|
||||
}
|
||||
|
||||
void erase_return_void(const_iterator position)
|
||||
{
|
||||
table_.erase(get(position));
|
||||
|
||||
@@ -23,13 +23,13 @@ namespace boost
|
||||
class A = std::allocator<T> >
|
||||
class unordered_set;
|
||||
template <class T, class H, class P, class A>
|
||||
inline bool operator==(unordered_set<T, H, P, A> const&,
|
||||
bool operator==(unordered_set<T, H, P, A> const&,
|
||||
unordered_set<T, H, P, A> const&);
|
||||
template <class T, class H, class P, class A>
|
||||
inline bool operator!=(unordered_set<T, H, P, A> const&,
|
||||
bool operator!=(unordered_set<T, H, P, A> const&,
|
||||
unordered_set<T, H, P, A> const&);
|
||||
template <class T, class H, class P, class A>
|
||||
inline void swap(unordered_set<T, H, P, A> &m1,
|
||||
void swap(unordered_set<T, H, P, A> &m1,
|
||||
unordered_set<T, H, P, A> &m2);
|
||||
|
||||
template <class T,
|
||||
@@ -38,13 +38,13 @@ namespace boost
|
||||
class A = std::allocator<T> >
|
||||
class unordered_multiset;
|
||||
template <class T, class H, class P, class A>
|
||||
inline bool operator==(unordered_multiset<T, H, P, A> const&,
|
||||
bool operator==(unordered_multiset<T, H, P, A> const&,
|
||||
unordered_multiset<T, H, P, A> const&);
|
||||
template <class T, class H, class P, class A>
|
||||
inline bool operator!=(unordered_multiset<T, H, P, A> const&,
|
||||
bool operator!=(unordered_multiset<T, H, P, A> const&,
|
||||
unordered_multiset<T, H, P, A> const&);
|
||||
template <class T, class H, class P, class A>
|
||||
inline void swap(unordered_multiset<T, H, P, A> &m1,
|
||||
void swap(unordered_multiset<T, H, P, A> &m1,
|
||||
unordered_multiset<T, H, P, A> &m2);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ project unordered-test/exception-tests
|
||||
<toolset>gcc:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter"
|
||||
<toolset>darwin:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter"
|
||||
<toolset>gcc:<define>_GLIBCXX_DEBUG
|
||||
#<toolset>darwin:<define>_GLIBCXX_DEBUG
|
||||
<toolset>darwin:<define>_GLIBCXX_DEBUG
|
||||
<toolset>msvc:<warnings-as-errors>on
|
||||
#<toolset>gcc:<warnings-as-errors>on
|
||||
#<toolset>darwin:<warnings-as-errors>on
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
#include "../helpers/random_values.hpp"
|
||||
#include "../helpers/input_iterator.hpp"
|
||||
|
||||
template <typename T> inline void avoid_unused_warning(T const&) {}
|
||||
|
||||
test::seed_t seed(91274);
|
||||
|
||||
struct objects
|
||||
@@ -26,7 +24,6 @@ struct construct_test1 : public objects, test::exception_base
|
||||
{
|
||||
void run() const {
|
||||
T x;
|
||||
avoid_unused_warning(x);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -35,7 +32,6 @@ struct construct_test2 : public objects, test::exception_base
|
||||
{
|
||||
void run() const {
|
||||
T x(300);
|
||||
avoid_unused_warning(x);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -44,7 +40,6 @@ struct construct_test3 : public objects, test::exception_base
|
||||
{
|
||||
void run() const {
|
||||
T x(0, hash);
|
||||
avoid_unused_warning(x);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -53,7 +48,6 @@ struct construct_test4 : public objects, test::exception_base
|
||||
{
|
||||
void run() const {
|
||||
T x(0, hash, equal_to);
|
||||
avoid_unused_warning(x);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -62,7 +56,6 @@ struct construct_test5 : public objects, test::exception_base
|
||||
{
|
||||
void run() const {
|
||||
T x(50, hash, equal_to, allocator);
|
||||
avoid_unused_warning(x);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -71,7 +64,6 @@ struct construct_test6 : public objects, test::exception_base
|
||||
{
|
||||
void run() const {
|
||||
T x(allocator);
|
||||
avoid_unused_warning(x);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -89,7 +81,6 @@ struct range_construct_test1 : public range<T>, objects
|
||||
{
|
||||
void run() const {
|
||||
T x(this->values.begin(), this->values.end());
|
||||
avoid_unused_warning(x);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -98,7 +89,6 @@ struct range_construct_test2 : public range<T>, objects
|
||||
{
|
||||
void run() const {
|
||||
T x(this->values.begin(), this->values.end(), 0);
|
||||
avoid_unused_warning(x);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -107,7 +97,6 @@ struct range_construct_test3 : public range<T>, objects
|
||||
{
|
||||
void run() const {
|
||||
T x(this->values.begin(), this->values.end(), 0, hash);
|
||||
avoid_unused_warning(x);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -116,7 +105,6 @@ struct range_construct_test4 : public range<T>, objects
|
||||
{
|
||||
void run() const {
|
||||
T x(this->values.begin(), this->values.end(), 100, hash, equal_to);
|
||||
avoid_unused_warning(x);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -130,7 +118,6 @@ struct range_construct_test5 : public range<T>, objects
|
||||
void run() const {
|
||||
T x(this->values.begin(), this->values.end(), 0,
|
||||
hash, equal_to, allocator);
|
||||
avoid_unused_warning(x);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -144,20 +131,6 @@ struct input_range_construct_test : public range<T>, objects
|
||||
begin = this->values.begin(), end = this->values.end();
|
||||
T x(test::input_iterator(begin), test::input_iterator(end),
|
||||
0, hash, equal_to, allocator);
|
||||
avoid_unused_warning(x);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct copy_range_construct_test : public range<T>, objects
|
||||
{
|
||||
copy_range_construct_test() : range<T>(60) {}
|
||||
|
||||
void run() const {
|
||||
T x(test::copy_iterator(this->values.begin()),
|
||||
test::copy_iterator(this->values.end()),
|
||||
0, hash, equal_to, allocator);
|
||||
avoid_unused_warning(x);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -173,6 +146,5 @@ RUN_EXCEPTION_TESTS(
|
||||
(range_construct_test3)
|
||||
(range_construct_test4)
|
||||
(range_construct_test5)
|
||||
(input_range_construct_test)
|
||||
(copy_range_construct_test),
|
||||
(input_range_construct_test),
|
||||
CONTAINER_SEQ)
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
#include "./containers.hpp"
|
||||
#include "../helpers/random_values.hpp"
|
||||
|
||||
template <typename T> inline void avoid_unused_warning(T const&) {}
|
||||
|
||||
test::seed_t seed(73041);
|
||||
|
||||
template <class T>
|
||||
@@ -19,7 +17,6 @@ struct copy_test1 : public test::exception_base
|
||||
|
||||
void run() const {
|
||||
T y(x);
|
||||
avoid_unused_warning(y);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -33,7 +30,6 @@ struct copy_test2 : public test::exception_base
|
||||
|
||||
void run() const {
|
||||
T y(x);
|
||||
avoid_unused_warning(y);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -47,7 +43,6 @@ struct copy_test3 : public test::exception_base
|
||||
|
||||
void run() const {
|
||||
T y(x);
|
||||
avoid_unused_warning(y);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -62,7 +57,6 @@ struct copy_with_allocator_test : public test::exception_base
|
||||
|
||||
void run() const {
|
||||
T y(x, allocator);
|
||||
avoid_unused_warning(y);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ struct insert_test_base : public test::exception_base
|
||||
}
|
||||
};
|
||||
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_NO_VARIADIC_TEMPLATES)
|
||||
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
|
||||
|
||||
template <class T>
|
||||
struct emplace_test1 : public insert_test_base<T>
|
||||
@@ -238,7 +238,7 @@ struct insert_test_rehash3 : public insert_test_base<T>
|
||||
(insert_test1)(insert_test2)(insert_test3)(insert_test4) \
|
||||
(insert_test_rehash1)(insert_test_rehash2)(insert_test_rehash3)
|
||||
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_NO_VARIADIC_TEMPLATES)
|
||||
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
|
||||
#define ALL_TESTS (emplace_test1)BASIC_TESTS
|
||||
#else
|
||||
#define ALL_TESTS BASIC_TESTS
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
// Copyright 2005-2010 Daniel James.
|
||||
// Copyright 2005-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)
|
||||
|
||||
@@ -69,96 +69,6 @@ namespace test
|
||||
{
|
||||
return input_iterator_adaptor<Iterator>(it);
|
||||
}
|
||||
|
||||
template <class Iterator>
|
||||
struct copy_iterator_adaptor
|
||||
: public boost::iterator<
|
||||
BOOST_DEDUCED_TYPENAME boost::iterator_category<Iterator>::type,
|
||||
BOOST_DEDUCED_TYPENAME boost::iterator_value<Iterator>::type,
|
||||
BOOST_DEDUCED_TYPENAME boost::iterator_difference<Iterator>::type,
|
||||
BOOST_DEDUCED_TYPENAME boost::iterator_pointer<Iterator>::type,
|
||||
proxy<Iterator>
|
||||
>
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_value<Iterator>::type
|
||||
value_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_difference<Iterator>::type
|
||||
difference_type;
|
||||
|
||||
copy_iterator_adaptor()
|
||||
: base_() {}
|
||||
explicit copy_iterator_adaptor(Iterator const& it)
|
||||
: base_(it) {}
|
||||
value_type operator*() const {
|
||||
return *base_;
|
||||
}
|
||||
value_type* operator->() const {
|
||||
return &*base_;
|
||||
}
|
||||
value_type operator[](difference_type d) {
|
||||
return base_[d];
|
||||
}
|
||||
copy_iterator_adaptor& operator++() {
|
||||
++base_; return *this;
|
||||
}
|
||||
copy_iterator_adaptor operator++(int) {
|
||||
copy_iterator_adaptor tmp(*this); ++base_; return tmp;
|
||||
}
|
||||
copy_iterator_adaptor& operator--() {
|
||||
--base_; return *this;
|
||||
}
|
||||
copy_iterator_adaptor operator--(int) {
|
||||
copy_iterator_adaptor tmp(*this); --base_; return tmp;
|
||||
}
|
||||
copy_iterator_adaptor operator+=(difference_type x) {
|
||||
base_ += x;
|
||||
return *this;
|
||||
}
|
||||
copy_iterator_adaptor operator-=(difference_type x) {
|
||||
base_ -= x;
|
||||
return *this;
|
||||
}
|
||||
copy_iterator_adaptor operator+(difference_type n) {
|
||||
return copy_iterator_adaptor(base_+n);
|
||||
}
|
||||
copy_iterator_adaptor operator-(difference_type n) {
|
||||
return copy_iterator_adaptor(base_-n);
|
||||
}
|
||||
friend copy_iterator_adaptor operator+(
|
||||
difference_type n, copy_iterator_adaptor x) {
|
||||
return x+n;
|
||||
}
|
||||
difference_type operator-(copy_iterator_adaptor const& other) {
|
||||
return base_-other.base_;
|
||||
}
|
||||
bool operator==(copy_iterator_adaptor const& x) const {
|
||||
return base_ == x.base_;
|
||||
}
|
||||
bool operator!=(copy_iterator_adaptor const& x) const {
|
||||
return base_ != x.base_;
|
||||
}
|
||||
bool operator<(copy_iterator_adaptor const& x) const {
|
||||
return base_ < x.base_;
|
||||
}
|
||||
bool operator>(copy_iterator_adaptor const& x) const {
|
||||
return base_ > x.base_;
|
||||
}
|
||||
bool operator<=(copy_iterator_adaptor const& x) const {
|
||||
return base_ <= x.base_;
|
||||
}
|
||||
bool operator>=(copy_iterator_adaptor const& x) const {
|
||||
return base_ >= x.base_;
|
||||
}
|
||||
private:
|
||||
Iterator base_;
|
||||
};
|
||||
|
||||
template <class Iterator>
|
||||
copy_iterator_adaptor<Iterator> copy_iterator(Iterator const& it)
|
||||
{
|
||||
return copy_iterator_adaptor<Iterator>(it);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -94,7 +94,7 @@ namespace test
|
||||
|
||||
node* ptr_;
|
||||
public:
|
||||
list_iterator() : ptr_(0) {}
|
||||
list_iterator() : ptr_(0) {};
|
||||
explicit list_iterator(node* x) : ptr_(x) {}
|
||||
|
||||
T& operator*() const { return ptr_->value_; }
|
||||
|
||||
@@ -26,8 +26,6 @@ namespace minimal
|
||||
class default_copy_constructible;
|
||||
class assignable;
|
||||
|
||||
struct ampersand_operator_used {};
|
||||
|
||||
template <class T> class hash;
|
||||
template <class T> class equal_to;
|
||||
template <class T> class ptr;
|
||||
@@ -65,7 +63,6 @@ namespace minimal
|
||||
copy_constructible_equality_comparable& operator=(
|
||||
copy_constructible_equality_comparable const&);
|
||||
copy_constructible_equality_comparable() {}
|
||||
ampersand_operator_used operator&() const { return ampersand_operator_used(); }
|
||||
};
|
||||
|
||||
bool operator==(
|
||||
@@ -101,11 +98,9 @@ namespace minimal
|
||||
~default_copy_constructible()
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
default_copy_constructible& operator=(
|
||||
default_copy_constructible const&);
|
||||
ampersand_operator_used operator&() const { return ampersand_operator_used(); }
|
||||
};
|
||||
|
||||
class assignable
|
||||
@@ -115,11 +110,8 @@ namespace minimal
|
||||
assignable(assignable const&) {}
|
||||
assignable& operator=(assignable const&) { return *this; }
|
||||
~assignable() {}
|
||||
|
||||
private:
|
||||
assignable() {}
|
||||
// TODO: This messes up a concept check in the tests.
|
||||
//ampersand_operator_used operator&() const { return ampersand_operator_used(); }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
@@ -133,8 +125,6 @@ namespace minimal
|
||||
~hash() {}
|
||||
|
||||
std::size_t operator()(T const&) const { return 0; }
|
||||
private:
|
||||
ampersand_operator_used operator&() const { return ampersand_operator_used(); }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
@@ -148,8 +138,6 @@ namespace minimal
|
||||
~equal_to() {}
|
||||
|
||||
bool operator()(T const&, T const&) const { return true; }
|
||||
private:
|
||||
ampersand_operator_used operator&() const { return ampersand_operator_used(); }
|
||||
};
|
||||
|
||||
template <class T> class ptr;
|
||||
@@ -194,9 +182,6 @@ namespace minimal
|
||||
bool operator>(const_ptr<T> const& x) const { return ptr_ > x.ptr_; }
|
||||
bool operator<=(const_ptr<T> const& x) const { return ptr_ <= x.ptr_; }
|
||||
bool operator>=(const_ptr<T> const& x) const { return ptr_ >= x.ptr_; }
|
||||
private:
|
||||
// TODO:
|
||||
//ampersand_operator_used operator&() const { return ampersand_operator_used(); }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
@@ -236,9 +221,6 @@ namespace minimal
|
||||
bool operator>(const_ptr const& x) const { return ptr_ > x.ptr_; }
|
||||
bool operator<=(const_ptr const& x) const { return ptr_ <= x.ptr_; }
|
||||
bool operator>=(const_ptr const& x) const { return ptr_ >= x.ptr_; }
|
||||
private:
|
||||
// TODO:
|
||||
//ampersand_operator_used operator&() const { return ampersand_operator_used(); }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
@@ -296,8 +278,6 @@ namespace minimal
|
||||
#else
|
||||
private: allocator& operator=(allocator const&);
|
||||
#endif
|
||||
private:
|
||||
ampersand_operator_used operator&() const { return ampersand_operator_used(); }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
|
||||
+38
-27
@@ -20,13 +20,11 @@ namespace test
|
||||
// Note that the default hash function will work for any equal_to (but not
|
||||
// very well).
|
||||
class object;
|
||||
class implicitly_convertible;
|
||||
class hash;
|
||||
class less;
|
||||
class equal_to;
|
||||
template <class T> class allocator;
|
||||
object generate(object const*);
|
||||
implicitly_convertible generate(implicitly_convertible const*);
|
||||
|
||||
class object : globally_counted_object
|
||||
{
|
||||
@@ -66,31 +64,6 @@ namespace test
|
||||
}
|
||||
};
|
||||
|
||||
class implicitly_convertible : globally_counted_object
|
||||
{
|
||||
int tag1_, tag2_;
|
||||
public:
|
||||
|
||||
explicit implicitly_convertible(int t1 = 0, int t2 = 0)
|
||||
: tag1_(t1), tag2_(t2)
|
||||
{}
|
||||
|
||||
operator object() const
|
||||
{
|
||||
return object(tag1_, tag2_);
|
||||
}
|
||||
|
||||
friend implicitly_convertible generate(implicitly_convertible const*) {
|
||||
int* x = 0;
|
||||
return implicitly_convertible(generate(x), generate(x));
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& out, implicitly_convertible const& o)
|
||||
{
|
||||
return out<<"("<<o.tag1_<<","<<o.tag2_<<")";
|
||||
}
|
||||
};
|
||||
|
||||
class hash
|
||||
{
|
||||
int type_;
|
||||
@@ -306,6 +279,44 @@ namespace test
|
||||
{
|
||||
return x == y;
|
||||
}
|
||||
|
||||
#if BOOST_WORKAROUND(__GNUC__, < 3)
|
||||
void swap(test::object& x, test::object& y) {
|
||||
test::object tmp;
|
||||
tmp = x;
|
||||
x = y;
|
||||
y = tmp;
|
||||
}
|
||||
|
||||
void swap(test::hash& x, test::hash& y) {
|
||||
test::hash tmp;
|
||||
tmp = x;
|
||||
x = y;
|
||||
y = tmp;
|
||||
}
|
||||
|
||||
void swap(test::less& x, test::less& y) {
|
||||
test::less tmp;
|
||||
tmp = x;
|
||||
x = y;
|
||||
y = tmp;
|
||||
}
|
||||
|
||||
void swap(test::equal_to& x, test::equal_to& y) {
|
||||
test::equal_to tmp;
|
||||
tmp = x;
|
||||
x = y;
|
||||
y = tmp;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void swap(test::allocator<T>& x, test::allocator<T>& y) {
|
||||
test::allocator<T> tmp;
|
||||
tmp = x;
|
||||
x = y;
|
||||
y = tmp;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -9,10 +9,10 @@ project unordered-test/unordered
|
||||
: requirements
|
||||
<warnings>all
|
||||
<toolset>intel:<warnings>on
|
||||
<toolset>gcc:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter -Wconversion"
|
||||
<toolset>darwin:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter -Wconversion"
|
||||
<toolset>gcc:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter"
|
||||
<toolset>darwin:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter"
|
||||
<toolset>gcc:<define>_GLIBCXX_DEBUG
|
||||
#<toolset>darwin:<define>_GLIBCXX_DEBUG
|
||||
<toolset>darwin:<define>_GLIBCXX_DEBUG
|
||||
<toolset>msvc:<warnings-as-errors>on
|
||||
#<toolset>gcc:<warnings-as-errors>on
|
||||
#<toolset>darwin:<warnings-as-errors>on
|
||||
@@ -30,7 +30,7 @@ test-suite unordered
|
||||
[ run equivalent_keys_tests.cpp ]
|
||||
[ run constructor_tests.cpp ]
|
||||
[ run copy_tests.cpp ]
|
||||
[ run move_tests.cpp ]
|
||||
[ run move_tests.cpp : : : <test-info>always_show_run_output ]
|
||||
[ run assign_tests.cpp ]
|
||||
[ run insert_tests.cpp ]
|
||||
[ run insert_stable_tests.cpp ]
|
||||
|
||||
@@ -138,12 +138,6 @@ void container_test(X& r, T const&)
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME X::allocator_type allocator_type;
|
||||
test::check_return_type<allocator_type>::equals(a_const.get_allocator());
|
||||
|
||||
// Avoid unused variable warnings:
|
||||
|
||||
sink(u);
|
||||
sink(u2);
|
||||
sink(u3);
|
||||
}
|
||||
|
||||
template <class X, class Key>
|
||||
@@ -381,16 +375,4 @@ void unordered_test(X&, Key& k, T& t, Hash& hf, Pred& eq)
|
||||
test::check_return_type<float>::equals(b.max_load_factor());
|
||||
a.max_load_factor((float) 2.0);
|
||||
a.rehash(100);
|
||||
|
||||
// Avoid unused variable warnings:
|
||||
|
||||
sink(a);
|
||||
sink(a2);
|
||||
sink(a3);
|
||||
sink(a4);
|
||||
sink(a5);
|
||||
sink(a6);
|
||||
sink(a7);
|
||||
sink(a8);
|
||||
sink(a9);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
// Copyright 2006-2010 Daniel James.
|
||||
// Copyright 2006-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)
|
||||
|
||||
@@ -142,6 +142,7 @@ void constructor_tests1(T*,
|
||||
|
||||
std::cerr<<"Construct 11\n";
|
||||
{
|
||||
test::random_values<T> v(1000, generator);
|
||||
T x(al);
|
||||
BOOST_TEST(x.empty());
|
||||
BOOST_TEST(test::equivalent(x.hash_function(), hf));
|
||||
@@ -260,19 +261,6 @@ void constructor_tests2(T*,
|
||||
test::check_equivalent_keys(y);
|
||||
}
|
||||
|
||||
std::cerr<<"Construct 8.5 - from copy iterator\n";
|
||||
{
|
||||
test::random_values<T> v(100, generator);
|
||||
T x(test::copy_iterator(v.begin()),
|
||||
test::copy_iterator(v.end()), 0, hf1, eq1);
|
||||
T y(test::copy_iterator(x.begin()),
|
||||
test::copy_iterator(x.end()), 0, hf2, eq2);
|
||||
test::check_container(x, v);
|
||||
test::check_container(y, x);
|
||||
test::check_equivalent_keys(x);
|
||||
test::check_equivalent_keys(y);
|
||||
}
|
||||
|
||||
std::cerr<<"Construct 9\n";
|
||||
{
|
||||
test::random_values<T> v(100, generator);
|
||||
|
||||
@@ -116,7 +116,7 @@ void erase_tests1(Container*,
|
||||
BOOST_TEST(x.erase(x.begin(), x.end()) == x.begin());
|
||||
}
|
||||
|
||||
std::cerr<<"quick_erase(begin()).\n";
|
||||
std::cerr<<"erase_return_void(begin()).\n";
|
||||
{
|
||||
test::random_values<Container> v(1000, generator);
|
||||
Container x(v.begin(), v.end());
|
||||
@@ -126,7 +126,7 @@ void erase_tests1(Container*,
|
||||
BOOST_DEDUCED_TYPENAME Container::key_type
|
||||
key = test::get_key<Container>(*x.begin());
|
||||
std::size_t count = x.count(key);
|
||||
x.quick_erase(x.begin());
|
||||
x.erase_return_void(x.begin());
|
||||
--size;
|
||||
BOOST_TEST(x.count(key) == count - 1);
|
||||
BOOST_TEST(x.size() == size);
|
||||
@@ -134,7 +134,7 @@ void erase_tests1(Container*,
|
||||
BOOST_TEST(x.empty());
|
||||
}
|
||||
|
||||
std::cerr<<"quick_erase(random position).\n";
|
||||
std::cerr<<"erase_return_void(random position).\n";
|
||||
{
|
||||
test::random_values<Container> v(1000, generator);
|
||||
Container x(v.begin(), v.end());
|
||||
@@ -155,7 +155,7 @@ void erase_tests1(Container*,
|
||||
BOOST_DEDUCED_TYPENAME Container::key_type
|
||||
key = test::get_key<Container>(*pos);
|
||||
std::size_t count = x.count(key);
|
||||
x.quick_erase(pos);
|
||||
x.erase_return_void(pos);
|
||||
--size;
|
||||
if(size > 0)
|
||||
BOOST_TEST(index == 0 ? next == x.begin() :
|
||||
|
||||
@@ -7,54 +7,37 @@
|
||||
|
||||
#include <boost/unordered/unordered_map_fwd.hpp>
|
||||
|
||||
template <typename T>
|
||||
void call_swap(boost::unordered_map<T,T>& x,
|
||||
boost::unordered_map<T,T>& y)
|
||||
{
|
||||
typedef boost::unordered_map<int, int> int_map;
|
||||
|
||||
void call_swap(int_map& x, int_map& y) {
|
||||
swap(x,y);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool call_equals(boost::unordered_map<T,T>& x,
|
||||
boost::unordered_map<T,T>& y)
|
||||
{
|
||||
bool call_equals(int_map& x, int_map& y) {
|
||||
return x == y;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool call_not_equals(boost::unordered_map<T,T>& x,
|
||||
boost::unordered_map<T,T>& y)
|
||||
{
|
||||
bool call_not_equals(int_map& x, int_map& y) {
|
||||
return x != y;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void call_swap(boost::unordered_multimap<T,T>& x,
|
||||
boost::unordered_multimap<T,T>& y)
|
||||
{
|
||||
typedef boost::unordered_multimap<int, int> int_multimap;
|
||||
|
||||
void call_swap(int_multimap& x, int_multimap& y) {
|
||||
swap(x,y);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool call_equals(boost::unordered_multimap<T,T>& x,
|
||||
boost::unordered_multimap<T,T>& y)
|
||||
{
|
||||
bool call_equals(int_multimap& x, int_multimap& y) {
|
||||
return x == y;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool call_not_equals(boost::unordered_multimap<T,T>& x,
|
||||
boost::unordered_multimap<T,T>& y)
|
||||
{
|
||||
bool call_not_equals(int_multimap& x, int_multimap& y) {
|
||||
return x != y;
|
||||
}
|
||||
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/test.hpp"
|
||||
|
||||
typedef boost::unordered_map<int, int> int_map;
|
||||
typedef boost::unordered_multimap<int, int> int_multimap;
|
||||
|
||||
UNORDERED_AUTO_TEST(use_map_fwd_declared_function) {
|
||||
int_map x, y;
|
||||
x[1] = 2;
|
||||
|
||||
@@ -16,53 +16,36 @@ template <class Value, class Hash, class Pred, class Alloc>
|
||||
true_type is_unordered_set_impl(
|
||||
boost::unordered_set<Value, Hash, Pred, Alloc>*);
|
||||
|
||||
template<typename T>
|
||||
void call_swap(boost::unordered_set<T>& x,
|
||||
boost::unordered_set<T>& y)
|
||||
{
|
||||
typedef boost::unordered_set<int> int_set;
|
||||
|
||||
void call_swap(int_set& x, int_set& y) {
|
||||
swap(x,y);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool call_equals(boost::unordered_set<T>& x,
|
||||
boost::unordered_set<T>& y)
|
||||
{
|
||||
bool call_equals(int_set& x, int_set& y) {
|
||||
return x == y;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool call_not_equals(boost::unordered_set<T>& x,
|
||||
boost::unordered_set<T>& y)
|
||||
{
|
||||
bool call_not_equals(int_set& x, int_set& y) {
|
||||
return x != y;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void call_swap(boost::unordered_multiset<T>& x,
|
||||
boost::unordered_multiset<T>& y)
|
||||
{
|
||||
typedef boost::unordered_multiset<int> int_multiset;
|
||||
|
||||
void call_swap(int_multiset& x, int_multiset& y) {
|
||||
swap(x,y);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool call_equals(boost::unordered_multiset<T>& x,
|
||||
boost::unordered_multiset<T>& y)
|
||||
{
|
||||
bool call_equals(int_multiset& x, int_multiset& y) {
|
||||
return x == y;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool call_not_equals(boost::unordered_multiset<T>& x,
|
||||
boost::unordered_multiset<T>& y)
|
||||
{
|
||||
bool call_not_equals(int_multiset& x, int_multiset& y) {
|
||||
return x != y;
|
||||
}
|
||||
|
||||
#include "../helpers/test.hpp"
|
||||
|
||||
typedef boost::unordered_set<int> int_set;
|
||||
typedef boost::unordered_multiset<int> int_multiset;
|
||||
|
||||
UNORDERED_AUTO_TEST(use_fwd_declared_trait_without_definition) {
|
||||
BOOST_TEST(sizeof(is_unordered_set_impl((int_set*) 0))
|
||||
== sizeof(true_type));
|
||||
@@ -74,7 +57,8 @@ UNORDERED_AUTO_TEST(use_fwd_declared_trait) {
|
||||
boost::unordered_set<int> x;
|
||||
BOOST_TEST(sizeof(is_unordered_set_impl(&x)) == sizeof(true_type));
|
||||
|
||||
BOOST_TEST(sizeof(is_unordered_set_impl((int*) 0)) == sizeof(false_type));
|
||||
int dummy;
|
||||
BOOST_TEST(sizeof(is_unordered_set_impl(&dummy)) == sizeof(false_type));
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(use_set_fwd_declared_function) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
// Copyright 2006-2010 Daniel James.
|
||||
// Copyright 2006-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)
|
||||
|
||||
@@ -52,7 +52,7 @@ void unique_insert_tests1(X*,
|
||||
|
||||
tracker.compare_key(x, *it);
|
||||
|
||||
if(static_cast<double>(x.size()) < b * static_cast<double>(old_bucket_count))
|
||||
if(x.size() < b * old_bucket_count)
|
||||
BOOST_TEST(x.bucket_count() == old_bucket_count);
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ void equivalent_insert_tests1(X*,
|
||||
|
||||
tracker.compare_key(x, *it);
|
||||
|
||||
if(static_cast<double>(x.size()) < b * static_cast<double>(old_bucket_count))
|
||||
if(x.size() < b * old_bucket_count)
|
||||
BOOST_TEST(x.bucket_count() == old_bucket_count);
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ void insert_tests2(X*,
|
||||
BOOST_TEST(*r1 == *r2);
|
||||
tracker.compare_key(x, *it);
|
||||
|
||||
if(static_cast<double>(x.size()) < b * static_cast<double>(old_bucket_count))
|
||||
if(x.size() < b * old_bucket_count)
|
||||
BOOST_TEST(x.bucket_count() == old_bucket_count);
|
||||
}
|
||||
|
||||
@@ -145,7 +145,7 @@ void insert_tests2(X*,
|
||||
BOOST_TEST(*r1 == *r2);
|
||||
tracker.compare_key(x, *it);
|
||||
|
||||
if(static_cast<double>(x.size()) < b * static_cast<double>(old_bucket_count))
|
||||
if(x.size() < b * old_bucket_count)
|
||||
BOOST_TEST(x.bucket_count() == old_bucket_count);
|
||||
}
|
||||
|
||||
@@ -172,7 +172,7 @@ void insert_tests2(X*,
|
||||
BOOST_TEST(*pos == *r2);
|
||||
tracker.compare_key(x, *it);
|
||||
|
||||
if(static_cast<double>(x.size()) < b * static_cast<double>(old_bucket_count))
|
||||
if(x.size() < b * old_bucket_count)
|
||||
BOOST_TEST(x.bucket_count() == old_bucket_count);
|
||||
}
|
||||
|
||||
@@ -197,7 +197,7 @@ void insert_tests2(X*,
|
||||
tracker.insert(*it);
|
||||
tracker.compare_key(x, *it);
|
||||
|
||||
if(static_cast<double>(x.size()) < b * static_cast<double>(old_bucket_count))
|
||||
if(x.size() < b * old_bucket_count)
|
||||
BOOST_TEST(x.bucket_count() == old_bucket_count);
|
||||
}
|
||||
|
||||
@@ -229,21 +229,9 @@ void insert_tests2(X*,
|
||||
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
std::cerr<<"insert copy iterator range tests.\n";
|
||||
|
||||
{
|
||||
X x;
|
||||
|
||||
test::random_values<X> v(1000, generator);
|
||||
x.insert(test::copy_iterator(v.begin()), test::copy_iterator(v.end()));
|
||||
test::check_container(x, v);
|
||||
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_NO_VARIADIC_TEMPLATES)
|
||||
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
|
||||
|
||||
template <class X>
|
||||
void unique_emplace_tests1(X*,
|
||||
@@ -275,7 +263,7 @@ void unique_emplace_tests1(X*,
|
||||
|
||||
tracker.compare_key(x, *it);
|
||||
|
||||
if(static_cast<double>(x.size()) < b * static_cast<double>(old_bucket_count))
|
||||
if(x.size() < b * old_bucket_count)
|
||||
BOOST_TEST(x.bucket_count() == old_bucket_count);
|
||||
}
|
||||
|
||||
@@ -306,7 +294,7 @@ void equivalent_emplace_tests1(X*,
|
||||
|
||||
tracker.compare_key(x, *it);
|
||||
|
||||
if(static_cast<double>(x.size()) < b * static_cast<double>(old_bucket_count))
|
||||
if(x.size() < b * old_bucket_count)
|
||||
BOOST_TEST(x.bucket_count() == old_bucket_count);
|
||||
}
|
||||
|
||||
@@ -335,7 +323,7 @@ void map_tests(X*, test::random_generator generator = test::default_generator)
|
||||
|
||||
tracker.compare_key(x, *it);
|
||||
|
||||
if(static_cast<double>(x.size()) < b * static_cast<double>(old_bucket_count))
|
||||
if(x.size() < b * old_bucket_count)
|
||||
BOOST_TEST(x.bucket_count() == old_bucket_count);
|
||||
}
|
||||
|
||||
@@ -372,10 +360,10 @@ void map_insert_range_test2(X*,
|
||||
std::cerr<<"map_insert_range_test2\n";
|
||||
|
||||
typedef test::list<
|
||||
std::pair<BOOST_DEDUCED_TYPENAME X::key_type const, test::implicitly_convertible>
|
||||
std::pair<BOOST_DEDUCED_TYPENAME X::key_type const, int>
|
||||
> list;
|
||||
test::random_values<
|
||||
boost::unordered_map<BOOST_DEDUCED_TYPENAME X::key_type, test::implicitly_convertible>
|
||||
boost::unordered_map<BOOST_DEDUCED_TYPENAME X::key_type, int>
|
||||
> v(1000, generator);
|
||||
list l(v.begin(), v.end());
|
||||
|
||||
@@ -415,7 +403,7 @@ UNORDERED_TEST(insert_tests2,
|
||||
((default_generator)(generate_collisions))
|
||||
)
|
||||
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_NO_VARIADIC_TEMPLATES)
|
||||
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
|
||||
UNORDERED_TEST(unique_emplace_tests1,
|
||||
((test_set)(test_map))
|
||||
((default_generator)(generate_collisions))
|
||||
|
||||
@@ -51,7 +51,7 @@ void insert_test(X*, float mlf,
|
||||
BOOST_DEDUCED_TYPENAME X::size_type old_size = x.size(),
|
||||
old_bucket_count = x.bucket_count();
|
||||
x.insert(*it);
|
||||
if(static_cast<double>(old_size + 1) < b * static_cast<double>(old_bucket_count))
|
||||
if(old_size + 1 < b * old_bucket_count)
|
||||
BOOST_TEST(x.bucket_count() == old_bucket_count);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ namespace move_tests
|
||||
{
|
||||
test::random_values<T> v(25, generator);
|
||||
T y(create(v, count, hf, eq, al, 1.0), al);
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES)
|
||||
#if defined(BOOST_HAS_RVALUE_REFS)
|
||||
BOOST_TEST(count == test::global_object_count);
|
||||
#else
|
||||
BOOST_TEST(
|
||||
|
||||
@@ -19,8 +19,7 @@ test::seed_t seed(2974);
|
||||
template <class X>
|
||||
bool postcondition(X const& x, BOOST_DEDUCED_TYPENAME X::size_type n)
|
||||
{
|
||||
return static_cast<double>(x.bucket_count()) >
|
||||
static_cast<double>(x.size()) / x.max_load_factor() &&
|
||||
return x.bucket_count() > x.size() / x.max_load_factor() &&
|
||||
x.bucket_count() >= n;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace unnecessary_copy_tests
|
||||
: tag_(x.tag_) { ++copies; }
|
||||
|
||||
count_copies(count_copies const& x) : tag_(x.tag_) { ++copies; }
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES)
|
||||
#if defined(BOOST_HAS_RVALUE_REFS)
|
||||
count_copies(count_copies&& x) : tag_(x.tag_) {
|
||||
x.tag_ = -1; ++moves;
|
||||
}
|
||||
@@ -136,7 +136,7 @@ namespace unnecessary_copy_tests
|
||||
reset();
|
||||
T x;
|
||||
x.emplace(source<BOOST_DEDUCED_TYPENAME T::value_type>());
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_NO_VARIADIC_TEMPLATES)
|
||||
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
|
||||
COPY_COUNT(1);
|
||||
#else
|
||||
COPY_COUNT(2);
|
||||
@@ -148,7 +148,7 @@ namespace unnecessary_copy_tests
|
||||
UNORDERED_TEST(unnecessary_copy_emplace_rvalue_test,
|
||||
((set)(multiset)(map)(multimap)))
|
||||
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_NO_VARIADIC_TEMPLATES)
|
||||
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
|
||||
template <class T>
|
||||
void unnecessary_copy_emplace_move_test(T*)
|
||||
{
|
||||
@@ -199,7 +199,7 @@ namespace unnecessary_copy_tests
|
||||
x.emplace(source<count_copies>());
|
||||
COPY_COUNT(1); MOVE_COUNT(0);
|
||||
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES)
|
||||
#if defined(BOOST_HAS_RVALUE_REFS)
|
||||
// No move should take place.
|
||||
reset();
|
||||
x.emplace(std::move(a));
|
||||
@@ -261,7 +261,7 @@ namespace unnecessary_copy_tests
|
||||
// copied.
|
||||
reset();
|
||||
x.emplace(source<std::pair<count_copies, count_copies> >());
|
||||
COPY_COUNT(2); MOVE_COUNT_RANGE(0,2);
|
||||
COPY_COUNT(2); MOVE_COUNT(0);
|
||||
|
||||
// TODO: This doesn't work on older versions of gcc.
|
||||
//count_copies part;
|
||||
@@ -271,7 +271,7 @@ namespace unnecessary_copy_tests
|
||||
//x.emplace(a_ref);
|
||||
//COPY_COUNT(0); MOVE_COUNT(0);
|
||||
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES)
|
||||
#if defined(BOOST_HAS_RVALUE_REFS)
|
||||
// No move should take place.
|
||||
// (since a is already in the container)
|
||||
reset();
|
||||
|
||||
Reference in New Issue
Block a user