mirror of
https://github.com/boostorg/unordered.git
synced 2026-08-06 13:44:12 +02:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 68db81064b |
@@ -1 +0,0 @@
|
||||
/doc/html/
|
||||
+1
-42
@@ -47,7 +47,7 @@ First official release.
|
||||
|
||||
[h2 Boost 1.38.0]
|
||||
|
||||
* Use [@boost:/libs/core/swap.html `boost::swap`].
|
||||
* Use [@boost:/libs/utility/swap.html `boost::swap`].
|
||||
* [@https://svn.boost.org/trac/boost/ticket/2237 Ticket 2237]:
|
||||
Document that the equality and inequality operators are undefined for two
|
||||
objects if their equality predicates aren't equivalent. Thanks to Daniel
|
||||
@@ -228,45 +228,4 @@ C++11 support has resulted in some breaking changes:
|
||||
* More internal implementation changes, including a much simpler
|
||||
implementation of `erase`.
|
||||
|
||||
[h2 Boost 1.54.0]
|
||||
|
||||
* Mark methods specified in standard as `noexpect`. More to come in the next
|
||||
release.
|
||||
* If the hash function and equality predicate are known to both have nothrow
|
||||
move assignment or construction then use them.
|
||||
|
||||
[h2 Boost 1.55.0]
|
||||
|
||||
* Avoid some warnings ([ticket 8851], [ticket 8874]).
|
||||
* Avoid exposing some detail functions via. ADL on the iterators.
|
||||
* Follow the standard by only using the allocators' construct and destroy
|
||||
methods to construct and destroy stored elements. Don't use them for internal
|
||||
data like pointers.
|
||||
|
||||
[h2 Boost 1.56.0]
|
||||
|
||||
* Fix some shadowed variable warnings ([ticket 9377]).
|
||||
* Fix allocator use in documentation ([ticket 9719]).
|
||||
* Always use prime number of buckets for integers. Fixes performance
|
||||
regression when inserting consecutive integers, although makes other
|
||||
uses slower ([ticket 9282]).
|
||||
* Only construct elements using allocators, as specified in C++11 standard.
|
||||
|
||||
[h2 Boost 1.57.0]
|
||||
|
||||
* Fix the `pointer` typedef in iterators ([ticket 10672]).
|
||||
* Fix Coverity warning
|
||||
([@https://github.com/boostorg/unordered/pull/2 GitHub #2]).
|
||||
|
||||
[h2 Boost 1.58.0]
|
||||
|
||||
* Remove unnecessary template parameter from const iterators.
|
||||
* Rename private `iterator` typedef in some iterator classes, as it
|
||||
confuses some traits classes.
|
||||
* Fix move assignment with stateful, propagate_on_container_move_assign
|
||||
allocators ([ticket 10777]).
|
||||
* Fix rare exception safety issue in move assignment.
|
||||
* Fix potential overflow when calculating number of buckets to allocate
|
||||
([@https://github.com/boostorg/unordered/pull/4 GitHub #4]).
|
||||
|
||||
[endsect]
|
||||
|
||||
+4
-5
@@ -8,12 +8,11 @@
|
||||
|
||||
Support for move semantics is implemented using Boost.Move. If rvalue
|
||||
references are available it will use them, but if not it uses a close,
|
||||
but imperfect emulation. On such compilers:
|
||||
but imperfect emulation. On such compilers you'll need to use Boost.Move
|
||||
to take advantage of using movable container elements, also note that:
|
||||
|
||||
* Non-copyable objects can be stored in the containers.
|
||||
They can be constructed in place using `emplace`, or if they support
|
||||
Boost.Move, moved into place.
|
||||
* The containers themselves are not movable.
|
||||
* Non-copyable objects can be stored in the containers, but without support
|
||||
for rvalue references the container will not be movable.
|
||||
* Argument forwarding is not perfect.
|
||||
|
||||
[endsect]
|
||||
|
||||
+2
-2
@@ -54,14 +54,14 @@ order to work with non-C++11 compilers and libraries.
|
||||
class Key, class Mapped,
|
||||
class Hash = ``[classref boost::hash]``<Key>,
|
||||
class Pred = std::equal_to<Key>,
|
||||
class Alloc = std::allocator<std::pair<Key const, Mapped> > >
|
||||
class Alloc = std::allocator<Key> >
|
||||
class ``[classref boost::unordered_map unordered_map]``;
|
||||
|
||||
template<
|
||||
class Key, class Mapped,
|
||||
class Hash = ``[classref boost::hash]``<Key>,
|
||||
class Pred = std::equal_to<Key>,
|
||||
class Alloc = std::allocator<std::pair<Key const, Mapped> > >
|
||||
class Alloc = std::allocator<Key> >
|
||||
class ``[classref boost::unordered_multimap unordered_multimap]``;
|
||||
}
|
||||
|
||||
|
||||
+8
-13
@@ -3,7 +3,7 @@
|
||||
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ]
|
||||
|
||||
[def __wang__
|
||||
[@http://web.archive.org/web/20121102023700/http://www.concentric.net/~Ttwang/tech/inthash.htm
|
||||
[@http://www.concentric.net/~Ttwang/tech/inthash.htm
|
||||
Thomas Wang's article on integer hash functions]]
|
||||
|
||||
[section:rationale Implementation Rationale]
|
||||
@@ -85,8 +85,7 @@ of 2.
|
||||
|
||||
Using a prime number of buckets, and choosing a bucket by using the modulus
|
||||
of the hash function's result will usually give a good result. The downside
|
||||
is that the required modulus operation is fairly expensive. This is what the
|
||||
containers do in most cases.
|
||||
is that the required modulus operation is fairly expensive.
|
||||
|
||||
Using a power of 2 allows for much quicker selection of the bucket
|
||||
to use, but at the expense of loosing the upper bits of the hash value.
|
||||
@@ -96,16 +95,12 @@ functions this can't be relied on.
|
||||
|
||||
To avoid this a transformation could be applied to the hash function, for an
|
||||
example see __wang__. Unfortunately, a transformation like Wang's requires
|
||||
knowledge of the number of bits in the hash value, so it isn't portable enough
|
||||
to use as a default. It can applicable in certain cases so the containers
|
||||
have a policy based implementation that can use this alternative technique.
|
||||
knowledge of the number of bits in the hash value, so it isn't portable enough.
|
||||
This leaves more expensive methods, such as Knuth's Multiplicative Method
|
||||
(mentioned in Wang's article). These don't tend to work as well as taking the
|
||||
modulus of a prime, and the extra computation required might negate
|
||||
efficiency advantage of power of 2 hash tables.
|
||||
|
||||
Currently this is only done on 64 bit architecures, where prime number
|
||||
modulus can be expensive. Although this varies depending on the architecture,
|
||||
so I probably should revisit it.
|
||||
|
||||
I'm also thinking of introducing a mechanism whereby a hash function can
|
||||
indicate that it's safe to be used directly with power of 2 buckets, in
|
||||
which case a faster plain power of 2 implementation can be used.
|
||||
So, this implementation uses a prime number for the hash table size.
|
||||
|
||||
[endsect]
|
||||
|
||||
@@ -9,9 +9,8 @@
|
||||
#ifndef BOOST_UNORDERED_ALLOCATE_HPP
|
||||
#define BOOST_UNORDERED_ALLOCATE_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
#pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/unordered/detail/fwd.hpp>
|
||||
@@ -235,11 +234,9 @@ namespace boost { namespace unordered { namespace detail {
|
||||
#pragma warning(disable:4100) // unreferenced formal parameter
|
||||
#endif
|
||||
|
||||
namespace func {
|
||||
template <class T>
|
||||
inline void destroy(T* x) {
|
||||
x->~T();
|
||||
}
|
||||
template <class T>
|
||||
inline void destroy(T* x) {
|
||||
x->~T();
|
||||
}
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
@@ -260,12 +257,13 @@ namespace boost { namespace unordered { namespace detail {
|
||||
|
||||
template <typename T, unsigned int> struct expr_test;
|
||||
template <typename T> struct expr_test<T, sizeof(char)> : T {};
|
||||
template <typename U> static char for_expr_test(U const&);
|
||||
|
||||
# define BOOST_UNORDERED_CHECK_EXPRESSION(count, result, expression) \
|
||||
template <typename U> \
|
||||
static typename boost::unordered::detail::expr_test< \
|
||||
BOOST_PP_CAT(choice, result), \
|
||||
sizeof(for_expr_test(( \
|
||||
sizeof(boost::unordered::detail::for_expr_test(( \
|
||||
(expression), \
|
||||
0)))>::type test( \
|
||||
BOOST_PP_CAT(choice, count))
|
||||
@@ -278,7 +276,6 @@ namespace boost { namespace unordered { namespace detail {
|
||||
# define BOOST_UNORDERED_HAS_FUNCTION(name, thing, args, _) \
|
||||
struct BOOST_PP_CAT(has_, name) \
|
||||
{ \
|
||||
template <typename U> static char for_expr_test(U const&); \
|
||||
BOOST_UNORDERED_CHECK_EXPRESSION(1, 1, \
|
||||
boost::unordered::detail::make< thing >().name args); \
|
||||
BOOST_UNORDERED_DEFAULT_EXPRESSION(2, 2); \
|
||||
@@ -476,9 +473,6 @@ namespace boost { namespace unordered { namespace detail {
|
||||
|
||||
# endif
|
||||
|
||||
namespace func
|
||||
{
|
||||
|
||||
template <typename Alloc>
|
||||
inline Alloc call_select_on_container_copy_construction(const Alloc& rhs,
|
||||
typename boost::enable_if_c<
|
||||
@@ -516,8 +510,6 @@ namespace boost { namespace unordered { namespace detail {
|
||||
return (std::numeric_limits<SizeType>::max)();
|
||||
}
|
||||
|
||||
} // namespace func.
|
||||
|
||||
template <typename Alloc>
|
||||
struct allocator_traits
|
||||
{
|
||||
@@ -597,7 +589,7 @@ namespace boost { namespace unordered { namespace detail {
|
||||
boost::unordered::detail::has_destroy<Alloc, T>::value>::type
|
||||
destroy(Alloc&, T* p)
|
||||
{
|
||||
boost::unordered::detail::func::destroy(p);
|
||||
boost::unordered::detail::destroy(p);
|
||||
}
|
||||
|
||||
# elif !defined(BOOST_NO_SFINAE_EXPR)
|
||||
@@ -631,7 +623,7 @@ namespace boost { namespace unordered { namespace detail {
|
||||
boost::unordered::detail::has_destroy<Alloc, T>::value>::type
|
||||
destroy(Alloc&, T* p)
|
||||
{
|
||||
boost::unordered::detail::func::destroy(p);
|
||||
boost::unordered::detail::destroy(p);
|
||||
}
|
||||
|
||||
# else
|
||||
@@ -677,22 +669,21 @@ namespace boost { namespace unordered { namespace detail {
|
||||
boost::is_same<T, value_type>::value,
|
||||
void*>::type = 0)
|
||||
{
|
||||
boost::unordered::detail::func::destroy(p);
|
||||
boost::unordered::detail::destroy(p);
|
||||
}
|
||||
|
||||
# endif
|
||||
|
||||
static size_type max_size(const Alloc& a)
|
||||
{
|
||||
return boost::unordered::detail::func::
|
||||
call_max_size<size_type>(a);
|
||||
return boost::unordered::detail::call_max_size<size_type>(a);
|
||||
}
|
||||
|
||||
// Allocator propagation on construction
|
||||
|
||||
static Alloc select_on_container_copy_construction(Alloc const& rhs)
|
||||
{
|
||||
return boost::unordered::detail::func::
|
||||
return boost::unordered::detail::
|
||||
call_select_on_container_copy_construction(rhs);
|
||||
}
|
||||
|
||||
@@ -767,7 +758,7 @@ namespace boost { namespace unordered { namespace detail {
|
||||
#endif
|
||||
|
||||
|
||||
namespace boost { namespace unordered { namespace detail { namespace func {
|
||||
namespace boost { namespace unordered { namespace detail {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// call_construct
|
||||
@@ -801,7 +792,7 @@ namespace boost { namespace unordered { namespace detail { namespace func {
|
||||
|
||||
template <typename Alloc, typename T>
|
||||
inline void destroy_value_impl(Alloc&, T* x) {
|
||||
boost::unordered::detail::func::destroy(x);
|
||||
boost::unordered::detail::destroy(x);
|
||||
}
|
||||
|
||||
|
||||
@@ -811,7 +802,7 @@ namespace boost { namespace unordered { namespace detail { namespace func {
|
||||
|
||||
template <typename Alloc, typename T>
|
||||
inline void destroy_value_impl(Alloc&, T* x) {
|
||||
boost::unordered::detail::func::destroy(x);
|
||||
boost::unordered::detail::destroy(x);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -827,7 +818,7 @@ namespace boost { namespace unordered { namespace detail { namespace func {
|
||||
template<typename Alloc, typename T> \
|
||||
void construct_from_tuple(Alloc& alloc, T* ptr, namespace_ tuple<>) \
|
||||
{ \
|
||||
boost::unordered::detail::func::call_construct(alloc, ptr); \
|
||||
boost::unordered::detail::call_construct(alloc, ptr); \
|
||||
} \
|
||||
\
|
||||
BOOST_PP_REPEAT_FROM_TO(1, n, \
|
||||
@@ -839,7 +830,7 @@ namespace boost { namespace unordered { namespace detail { namespace func {
|
||||
void construct_from_tuple(Alloc& alloc, T* ptr, \
|
||||
namespace_ tuple<BOOST_PP_ENUM_PARAMS_Z(z, n, A)> const& x) \
|
||||
{ \
|
||||
boost::unordered::detail::func::call_construct(alloc, ptr, \
|
||||
boost::unordered::detail::call_construct(alloc, ptr, \
|
||||
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_GET_TUPLE_ARG, namespace_) \
|
||||
); \
|
||||
}
|
||||
@@ -880,7 +871,7 @@ namespace boost { namespace unordered { namespace detail { namespace func {
|
||||
# define BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(n, namespace_) \
|
||||
template<typename Alloc, typename T> \
|
||||
void construct_from_tuple_impl( \
|
||||
boost::unordered::detail::func::length<0>, Alloc&, T* ptr, \
|
||||
boost::unordered::detail::length<0>, Alloc&, T* ptr, \
|
||||
namespace_ tuple<>) \
|
||||
{ \
|
||||
new ((void*) ptr) T(); \
|
||||
@@ -893,7 +884,7 @@ namespace boost { namespace unordered { namespace detail { namespace func {
|
||||
template<typename Alloc, typename T, \
|
||||
BOOST_PP_ENUM_PARAMS_Z(z, n, typename A)> \
|
||||
void construct_from_tuple_impl( \
|
||||
boost::unordered::detail::func::length<n>, Alloc&, T* ptr, \
|
||||
boost::unordered::detail::length<n>, Alloc&, T* ptr, \
|
||||
namespace_ tuple<BOOST_PP_ENUM_PARAMS_Z(z, n, A)> const& x) \
|
||||
{ \
|
||||
new ((void*) ptr) T( \
|
||||
@@ -922,7 +913,7 @@ BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(10, boost::)
|
||||
void construct_from_tuple(Alloc& alloc, T* ptr, Tuple const& x)
|
||||
{
|
||||
construct_from_tuple_impl(
|
||||
boost::unordered::detail::func::length<
|
||||
boost::unordered::detail::length<
|
||||
boost::tuples::length<Tuple>::value>(),
|
||||
alloc, ptr, x);
|
||||
}
|
||||
@@ -954,7 +945,7 @@ BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(10, boost::)
|
||||
inline void construct_value_impl(Alloc& alloc, T* address,
|
||||
BOOST_FWD_REF(Args)... args)
|
||||
{
|
||||
boost::unordered::detail::func::call_construct(alloc,
|
||||
boost::unordered::detail::call_construct(alloc,
|
||||
address, boost::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
@@ -969,9 +960,9 @@ BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(10, boost::)
|
||||
construct_value_impl(Alloc& alloc, std::pair<A, B>* address,
|
||||
BOOST_FWD_REF(A0), BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2)
|
||||
{
|
||||
boost::unordered::detail::func::construct_from_tuple(alloc,
|
||||
boost::unordered::detail::construct_from_tuple(alloc,
|
||||
boost::addressof(address->first), boost::forward<A1>(a1));
|
||||
boost::unordered::detail::func::construct_from_tuple(alloc,
|
||||
boost::unordered::detail::construct_from_tuple(alloc,
|
||||
boost::addressof(address->second), boost::forward<A2>(a2));
|
||||
}
|
||||
|
||||
@@ -1041,15 +1032,19 @@ BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(10, boost::)
|
||||
boost::unordered::detail::emplace_args3<A0, A1, A2> const& args,
|
||||
typename enable_if<use_piecewise<A0>, void*>::type = 0)
|
||||
{
|
||||
boost::unordered::detail::func::construct_from_tuple(alloc,
|
||||
boost::unordered::detail::construct_from_tuple(alloc,
|
||||
boost::addressof(address->first), args.a1);
|
||||
boost::unordered::detail::func::construct_from_tuple(alloc,
|
||||
boost::unordered::detail::construct_from_tuple(alloc,
|
||||
boost::addressof(address->second), args.a2);
|
||||
}
|
||||
|
||||
#endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES
|
||||
|
||||
}}}}
|
||||
}}}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Some helper functions for allocating & constructing
|
||||
|
||||
namespace boost { namespace unordered { namespace detail {
|
||||
|
||||
@@ -1081,10 +1076,8 @@ namespace boost { namespace unordered { namespace detail {
|
||||
|
||||
~array_constructor() {
|
||||
if (ptr_) {
|
||||
for(pointer p = ptr_; p != constructed_; ++p) {
|
||||
boost::unordered::detail::func::destroy(
|
||||
boost::addressof(*p));
|
||||
}
|
||||
for(pointer p = ptr_; p != constructed_; ++p)
|
||||
traits::destroy(alloc_, boost::addressof(*p));
|
||||
|
||||
traits::deallocate(alloc_, ptr_, length_);
|
||||
}
|
||||
@@ -1097,9 +1090,8 @@ namespace boost { namespace unordered { namespace detail {
|
||||
length_ = l;
|
||||
ptr_ = traits::allocate(alloc_, length_);
|
||||
pointer end = ptr_ + static_cast<std::ptrdiff_t>(length_);
|
||||
for(constructed_ = ptr_; constructed_ != end; ++constructed_) {
|
||||
new ((void*) boost::addressof(*constructed_)) V(v);
|
||||
}
|
||||
for(constructed_ = ptr_; constructed_ != end; ++constructed_)
|
||||
traits::construct(alloc_, boost::addressof(*constructed_), v);
|
||||
}
|
||||
|
||||
pointer get() const
|
||||
|
||||
@@ -7,17 +7,14 @@
|
||||
#ifndef BOOST_UNORDERED_DETAIL_MANAGER_HPP_INCLUDED
|
||||
#define BOOST_UNORDERED_DETAIL_MANAGER_HPP_INCLUDED
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
#pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/unordered/detail/util.hpp>
|
||||
#include <boost/unordered/detail/allocate.hpp>
|
||||
#include <boost/type_traits/aligned_storage.hpp>
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
#include <boost/type_traits/is_nothrow_move_constructible.hpp>
|
||||
#include <boost/type_traits/is_nothrow_move_assignable.hpp>
|
||||
#include <boost/swap.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/limits.hpp>
|
||||
@@ -33,10 +30,6 @@ namespace boost { namespace unordered { namespace detail {
|
||||
|
||||
}}}
|
||||
|
||||
// The 'iterator_detail' namespace was a misguided attempt at avoiding ADL
|
||||
// in the detail namespace. It didn't work because the template parameters
|
||||
// were in detail. I'm not changing it at the moment to be safe. I might
|
||||
// do in the future if I change the iterator types.
|
||||
namespace boost { namespace unordered { namespace iterator_detail {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
@@ -45,9 +38,9 @@ namespace boost { namespace unordered { namespace iterator_detail {
|
||||
// all no throw
|
||||
|
||||
template <typename Node> struct iterator;
|
||||
template <typename Node> struct c_iterator;
|
||||
template <typename Node, typename ConstNodePointer> struct c_iterator;
|
||||
template <typename Node, typename Policy> struct l_iterator;
|
||||
template <typename Node, typename Policy>
|
||||
template <typename Node, typename ConstNodePointer, typename Policy>
|
||||
struct cl_iterator;
|
||||
|
||||
// Local Iterators
|
||||
@@ -60,16 +53,16 @@ namespace boost { namespace unordered { namespace iterator_detail {
|
||||
std::forward_iterator_tag,
|
||||
typename Node::value_type,
|
||||
std::ptrdiff_t,
|
||||
typename Node::value_type*,
|
||||
typename Node::node_pointer,
|
||||
typename Node::value_type&>
|
||||
{
|
||||
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
|
||||
template <typename Node2, typename Policy2>
|
||||
template <typename Node2, typename ConstNodePointer, typename Policy2>
|
||||
friend struct boost::unordered::iterator_detail::cl_iterator;
|
||||
private:
|
||||
#endif
|
||||
typedef typename Node::node_pointer node_pointer;
|
||||
typedef boost::unordered::iterator_detail::iterator<Node> n_iterator;
|
||||
typedef boost::unordered::iterator_detail::iterator<Node> iterator;
|
||||
node_pointer ptr_;
|
||||
std::size_t bucket_;
|
||||
std::size_t bucket_count_;
|
||||
@@ -78,9 +71,9 @@ namespace boost { namespace unordered { namespace iterator_detail {
|
||||
|
||||
typedef typename Node::value_type value_type;
|
||||
|
||||
l_iterator() BOOST_NOEXCEPT : ptr_() {}
|
||||
l_iterator() : ptr_() {}
|
||||
|
||||
l_iterator(n_iterator x, std::size_t b, std::size_t c) BOOST_NOEXCEPT
|
||||
l_iterator(iterator x, std::size_t b, std::size_t c)
|
||||
: ptr_(x.node_), bucket_(b), bucket_count_(c) {}
|
||||
|
||||
value_type& operator*() const {
|
||||
@@ -105,22 +98,22 @@ namespace boost { namespace unordered { namespace iterator_detail {
|
||||
return tmp;
|
||||
}
|
||||
|
||||
bool operator==(l_iterator x) const BOOST_NOEXCEPT {
|
||||
bool operator==(l_iterator x) const {
|
||||
return ptr_ == x.ptr_;
|
||||
}
|
||||
|
||||
bool operator!=(l_iterator x) const BOOST_NOEXCEPT {
|
||||
bool operator!=(l_iterator x) const {
|
||||
return ptr_ != x.ptr_;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Node, typename Policy>
|
||||
template <typename Node, typename ConstNodePointer, typename Policy>
|
||||
struct cl_iterator
|
||||
: public boost::iterator<
|
||||
std::forward_iterator_tag,
|
||||
typename Node::value_type,
|
||||
std::ptrdiff_t,
|
||||
typename Node::value_type const*,
|
||||
ConstNodePointer,
|
||||
typename Node::value_type const&>
|
||||
{
|
||||
friend struct boost::unordered::iterator_detail::l_iterator
|
||||
@@ -128,7 +121,7 @@ namespace boost { namespace unordered { namespace iterator_detail {
|
||||
private:
|
||||
|
||||
typedef typename Node::node_pointer node_pointer;
|
||||
typedef boost::unordered::iterator_detail::iterator<Node> n_iterator;
|
||||
typedef boost::unordered::iterator_detail::iterator<Node> iterator;
|
||||
node_pointer ptr_;
|
||||
std::size_t bucket_;
|
||||
std::size_t bucket_count_;
|
||||
@@ -137,13 +130,13 @@ namespace boost { namespace unordered { namespace iterator_detail {
|
||||
|
||||
typedef typename Node::value_type value_type;
|
||||
|
||||
cl_iterator() BOOST_NOEXCEPT : ptr_() {}
|
||||
cl_iterator() : ptr_() {}
|
||||
|
||||
cl_iterator(n_iterator x, std::size_t b, std::size_t c) BOOST_NOEXCEPT :
|
||||
cl_iterator(iterator x, std::size_t b, std::size_t c) :
|
||||
ptr_(x.node_), bucket_(b), bucket_count_(c) {}
|
||||
|
||||
cl_iterator(boost::unordered::iterator_detail::l_iterator<
|
||||
Node, Policy> const& x) BOOST_NOEXCEPT :
|
||||
Node, Policy> const& x) :
|
||||
ptr_(x.ptr_), bucket_(x.bucket_), bucket_count_(x.bucket_count_)
|
||||
{}
|
||||
|
||||
@@ -169,15 +162,11 @@ namespace boost { namespace unordered { namespace iterator_detail {
|
||||
return tmp;
|
||||
}
|
||||
|
||||
friend bool operator==(cl_iterator const& x, cl_iterator const& y)
|
||||
BOOST_NOEXCEPT
|
||||
{
|
||||
friend bool operator==(cl_iterator const& x, cl_iterator const& y) {
|
||||
return x.ptr_ == y.ptr_;
|
||||
}
|
||||
|
||||
friend bool operator!=(cl_iterator const& x, cl_iterator const& y)
|
||||
BOOST_NOEXCEPT
|
||||
{
|
||||
friend bool operator!=(cl_iterator const& x, cl_iterator const& y) {
|
||||
return x.ptr_ != y.ptr_;
|
||||
}
|
||||
};
|
||||
@@ -188,15 +177,15 @@ namespace boost { namespace unordered { namespace iterator_detail {
|
||||
std::forward_iterator_tag,
|
||||
typename Node::value_type,
|
||||
std::ptrdiff_t,
|
||||
typename Node::value_type*,
|
||||
typename Node::node_pointer,
|
||||
typename Node::value_type&>
|
||||
{
|
||||
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
|
||||
template <typename>
|
||||
template <typename, typename>
|
||||
friend struct boost::unordered::iterator_detail::c_iterator;
|
||||
template <typename, typename>
|
||||
friend struct boost::unordered::iterator_detail::l_iterator;
|
||||
template <typename, typename>
|
||||
template <typename, typename, typename>
|
||||
friend struct boost::unordered::iterator_detail::cl_iterator;
|
||||
template <typename>
|
||||
friend struct boost::unordered::detail::table;
|
||||
@@ -213,9 +202,9 @@ namespace boost { namespace unordered { namespace iterator_detail {
|
||||
|
||||
typedef typename Node::value_type value_type;
|
||||
|
||||
iterator() BOOST_NOEXCEPT : node_() {}
|
||||
iterator() : node_() {}
|
||||
|
||||
explicit iterator(typename Node::link_pointer x) BOOST_NOEXCEPT :
|
||||
explicit iterator(typename Node::link_pointer x) :
|
||||
node_(static_cast<node_pointer>(x)) {}
|
||||
|
||||
value_type& operator*() const {
|
||||
@@ -223,7 +212,7 @@ namespace boost { namespace unordered { namespace iterator_detail {
|
||||
}
|
||||
|
||||
value_type* operator->() const {
|
||||
return node_->value_ptr();
|
||||
return &node_->value();
|
||||
}
|
||||
|
||||
iterator& operator++() {
|
||||
@@ -237,22 +226,22 @@ namespace boost { namespace unordered { namespace iterator_detail {
|
||||
return tmp;
|
||||
}
|
||||
|
||||
bool operator==(iterator const& x) const BOOST_NOEXCEPT {
|
||||
bool operator==(iterator const& x) const {
|
||||
return node_ == x.node_;
|
||||
}
|
||||
|
||||
bool operator!=(iterator const& x) const BOOST_NOEXCEPT {
|
||||
bool operator!=(iterator const& x) const {
|
||||
return node_ != x.node_;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Node>
|
||||
template <typename Node, typename ConstNodePointer>
|
||||
struct c_iterator
|
||||
: public boost::iterator<
|
||||
std::forward_iterator_tag,
|
||||
typename Node::value_type,
|
||||
std::ptrdiff_t,
|
||||
typename Node::value_type const*,
|
||||
ConstNodePointer,
|
||||
typename Node::value_type const&>
|
||||
{
|
||||
friend struct boost::unordered::iterator_detail::iterator<Node>;
|
||||
@@ -268,26 +257,26 @@ namespace boost { namespace unordered { namespace iterator_detail {
|
||||
private:
|
||||
#endif
|
||||
typedef typename Node::node_pointer node_pointer;
|
||||
typedef boost::unordered::iterator_detail::iterator<Node> n_iterator;
|
||||
typedef boost::unordered::iterator_detail::iterator<Node> iterator;
|
||||
node_pointer node_;
|
||||
|
||||
public:
|
||||
|
||||
typedef typename Node::value_type value_type;
|
||||
|
||||
c_iterator() BOOST_NOEXCEPT : node_() {}
|
||||
c_iterator() : node_() {}
|
||||
|
||||
explicit c_iterator(typename Node::link_pointer x) BOOST_NOEXCEPT :
|
||||
explicit c_iterator(typename Node::link_pointer x) :
|
||||
node_(static_cast<node_pointer>(x)) {}
|
||||
|
||||
c_iterator(n_iterator const& x) BOOST_NOEXCEPT : node_(x.node_) {}
|
||||
c_iterator(iterator const& x) : node_(x.node_) {}
|
||||
|
||||
value_type const& operator*() const {
|
||||
return node_->value();
|
||||
}
|
||||
|
||||
value_type const* operator->() const {
|
||||
return node_->value_ptr();
|
||||
return &node_->value();
|
||||
}
|
||||
|
||||
c_iterator& operator++() {
|
||||
@@ -301,15 +290,11 @@ namespace boost { namespace unordered { namespace iterator_detail {
|
||||
return tmp;
|
||||
}
|
||||
|
||||
friend bool operator==(c_iterator const& x, c_iterator const& y)
|
||||
BOOST_NOEXCEPT
|
||||
{
|
||||
friend bool operator==(c_iterator const& x, c_iterator const& y) {
|
||||
return x.node_ == y.node_;
|
||||
}
|
||||
|
||||
friend bool operator!=(c_iterator const& x, c_iterator const& y)
|
||||
BOOST_NOEXCEPT
|
||||
{
|
||||
friend bool operator!=(c_iterator const& x, c_iterator const& y) {
|
||||
return x.node_ != y.node_;
|
||||
}
|
||||
};
|
||||
@@ -358,7 +343,7 @@ namespace boost { namespace unordered { namespace detail {
|
||||
void construct_with_value(BOOST_UNORDERED_EMPLACE_ARGS)
|
||||
{
|
||||
construct();
|
||||
boost::unordered::detail::func::construct_value_impl(
|
||||
boost::unordered::detail::construct_value_impl(
|
||||
alloc_, node_->value_ptr(), BOOST_UNORDERED_EMPLACE_FORWARD);
|
||||
value_constructed_ = true;
|
||||
}
|
||||
@@ -367,7 +352,7 @@ namespace boost { namespace unordered { namespace detail {
|
||||
void construct_with_value2(BOOST_FWD_REF(A0) a0)
|
||||
{
|
||||
construct();
|
||||
boost::unordered::detail::func::construct_value_impl(
|
||||
boost::unordered::detail::construct_value_impl(
|
||||
alloc_, node_->value_ptr(),
|
||||
BOOST_UNORDERED_EMPLACE_ARGS1(boost::forward<A0>(a0)));
|
||||
value_constructed_ = true;
|
||||
@@ -397,12 +382,12 @@ namespace boost { namespace unordered { namespace detail {
|
||||
{
|
||||
if (node_) {
|
||||
if (value_constructed_) {
|
||||
boost::unordered::detail::func::destroy_value_impl(alloc_,
|
||||
boost::unordered::detail::destroy_value_impl(alloc_,
|
||||
node_->value_ptr());
|
||||
}
|
||||
|
||||
if (node_constructed_) {
|
||||
boost::unordered::detail::func::destroy(
|
||||
node_allocator_traits::destroy(alloc_,
|
||||
boost::addressof(*node_));
|
||||
}
|
||||
|
||||
@@ -419,7 +404,8 @@ namespace boost { namespace unordered { namespace detail {
|
||||
|
||||
node_ = node_allocator_traits::allocate(alloc_, 1);
|
||||
|
||||
new ((void*) boost::addressof(*node_)) node();
|
||||
node_allocator_traits::construct(alloc_,
|
||||
boost::addressof(*node_), node());
|
||||
node_->init(node_);
|
||||
node_constructed_ = true;
|
||||
}
|
||||
@@ -428,7 +414,7 @@ namespace boost { namespace unordered { namespace detail {
|
||||
|
||||
if (value_constructed_)
|
||||
{
|
||||
boost::unordered::detail::func::destroy_value_impl(alloc_,
|
||||
boost::unordered::detail::destroy_value_impl(alloc_,
|
||||
node_->value_ptr());
|
||||
value_constructed_ = false;
|
||||
}
|
||||
@@ -545,9 +531,9 @@ namespace boost { namespace unordered { namespace detail {
|
||||
node_pointer p = nodes_;
|
||||
nodes_ = static_cast<node_pointer>(p->next_);
|
||||
|
||||
boost::unordered::detail::func::destroy_value_impl(this->alloc_,
|
||||
boost::unordered::detail::destroy_value_impl(this->alloc_,
|
||||
p->value_ptr());
|
||||
boost::unordered::detail::func::destroy(boost::addressof(*p));
|
||||
node_allocator_traits::destroy(this->alloc_, boost::addressof(*p));
|
||||
node_allocator_traits::deallocate(this->alloc_, p, 1);
|
||||
}
|
||||
}
|
||||
@@ -665,51 +651,11 @@ namespace boost { namespace unordered { namespace detail {
|
||||
typedef mix64_policy<std::size_t> type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct pick_policy :
|
||||
pick_policy_impl<
|
||||
std::numeric_limits<std::size_t>::digits,
|
||||
std::numeric_limits<std::size_t>::radix> {};
|
||||
|
||||
// While the mix policy is generally faster, the prime policy is a lot
|
||||
// faster when a large number consecutive integers are used, because
|
||||
// there are no collisions. Since that is probably quite common, use
|
||||
// prime policy for integeral types. But not the smaller ones, as they
|
||||
// don't have enough unique values for this to be an issue.
|
||||
|
||||
template <>
|
||||
struct pick_policy<int> {
|
||||
typedef prime_policy<std::size_t> type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct pick_policy<unsigned int> {
|
||||
typedef prime_policy<std::size_t> type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct pick_policy<long> {
|
||||
typedef prime_policy<std::size_t> type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct pick_policy<unsigned long> {
|
||||
typedef prime_policy<std::size_t> type;
|
||||
};
|
||||
|
||||
// TODO: Maybe not if std::size_t is smaller than long long.
|
||||
#if !defined(BOOST_NO_LONG_LONG)
|
||||
template <>
|
||||
struct pick_policy<long long> {
|
||||
typedef prime_policy<std::size_t> type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct pick_policy<unsigned long long> {
|
||||
typedef prime_policy<std::size_t> type;
|
||||
};
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Functions
|
||||
|
||||
@@ -724,23 +670,12 @@ namespace boost { namespace unordered { namespace detail {
|
||||
// atomically assigns the new function objects in a strongly
|
||||
// exception safe manner.
|
||||
|
||||
template <class H, class P, bool NoThrowMoveAssign>
|
||||
class set_hash_functions;
|
||||
template <class H, class P> class set_hash_functions;
|
||||
|
||||
template <class H, class P>
|
||||
class functions
|
||||
{
|
||||
public:
|
||||
static const bool nothrow_move_assignable =
|
||||
boost::is_nothrow_move_assignable<H>::value &&
|
||||
boost::is_nothrow_move_assignable<P>::value;
|
||||
static const bool nothrow_move_constructible =
|
||||
boost::is_nothrow_move_constructible<H>::value &&
|
||||
boost::is_nothrow_move_constructible<P>::value;
|
||||
|
||||
private:
|
||||
friend class boost::unordered::detail::set_hash_functions<H, P,
|
||||
nothrow_move_assignable>;
|
||||
friend class boost::unordered::detail::set_hash_functions<H, P>;
|
||||
functions& operator=(functions const&);
|
||||
|
||||
typedef compressed<H, P> function_pair;
|
||||
@@ -757,40 +692,23 @@ namespace boost { namespace unordered { namespace detail {
|
||||
static_cast<void const*>(&funcs_[current_]));
|
||||
}
|
||||
|
||||
function_pair& current() {
|
||||
return *static_cast<function_pair*>(
|
||||
static_cast<void*>(&funcs_[current_]));
|
||||
}
|
||||
|
||||
void construct(bool which, H const& hf, P const& eq)
|
||||
{
|
||||
new((void*) &funcs_[which]) function_pair(hf, eq);
|
||||
}
|
||||
|
||||
void construct(bool which, function_pair const& f,
|
||||
boost::unordered::detail::false_type =
|
||||
boost::unordered::detail::false_type())
|
||||
void construct(bool which, function_pair const& f)
|
||||
{
|
||||
new((void*) &funcs_[which]) function_pair(f);
|
||||
}
|
||||
|
||||
void construct(bool which, function_pair& f,
|
||||
boost::unordered::detail::true_type)
|
||||
{
|
||||
new((void*) &funcs_[which]) function_pair(f,
|
||||
boost::unordered::detail::move_tag());
|
||||
}
|
||||
|
||||
void destroy(bool which)
|
||||
{
|
||||
boost::unordered::detail::func::destroy((function_pair*)(&funcs_[which]));
|
||||
boost::unordered::detail::destroy((function_pair*)(&funcs_[which]));
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
typedef boost::unordered::detail::set_hash_functions<H, P,
|
||||
nothrow_move_assignable> set_hash_functions;
|
||||
|
||||
functions(H const& hf, P const& eq)
|
||||
: current_(false)
|
||||
{
|
||||
@@ -803,14 +721,6 @@ namespace boost { namespace unordered { namespace detail {
|
||||
construct(current_, bf.current());
|
||||
}
|
||||
|
||||
functions(functions& bf, boost::unordered::detail::move_tag)
|
||||
: current_(false)
|
||||
{
|
||||
construct(current_, bf.current(),
|
||||
boost::unordered::detail::integral_constant<bool,
|
||||
nothrow_move_constructible>());
|
||||
}
|
||||
|
||||
~functions() {
|
||||
this->destroy(current_);
|
||||
}
|
||||
@@ -823,28 +733,26 @@ namespace boost { namespace unordered { namespace detail {
|
||||
return current().second();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <class H, class P>
|
||||
class set_hash_functions<H, P, false>
|
||||
class set_hash_functions
|
||||
{
|
||||
set_hash_functions(set_hash_functions const&);
|
||||
set_hash_functions& operator=(set_hash_functions const&);
|
||||
|
||||
typedef functions<H, P> functions_type;
|
||||
|
||||
functions_type& functions_;
|
||||
functions<H,P>& functions_;
|
||||
bool tmp_functions_;
|
||||
|
||||
public:
|
||||
|
||||
set_hash_functions(functions_type& f, H const& h, P const& p)
|
||||
set_hash_functions(functions<H,P>& f, H const& h, P const& p)
|
||||
: functions_(f),
|
||||
tmp_functions_(!f.current_)
|
||||
{
|
||||
f.construct(tmp_functions_, h, p);
|
||||
}
|
||||
|
||||
set_hash_functions(functions_type& f, functions_type const& other)
|
||||
set_hash_functions(functions<H,P>& f, functions<H,P> const& other)
|
||||
: functions_(f),
|
||||
tmp_functions_(!f.current_)
|
||||
{
|
||||
@@ -863,37 +771,6 @@ namespace boost { namespace unordered { namespace detail {
|
||||
}
|
||||
};
|
||||
|
||||
template <class H, class P>
|
||||
class set_hash_functions<H, P, true>
|
||||
{
|
||||
set_hash_functions(set_hash_functions const&);
|
||||
set_hash_functions& operator=(set_hash_functions const&);
|
||||
|
||||
typedef functions<H, P> functions_type;
|
||||
|
||||
functions_type& functions_;
|
||||
H hash_;
|
||||
P pred_;
|
||||
|
||||
public:
|
||||
|
||||
set_hash_functions(functions_type& f, H const& h, P const& p) :
|
||||
functions_(f),
|
||||
hash_(h),
|
||||
pred_(p) {}
|
||||
|
||||
set_hash_functions(functions_type& f, functions_type const& other) :
|
||||
functions_(f),
|
||||
hash_(other.hash_function()),
|
||||
pred_(other.key_eq()) {}
|
||||
|
||||
void commit()
|
||||
{
|
||||
functions_.current().first() = boost::move(hash_);
|
||||
functions_.current().second() = boost::move(pred_);
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// rvalue parameters when type can't be a BOOST_RV_REF(T) parameter
|
||||
// e.g. for int
|
||||
|
||||
@@ -7,9 +7,8 @@
|
||||
#ifndef BOOST_UNORDERED_DETAIL_EQUIVALENT_HPP_INCLUDED
|
||||
#define BOOST_UNORDERED_DETAIL_EQUIVALENT_HPP_INCLUDED
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
#pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/unordered/detail/table.hpp>
|
||||
@@ -52,16 +51,15 @@ namespace boost { namespace unordered { namespace detail {
|
||||
|
||||
template <typename T>
|
||||
struct grouped_ptr_node :
|
||||
boost::unordered::detail::value_base<T>,
|
||||
boost::unordered::detail::ptr_bucket
|
||||
{
|
||||
typedef T value_type;
|
||||
typedef boost::unordered::detail::ptr_bucket bucket_base;
|
||||
typedef grouped_ptr_node<T>* node_pointer;
|
||||
typedef ptr_bucket* link_pointer;
|
||||
|
||||
node_pointer group_prev_;
|
||||
std::size_t hash_;
|
||||
boost::unordered::detail::value_base<T> value_base_;
|
||||
|
||||
grouped_ptr_node() :
|
||||
bucket_base(),
|
||||
@@ -74,10 +72,6 @@ namespace boost { namespace unordered { namespace detail {
|
||||
group_prev_ = self;
|
||||
}
|
||||
|
||||
void* address() { return value_base_.address(); }
|
||||
value_type& value() { return value_base_.value(); }
|
||||
value_type* value_ptr() { return value_base_.value_ptr(); }
|
||||
|
||||
private:
|
||||
grouped_ptr_node& operator=(grouped_ptr_node const&);
|
||||
};
|
||||
@@ -151,7 +145,7 @@ namespace boost { namespace unordered { namespace detail {
|
||||
typedef boost::unordered::detail::grouped_table_impl<types> table;
|
||||
typedef boost::unordered::detail::set_extractor<value_type> extractor;
|
||||
|
||||
typedef typename boost::unordered::detail::pick_policy<T>::type policy;
|
||||
typedef boost::unordered::detail::pick_policy::type policy;
|
||||
};
|
||||
|
||||
template <typename A, typename K, typename M, typename H, typename P>
|
||||
@@ -176,7 +170,7 @@ namespace boost { namespace unordered { namespace detail {
|
||||
typedef boost::unordered::detail::map_extractor<key_type, value_type>
|
||||
extractor;
|
||||
|
||||
typedef typename boost::unordered::detail::pick_policy<K>::type policy;
|
||||
typedef boost::unordered::detail::pick_policy::type policy;
|
||||
};
|
||||
|
||||
template <typename Types>
|
||||
@@ -542,9 +536,9 @@ namespace boost { namespace unordered { namespace detail {
|
||||
node_pointer first_node = static_cast<node_pointer>(prev->next_);
|
||||
link_pointer end = first_node->group_prev_->next_;
|
||||
|
||||
std::size_t deleted_count = this->delete_nodes(prev, end);
|
||||
std::size_t count = this->delete_nodes(prev, end);
|
||||
this->fix_bucket(bucket_index, prev);
|
||||
return deleted_count;
|
||||
return count;
|
||||
}
|
||||
|
||||
iterator erase(c_iterator r)
|
||||
@@ -563,21 +557,21 @@ namespace boost { namespace unordered { namespace detail {
|
||||
return iterator(r2.node_);
|
||||
}
|
||||
|
||||
link_pointer erase_nodes(node_pointer i, node_pointer j)
|
||||
link_pointer erase_nodes(node_pointer begin, node_pointer end)
|
||||
{
|
||||
std::size_t bucket_index = this->hash_to_bucket(i->hash_);
|
||||
std::size_t bucket_index = this->hash_to_bucket(begin->hash_);
|
||||
|
||||
// Split the groups containing 'i' and 'j'.
|
||||
// And get the pointer to the node before i while
|
||||
// Split the groups containing 'begin' and 'end'.
|
||||
// And get the pointer to the node before begin while
|
||||
// we're at it.
|
||||
link_pointer prev = split_groups(i, j);
|
||||
link_pointer prev = split_groups(begin, end);
|
||||
|
||||
// If we don't have a 'prev' it means that i is at the
|
||||
// If we don't have a 'prev' it means that begin is at the
|
||||
// beginning of a block, so search through the blocks in the
|
||||
// same bucket.
|
||||
if (!prev) {
|
||||
prev = this->get_previous_start(bucket_index);
|
||||
while (prev->next_ != i)
|
||||
while (prev->next_ != begin)
|
||||
prev = static_cast<node_pointer>(prev->next_)->group_prev_;
|
||||
}
|
||||
|
||||
@@ -587,24 +581,24 @@ namespace boost { namespace unordered { namespace detail {
|
||||
static_cast<node_pointer>(prev->next_)->group_prev_->next_;
|
||||
this->delete_nodes(prev, group_end);
|
||||
bucket_index = this->fix_bucket(bucket_index, prev);
|
||||
} while(prev->next_ != j);
|
||||
} while(prev->next_ != end);
|
||||
|
||||
return prev;
|
||||
}
|
||||
|
||||
static link_pointer split_groups(node_pointer i, node_pointer j)
|
||||
static link_pointer split_groups(node_pointer begin, node_pointer end)
|
||||
{
|
||||
node_pointer prev = i->group_prev_;
|
||||
if (prev->next_ != i) prev = node_pointer();
|
||||
node_pointer prev = begin->group_prev_;
|
||||
if (prev->next_ != begin) prev = node_pointer();
|
||||
|
||||
if (j) {
|
||||
node_pointer first = j;
|
||||
while (first != i && first->group_prev_->next_ == first) {
|
||||
if (end) {
|
||||
node_pointer first = end;
|
||||
while (first != begin && first->group_prev_->next_ == first) {
|
||||
first = first->group_prev_;
|
||||
}
|
||||
|
||||
boost::swap(first->group_prev_, j->group_prev_);
|
||||
if (first == i) return prev;
|
||||
boost::swap(first->group_prev_, end->group_prev_);
|
||||
if (first == begin) return prev;
|
||||
}
|
||||
|
||||
if (prev) {
|
||||
@@ -612,7 +606,7 @@ namespace boost { namespace unordered { namespace detail {
|
||||
while (first->group_prev_->next_ == first) {
|
||||
first = first->group_prev_;
|
||||
}
|
||||
boost::swap(first->group_prev_, i->group_prev_);
|
||||
boost::swap(first->group_prev_, begin->group_prev_);
|
||||
}
|
||||
|
||||
return prev;
|
||||
|
||||
@@ -6,11 +6,6 @@
|
||||
#ifndef BOOST_UNORDERED_DETAIL_EXTRACT_KEY_HPP_INCLUDED
|
||||
#define BOOST_UNORDERED_DETAIL_EXTRACT_KEY_HPP_INCLUDED
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/unordered/detail/table.hpp>
|
||||
|
||||
namespace boost {
|
||||
@@ -61,19 +56,19 @@ namespace detail {
|
||||
return no_key();
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template <class... Args>
|
||||
static no_key extract(Args const&...)
|
||||
{
|
||||
return no_key();
|
||||
}
|
||||
#else
|
||||
template <class Arg>
|
||||
static no_key extract(Arg const&)
|
||||
{
|
||||
return no_key();
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template <class Arg1, class Arg2, class... Args>
|
||||
static no_key extract(Arg1 const&, Arg2 const&, Args const&...)
|
||||
{
|
||||
return no_key();
|
||||
}
|
||||
#else
|
||||
template <class Arg1, class Arg2>
|
||||
static no_key extract(Arg1 const&, Arg2 const&)
|
||||
{
|
||||
@@ -112,6 +107,14 @@ namespace detail {
|
||||
return k;
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template <class... Args>
|
||||
static no_key extract(Args const&...)
|
||||
{
|
||||
return no_key();
|
||||
}
|
||||
#else
|
||||
|
||||
static no_key extract()
|
||||
{
|
||||
return no_key();
|
||||
@@ -123,16 +126,8 @@ namespace detail {
|
||||
return no_key();
|
||||
}
|
||||
|
||||
template <class Arg1, class Arg2>
|
||||
static no_key extract(Arg1 const&, Arg2 const&)
|
||||
{
|
||||
return no_key();
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template <class Arg1, class Arg2, class Arg3, class... Args>
|
||||
static no_key extract(Arg1 const&, Arg2 const&, Arg3 const&,
|
||||
Args const&...)
|
||||
template <class Arg, class Arg1>
|
||||
static no_key extract(Arg const&, Arg1 const&)
|
||||
{
|
||||
return no_key();
|
||||
}
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
#ifndef BOOST_UNORDERED_FWD_HPP_INCLUDED
|
||||
#define BOOST_UNORDERED_FWD_HPP_INCLUDED
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
#pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace unordered
|
||||
|
||||
@@ -7,11 +7,6 @@
|
||||
#ifndef BOOST_UNORDERED_DETAIL_ALL_HPP_INCLUDED
|
||||
#define BOOST_UNORDERED_DETAIL_ALL_HPP_INCLUDED
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/unordered/detail/buckets.hpp>
|
||||
#include <boost/unordered/detail/util.hpp>
|
||||
#include <boost/type_traits/aligned_storage.hpp>
|
||||
@@ -59,10 +54,6 @@ namespace boost { namespace unordered { namespace detail {
|
||||
sizeof(value_type),
|
||||
boost::alignment_of<value_type>::value>::type data_;
|
||||
|
||||
value_base() :
|
||||
data_()
|
||||
{}
|
||||
|
||||
void* address() {
|
||||
return this;
|
||||
}
|
||||
@@ -168,7 +159,6 @@ namespace boost { namespace unordered { namespace detail {
|
||||
typedef boost::unordered::detail::functions<
|
||||
typename Types::hasher,
|
||||
typename Types::key_equal> functions;
|
||||
typedef typename functions::set_hash_functions set_hash_functions;
|
||||
|
||||
typedef typename Types::allocator allocator;
|
||||
typedef typename boost::unordered::detail::
|
||||
@@ -191,11 +181,11 @@ namespace boost { namespace unordered { namespace detail {
|
||||
typedef boost::unordered::iterator_detail::
|
||||
iterator<node> iterator;
|
||||
typedef boost::unordered::iterator_detail::
|
||||
c_iterator<node> c_iterator;
|
||||
c_iterator<node, const_node_pointer> c_iterator;
|
||||
typedef boost::unordered::iterator_detail::
|
||||
l_iterator<node, policy> l_iterator;
|
||||
typedef boost::unordered::iterator_detail::
|
||||
cl_iterator<node, policy> cl_iterator;
|
||||
cl_iterator<node, const_node_pointer, policy> cl_iterator;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Members
|
||||
@@ -266,9 +256,9 @@ namespace boost { namespace unordered { namespace detail {
|
||||
return prev ? iterator(prev->next_) : iterator();
|
||||
}
|
||||
|
||||
std::size_t hash_to_bucket(std::size_t hash_value) const
|
||||
std::size_t hash_to_bucket(std::size_t hash) const
|
||||
{
|
||||
return policy::to_bucket(bucket_count_, hash_value);
|
||||
return policy::to_bucket(bucket_count_, hash);
|
||||
}
|
||||
|
||||
float load_factor() const
|
||||
@@ -343,7 +333,7 @@ namespace boost { namespace unordered { namespace detail {
|
||||
return policy::new_bucket_count(
|
||||
boost::unordered::detail::double_to_size(floor(
|
||||
static_cast<double>(size) /
|
||||
static_cast<double>(mlf_)) + 1));
|
||||
static_cast<double>(mlf_))) + 1);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@@ -373,7 +363,7 @@ namespace boost { namespace unordered { namespace detail {
|
||||
{}
|
||||
|
||||
table(table& x, boost::unordered::detail::move_tag m) :
|
||||
functions(x, m),
|
||||
functions(x),
|
||||
allocators_(x.allocators_, m),
|
||||
bucket_count_(x.bucket_count_),
|
||||
size_(x.size_),
|
||||
@@ -387,8 +377,8 @@ namespace boost { namespace unordered { namespace detail {
|
||||
}
|
||||
|
||||
table(table& x, node_allocator const& a,
|
||||
boost::unordered::detail::move_tag m) :
|
||||
functions(x, m),
|
||||
boost::unordered::detail::move_tag) :
|
||||
functions(x),
|
||||
allocators_(a, a),
|
||||
bucket_count_(x.bucket_count_),
|
||||
size_(0),
|
||||
@@ -404,8 +394,8 @@ namespace boost { namespace unordered { namespace detail {
|
||||
{
|
||||
if (x.size_) {
|
||||
create_buckets(bucket_count_);
|
||||
copy_nodes<node_allocator> node_creator(node_alloc());
|
||||
table_impl::fill_buckets(x.begin(), *this, node_creator);
|
||||
copy_nodes<node_allocator> copy(node_alloc());
|
||||
table_impl::fill_buckets(x.begin(), *this, copy);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -418,9 +408,9 @@ namespace boost { namespace unordered { namespace detail {
|
||||
// TODO: Could pick new bucket size?
|
||||
create_buckets(bucket_count_);
|
||||
|
||||
move_nodes<node_allocator> node_creator(node_alloc());
|
||||
move_nodes<node_allocator> move(node_alloc());
|
||||
node_holder<node_allocator> nodes(x);
|
||||
table_impl::fill_buckets(nodes.begin(), *this, node_creator);
|
||||
table_impl::fill_buckets(nodes.begin(), *this, move);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -465,8 +455,6 @@ namespace boost { namespace unordered { namespace detail {
|
||||
|
||||
void swap_allocators(table& other, false_type)
|
||||
{
|
||||
boost::unordered::detail::func::ignore_unused_variable_warning(other);
|
||||
|
||||
// According to 23.2.1.8, if propagate_on_container_swap is
|
||||
// false the behaviour is undefined unless the allocators
|
||||
// are equal.
|
||||
@@ -481,8 +469,10 @@ namespace boost { namespace unordered { namespace detail {
|
||||
// Only swaps the allocators if propagate_on_container_swap
|
||||
void swap(table& x)
|
||||
{
|
||||
set_hash_functions op1(*this, x);
|
||||
set_hash_functions op2(x, *this);
|
||||
boost::unordered::detail::set_hash_functions<hasher, key_equal>
|
||||
op1(*this, x);
|
||||
boost::unordered::detail::set_hash_functions<hasher, key_equal>
|
||||
op2(x, *this);
|
||||
|
||||
// I think swap can throw if Propagate::value,
|
||||
// since the allocators' swap can throw. Not sure though.
|
||||
@@ -500,11 +490,9 @@ namespace boost { namespace unordered { namespace detail {
|
||||
op2.commit();
|
||||
}
|
||||
|
||||
// Only call with nodes allocated with the currect allocator, or
|
||||
// one that is equal to it. (Can't assert because other's
|
||||
// allocators might have already been moved).
|
||||
void move_buckets_from(table& other)
|
||||
{
|
||||
BOOST_ASSERT(node_alloc() == other.node_alloc());
|
||||
BOOST_ASSERT(!buckets_);
|
||||
buckets_ = other.buckets_;
|
||||
bucket_count_ = other.bucket_count_;
|
||||
@@ -527,9 +515,10 @@ namespace boost { namespace unordered { namespace detail {
|
||||
node_pointer n = static_cast<node_pointer>(prev->next_);
|
||||
prev->next_ = n->next_;
|
||||
|
||||
boost::unordered::detail::func::destroy_value_impl(node_alloc(),
|
||||
boost::unordered::detail::destroy_value_impl(node_alloc(),
|
||||
n->value_ptr());
|
||||
boost::unordered::detail::func::destroy(boost::addressof(*n));
|
||||
node_allocator_traits::destroy(node_alloc(),
|
||||
boost::addressof(*n));
|
||||
node_allocator_traits::deallocate(node_alloc(), n, 1);
|
||||
--size_;
|
||||
}
|
||||
@@ -556,7 +545,7 @@ namespace boost { namespace unordered { namespace detail {
|
||||
if (bucket::extra_node) {
|
||||
node_pointer n = static_cast<node_pointer>(
|
||||
get_bucket(bucket_count_)->next_);
|
||||
boost::unordered::detail::func::destroy(
|
||||
node_allocator_traits::destroy(node_alloc(),
|
||||
boost::addressof(*n));
|
||||
node_allocator_traits::deallocate(node_alloc(), n, 1);
|
||||
}
|
||||
@@ -593,7 +582,7 @@ namespace boost { namespace unordered { namespace detail {
|
||||
bucket_pointer end = get_bucket(bucket_count_ + 1);
|
||||
for(bucket_pointer it = buckets_; it != end; ++it)
|
||||
{
|
||||
boost::unordered::detail::func::destroy(
|
||||
bucket_allocator_traits::destroy(bucket_alloc(),
|
||||
boost::addressof(*it));
|
||||
}
|
||||
|
||||
@@ -648,7 +637,8 @@ namespace boost { namespace unordered { namespace detail {
|
||||
void assign(table const& x, false_type)
|
||||
{
|
||||
// Strong exception safety.
|
||||
set_hash_functions new_func_this(*this, x);
|
||||
boost::unordered::detail::set_hash_functions<hasher, key_equal>
|
||||
new_func_this(*this, x);
|
||||
new_func_this.commit();
|
||||
mlf_ = x.mlf_;
|
||||
recalculate_max_load();
|
||||
@@ -665,8 +655,8 @@ namespace boost { namespace unordered { namespace detail {
|
||||
// assign_nodes takes ownership of the container's elements,
|
||||
// assigning to them if possible, and deleting any that are
|
||||
// left over.
|
||||
assign_nodes<table> node_creator(*this);
|
||||
table_impl::fill_buckets(x.begin(), *this, node_creator);
|
||||
assign_nodes<table> assign(*this);
|
||||
table_impl::fill_buckets(x.begin(), *this, assign);
|
||||
}
|
||||
|
||||
void assign(table const& x, true_type)
|
||||
@@ -676,7 +666,8 @@ namespace boost { namespace unordered { namespace detail {
|
||||
assign(x, false_type());
|
||||
}
|
||||
else {
|
||||
set_hash_functions new_func_this(*this, x);
|
||||
boost::unordered::detail::set_hash_functions<hasher, key_equal>
|
||||
new_func_this(*this, x);
|
||||
|
||||
// Delete everything with current allocators before assigning
|
||||
// the new ones.
|
||||
@@ -692,8 +683,8 @@ namespace boost { namespace unordered { namespace detail {
|
||||
// Finally copy the elements.
|
||||
if (x.size_) {
|
||||
create_buckets(bucket_count_);
|
||||
copy_nodes<node_allocator> node_creator(node_alloc());
|
||||
table_impl::fill_buckets(x.begin(), *this, node_creator);
|
||||
copy_nodes<node_allocator> copy(node_alloc());
|
||||
table_impl::fill_buckets(x.begin(), *this, copy);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -712,28 +703,19 @@ namespace boost { namespace unordered { namespace detail {
|
||||
void move_assign(table& x, true_type)
|
||||
{
|
||||
delete_buckets();
|
||||
set_hash_functions new_func_this(*this, x);
|
||||
allocators_.move_assign(x.allocators_);
|
||||
// No throw from here.
|
||||
mlf_ = x.mlf_;
|
||||
max_load_ = x.max_load_;
|
||||
move_buckets_from(x);
|
||||
new_func_this.commit();
|
||||
move_assign_no_alloc(x);
|
||||
}
|
||||
|
||||
void move_assign(table& x, false_type)
|
||||
{
|
||||
if (node_alloc() == x.node_alloc()) {
|
||||
delete_buckets();
|
||||
set_hash_functions new_func_this(*this, x);
|
||||
// No throw from here.
|
||||
mlf_ = x.mlf_;
|
||||
max_load_ = x.max_load_;
|
||||
move_buckets_from(x);
|
||||
new_func_this.commit();
|
||||
move_assign_no_alloc(x);
|
||||
}
|
||||
else {
|
||||
set_hash_functions new_func_this(*this, x);
|
||||
boost::unordered::detail::set_hash_functions<hasher, key_equal>
|
||||
new_func_this(*this, x);
|
||||
new_func_this.commit();
|
||||
mlf_ = x.mlf_;
|
||||
recalculate_max_load();
|
||||
@@ -750,11 +732,22 @@ namespace boost { namespace unordered { namespace detail {
|
||||
// move_assign_nodes takes ownership of the container's
|
||||
// elements, assigning to them if possible, and deleting
|
||||
// any that are left over.
|
||||
move_assign_nodes<table> node_creator(*this);
|
||||
move_assign_nodes<table> assign(*this);
|
||||
node_holder<node_allocator> nodes(x);
|
||||
table_impl::fill_buckets(nodes.begin(), *this, node_creator);
|
||||
table_impl::fill_buckets(nodes.begin(), *this, assign);
|
||||
}
|
||||
}
|
||||
|
||||
void move_assign_no_alloc(table& x)
|
||||
{
|
||||
boost::unordered::detail::set_hash_functions<hasher, key_equal>
|
||||
new_func_this(*this, x);
|
||||
// No throw from here.
|
||||
mlf_ = x.mlf_;
|
||||
max_load_ = x.max_load_;
|
||||
move_buckets_from(x);
|
||||
new_func_this.commit();
|
||||
}
|
||||
|
||||
// Accessors
|
||||
|
||||
|
||||
@@ -7,9 +7,8 @@
|
||||
#ifndef BOOST_UNORDERED_DETAIL_UNIQUE_HPP_INCLUDED
|
||||
#define BOOST_UNORDERED_DETAIL_UNIQUE_HPP_INCLUDED
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
#pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/unordered/detail/table.hpp>
|
||||
@@ -28,9 +27,7 @@ namespace boost { namespace unordered { namespace detail {
|
||||
boost::unordered::detail::value_base<T>
|
||||
{
|
||||
typedef typename ::boost::unordered::detail::rebind_wrap<
|
||||
A, unique_node<A, T> >::type allocator;
|
||||
typedef typename ::boost::unordered::detail::
|
||||
allocator_traits<allocator>::pointer node_pointer;
|
||||
A, unique_node<A, T> >::type::pointer node_pointer;
|
||||
typedef node_pointer link_pointer;
|
||||
|
||||
link_pointer next_;
|
||||
@@ -51,15 +48,14 @@ namespace boost { namespace unordered { namespace detail {
|
||||
|
||||
template <typename T>
|
||||
struct ptr_node :
|
||||
boost::unordered::detail::value_base<T>,
|
||||
boost::unordered::detail::ptr_bucket
|
||||
{
|
||||
typedef T value_type;
|
||||
typedef boost::unordered::detail::ptr_bucket bucket_base;
|
||||
typedef ptr_node<T>* node_pointer;
|
||||
typedef ptr_bucket* link_pointer;
|
||||
|
||||
std::size_t hash_;
|
||||
boost::unordered::detail::value_base<T> value_base_;
|
||||
|
||||
ptr_node() :
|
||||
bucket_base(),
|
||||
@@ -70,10 +66,6 @@ namespace boost { namespace unordered { namespace detail {
|
||||
{
|
||||
}
|
||||
|
||||
void* address() { return value_base_.address(); }
|
||||
value_type& value() { return value_base_.value(); }
|
||||
value_type* value_ptr() { return value_base_.value_ptr(); }
|
||||
|
||||
private:
|
||||
ptr_node& operator=(ptr_node const&);
|
||||
};
|
||||
@@ -146,7 +138,7 @@ namespace boost { namespace unordered { namespace detail {
|
||||
typedef boost::unordered::detail::table_impl<types> table;
|
||||
typedef boost::unordered::detail::set_extractor<value_type> extractor;
|
||||
|
||||
typedef typename boost::unordered::detail::pick_policy<T>::type policy;
|
||||
typedef boost::unordered::detail::pick_policy::type policy;
|
||||
};
|
||||
|
||||
template <typename A, typename K, typename M, typename H, typename P>
|
||||
@@ -171,7 +163,7 @@ namespace boost { namespace unordered { namespace detail {
|
||||
typedef boost::unordered::detail::map_extractor<key_type, value_type>
|
||||
extractor;
|
||||
|
||||
typedef typename boost::unordered::detail::pick_policy<K>::type policy;
|
||||
typedef boost::unordered::detail::pick_policy::type policy;
|
||||
};
|
||||
|
||||
template <typename Types>
|
||||
@@ -342,6 +334,8 @@ namespace boost { namespace unordered { namespace detail {
|
||||
|
||||
value_type& operator[](key_type const& k)
|
||||
{
|
||||
typedef typename value_type::second_type mapped_type;
|
||||
|
||||
std::size_t key_hash = this->hash(k);
|
||||
iterator pos = this->find_node(key_hash, k);
|
||||
|
||||
@@ -537,9 +531,9 @@ namespace boost { namespace unordered { namespace detail {
|
||||
|
||||
link_pointer end = static_cast<node_pointer>(prev->next_)->next_;
|
||||
|
||||
std::size_t deleted_count = this->delete_nodes(prev, end);
|
||||
std::size_t count = this->delete_nodes(prev, end);
|
||||
this->fix_bucket(bucket_index, prev);
|
||||
return deleted_count;
|
||||
return count;
|
||||
}
|
||||
|
||||
iterator erase(c_iterator r)
|
||||
@@ -558,19 +552,19 @@ namespace boost { namespace unordered { namespace detail {
|
||||
return iterator(r2.node_);
|
||||
}
|
||||
|
||||
void erase_nodes(node_pointer i, node_pointer j)
|
||||
void erase_nodes(node_pointer begin, node_pointer end)
|
||||
{
|
||||
std::size_t bucket_index = this->hash_to_bucket(i->hash_);
|
||||
std::size_t bucket_index = this->hash_to_bucket(begin->hash_);
|
||||
|
||||
// Find the node before i.
|
||||
// Find the node before begin.
|
||||
link_pointer prev = this->get_previous_start(bucket_index);
|
||||
while(prev->next_ != i) prev = prev->next_;
|
||||
while(prev->next_ != begin) prev = prev->next_;
|
||||
|
||||
// Delete the nodes.
|
||||
do {
|
||||
this->delete_node(prev);
|
||||
bucket_index = this->fix_bucket(bucket_index, prev);
|
||||
} while (prev->next_ != j);
|
||||
} while (prev->next_ != end);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -7,9 +7,8 @@
|
||||
#ifndef BOOST_UNORDERED_DETAIL_UTIL_HPP_INCLUDED
|
||||
#define BOOST_UNORDERED_DETAIL_UTIL_HPP_INCLUDED
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
#pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
@@ -29,11 +28,6 @@ namespace boost { namespace unordered { namespace detail {
|
||||
struct move_tag {};
|
||||
struct empty_emplace {};
|
||||
|
||||
namespace func {
|
||||
template <class T>
|
||||
inline void ignore_unused_variable_warning(T const&) {}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// iterator SFINAE
|
||||
|
||||
|
||||
@@ -9,9 +9,8 @@
|
||||
#ifndef BOOST_UNORDERED_UNORDERED_MAP_HPP_INCLUDED
|
||||
#define BOOST_UNORDERED_UNORDERED_MAP_HPP_INCLUDED
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
#pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/unordered/unordered_map_fwd.hpp>
|
||||
@@ -118,13 +117,11 @@ namespace unordered
|
||||
|
||||
#if defined(BOOST_UNORDERED_USE_MOVE)
|
||||
unordered_map(BOOST_RV_REF(unordered_map) other)
|
||||
BOOST_NOEXCEPT_IF(table::nothrow_move_constructible)
|
||||
: table_(other.table_, boost::unordered::detail::move_tag())
|
||||
{
|
||||
}
|
||||
#elif !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
unordered_map(unordered_map&& other)
|
||||
BOOST_NOEXCEPT_IF(table::nothrow_move_constructible)
|
||||
: table_(other.table_, boost::unordered::detail::move_tag())
|
||||
{
|
||||
}
|
||||
@@ -145,7 +142,7 @@ namespace unordered
|
||||
|
||||
// Destructor
|
||||
|
||||
~unordered_map() BOOST_NOEXCEPT;
|
||||
~unordered_map();
|
||||
|
||||
// Assign
|
||||
|
||||
@@ -181,53 +178,53 @@ namespace unordered
|
||||
unordered_map& operator=(std::initializer_list<value_type>);
|
||||
#endif
|
||||
|
||||
allocator_type get_allocator() const BOOST_NOEXCEPT
|
||||
allocator_type get_allocator() const
|
||||
{
|
||||
return table_.node_alloc();
|
||||
}
|
||||
|
||||
// size and capacity
|
||||
|
||||
bool empty() const BOOST_NOEXCEPT
|
||||
bool empty() const
|
||||
{
|
||||
return table_.size_ == 0;
|
||||
}
|
||||
|
||||
size_type size() const BOOST_NOEXCEPT
|
||||
size_type size() const
|
||||
{
|
||||
return table_.size_;
|
||||
}
|
||||
|
||||
size_type max_size() const BOOST_NOEXCEPT;
|
||||
size_type max_size() const;
|
||||
|
||||
// iterators
|
||||
|
||||
iterator begin() BOOST_NOEXCEPT
|
||||
iterator begin()
|
||||
{
|
||||
return table_.begin();
|
||||
}
|
||||
|
||||
const_iterator begin() const BOOST_NOEXCEPT
|
||||
const_iterator begin() const
|
||||
{
|
||||
return table_.begin();
|
||||
}
|
||||
|
||||
iterator end() BOOST_NOEXCEPT
|
||||
iterator end()
|
||||
{
|
||||
return iterator();
|
||||
}
|
||||
|
||||
const_iterator end() const BOOST_NOEXCEPT
|
||||
const_iterator end() const
|
||||
{
|
||||
return const_iterator();
|
||||
}
|
||||
|
||||
const_iterator cbegin() const BOOST_NOEXCEPT
|
||||
const_iterator cbegin() const
|
||||
{
|
||||
return table_.begin();
|
||||
}
|
||||
|
||||
const_iterator cend() const BOOST_NOEXCEPT
|
||||
const_iterator cend() const
|
||||
{
|
||||
return const_iterator();
|
||||
}
|
||||
@@ -452,12 +449,12 @@ namespace unordered
|
||||
|
||||
// bucket interface
|
||||
|
||||
size_type bucket_count() const BOOST_NOEXCEPT
|
||||
size_type bucket_count() const
|
||||
{
|
||||
return table_.bucket_count_;
|
||||
}
|
||||
|
||||
size_type max_bucket_count() const BOOST_NOEXCEPT
|
||||
size_type max_bucket_count() const
|
||||
{
|
||||
return table_.max_bucket_count();
|
||||
}
|
||||
@@ -504,13 +501,13 @@ namespace unordered
|
||||
|
||||
// hash policy
|
||||
|
||||
float max_load_factor() const BOOST_NOEXCEPT
|
||||
float max_load_factor() const
|
||||
{
|
||||
return table_.mlf_;
|
||||
}
|
||||
|
||||
float load_factor() const BOOST_NOEXCEPT;
|
||||
void max_load_factor(float) BOOST_NOEXCEPT;
|
||||
float load_factor() const;
|
||||
void max_load_factor(float);
|
||||
void rehash(size_type);
|
||||
void reserve(size_type);
|
||||
|
||||
@@ -601,13 +598,11 @@ namespace unordered
|
||||
|
||||
#if defined(BOOST_UNORDERED_USE_MOVE)
|
||||
unordered_multimap(BOOST_RV_REF(unordered_multimap) other)
|
||||
BOOST_NOEXCEPT_IF(table::nothrow_move_constructible)
|
||||
: table_(other.table_, boost::unordered::detail::move_tag())
|
||||
{
|
||||
}
|
||||
#elif !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
unordered_multimap(unordered_multimap&& other)
|
||||
BOOST_NOEXCEPT_IF(table::nothrow_move_constructible)
|
||||
: table_(other.table_, boost::unordered::detail::move_tag())
|
||||
{
|
||||
}
|
||||
@@ -628,7 +623,7 @@ namespace unordered
|
||||
|
||||
// Destructor
|
||||
|
||||
~unordered_multimap() BOOST_NOEXCEPT;
|
||||
~unordered_multimap();
|
||||
|
||||
// Assign
|
||||
|
||||
@@ -665,53 +660,53 @@ namespace unordered
|
||||
unordered_multimap& operator=(std::initializer_list<value_type>);
|
||||
#endif
|
||||
|
||||
allocator_type get_allocator() const BOOST_NOEXCEPT
|
||||
allocator_type get_allocator() const
|
||||
{
|
||||
return table_.node_alloc();
|
||||
}
|
||||
|
||||
// size and capacity
|
||||
|
||||
bool empty() const BOOST_NOEXCEPT
|
||||
bool empty() const
|
||||
{
|
||||
return table_.size_ == 0;
|
||||
}
|
||||
|
||||
size_type size() const BOOST_NOEXCEPT
|
||||
size_type size() const
|
||||
{
|
||||
return table_.size_;
|
||||
}
|
||||
|
||||
size_type max_size() const BOOST_NOEXCEPT;
|
||||
size_type max_size() const;
|
||||
|
||||
// iterators
|
||||
|
||||
iterator begin() BOOST_NOEXCEPT
|
||||
iterator begin()
|
||||
{
|
||||
return table_.begin();
|
||||
}
|
||||
|
||||
const_iterator begin() const BOOST_NOEXCEPT
|
||||
const_iterator begin() const
|
||||
{
|
||||
return table_.begin();
|
||||
}
|
||||
|
||||
iterator end() BOOST_NOEXCEPT
|
||||
iterator end()
|
||||
{
|
||||
return iterator();
|
||||
}
|
||||
|
||||
const_iterator end() const BOOST_NOEXCEPT
|
||||
const_iterator end() const
|
||||
{
|
||||
return const_iterator();
|
||||
}
|
||||
|
||||
const_iterator cbegin() const BOOST_NOEXCEPT
|
||||
const_iterator cbegin() const
|
||||
{
|
||||
return table_.begin();
|
||||
}
|
||||
|
||||
const_iterator cend() const BOOST_NOEXCEPT
|
||||
const_iterator cend() const
|
||||
{
|
||||
return const_iterator();
|
||||
}
|
||||
@@ -932,12 +927,12 @@ namespace unordered
|
||||
|
||||
// bucket interface
|
||||
|
||||
size_type bucket_count() const BOOST_NOEXCEPT
|
||||
size_type bucket_count() const
|
||||
{
|
||||
return table_.bucket_count_;
|
||||
}
|
||||
|
||||
size_type max_bucket_count() const BOOST_NOEXCEPT
|
||||
size_type max_bucket_count() const
|
||||
{
|
||||
return table_.max_bucket_count();
|
||||
}
|
||||
@@ -984,13 +979,13 @@ namespace unordered
|
||||
|
||||
// hash policy
|
||||
|
||||
float max_load_factor() const BOOST_NOEXCEPT
|
||||
float max_load_factor() const
|
||||
{
|
||||
return table_.mlf_;
|
||||
}
|
||||
|
||||
float load_factor() const BOOST_NOEXCEPT;
|
||||
void max_load_factor(float) BOOST_NOEXCEPT;
|
||||
float load_factor() const;
|
||||
void max_load_factor(float);
|
||||
void rehash(size_type);
|
||||
void reserve(size_type);
|
||||
|
||||
@@ -1062,7 +1057,7 @@ namespace unordered
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
unordered_map<K,T,H,P,A>::~unordered_map() BOOST_NOEXCEPT {}
|
||||
unordered_map<K,T,H,P,A>::~unordered_map() {}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
unordered_map<K,T,H,P,A>::unordered_map(
|
||||
@@ -1110,7 +1105,7 @@ namespace unordered
|
||||
// size and capacity
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
std::size_t unordered_map<K,T,H,P,A>::max_size() const BOOST_NOEXCEPT
|
||||
std::size_t unordered_map<K,T,H,P,A>::max_size() const
|
||||
{
|
||||
return table_.max_size();
|
||||
}
|
||||
@@ -1279,13 +1274,13 @@ namespace unordered
|
||||
// hash policy
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
float unordered_map<K,T,H,P,A>::load_factor() const BOOST_NOEXCEPT
|
||||
float unordered_map<K,T,H,P,A>::load_factor() const
|
||||
{
|
||||
return table_.load_factor();
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
void unordered_map<K,T,H,P,A>::max_load_factor(float m) BOOST_NOEXCEPT
|
||||
void unordered_map<K,T,H,P,A>::max_load_factor(float m)
|
||||
{
|
||||
table_.max_load_factor(m);
|
||||
}
|
||||
@@ -1395,7 +1390,7 @@ namespace unordered
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
unordered_multimap<K,T,H,P,A>::~unordered_multimap() BOOST_NOEXCEPT {}
|
||||
unordered_multimap<K,T,H,P,A>::~unordered_multimap() {}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
unordered_multimap<K,T,H,P,A>::unordered_multimap(
|
||||
@@ -1443,7 +1438,7 @@ namespace unordered
|
||||
// size and capacity
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
std::size_t unordered_multimap<K,T,H,P,A>::max_size() const BOOST_NOEXCEPT
|
||||
std::size_t unordered_multimap<K,T,H,P,A>::max_size() const
|
||||
{
|
||||
return table_.max_size();
|
||||
}
|
||||
@@ -1591,13 +1586,13 @@ namespace unordered
|
||||
// hash policy
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
float unordered_multimap<K,T,H,P,A>::load_factor() const BOOST_NOEXCEPT
|
||||
float unordered_multimap<K,T,H,P,A>::load_factor() const
|
||||
{
|
||||
return table_.load_factor();
|
||||
}
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
void unordered_multimap<K,T,H,P,A>::max_load_factor(float m) BOOST_NOEXCEPT
|
||||
void unordered_multimap<K,T,H,P,A>::max_load_factor(float m)
|
||||
{
|
||||
table_.max_load_factor(m);
|
||||
}
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
#ifndef BOOST_UNORDERED_MAP_FWD_HPP_INCLUDED
|
||||
#define BOOST_UNORDERED_MAP_FWD_HPP_INCLUDED
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
#pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <boost/functional/hash_fwd.hpp>
|
||||
|
||||
@@ -9,9 +9,8 @@
|
||||
#ifndef BOOST_UNORDERED_UNORDERED_SET_HPP_INCLUDED
|
||||
#define BOOST_UNORDERED_UNORDERED_SET_HPP_INCLUDED
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
#pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/unordered/unordered_set_fwd.hpp>
|
||||
@@ -116,13 +115,11 @@ namespace unordered
|
||||
|
||||
#if defined(BOOST_UNORDERED_USE_MOVE)
|
||||
unordered_set(BOOST_RV_REF(unordered_set) other)
|
||||
BOOST_NOEXCEPT_IF(table::nothrow_move_constructible)
|
||||
: table_(other.table_, boost::unordered::detail::move_tag())
|
||||
{
|
||||
}
|
||||
#elif !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
unordered_set(unordered_set&& other)
|
||||
BOOST_NOEXCEPT_IF(table::nothrow_move_constructible)
|
||||
: table_(other.table_, boost::unordered::detail::move_tag())
|
||||
{
|
||||
}
|
||||
@@ -143,7 +140,7 @@ namespace unordered
|
||||
|
||||
// Destructor
|
||||
|
||||
~unordered_set() BOOST_NOEXCEPT;
|
||||
~unordered_set();
|
||||
|
||||
// Assign
|
||||
|
||||
@@ -179,53 +176,53 @@ namespace unordered
|
||||
unordered_set& operator=(std::initializer_list<value_type>);
|
||||
#endif
|
||||
|
||||
allocator_type get_allocator() const BOOST_NOEXCEPT
|
||||
allocator_type get_allocator() const
|
||||
{
|
||||
return table_.node_alloc();
|
||||
}
|
||||
|
||||
// size and capacity
|
||||
|
||||
bool empty() const BOOST_NOEXCEPT
|
||||
bool empty() const
|
||||
{
|
||||
return table_.size_ == 0;
|
||||
}
|
||||
|
||||
size_type size() const BOOST_NOEXCEPT
|
||||
size_type size() const
|
||||
{
|
||||
return table_.size_;
|
||||
}
|
||||
|
||||
size_type max_size() const BOOST_NOEXCEPT;
|
||||
size_type max_size() const;
|
||||
|
||||
// iterators
|
||||
|
||||
iterator begin() BOOST_NOEXCEPT
|
||||
iterator begin()
|
||||
{
|
||||
return table_.begin();
|
||||
}
|
||||
|
||||
const_iterator begin() const BOOST_NOEXCEPT
|
||||
const_iterator begin() const
|
||||
{
|
||||
return table_.begin();
|
||||
}
|
||||
|
||||
iterator end() BOOST_NOEXCEPT
|
||||
iterator end()
|
||||
{
|
||||
return iterator();
|
||||
}
|
||||
|
||||
const_iterator end() const BOOST_NOEXCEPT
|
||||
const_iterator end() const
|
||||
{
|
||||
return const_iterator();
|
||||
}
|
||||
|
||||
const_iterator cbegin() const BOOST_NOEXCEPT
|
||||
const_iterator cbegin() const
|
||||
{
|
||||
return table_.begin();
|
||||
}
|
||||
|
||||
const_iterator cend() const BOOST_NOEXCEPT
|
||||
const_iterator cend() const
|
||||
{
|
||||
return const_iterator();
|
||||
}
|
||||
@@ -437,12 +434,12 @@ namespace unordered
|
||||
|
||||
// bucket interface
|
||||
|
||||
size_type bucket_count() const BOOST_NOEXCEPT
|
||||
size_type bucket_count() const
|
||||
{
|
||||
return table_.bucket_count_;
|
||||
}
|
||||
|
||||
size_type max_bucket_count() const BOOST_NOEXCEPT
|
||||
size_type max_bucket_count() const
|
||||
{
|
||||
return table_.max_bucket_count();
|
||||
}
|
||||
@@ -489,13 +486,13 @@ namespace unordered
|
||||
|
||||
// hash policy
|
||||
|
||||
float max_load_factor() const BOOST_NOEXCEPT
|
||||
float max_load_factor() const
|
||||
{
|
||||
return table_.mlf_;
|
||||
}
|
||||
|
||||
float load_factor() const BOOST_NOEXCEPT;
|
||||
void max_load_factor(float) BOOST_NOEXCEPT;
|
||||
float load_factor() const;
|
||||
void max_load_factor(float);
|
||||
void rehash(size_type);
|
||||
void reserve(size_type);
|
||||
|
||||
@@ -585,13 +582,11 @@ namespace unordered
|
||||
|
||||
#if defined(BOOST_UNORDERED_USE_MOVE)
|
||||
unordered_multiset(BOOST_RV_REF(unordered_multiset) other)
|
||||
BOOST_NOEXCEPT_IF(table::nothrow_move_constructible)
|
||||
: table_(other.table_, boost::unordered::detail::move_tag())
|
||||
{
|
||||
}
|
||||
#elif !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
unordered_multiset(unordered_multiset&& other)
|
||||
BOOST_NOEXCEPT_IF(table::nothrow_move_constructible)
|
||||
: table_(other.table_, boost::unordered::detail::move_tag())
|
||||
{
|
||||
}
|
||||
@@ -612,7 +607,7 @@ namespace unordered
|
||||
|
||||
// Destructor
|
||||
|
||||
~unordered_multiset() BOOST_NOEXCEPT;
|
||||
~unordered_multiset();
|
||||
|
||||
// Assign
|
||||
|
||||
@@ -649,53 +644,53 @@ namespace unordered
|
||||
unordered_multiset& operator=(std::initializer_list<value_type>);
|
||||
#endif
|
||||
|
||||
allocator_type get_allocator() const BOOST_NOEXCEPT
|
||||
allocator_type get_allocator() const
|
||||
{
|
||||
return table_.node_alloc();
|
||||
}
|
||||
|
||||
// size and capacity
|
||||
|
||||
bool empty() const BOOST_NOEXCEPT
|
||||
bool empty() const
|
||||
{
|
||||
return table_.size_ == 0;
|
||||
}
|
||||
|
||||
size_type size() const BOOST_NOEXCEPT
|
||||
size_type size() const
|
||||
{
|
||||
return table_.size_;
|
||||
}
|
||||
|
||||
size_type max_size() const BOOST_NOEXCEPT;
|
||||
size_type max_size() const;
|
||||
|
||||
// iterators
|
||||
|
||||
iterator begin() BOOST_NOEXCEPT
|
||||
iterator begin()
|
||||
{
|
||||
return iterator(table_.begin());
|
||||
}
|
||||
|
||||
const_iterator begin() const BOOST_NOEXCEPT
|
||||
const_iterator begin() const
|
||||
{
|
||||
return const_iterator(table_.begin());
|
||||
}
|
||||
|
||||
iterator end() BOOST_NOEXCEPT
|
||||
iterator end()
|
||||
{
|
||||
return iterator();
|
||||
}
|
||||
|
||||
const_iterator end() const BOOST_NOEXCEPT
|
||||
const_iterator end() const
|
||||
{
|
||||
return const_iterator();
|
||||
}
|
||||
|
||||
const_iterator cbegin() const BOOST_NOEXCEPT
|
||||
const_iterator cbegin() const
|
||||
{
|
||||
return const_iterator(table_.begin());
|
||||
}
|
||||
|
||||
const_iterator cend() const BOOST_NOEXCEPT
|
||||
const_iterator cend() const
|
||||
{
|
||||
return const_iterator();
|
||||
}
|
||||
@@ -907,12 +902,12 @@ namespace unordered
|
||||
|
||||
// bucket interface
|
||||
|
||||
size_type bucket_count() const BOOST_NOEXCEPT
|
||||
size_type bucket_count() const
|
||||
{
|
||||
return table_.bucket_count_;
|
||||
}
|
||||
|
||||
size_type max_bucket_count() const BOOST_NOEXCEPT
|
||||
size_type max_bucket_count() const
|
||||
{
|
||||
return table_.max_bucket_count();
|
||||
}
|
||||
@@ -959,13 +954,13 @@ namespace unordered
|
||||
|
||||
// hash policy
|
||||
|
||||
float max_load_factor() const BOOST_NOEXCEPT
|
||||
float max_load_factor() const
|
||||
{
|
||||
return table_.mlf_;
|
||||
}
|
||||
|
||||
float load_factor() const BOOST_NOEXCEPT;
|
||||
void max_load_factor(float) BOOST_NOEXCEPT;
|
||||
float load_factor() const;
|
||||
void max_load_factor(float);
|
||||
void rehash(size_type);
|
||||
void reserve(size_type);
|
||||
|
||||
@@ -1037,7 +1032,7 @@ namespace unordered
|
||||
}
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
unordered_set<T,H,P,A>::~unordered_set() BOOST_NOEXCEPT {}
|
||||
unordered_set<T,H,P,A>::~unordered_set() {}
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
unordered_set<T,H,P,A>::unordered_set(
|
||||
@@ -1085,7 +1080,7 @@ namespace unordered
|
||||
// size and capacity
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
std::size_t unordered_set<T,H,P,A>::max_size() const BOOST_NOEXCEPT
|
||||
std::size_t unordered_set<T,H,P,A>::max_size() const
|
||||
{
|
||||
return table_.max_size();
|
||||
}
|
||||
@@ -1205,13 +1200,13 @@ namespace unordered
|
||||
// hash policy
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
float unordered_set<T,H,P,A>::load_factor() const BOOST_NOEXCEPT
|
||||
float unordered_set<T,H,P,A>::load_factor() const
|
||||
{
|
||||
return table_.load_factor();
|
||||
}
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
void unordered_set<T,H,P,A>::max_load_factor(float m) BOOST_NOEXCEPT
|
||||
void unordered_set<T,H,P,A>::max_load_factor(float m)
|
||||
{
|
||||
table_.max_load_factor(m);
|
||||
}
|
||||
@@ -1321,7 +1316,7 @@ namespace unordered
|
||||
}
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
unordered_multiset<T,H,P,A>::~unordered_multiset() BOOST_NOEXCEPT {}
|
||||
unordered_multiset<T,H,P,A>::~unordered_multiset() {}
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
unordered_multiset<T,H,P,A>::unordered_multiset(
|
||||
@@ -1369,7 +1364,7 @@ namespace unordered
|
||||
// size and capacity
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
std::size_t unordered_multiset<T,H,P,A>::max_size() const BOOST_NOEXCEPT
|
||||
std::size_t unordered_multiset<T,H,P,A>::max_size() const
|
||||
{
|
||||
return table_.max_size();
|
||||
}
|
||||
@@ -1489,13 +1484,13 @@ namespace unordered
|
||||
// hash policy
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
float unordered_multiset<T,H,P,A>::load_factor() const BOOST_NOEXCEPT
|
||||
float unordered_multiset<T,H,P,A>::load_factor() const
|
||||
{
|
||||
return table_.load_factor();
|
||||
}
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
void unordered_multiset<T,H,P,A>::max_load_factor(float m) BOOST_NOEXCEPT
|
||||
void unordered_multiset<T,H,P,A>::max_load_factor(float m)
|
||||
{
|
||||
table_.max_load_factor(m);
|
||||
}
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
#ifndef BOOST_UNORDERED_SET_FWD_HPP_INCLUDED
|
||||
#define BOOST_UNORDERED_SET_FWD_HPP_INCLUDED
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
#pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <boost/functional/hash_fwd.hpp>
|
||||
|
||||
@@ -9,9 +9,8 @@
|
||||
#ifndef BOOST_UNORDERED_MAP_HPP_INCLUDED
|
||||
#define BOOST_UNORDERED_MAP_HPP_INCLUDED
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
#pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/unordered/unordered_map.hpp>
|
||||
|
||||
@@ -9,9 +9,8 @@
|
||||
#ifndef BOOST_UNORDERED_SET_HPP_INCLUDED
|
||||
#define BOOST_UNORDERED_SET_HPP_INCLUDED
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
#pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/unordered/unordered_set.hpp>
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
{
|
||||
"key": "unordered",
|
||||
"name": "Unordered",
|
||||
"authors": [
|
||||
"Daniel James"
|
||||
],
|
||||
"maintainers": [
|
||||
"Daniel James <dnljms -at- gmail.com>"
|
||||
],
|
||||
"description": "Unordered associative containers.",
|
||||
"std": [
|
||||
"tr1"
|
||||
],
|
||||
"category": [
|
||||
"Containers"
|
||||
]
|
||||
}
|
||||
@@ -12,8 +12,13 @@ project unordered-test/exception-tests
|
||||
: requirements
|
||||
<warnings>all
|
||||
<toolset>intel:<warnings>on
|
||||
<toolset>gcc:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter -Wconversion -Wfloat-equal -Wshadow -Wno-long-long"
|
||||
<toolset>darwin:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter -Wconversion -Wfloat-equal -Wshadow"
|
||||
<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>msvc:<warnings-as-errors>on
|
||||
#<toolset>gcc:<warnings-as-errors>on
|
||||
#<toolset>darwin:<warnings-as-errors>on
|
||||
;
|
||||
|
||||
test-suite unordered-exception
|
||||
|
||||
@@ -105,8 +105,7 @@ namespace test
|
||||
i = 0; i < x1.bucket_count(); ++i)
|
||||
{
|
||||
for (BOOST_DEDUCED_TYPENAME X::const_local_iterator
|
||||
begin2 = x1.begin(i), end2 = x1.end(i);
|
||||
begin2 != end2; ++begin2)
|
||||
begin = x1.begin(i), end = x1.end(i); begin != end; ++begin)
|
||||
{
|
||||
++bucket_size;
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace test
|
||||
int count = type_ == generate_collisions ?
|
||||
1 + (generate(int_ptr) % 5) : 1;
|
||||
|
||||
for(int j = 0; j < count; ++j) {
|
||||
for(int i = 0; i < count; ++i) {
|
||||
x.push_back(value);
|
||||
}
|
||||
}
|
||||
@@ -71,7 +71,7 @@ namespace test
|
||||
int count = type_ == generate_collisions ?
|
||||
1 + (generate(int_ptr) % 5) : 1;
|
||||
|
||||
for(int j = 0; j < count; ++j) {
|
||||
for(int i = 0; i < count; ++i) {
|
||||
x.push_back(std::pair<key_type const, mapped_type>(
|
||||
key, generate(mapped_ptr)));
|
||||
}
|
||||
|
||||
+18
-47
@@ -19,12 +19,6 @@
|
||||
#pragma warning(disable:4100) // unreferenced formal parameter
|
||||
#endif
|
||||
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, == 1500)
|
||||
#define BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED 1
|
||||
#else
|
||||
#define BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED 0
|
||||
#endif
|
||||
|
||||
namespace test
|
||||
{
|
||||
namespace minimal
|
||||
@@ -35,9 +29,7 @@ namespace minimal
|
||||
class default_assignable;
|
||||
class assignable;
|
||||
|
||||
struct ampersand_operator_used {
|
||||
ampersand_operator_used() { BOOST_TEST(false); }
|
||||
};
|
||||
struct ampersand_operator_used {};
|
||||
|
||||
template <class T> class hash;
|
||||
template <class T> class equal_to;
|
||||
@@ -56,7 +48,6 @@ namespace minimal
|
||||
public:
|
||||
destructible(constructor_param const&) {}
|
||||
~destructible() {}
|
||||
void dummy_member() const {}
|
||||
private:
|
||||
destructible(destructible const&);
|
||||
destructible& operator=(destructible const&);
|
||||
@@ -68,7 +59,6 @@ namespace minimal
|
||||
copy_constructible(constructor_param const&) {}
|
||||
copy_constructible(copy_constructible const&) {}
|
||||
~copy_constructible() {}
|
||||
void dummy_member() const {}
|
||||
private:
|
||||
copy_constructible& operator=(copy_constructible const&);
|
||||
copy_constructible() {}
|
||||
@@ -88,15 +78,11 @@ namespace minimal
|
||||
{
|
||||
}
|
||||
|
||||
void dummy_member() const {}
|
||||
private:
|
||||
copy_constructible_equality_comparable& operator=(
|
||||
copy_constructible_equality_comparable const&);
|
||||
copy_constructible_equality_comparable() {}
|
||||
#if BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED
|
||||
ampersand_operator_used operator&() const {
|
||||
return ampersand_operator_used(); }
|
||||
#endif
|
||||
ampersand_operator_used operator&() const { return ampersand_operator_used(); }
|
||||
};
|
||||
|
||||
bool operator==(
|
||||
@@ -135,12 +121,9 @@ namespace minimal
|
||||
{
|
||||
}
|
||||
|
||||
void dummy_member() const {}
|
||||
|
||||
#if BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED
|
||||
private:
|
||||
ampersand_operator_used operator&() const {
|
||||
return ampersand_operator_used(); }
|
||||
#endif
|
||||
};
|
||||
|
||||
class assignable
|
||||
@@ -150,13 +133,11 @@ namespace minimal
|
||||
assignable(assignable const&) {}
|
||||
assignable& operator=(assignable const&) { return *this; }
|
||||
~assignable() {}
|
||||
void dummy_member() const {}
|
||||
|
||||
private:
|
||||
assignable() {}
|
||||
#if BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED
|
||||
ampersand_operator_used operator&() const {
|
||||
return ampersand_operator_used(); }
|
||||
#endif
|
||||
// TODO: This messes up a concept check in the tests.
|
||||
//ampersand_operator_used operator&() const { return ampersand_operator_used(); }
|
||||
};
|
||||
|
||||
struct movable_init {};
|
||||
@@ -172,7 +153,6 @@ namespace minimal
|
||||
movable1(BOOST_RV_REF(movable1)) {}
|
||||
movable1& operator=(BOOST_RV_REF(movable1)) { return *this; }
|
||||
~movable1() {}
|
||||
void dummy_member() const {}
|
||||
};
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
@@ -184,7 +164,6 @@ namespace minimal
|
||||
movable2(movable2&&) {}
|
||||
~movable2() {}
|
||||
movable2& operator=(movable2&&) { return *this; }
|
||||
void dummy_member() const {}
|
||||
private:
|
||||
movable2() {}
|
||||
movable2(movable2 const&);
|
||||
@@ -205,10 +184,8 @@ namespace minimal
|
||||
~hash() {}
|
||||
|
||||
std::size_t operator()(T const&) const { return 0; }
|
||||
#if BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED
|
||||
ampersand_operator_used operator&() const {
|
||||
return ampersand_operator_used(); }
|
||||
#endif
|
||||
private:
|
||||
ampersand_operator_used operator&() const { return ampersand_operator_used(); }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
@@ -222,10 +199,8 @@ namespace minimal
|
||||
~equal_to() {}
|
||||
|
||||
bool operator()(T const&, T const&) const { return true; }
|
||||
#if BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED
|
||||
ampersand_operator_used operator&() const {
|
||||
return ampersand_operator_used(); }
|
||||
#endif
|
||||
private:
|
||||
ampersand_operator_used operator&() const { return ampersand_operator_used(); }
|
||||
};
|
||||
|
||||
template <class T> class ptr;
|
||||
@@ -313,10 +288,9 @@ namespace minimal
|
||||
bool operator>(ptr const& x) const { return ptr_ > x.ptr_; }
|
||||
bool operator<=(ptr const& x) const { return ptr_ <= x.ptr_; }
|
||||
bool operator>=(ptr const& x) const { return ptr_ >= x.ptr_; }
|
||||
#if BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED
|
||||
ampersand_operator_used operator&() const {
|
||||
return ampersand_operator_used(); }
|
||||
#endif
|
||||
private:
|
||||
// TODO:
|
||||
//ampersand_operator_used operator&() const { return ampersand_operator_used(); }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
@@ -351,10 +325,9 @@ 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_; }
|
||||
#if BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED
|
||||
ampersand_operator_used operator&() const {
|
||||
return ampersand_operator_used(); }
|
||||
#endif
|
||||
private:
|
||||
// TODO:
|
||||
//ampersand_operator_used operator&() const { return ampersand_operator_used(); }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
@@ -414,10 +387,8 @@ namespace minimal
|
||||
#else
|
||||
private: allocator& operator=(allocator const&);
|
||||
#endif
|
||||
#if BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED
|
||||
ampersand_operator_used operator&() const {
|
||||
return ampersand_operator_used(); }
|
||||
#endif
|
||||
private:
|
||||
ampersand_operator_used operator&() const { return ampersand_operator_used(); }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
|
||||
@@ -11,8 +11,10 @@ project unordered-test/unordered
|
||||
<toolset>intel:<warnings>on
|
||||
# Would be nice to define -Wundef, but I'm getting warnings from
|
||||
# Boost.Preprocessor on trunk.
|
||||
<toolset>gcc:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter -Wconversion -Wfloat-equal -Wshadow -Wno-long-long"
|
||||
<toolset>darwin:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter -Wconversion -Wfloat-equal -Wshadow"
|
||||
<toolset>gcc:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter -Wconversion -Wno-long-long -Wfloat-equal"
|
||||
<toolset>darwin:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter -Wconversion -Wfloat-equal"
|
||||
#<toolset>gcc:<define>_GLIBCXX_DEBUG
|
||||
#<toolset>darwin:<define>_GLIBCXX_DEBUG
|
||||
;
|
||||
|
||||
test-suite unordered
|
||||
@@ -23,7 +25,6 @@ test-suite unordered
|
||||
[ run minimal_allocator.cpp ]
|
||||
[ run compile_set.cpp ]
|
||||
[ run compile_map.cpp ]
|
||||
[ run noexcept_tests.cpp ]
|
||||
[ run link_test_1.cpp link_test_2.cpp ]
|
||||
[ run incomplete_test.cpp ]
|
||||
[ run simple_tests.cpp ]
|
||||
|
||||
@@ -202,7 +202,6 @@ UNORDERED_AUTO_TEST(test2)
|
||||
unordered_unique_test(map, map_value);
|
||||
unordered_map_test(map, assignable, assignable);
|
||||
unordered_copyable_test(map, assignable, map_value, hash, equal_to);
|
||||
unordered_map_member_test(map, map_value);
|
||||
|
||||
boost::unordered_map<
|
||||
test::minimal::assignable,
|
||||
@@ -227,7 +226,6 @@ UNORDERED_AUTO_TEST(test2)
|
||||
unordered_equivalent_test(multimap, map_value);
|
||||
unordered_map_test(multimap, assignable, assignable);
|
||||
unordered_copyable_test(multimap, assignable, map_value, hash, equal_to);
|
||||
unordered_map_member_test(multimap, map_value);
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
||||
|
||||
@@ -183,7 +183,6 @@ UNORDERED_AUTO_TEST(test2)
|
||||
unordered_unique_test(set, assignable);
|
||||
unordered_set_test(set, assignable);
|
||||
unordered_copyable_test(set, assignable, assignable, hash, equal_to);
|
||||
unordered_set_member_test(set, assignable);
|
||||
|
||||
std::cout<<"Test unordered_multiset.\n";
|
||||
|
||||
@@ -196,7 +195,6 @@ UNORDERED_AUTO_TEST(test2)
|
||||
unordered_equivalent_test(multiset, assignable);
|
||||
unordered_set_test(multiset, assignable);
|
||||
unordered_copyable_test(multiset, assignable, assignable, hash, equal_to);
|
||||
unordered_set_member_test(multiset, assignable);
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(movable1_tests)
|
||||
|
||||
@@ -180,28 +180,6 @@ void unordered_set_test(X&, Key const&)
|
||||
typedef BOOST_DEDUCED_TYPENAME X::key_type key_type;
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::is_same<value_type, key_type>::value));
|
||||
|
||||
// iterator pointer / const_pointer_type
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME X::const_iterator const_iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME X::local_iterator local_iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME X::const_local_iterator const_local_iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_pointer<iterator>::type iterator_pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_pointer<const_iterator>::type
|
||||
const_iterator_pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_pointer<local_iterator>::type local_iterator_pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_pointer<const_local_iterator>::type
|
||||
const_local_iterator_pointer;
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::is_same<value_type const*, iterator_pointer>::value));
|
||||
BOOST_STATIC_ASSERT((boost::is_same<value_type const*, const_iterator_pointer>::value));
|
||||
BOOST_STATIC_ASSERT((boost::is_same<value_type const*, local_iterator_pointer>::value));
|
||||
BOOST_STATIC_ASSERT((boost::is_same<value_type const*, const_local_iterator_pointer>::value));
|
||||
}
|
||||
|
||||
template <class X, class Key, class T>
|
||||
@@ -213,30 +191,6 @@ void unordered_map_test(X& r, Key const& k, T const& v)
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_same<value_type, std::pair<key_type const, T> >::value));
|
||||
|
||||
// iterator pointer / const_pointer_type
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME X::const_iterator const_iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME X::local_iterator local_iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME X::const_local_iterator const_local_iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_pointer<iterator>::type iterator_pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_pointer<const_iterator>::type
|
||||
const_iterator_pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_pointer<local_iterator>::type local_iterator_pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_pointer<const_local_iterator>::type
|
||||
const_local_iterator_pointer;
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::is_same<value_type*, iterator_pointer>::value));
|
||||
BOOST_STATIC_ASSERT((boost::is_same<value_type const*, const_iterator_pointer>::value));
|
||||
BOOST_STATIC_ASSERT((boost::is_same<value_type*, local_iterator_pointer>::value));
|
||||
BOOST_STATIC_ASSERT((boost::is_same<value_type const*, const_local_iterator_pointer>::value));
|
||||
|
||||
// Calling functions
|
||||
|
||||
r.insert(std::pair<Key const, T>(k, v));
|
||||
|
||||
Key k_lvalue(k);
|
||||
@@ -554,23 +508,3 @@ void unordered_movable_test(X& x, Key& k, T& /* t */, Hash& hf, Pred& eq)
|
||||
sink(a8);
|
||||
sink(a10);
|
||||
}
|
||||
|
||||
template <class X, class T>
|
||||
void unordered_set_member_test(X& x, T& t)
|
||||
{
|
||||
X x1(x);
|
||||
x1.insert(t);
|
||||
x1.begin()->dummy_member();
|
||||
x1.cbegin()->dummy_member();
|
||||
}
|
||||
|
||||
template <class X, class T>
|
||||
void unordered_map_member_test(X& x, T& t)
|
||||
{
|
||||
X x1(x);
|
||||
x1.insert(t);
|
||||
x1.begin()->first.dummy_member();
|
||||
x1.cbegin()->first.dummy_member();
|
||||
x1.begin()->second.dummy_member();
|
||||
x1.cbegin()->second.dummy_member();
|
||||
}
|
||||
|
||||
@@ -117,6 +117,7 @@ struct compatible_predicate
|
||||
template <class X>
|
||||
void find_compatible_keys_test(X*, test::random_generator generator)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator
|
||||
value_iterator;
|
||||
test::random_values<X> v(500, generator);
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include "../helpers/postfix.hpp"
|
||||
|
||||
#include "../helpers/test.hpp"
|
||||
#include <boost/predef.h>
|
||||
#include <boost/next_prior.hpp>
|
||||
#include "../objects/test.hpp"
|
||||
#include "../helpers/random_values.hpp"
|
||||
@@ -364,6 +363,9 @@ void equivalent_emplace_tests1(X*, test::random_generator generator)
|
||||
template <class X>
|
||||
void move_emplace_tests(X*, test::random_generator generator)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
|
||||
typedef test::ordered<X> ordered;
|
||||
|
||||
std::cerr<<"emplace(move(value)) tests for containers with unique keys.\n";
|
||||
|
||||
X x;
|
||||
@@ -574,21 +576,6 @@ UNORDERED_TEST(map_insert_range_test2,
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
|
||||
struct initialize_from_two_ints
|
||||
{
|
||||
int a, b;
|
||||
|
||||
friend std::size_t hash_value(initialize_from_two_ints const& x)
|
||||
{
|
||||
return x.a + x.b;
|
||||
}
|
||||
|
||||
bool operator==(initialize_from_two_ints const& x) const
|
||||
{
|
||||
return a == x.a && b == x.b;
|
||||
}
|
||||
};
|
||||
|
||||
UNORDERED_AUTO_TEST(insert_initializer_list_set)
|
||||
{
|
||||
boost::unordered_set<int> set;
|
||||
@@ -596,38 +583,8 @@ UNORDERED_AUTO_TEST(insert_initializer_list_set)
|
||||
BOOST_TEST_EQ(set.size(), 3u);
|
||||
BOOST_TEST(set.find(1) != set.end());
|
||||
BOOST_TEST(set.find(4) == set.end());
|
||||
|
||||
boost::unordered_set<initialize_from_two_ints> set2;
|
||||
|
||||
#if BOOST_COMP_GNUC && BOOST_COMP_GNUC < BOOST_VERSION_NUMBER(4,5,0)
|
||||
set2.insert({{1, 2}});
|
||||
#else
|
||||
set2.insert({1, 2});
|
||||
#endif
|
||||
BOOST_TEST(set2.size() == 1);
|
||||
BOOST_TEST(set2.find({1,2}) != set2.end());
|
||||
BOOST_TEST(set2.find({2,1}) == set2.end());
|
||||
|
||||
set2.insert({{3,4},{5,6},{7,8}});
|
||||
BOOST_TEST(set2.size() == 4);
|
||||
BOOST_TEST(set2.find({1,2}) != set2.end());
|
||||
BOOST_TEST(set2.find({3,4}) != set2.end());
|
||||
BOOST_TEST(set2.find({5,6}) != set2.end());
|
||||
BOOST_TEST(set2.find({7,8}) != set2.end());
|
||||
BOOST_TEST(set2.find({8,7}) == set2.end());
|
||||
|
||||
set2.insert({{2, 1}, {3,4}});
|
||||
BOOST_TEST(set2.size() == 5);
|
||||
BOOST_TEST(set2.find({1,2}) != set2.end());
|
||||
BOOST_TEST(set2.find({2,1}) != set2.end());
|
||||
BOOST_TEST(set2.find({3,4}) != set2.end());
|
||||
BOOST_TEST(set2.find({5,6}) != set2.end());
|
||||
BOOST_TEST(set2.find({7,8}) != set2.end());
|
||||
BOOST_TEST(set2.find({8,7}) == set2.end());
|
||||
}
|
||||
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, == 1800)
|
||||
|
||||
UNORDERED_AUTO_TEST(insert_initializer_list_multiset)
|
||||
{
|
||||
boost::unordered_multiset<std::string> multiset;
|
||||
@@ -644,8 +601,6 @@ UNORDERED_AUTO_TEST(insert_initializer_list_multiset)
|
||||
BOOST_TEST_EQ(multiset.count("c"), 0u);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
UNORDERED_AUTO_TEST(insert_initializer_list_map)
|
||||
{
|
||||
boost::unordered_map<std::string, std::string> map;
|
||||
@@ -669,8 +624,8 @@ UNORDERED_AUTO_TEST(insert_initializer_list_multimap)
|
||||
|
||||
struct overloaded_constructor
|
||||
{
|
||||
overloaded_constructor(int x1_ = 1, int x2_ = 2, int x3_ = 3, int x4_ = 4)
|
||||
: x1(x1_), x2(x2_), x3(x3_), x4(x4_) {}
|
||||
overloaded_constructor(int x1 = 1, int x2 = 2, int x3 = 3, int x4 = 4)
|
||||
: x1(x1), x2(x2), x3(x3), x4(x4) {}
|
||||
|
||||
int x1, x2, x3, x4;
|
||||
|
||||
|
||||
@@ -1,125 +0,0 @@
|
||||
|
||||
// Copyright 2013 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "../helpers/prefix.hpp"
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/postfix.hpp"
|
||||
|
||||
#include "../helpers/test.hpp"
|
||||
|
||||
namespace noexcept_tests
|
||||
{
|
||||
// Test the noexcept is set correctly for the move constructor.
|
||||
|
||||
struct hash_possible_exception : boost::hash<int>
|
||||
{
|
||||
hash_possible_exception(hash_possible_exception const&) {}
|
||||
};
|
||||
|
||||
struct equal_to_possible_exception : std::equal_to<int>
|
||||
{
|
||||
equal_to_possible_exception(equal_to_possible_exception const&) {}
|
||||
};
|
||||
|
||||
UNORDERED_AUTO_TEST(test_noexcept)
|
||||
{
|
||||
#if !defined(BOOST_NO_CXX11_NOEXCEPT)
|
||||
BOOST_TEST((boost::is_nothrow_move_constructible<
|
||||
boost::unordered_set<int> >::value));
|
||||
BOOST_TEST((boost::is_nothrow_move_constructible<
|
||||
boost::unordered_multiset<int> >::value));
|
||||
BOOST_TEST((boost::is_nothrow_move_constructible<
|
||||
boost::unordered_map<int, int> >::value));
|
||||
BOOST_TEST((boost::is_nothrow_move_constructible<
|
||||
boost::unordered_multimap<int, int> >::value));
|
||||
#endif
|
||||
|
||||
BOOST_TEST((!boost::is_nothrow_move_constructible<
|
||||
boost::unordered_set<int, hash_possible_exception>
|
||||
>::value));
|
||||
BOOST_TEST((!boost::is_nothrow_move_constructible<
|
||||
boost::unordered_multiset<int, boost::hash<int>,
|
||||
equal_to_possible_exception>
|
||||
>::value));
|
||||
}
|
||||
|
||||
// Test that the move constructor does actually move without throwing
|
||||
// an exception when it claims to.
|
||||
|
||||
struct test_exception {};
|
||||
|
||||
bool throwing_test_exception = false;
|
||||
void test_throw(char const* name) {
|
||||
if (throwing_test_exception) {
|
||||
std::cerr << "Throw exception in: " << name << std::endl;
|
||||
throw test_exception();
|
||||
}
|
||||
}
|
||||
|
||||
class hash_nothrow_move : boost::hash<int>
|
||||
{
|
||||
BOOST_COPYABLE_AND_MOVABLE(hash_nothrow_move)
|
||||
|
||||
typedef boost::hash<int> base;
|
||||
public:
|
||||
hash_nothrow_move(BOOST_RV_REF(hash_nothrow_move))
|
||||
BOOST_NOEXCEPT {}
|
||||
|
||||
hash_nothrow_move() { test_throw("Constructor"); }
|
||||
hash_nothrow_move(hash_nothrow_move const&) { test_throw("Copy"); }
|
||||
hash_nothrow_move& operator=(hash_nothrow_move const&)
|
||||
{ test_throw("Assign"); return *this; }
|
||||
std::size_t operator()(int x) const
|
||||
{ test_throw("Operator"); return static_cast<base const&>(*this)(x); }
|
||||
};
|
||||
|
||||
class equal_to_nothrow_move : std::equal_to<int>
|
||||
{
|
||||
BOOST_COPYABLE_AND_MOVABLE(equal_to_nothrow_move)
|
||||
|
||||
typedef std::equal_to<int> base;
|
||||
public:
|
||||
equal_to_nothrow_move(BOOST_RV_REF(equal_to_nothrow_move))
|
||||
BOOST_NOEXCEPT {}
|
||||
equal_to_nothrow_move() { test_throw("Constructor"); }
|
||||
equal_to_nothrow_move(equal_to_nothrow_move const&)
|
||||
{ test_throw("Copy"); }
|
||||
equal_to_nothrow_move& operator=(equal_to_nothrow_move const&)
|
||||
{ test_throw("Assign"); return *this; }
|
||||
std::size_t operator()(int x, int y) const
|
||||
{ test_throw("Operator"); return static_cast<base const&>(*this)(x, y); }
|
||||
};
|
||||
|
||||
UNORDERED_AUTO_TEST(test_no_throw_when_noexcept)
|
||||
{
|
||||
typedef boost::unordered_set<int,
|
||||
hash_nothrow_move, equal_to_nothrow_move> throwing_set;
|
||||
|
||||
if (boost::is_nothrow_move_constructible<throwing_set>::value)
|
||||
{
|
||||
throwing_test_exception = false;
|
||||
|
||||
throwing_set x1;
|
||||
x1.insert(10);
|
||||
x1.insert(50);
|
||||
|
||||
|
||||
try {
|
||||
throwing_test_exception = true;
|
||||
|
||||
throwing_set x2 = boost::move(x1);
|
||||
BOOST_TEST(x2.size() == 2);
|
||||
BOOST_TEST(*x2.begin() == 10 || *x2.begin() == 50);
|
||||
} catch(test_exception) {
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
|
||||
throwing_test_exception = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
||||
@@ -119,20 +119,6 @@ namespace unnecessary_copy_tests
|
||||
}
|
||||
}
|
||||
|
||||
// Boost.Move doesn't seem to work very well on this compiler.
|
||||
// For example for:
|
||||
//
|
||||
// T x;
|
||||
//
|
||||
// It will default construct T, and then move it in.
|
||||
// For 'T const' it seems to copy.
|
||||
|
||||
#if defined(__IBMCPP__) && __IBMCPP__ <= 1210
|
||||
#define EXTRA_CONSTRUCT_COST 1
|
||||
#else
|
||||
#define EXTRA_CONSTRUCT_COST 0
|
||||
#endif
|
||||
|
||||
#define COPY_COUNT(n) \
|
||||
if(::unnecessary_copy_tests::count_copies::copies != n) { \
|
||||
BOOST_ERROR("Wrong number of copies."); \
|
||||
@@ -164,13 +150,9 @@ namespace unnecessary_copy_tests
|
||||
BOOST_ERROR("Wrong number of moves."); \
|
||||
std::cerr \
|
||||
<< "Number of moves: " \
|
||||
<< ::unnecessary_copy_tests::count_copies::moves \
|
||||
<< ::unnecessary_copy_tests::count_copies::copies \
|
||||
<< " expecting: [" << a << ", " << b << "]" << std::endl; \
|
||||
}
|
||||
#define COPY_COUNT_EXTRA(a, b) \
|
||||
COPY_COUNT_RANGE(a, a + b * EXTRA_CONSTRUCT_COST)
|
||||
#define MOVE_COUNT_EXTRA(a, b) \
|
||||
MOVE_COUNT_RANGE(a, a + b * EXTRA_CONSTRUCT_COST)
|
||||
|
||||
namespace unnecessary_copy_tests
|
||||
{
|
||||
@@ -225,29 +207,13 @@ namespace unnecessary_copy_tests
|
||||
UNORDERED_TEST(unnecessary_copy_emplace_rvalue_test,
|
||||
((set)(multiset)(map)(multimap)))
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
template <class T>
|
||||
void unnecessary_copy_emplace_std_move_test(T*)
|
||||
void unnecessary_copy_emplace_move_test(T*)
|
||||
{
|
||||
reset();
|
||||
T x;
|
||||
BOOST_DEDUCED_TYPENAME T::value_type a;
|
||||
COPY_COUNT(1); MOVE_COUNT(0);
|
||||
x.emplace(std::move(a));
|
||||
COPY_COUNT(1); MOVE_COUNT(1);
|
||||
}
|
||||
|
||||
UNORDERED_TEST(unnecessary_copy_emplace_std_move_test,
|
||||
((set)(multiset)(map)(multimap)))
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
void unnecessary_copy_emplace_boost_move_test(T*)
|
||||
{
|
||||
reset();
|
||||
T x;
|
||||
BOOST_DEDUCED_TYPENAME T::value_type a;
|
||||
COPY_COUNT(1); MOVE_COUNT_EXTRA(0, 1);
|
||||
x.emplace(boost::move(a));
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
COPY_COUNT(1); MOVE_COUNT(1);
|
||||
@@ -257,7 +223,7 @@ namespace unnecessary_copy_tests
|
||||
#endif
|
||||
}
|
||||
|
||||
UNORDERED_TEST(unnecessary_copy_emplace_boost_move_test,
|
||||
UNORDERED_TEST(unnecessary_copy_emplace_move_test,
|
||||
((set)(multiset)(map)(multimap)))
|
||||
|
||||
template <class T>
|
||||
@@ -281,10 +247,10 @@ namespace unnecessary_copy_tests
|
||||
T x;
|
||||
COPY_COUNT(0); MOVE_COUNT(0);
|
||||
BOOST_DEDUCED_TYPENAME T::value_type a;
|
||||
COPY_COUNT(1); MOVE_COUNT_EXTRA(0, 1);
|
||||
COPY_COUNT(1); MOVE_COUNT(0);
|
||||
x.emplace(boost::move(a));
|
||||
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
COPY_COUNT(2); MOVE_COUNT_EXTRA(0, 1);
|
||||
COPY_COUNT(2); MOVE_COUNT(0);
|
||||
#else
|
||||
COPY_COUNT(1); MOVE_COUNT(1);
|
||||
#endif
|
||||
@@ -398,7 +364,7 @@ namespace unnecessary_copy_tests
|
||||
// TODO: Run tests for pairs without const etc.
|
||||
std::pair<count_copies const, count_copies> a;
|
||||
x.emplace(a);
|
||||
COPY_COUNT_EXTRA(4, 1); MOVE_COUNT_EXTRA(0, 1);
|
||||
COPY_COUNT(4); MOVE_COUNT(0);
|
||||
|
||||
//
|
||||
// 0 arguments
|
||||
@@ -408,7 +374,7 @@ namespace unnecessary_copy_tests
|
||||
// COPY_COUNT(1) would be okay here.
|
||||
reset();
|
||||
x.emplace();
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, == 1700)
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, >= 1700)
|
||||
// This is a little odd, Visual C++ 11 seems to move the pair, which
|
||||
// results in one copy (for the const key) and one move (for the
|
||||
// non-const mapped value). Since 'emplace(boost::move(a))' (see below)
|
||||
@@ -416,7 +382,7 @@ namespace unnecessary_copy_tests
|
||||
// Visual C++ 11 handles calling move for default arguments.
|
||||
COPY_COUNT(3); MOVE_COUNT(1);
|
||||
# else
|
||||
COPY_COUNT_EXTRA(2, 1); MOVE_COUNT_EXTRA(0, 1);
|
||||
COPY_COUNT(2); MOVE_COUNT(0);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@@ -441,8 +407,9 @@ namespace unnecessary_copy_tests
|
||||
x.emplace(source<std::pair<count_copies, count_copies> >());
|
||||
COPY_COUNT(2); MOVE_COUNT(source_pair_cost);
|
||||
|
||||
#if !(defined(__GNUC__) && __cplusplus < 199900L) && \
|
||||
!(defined(_MSC_VER) && _MSC_VER < 1600)
|
||||
#if (defined(__GNUC__) && __GNUC__ > 4) || \
|
||||
(defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ > 2) || \
|
||||
(defined(BOOST_MSVC) && BOOST_MSVC >= 1600 )
|
||||
count_copies part;
|
||||
reset();
|
||||
std::pair<count_copies const&, count_copies const&> a_ref(part, part);
|
||||
@@ -509,9 +476,8 @@ namespace unnecessary_copy_tests
|
||||
COPY_COUNT(tuple_copy_cost);
|
||||
MOVE_COUNT(tuple_move_cost);
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_TUPLE) && \
|
||||
!(defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ < 6) && \
|
||||
!(defined(BOOST_MSVC) && BOOST_MSVC < 1700)
|
||||
#if defined(__GNUC__) && __GNUC__ > 4 || \
|
||||
defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ >= 6
|
||||
reset();
|
||||
x.emplace(boost::unordered::piecewise_construct,
|
||||
std::forward_as_tuple(b.first),
|
||||
|
||||
Reference in New Issue
Block a user