Compare commits

..

1 Commits

Author SHA1 Message Date
Beman Dawes f409496e68 Boost 1.42.0
[SVN r59432]
2010-02-02 20:03:43 +00:00
33 changed files with 403 additions and 918 deletions
+5 -11
View File
@@ -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
-17
View File
@@ -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
View File
@@ -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
View File
@@ -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]
]
]
+1 -1
View File
@@ -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
+217 -110
View File
@@ -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
+5 -6
View File
@@ -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
+25 -151
View File
@@ -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);
}
+8 -16
View File
@@ -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;
}
}
+3 -35
View File
@@ -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>&);
}
+3 -35
View File
@@ -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);
}
+1 -1
View File
@@ -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
+1 -29
View File
@@ -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)
-6
View File
@@ -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);
}
};
+2 -2
View File
@@ -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 -91
View File
@@ -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
+1 -1
View File
@@ -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_; }
-20
View File
@@ -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
View File
@@ -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
+4 -4
View File
@@ -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 ]
-18
View File
@@ -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);
}
+2 -14
View File
@@ -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);
+4 -4
View File
@@ -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() :
+10 -27
View File
@@ -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;
+12 -28
View File
@@ -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) {
+14 -26
View File
@@ -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))
+1 -1
View File
@@ -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);
}
}
+1 -1
View File
@@ -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(
+1 -2
View File
@@ -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;
}
+6 -6
View File
@@ -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();