mirror of
https://github.com/boostorg/unordered.git
synced 2026-08-07 14:14:07 +02:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 79900798e6 |
@@ -235,9 +235,4 @@ C++11 support has resulted in some breaking changes:
|
||||
* 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.
|
||||
|
||||
[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]
|
||||
|
||||
@@ -234,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)
|
||||
@@ -259,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))
|
||||
@@ -277,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); \
|
||||
@@ -475,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<
|
||||
@@ -515,8 +510,6 @@ namespace boost { namespace unordered { namespace detail {
|
||||
return (std::numeric_limits<SizeType>::max)();
|
||||
}
|
||||
|
||||
} // namespace func.
|
||||
|
||||
template <typename Alloc>
|
||||
struct allocator_traits
|
||||
{
|
||||
@@ -596,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)
|
||||
@@ -630,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
|
||||
@@ -676,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);
|
||||
}
|
||||
|
||||
@@ -766,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
|
||||
@@ -800,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);
|
||||
}
|
||||
|
||||
|
||||
@@ -810,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
|
||||
@@ -826,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, \
|
||||
@@ -838,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_) \
|
||||
); \
|
||||
}
|
||||
@@ -953,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)...);
|
||||
}
|
||||
|
||||
@@ -968,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));
|
||||
}
|
||||
|
||||
@@ -1040,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 {
|
||||
|
||||
|
||||
@@ -32,10 +32,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 {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
@@ -77,9 +73,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(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 {
|
||||
@@ -104,11 +100,11 @@ 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_;
|
||||
}
|
||||
};
|
||||
@@ -136,13 +132,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(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_)
|
||||
{}
|
||||
|
||||
@@ -168,15 +164,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_;
|
||||
}
|
||||
};
|
||||
@@ -212,9 +204,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 {
|
||||
@@ -236,11 +228,11 @@ 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_;
|
||||
}
|
||||
};
|
||||
@@ -274,12 +266,12 @@ namespace boost { namespace unordered { namespace iterator_detail {
|
||||
|
||||
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(iterator const& x) BOOST_NOEXCEPT : node_(x.node_) {}
|
||||
c_iterator(iterator const& x) : node_(x.node_) {}
|
||||
|
||||
value_type const& operator*() const {
|
||||
return node_->value();
|
||||
@@ -300,15 +292,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_;
|
||||
}
|
||||
};
|
||||
@@ -357,7 +345,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;
|
||||
}
|
||||
@@ -366,7 +354,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;
|
||||
@@ -396,7 +384,7 @@ 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());
|
||||
}
|
||||
|
||||
@@ -428,7 +416,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,7 +533,7 @@ 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());
|
||||
node_allocator_traits::destroy(this->alloc_, boost::addressof(*p));
|
||||
node_allocator_traits::deallocate(this->alloc_, p, 1);
|
||||
@@ -727,23 +715,20 @@ namespace boost { namespace unordered { namespace detail {
|
||||
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)
|
||||
boost::unordered::detail::move_tag m)
|
||||
{
|
||||
new((void*) &funcs_[which]) function_pair(f,
|
||||
boost::unordered::detail::move_tag());
|
||||
new((void*) &funcs_[which]) function_pair(f, m);
|
||||
}
|
||||
|
||||
void destroy(bool which)
|
||||
{
|
||||
boost::unordered::detail::func::destroy((function_pair*)(&funcs_[which]));
|
||||
boost::unordered::detail::destroy((function_pair*)(&funcs_[which]));
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -763,12 +748,15 @@ namespace boost { namespace unordered { namespace detail {
|
||||
construct(current_, bf.current());
|
||||
}
|
||||
|
||||
functions(functions& bf, boost::unordered::detail::move_tag)
|
||||
functions(functions& bf, boost::unordered::detail::move_tag m)
|
||||
: current_(false)
|
||||
{
|
||||
construct(current_, bf.current(),
|
||||
boost::unordered::detail::integral_constant<bool,
|
||||
nothrow_move_constructible>());
|
||||
if (nothrow_move_constructible) {
|
||||
construct(current_, bf.current(), m);
|
||||
}
|
||||
else {
|
||||
construct(current_, bf.current());
|
||||
}
|
||||
}
|
||||
|
||||
~functions() {
|
||||
|
||||
@@ -56,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&)
|
||||
{
|
||||
@@ -107,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();
|
||||
@@ -118,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();
|
||||
}
|
||||
|
||||
@@ -456,8 +456,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.
|
||||
@@ -516,7 +514,7 @@ 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());
|
||||
node_allocator_traits::destroy(node_alloc(),
|
||||
boost::addressof(*n));
|
||||
|
||||
@@ -334,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);
|
||||
|
||||
|
||||
@@ -28,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
|
||||
|
||||
|
||||
@@ -117,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())
|
||||
{
|
||||
}
|
||||
@@ -144,7 +142,7 @@ namespace unordered
|
||||
|
||||
// Destructor
|
||||
|
||||
~unordered_map() BOOST_NOEXCEPT;
|
||||
~unordered_map();
|
||||
|
||||
// Assign
|
||||
|
||||
@@ -600,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())
|
||||
{
|
||||
}
|
||||
@@ -627,7 +623,7 @@ namespace unordered
|
||||
|
||||
// Destructor
|
||||
|
||||
~unordered_multimap() BOOST_NOEXCEPT;
|
||||
~unordered_multimap();
|
||||
|
||||
// Assign
|
||||
|
||||
@@ -1061,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(
|
||||
@@ -1394,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(
|
||||
|
||||
@@ -115,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())
|
||||
{
|
||||
}
|
||||
@@ -142,7 +140,7 @@ namespace unordered
|
||||
|
||||
// Destructor
|
||||
|
||||
~unordered_set() BOOST_NOEXCEPT;
|
||||
~unordered_set();
|
||||
|
||||
// Assign
|
||||
|
||||
@@ -584,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())
|
||||
{
|
||||
}
|
||||
@@ -611,7 +607,7 @@ namespace unordered
|
||||
|
||||
// Destructor
|
||||
|
||||
~unordered_multiset() BOOST_NOEXCEPT;
|
||||
~unordered_multiset();
|
||||
|
||||
// Assign
|
||||
|
||||
@@ -1036,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(
|
||||
@@ -1320,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(
|
||||
|
||||
@@ -25,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 ]
|
||||
|
||||
@@ -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& x) { 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& x)
|
||||
{ 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()
|
||||
Reference in New Issue
Block a user