mirror of
https://github.com/boostorg/unordered.git
synced 2026-08-07 14:14:07 +02:00
Compare commits
42 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8f51dc6082 | |||
| 79deac97dd | |||
| e92f7d86c1 | |||
| 93a33ba15f | |||
| ad353c8e3d | |||
| 09717ffca4 | |||
| ce4b840299 | |||
| 5a8df0ebe4 | |||
| 6029d1cfd0 | |||
| 3fe46a1769 | |||
| 5490bcfe95 | |||
| 078c562b6c | |||
| 88612a8be4 | |||
| 37a6903831 | |||
| 8017d9e684 | |||
| 609ae6cb4e | |||
| 603f785739 | |||
| 992f9ccf21 | |||
| e250fb44f6 | |||
| 9767d86d97 | |||
| 7687c99708 | |||
| 81cc773013 | |||
| cdb887e880 | |||
| 041fee64df | |||
| e3dd1f276e | |||
| 0769ecd70d | |||
| 2be69b3eb9 | |||
| bc601e34d2 | |||
| 79e39d9d43 | |||
| 6bc57bd398 | |||
| 1bca2df642 | |||
| 59cbe3d483 | |||
| 21f2522695 | |||
| 3720b0be58 | |||
| 413b45a62e | |||
| 7b8e3d01de | |||
| b4a3c6f460 | |||
| 1d4845d6b8 | |||
| c26acdba15 | |||
| 3f42a56bae | |||
| 144a0c1791 | |||
| cc2b1a1ef1 |
+38
@@ -0,0 +1,38 @@
|
||||
# Copyright (C) 2016 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)
|
||||
|
||||
# Use Trusty to get a reasonably recent version of Boost.
|
||||
sudo: required
|
||||
dist: trusty
|
||||
|
||||
language: c++
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libboost-dev
|
||||
- libboost-tools-dev
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- compiler: gcc
|
||||
env: BJAM_TOOLSET=gcc
|
||||
- compiler: gcc
|
||||
env: BJAM_TOOLSET=gcc-std11
|
||||
- compiler: clang
|
||||
env: BJAM_TOOLSET=clang
|
||||
- compiler: clang
|
||||
env: BJAM_TOOLSET=clang-std11
|
||||
|
||||
before_script:
|
||||
- |
|
||||
echo "using gcc : : g++-4.8 -Werror --std=c++03 -fsanitize=address ;" > ~/user-config.jam
|
||||
echo "using gcc : std11 : g++-4.8 -Werror --std=c++11 -fsanitize=address ;" >> ~/user-config.jam
|
||||
echo "using clang : : clang++ -Werror --std=c++03 -fsanitize=address ;" >> ~/user-config.jam
|
||||
echo "using clang : std11 : clang++ -Werror --std=c++11 -fsanitize=address ;" >> ~/user-config.jam
|
||||
- cat ~/user-config.jam
|
||||
- touch Jamroot.jam
|
||||
|
||||
script:
|
||||
- cd test && bjam ${BJAM_TOOLSET} include=${TRAVIS_BUILD_DIR}/include
|
||||
@@ -269,4 +269,14 @@ C++11 support has resulted in some breaking changes:
|
||||
* Fix potential overflow when calculating number of buckets to allocate
|
||||
([@https://github.com/boostorg/unordered/pull/4 GitHub #4]).
|
||||
|
||||
[h2 Boost 1.62.0]
|
||||
|
||||
* Remove use of deprecated `boost::iterator`.
|
||||
* Remove `BOOST_NO_STD_DISTANCE` workaround.
|
||||
* Remove `BOOST_UNORDERED_DEPRECATED_EQUALITY` warning.
|
||||
* Simpler implementation of assignment, fixes an exception safety issue
|
||||
for `unordered_multiset` and `unordered_multimap`. Might be a little slower.
|
||||
* Stop using return value SFINAE which some older compilers have issues
|
||||
with.
|
||||
|
||||
[endsect]
|
||||
|
||||
@@ -14,23 +14,31 @@
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
// Some of these includes are required for other detail headers.
|
||||
#include <boost/unordered/detail/fwd.hpp>
|
||||
#include <boost/move/move.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/preprocessor/inc.hpp>
|
||||
#include <boost/preprocessor/dec.hpp>
|
||||
#include <boost/preprocessor/repetition/enum.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
|
||||
#include <boost/type_traits/is_class.hpp>
|
||||
#include <boost/type_traits/add_lvalue_reference.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/tuple/tuple.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/utility/addressof.hpp>
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
#include <boost/detail/select_type.hpp>
|
||||
#include <boost/swap.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/limits.hpp>
|
||||
#include <iterator>
|
||||
#include <utility>
|
||||
#include <cmath>
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_TUPLE)
|
||||
#include <tuple>
|
||||
@@ -808,6 +816,18 @@ namespace boost { namespace unordered { namespace detail { namespace func {
|
||||
# endif
|
||||
|
||||
#else
|
||||
template <typename Alloc, typename T>
|
||||
inline void call_construct(Alloc&, T* address)
|
||||
{
|
||||
new ((void*) address) T();
|
||||
}
|
||||
|
||||
template <typename Alloc, typename T, typename A0>
|
||||
inline void call_construct(Alloc&, T* address,
|
||||
BOOST_FWD_REF(A0) a0)
|
||||
{
|
||||
new ((void*) address) T(boost::forward<A0>(a0));
|
||||
}
|
||||
|
||||
template <typename Alloc, typename T>
|
||||
inline void destroy_value_impl(Alloc&, T* x) {
|
||||
@@ -1053,74 +1073,182 @@ BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(10, boost::)
|
||||
|
||||
namespace boost { namespace unordered { namespace detail {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// array_constructor
|
||||
//
|
||||
// Allocate and construct an array in an exception safe manner, and
|
||||
// clean up if an exception is thrown before the container takes charge
|
||||
// of it.
|
||||
// Node construction
|
||||
|
||||
template <typename Allocator>
|
||||
struct array_constructor
|
||||
template <typename NodeAlloc>
|
||||
struct node_constructor
|
||||
{
|
||||
typedef boost::unordered::detail::allocator_traits<Allocator> traits;
|
||||
typedef typename traits::pointer pointer;
|
||||
typedef NodeAlloc node_allocator;
|
||||
typedef boost::unordered::detail::allocator_traits<NodeAlloc>
|
||||
node_allocator_traits;
|
||||
typedef typename node_allocator_traits::value_type node;
|
||||
typedef typename node_allocator_traits::pointer node_pointer;
|
||||
typedef typename node::value_type value_type;
|
||||
|
||||
Allocator& alloc_;
|
||||
pointer ptr_;
|
||||
pointer constructed_;
|
||||
std::size_t length_;
|
||||
node_allocator& alloc_;
|
||||
node_pointer node_;
|
||||
bool node_constructed_;
|
||||
|
||||
array_constructor(Allocator& a)
|
||||
: alloc_(a), ptr_(), constructed_(), length_(0)
|
||||
node_constructor(node_allocator& n) :
|
||||
alloc_(n),
|
||||
node_(),
|
||||
node_constructed_(false)
|
||||
{
|
||||
constructed_ = pointer();
|
||||
ptr_ = pointer();
|
||||
}
|
||||
|
||||
~array_constructor() {
|
||||
if (ptr_) {
|
||||
for(pointer p = ptr_; p != constructed_; ++p) {
|
||||
boost::unordered::detail::func::destroy(
|
||||
boost::addressof(*p));
|
||||
}
|
||||
~node_constructor();
|
||||
|
||||
traits::deallocate(alloc_, ptr_, length_);
|
||||
}
|
||||
}
|
||||
void create_node();
|
||||
|
||||
template <typename V>
|
||||
void construct(V const& v, std::size_t l)
|
||||
// no throw
|
||||
node_pointer release()
|
||||
{
|
||||
BOOST_ASSERT(!ptr_);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
pointer get() const
|
||||
{
|
||||
return ptr_;
|
||||
}
|
||||
|
||||
pointer release()
|
||||
{
|
||||
pointer p(ptr_);
|
||||
ptr_ = pointer();
|
||||
BOOST_ASSERT(node_ && node_constructed_);
|
||||
node_pointer p = node_;
|
||||
node_ = node_pointer();
|
||||
return p;
|
||||
}
|
||||
|
||||
private:
|
||||
void reclaim(node_pointer p) {
|
||||
BOOST_ASSERT(!node_);
|
||||
node_ = p;
|
||||
node_constructed_ = true;
|
||||
boost::unordered::detail::func::destroy_value_impl(alloc_,
|
||||
node_->value_ptr());
|
||||
}
|
||||
|
||||
array_constructor(array_constructor const&);
|
||||
array_constructor& operator=(array_constructor const&);
|
||||
private:
|
||||
node_constructor(node_constructor const&);
|
||||
node_constructor& operator=(node_constructor const&);
|
||||
};
|
||||
|
||||
template <typename Alloc>
|
||||
node_constructor<Alloc>::~node_constructor()
|
||||
{
|
||||
if (node_) {
|
||||
if (node_constructed_) {
|
||||
boost::unordered::detail::func::destroy(
|
||||
boost::addressof(*node_));
|
||||
}
|
||||
|
||||
node_allocator_traits::deallocate(alloc_, node_, 1);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Alloc>
|
||||
void node_constructor<Alloc>::create_node()
|
||||
{
|
||||
BOOST_ASSERT(!node_);
|
||||
node_constructed_ = false;
|
||||
|
||||
node_ = node_allocator_traits::allocate(alloc_, 1);
|
||||
|
||||
new ((void*) boost::addressof(*node_)) node();
|
||||
node_->init(node_);
|
||||
node_constructed_ = true;
|
||||
}
|
||||
|
||||
template <typename NodeAlloc>
|
||||
struct node_tmp
|
||||
{
|
||||
typedef boost::unordered::detail::allocator_traits<NodeAlloc>
|
||||
node_allocator_traits;
|
||||
typedef typename node_allocator_traits::pointer node_pointer;
|
||||
|
||||
NodeAlloc& alloc_;
|
||||
node_pointer node_;
|
||||
|
||||
explicit node_tmp(node_pointer n, NodeAlloc& a):
|
||||
alloc_(a),
|
||||
node_(n)
|
||||
{
|
||||
}
|
||||
|
||||
~node_tmp();
|
||||
|
||||
// no throw
|
||||
node_pointer release()
|
||||
{
|
||||
node_pointer p = node_;
|
||||
node_ = node_pointer();
|
||||
return p;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Alloc>
|
||||
node_tmp<Alloc>::~node_tmp()
|
||||
{
|
||||
if (node_) {
|
||||
boost::unordered::detail::func::destroy_value_impl(alloc_,
|
||||
node_->value_ptr());
|
||||
boost::unordered::detail::func::destroy(
|
||||
boost::addressof(*node_));
|
||||
node_allocator_traits::deallocate(alloc_, node_, 1);
|
||||
}
|
||||
}
|
||||
}}}
|
||||
|
||||
namespace boost { namespace unordered { namespace detail { namespace func {
|
||||
|
||||
// Some nicer construct_value functions, might try to
|
||||
// improve implementation later.
|
||||
|
||||
template <typename Alloc, BOOST_UNORDERED_EMPLACE_TEMPLATE>
|
||||
inline typename boost::unordered::detail::allocator_traits<Alloc>::pointer
|
||||
construct_value_generic(Alloc& alloc, BOOST_UNORDERED_EMPLACE_ARGS)
|
||||
{
|
||||
node_constructor<Alloc> a(alloc);
|
||||
a.create_node();
|
||||
construct_value_impl(alloc, a.node_->value_ptr(),
|
||||
BOOST_UNORDERED_EMPLACE_FORWARD);
|
||||
return a.release();
|
||||
}
|
||||
|
||||
template <typename Alloc, typename U>
|
||||
inline typename boost::unordered::detail::allocator_traits<Alloc>::pointer
|
||||
construct_value(Alloc& alloc, BOOST_FWD_REF(U) x)
|
||||
{
|
||||
node_constructor<Alloc> a(alloc);
|
||||
a.create_node();
|
||||
boost::unordered::detail::func::call_construct(
|
||||
alloc, a.node_->value_ptr(), boost::forward<U>(x));
|
||||
return a.release();
|
||||
}
|
||||
|
||||
// TODO: When possible, it might be better to use std::pair's
|
||||
// constructor for std::piece_construct with std::tuple.
|
||||
template <typename Alloc, typename Key>
|
||||
inline typename boost::unordered::detail::allocator_traits<Alloc>::pointer
|
||||
construct_pair(Alloc& alloc, BOOST_FWD_REF(Key) k)
|
||||
{
|
||||
node_constructor<Alloc> a(alloc);
|
||||
a.create_node();
|
||||
boost::unordered::detail::func::call_construct(
|
||||
alloc, boost::addressof(a.node_->value_ptr()->first),
|
||||
boost::forward<Key>(k));
|
||||
boost::unordered::detail::func::call_construct(
|
||||
alloc, boost::addressof(a.node_->value_ptr()->second));
|
||||
return a.release();
|
||||
}
|
||||
|
||||
template <typename Alloc, typename Key, typename Mapped>
|
||||
inline typename boost::unordered::detail::allocator_traits<Alloc>::pointer
|
||||
construct_pair(Alloc& alloc, BOOST_FWD_REF(Key) k, BOOST_FWD_REF(Mapped) m)
|
||||
{
|
||||
node_constructor<Alloc> a(alloc);
|
||||
a.create_node();
|
||||
boost::unordered::detail::func::call_construct(
|
||||
alloc, boost::addressof(a.node_->value_ptr()->first),
|
||||
boost::forward<Key>(k));
|
||||
boost::unordered::detail::func::call_construct(
|
||||
alloc, boost::addressof(a.node_->value_ptr()->second),
|
||||
boost::forward<Mapped>(m));
|
||||
return a.release();
|
||||
}
|
||||
}}}}
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
@@ -14,14 +14,6 @@
|
||||
|
||||
#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>
|
||||
#include <boost/iterator.hpp>
|
||||
|
||||
namespace boost { namespace unordered { namespace detail {
|
||||
|
||||
@@ -56,7 +48,7 @@ namespace boost { namespace unordered { namespace iterator_detail {
|
||||
|
||||
template <typename Node, typename Policy>
|
||||
struct l_iterator
|
||||
: public boost::iterator<
|
||||
: public std::iterator<
|
||||
std::forward_iterator_tag,
|
||||
typename Node::value_type,
|
||||
std::ptrdiff_t,
|
||||
@@ -116,7 +108,7 @@ namespace boost { namespace unordered { namespace iterator_detail {
|
||||
|
||||
template <typename Node, typename Policy>
|
||||
struct cl_iterator
|
||||
: public boost::iterator<
|
||||
: public std::iterator<
|
||||
std::forward_iterator_tag,
|
||||
typename Node::value_type,
|
||||
std::ptrdiff_t,
|
||||
@@ -184,7 +176,7 @@ namespace boost { namespace unordered { namespace iterator_detail {
|
||||
|
||||
template <typename Node>
|
||||
struct iterator
|
||||
: public boost::iterator<
|
||||
: public std::iterator<
|
||||
std::forward_iterator_tag,
|
||||
typename Node::value_type,
|
||||
std::ptrdiff_t,
|
||||
@@ -248,7 +240,7 @@ namespace boost { namespace unordered { namespace iterator_detail {
|
||||
|
||||
template <typename Node>
|
||||
struct c_iterator
|
||||
: public boost::iterator<
|
||||
: public std::iterator<
|
||||
std::forward_iterator_tag,
|
||||
typename Node::value_type,
|
||||
std::ptrdiff_t,
|
||||
@@ -317,124 +309,6 @@ namespace boost { namespace unordered { namespace iterator_detail {
|
||||
|
||||
namespace boost { namespace unordered { namespace detail {
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Node construction
|
||||
|
||||
template <typename NodeAlloc>
|
||||
struct node_constructor
|
||||
{
|
||||
private:
|
||||
|
||||
typedef NodeAlloc node_allocator;
|
||||
typedef boost::unordered::detail::allocator_traits<NodeAlloc>
|
||||
node_allocator_traits;
|
||||
typedef typename node_allocator_traits::value_type node;
|
||||
typedef typename node_allocator_traits::pointer node_pointer;
|
||||
typedef typename node::value_type value_type;
|
||||
|
||||
protected:
|
||||
|
||||
node_allocator& alloc_;
|
||||
node_pointer node_;
|
||||
bool node_constructed_;
|
||||
bool value_constructed_;
|
||||
|
||||
public:
|
||||
|
||||
node_constructor(node_allocator& n) :
|
||||
alloc_(n),
|
||||
node_(),
|
||||
node_constructed_(false),
|
||||
value_constructed_(false)
|
||||
{
|
||||
}
|
||||
|
||||
~node_constructor();
|
||||
|
||||
void construct();
|
||||
|
||||
template <BOOST_UNORDERED_EMPLACE_TEMPLATE>
|
||||
void construct_with_value(BOOST_UNORDERED_EMPLACE_ARGS)
|
||||
{
|
||||
construct();
|
||||
boost::unordered::detail::func::construct_value_impl(
|
||||
alloc_, node_->value_ptr(), BOOST_UNORDERED_EMPLACE_FORWARD);
|
||||
value_constructed_ = true;
|
||||
}
|
||||
|
||||
template <typename A0>
|
||||
void construct_with_value2(BOOST_FWD_REF(A0) a0)
|
||||
{
|
||||
construct();
|
||||
boost::unordered::detail::func::construct_value_impl(
|
||||
alloc_, node_->value_ptr(),
|
||||
BOOST_UNORDERED_EMPLACE_ARGS1(boost::forward<A0>(a0)));
|
||||
value_constructed_ = true;
|
||||
}
|
||||
|
||||
value_type const& value() const {
|
||||
BOOST_ASSERT(node_ && node_constructed_ && value_constructed_);
|
||||
return node_->value();
|
||||
}
|
||||
|
||||
// no throw
|
||||
node_pointer release()
|
||||
{
|
||||
BOOST_ASSERT(node_ && node_constructed_);
|
||||
node_pointer p = node_;
|
||||
node_ = node_pointer();
|
||||
return p;
|
||||
}
|
||||
|
||||
private:
|
||||
node_constructor(node_constructor const&);
|
||||
node_constructor& operator=(node_constructor const&);
|
||||
};
|
||||
|
||||
template <typename Alloc>
|
||||
node_constructor<Alloc>::~node_constructor()
|
||||
{
|
||||
if (node_) {
|
||||
if (value_constructed_) {
|
||||
boost::unordered::detail::func::destroy_value_impl(alloc_,
|
||||
node_->value_ptr());
|
||||
}
|
||||
|
||||
if (node_constructed_) {
|
||||
boost::unordered::detail::func::destroy(
|
||||
boost::addressof(*node_));
|
||||
}
|
||||
|
||||
node_allocator_traits::deallocate(alloc_, node_, 1);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Alloc>
|
||||
void node_constructor<Alloc>::construct()
|
||||
{
|
||||
if(!node_) {
|
||||
node_constructed_ = false;
|
||||
value_constructed_ = false;
|
||||
|
||||
node_ = node_allocator_traits::allocate(alloc_, 1);
|
||||
|
||||
new ((void*) boost::addressof(*node_)) node();
|
||||
node_->init(node_);
|
||||
node_constructed_ = true;
|
||||
}
|
||||
else {
|
||||
BOOST_ASSERT(node_constructed_);
|
||||
|
||||
if (value_constructed_)
|
||||
{
|
||||
boost::unordered::detail::func::destroy_value_impl(alloc_,
|
||||
node_->value_ptr());
|
||||
value_constructed_ = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Node Holder
|
||||
@@ -442,11 +316,9 @@ namespace boost { namespace unordered { namespace detail {
|
||||
// Temporary store for nodes. Deletes any that aren't used.
|
||||
|
||||
template <typename NodeAlloc>
|
||||
struct node_holder : private node_constructor<NodeAlloc>
|
||||
struct node_holder
|
||||
{
|
||||
private:
|
||||
typedef node_constructor<NodeAlloc> base;
|
||||
|
||||
typedef NodeAlloc node_allocator;
|
||||
typedef boost::unordered::detail::allocator_traits<NodeAlloc>
|
||||
node_allocator_traits;
|
||||
@@ -456,13 +328,14 @@ namespace boost { namespace unordered { namespace detail {
|
||||
typedef typename node::link_pointer link_pointer;
|
||||
typedef boost::unordered::iterator_detail::iterator<node> iterator;
|
||||
|
||||
node_constructor<NodeAlloc> constructor_;
|
||||
node_pointer nodes_;
|
||||
|
||||
public:
|
||||
|
||||
template <typename Table>
|
||||
explicit node_holder(Table& b) :
|
||||
base(b.node_alloc()),
|
||||
constructor_(b.node_alloc()),
|
||||
nodes_()
|
||||
{
|
||||
if (b.size_) {
|
||||
@@ -475,61 +348,71 @@ namespace boost { namespace unordered { namespace detail {
|
||||
|
||||
~node_holder();
|
||||
|
||||
void node_for_assignment()
|
||||
node_pointer pop_node()
|
||||
{
|
||||
if (!this->node_ && nodes_) {
|
||||
this->node_ = nodes_;
|
||||
nodes_ = static_cast<node_pointer>(nodes_->next_);
|
||||
this->node_->init(this->node_);
|
||||
this->node_->next_ = link_pointer();
|
||||
|
||||
this->node_constructed_ = true;
|
||||
this->value_constructed_ = true;
|
||||
}
|
||||
node_pointer n = nodes_;
|
||||
nodes_ = static_cast<node_pointer>(nodes_->next_);
|
||||
n->init(n);
|
||||
n->next_ = link_pointer();
|
||||
return n;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void assign_impl(T const& v) {
|
||||
if (this->node_ && this->value_constructed_) {
|
||||
this->node_->value() = v;
|
||||
inline node_pointer copy_of(T const& v) {
|
||||
if (nodes_) {
|
||||
node_tmp<NodeAlloc> a(pop_node(), constructor_.alloc_);
|
||||
a.node_->value() = v;
|
||||
return a.release();
|
||||
}
|
||||
else {
|
||||
this->construct_with_value2(v);
|
||||
constructor_.create_node();
|
||||
boost::unordered::detail::func::call_construct(
|
||||
constructor_.alloc_, constructor_.node_->value_ptr(), v);
|
||||
return constructor_.release();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
inline void assign_impl(std::pair<T1 const, T2> const& v) {
|
||||
this->construct_with_value2(v);
|
||||
inline node_pointer copy_of(std::pair<T1 const, T2> const& v) {
|
||||
if (nodes_) {
|
||||
constructor_.reclaim(pop_node());
|
||||
}
|
||||
else {
|
||||
constructor_.create_node();
|
||||
}
|
||||
boost::unordered::detail::func::call_construct(
|
||||
constructor_.alloc_, constructor_.node_->value_ptr(), v);
|
||||
return constructor_.release();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void move_assign_impl(T& v) {
|
||||
if (this->node_ && this->value_constructed_) {
|
||||
this->node_->value() = boost::move(v);
|
||||
inline node_pointer move_copy_of(T& v) {
|
||||
if (nodes_) {
|
||||
node_tmp<NodeAlloc> a(pop_node(), constructor_.alloc_);
|
||||
a.node_->value() = boost::move(v);
|
||||
return a.release();
|
||||
}
|
||||
else {
|
||||
this->construct_with_value2(boost::move(v));
|
||||
constructor_.create_node();
|
||||
boost::unordered::detail::func::call_construct(
|
||||
constructor_.alloc_, constructor_.node_->value_ptr(),
|
||||
boost::move(v));
|
||||
return constructor_.release();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
inline void move_assign_impl(std::pair<T1 const, T2>& v) {
|
||||
this->construct_with_value2(boost::move(v));
|
||||
}
|
||||
|
||||
node_pointer copy_of(value_type const& v)
|
||||
{
|
||||
node_for_assignment();
|
||||
assign_impl(v);
|
||||
return base::release();
|
||||
}
|
||||
|
||||
node_pointer move_copy_of(value_type& v)
|
||||
{
|
||||
node_for_assignment();
|
||||
move_assign_impl(v);
|
||||
return base::release();
|
||||
inline node_pointer move_copy_of(std::pair<T1 const, T2>& v) {
|
||||
if (nodes_) {
|
||||
constructor_.reclaim(pop_node());
|
||||
}
|
||||
else {
|
||||
constructor_.create_node();
|
||||
}
|
||||
boost::unordered::detail::func::call_construct(
|
||||
constructor_.alloc_, constructor_.node_->value_ptr(),
|
||||
boost::move(v));
|
||||
return constructor_.release();
|
||||
}
|
||||
|
||||
iterator begin() const
|
||||
@@ -545,10 +428,10 @@ 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::func::destroy_value_impl(constructor_.alloc_,
|
||||
p->value_ptr());
|
||||
boost::unordered::detail::func::destroy(boost::addressof(*p));
|
||||
node_allocator_traits::deallocate(this->alloc_, p, 1);
|
||||
node_allocator_traits::deallocate(constructor_.alloc_, p, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/unordered/detail/table.hpp>
|
||||
#include <boost/unordered/detail/extract_key.hpp>
|
||||
|
||||
namespace boost { namespace unordered { namespace detail {
|
||||
@@ -130,55 +129,6 @@ namespace boost { namespace unordered { namespace detail {
|
||||
typedef typename pick::link_pointer link_pointer;
|
||||
};
|
||||
|
||||
template <typename A, typename T, typename H, typename P>
|
||||
struct multiset
|
||||
{
|
||||
typedef boost::unordered::detail::multiset<A, T, H, P> types;
|
||||
|
||||
typedef A allocator;
|
||||
typedef T value_type;
|
||||
typedef H hasher;
|
||||
typedef P key_equal;
|
||||
typedef T key_type;
|
||||
|
||||
typedef boost::unordered::detail::allocator_traits<allocator> traits;
|
||||
typedef boost::unordered::detail::pick_grouped_node<allocator,
|
||||
value_type> pick;
|
||||
typedef typename pick::node node;
|
||||
typedef typename pick::bucket bucket;
|
||||
typedef typename pick::link_pointer link_pointer;
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
template <typename A, typename K, typename M, typename H, typename P>
|
||||
struct multimap
|
||||
{
|
||||
typedef boost::unordered::detail::multimap<A, K, M, H, P> types;
|
||||
|
||||
typedef A allocator;
|
||||
typedef std::pair<K const, M> value_type;
|
||||
typedef H hasher;
|
||||
typedef P key_equal;
|
||||
typedef K key_type;
|
||||
|
||||
typedef boost::unordered::detail::allocator_traits<allocator> traits;
|
||||
typedef boost::unordered::detail::pick_grouped_node<allocator,
|
||||
value_type> pick;
|
||||
typedef typename pick::node node;
|
||||
typedef typename pick::bucket bucket;
|
||||
typedef typename pick::link_pointer link_pointer;
|
||||
|
||||
typedef boost::unordered::detail::grouped_table_impl<types> table;
|
||||
typedef boost::unordered::detail::map_extractor<key_type, value_type>
|
||||
extractor;
|
||||
|
||||
typedef typename boost::unordered::detail::pick_policy<K>::type policy;
|
||||
};
|
||||
|
||||
template <typename Types>
|
||||
struct grouped_table_impl : boost::unordered::detail::table<Types>
|
||||
{
|
||||
@@ -195,6 +145,7 @@ namespace boost { namespace unordered { namespace detail {
|
||||
typedef typename table::key_equal key_equal;
|
||||
typedef typename table::key_type key_type;
|
||||
typedef typename table::node_constructor node_constructor;
|
||||
typedef typename table::node_tmp node_tmp;
|
||||
typedef typename table::extractor extractor;
|
||||
typedef typename table::iterator iterator;
|
||||
typedef typename table::c_iterator c_iterator;
|
||||
@@ -381,11 +332,10 @@ namespace boost { namespace unordered { namespace detail {
|
||||
}
|
||||
|
||||
inline iterator add_node(
|
||||
node_constructor& a,
|
||||
node_pointer n,
|
||||
std::size_t key_hash,
|
||||
iterator pos)
|
||||
{
|
||||
node_pointer n = a.release();
|
||||
n->hash_ = key_hash;
|
||||
if (pos.node_) {
|
||||
this->add_after_node(n, pos.node_);
|
||||
@@ -425,23 +375,23 @@ namespace boost { namespace unordered { namespace detail {
|
||||
return iterator(n);
|
||||
}
|
||||
|
||||
iterator emplace_impl(node_constructor& a)
|
||||
iterator emplace_impl(node_pointer n)
|
||||
{
|
||||
key_type const& k = this->get_key(a.value());
|
||||
node_tmp a(n, this->node_alloc());
|
||||
key_type const& k = this->get_key(a.node_->value());
|
||||
std::size_t key_hash = this->hash(k);
|
||||
iterator position = this->find_node(key_hash, k);
|
||||
|
||||
// reserve has basic exception safety if the hash function
|
||||
// throws, strong otherwise.
|
||||
this->reserve_for_insert(this->size_ + 1);
|
||||
return this->add_node(a, key_hash, position);
|
||||
return this->add_node(a.release(), key_hash, position);
|
||||
}
|
||||
|
||||
void emplace_impl_no_rehash(node_constructor& a)
|
||||
void emplace_impl_no_rehash(node_pointer n)
|
||||
{
|
||||
key_type const& k = this->get_key(a.value());
|
||||
node_tmp a(n, this->node_alloc());
|
||||
key_type const& k = this->get_key(a.node_->value());
|
||||
std::size_t key_hash = this->hash(k);
|
||||
this->add_node(a, key_hash, this->find_node(key_hash, k));
|
||||
iterator position = this->find_node(key_hash, k);
|
||||
this->add_node(a.release(), key_hash, position);
|
||||
}
|
||||
|
||||
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
@@ -465,10 +415,9 @@ namespace boost { namespace unordered { namespace detail {
|
||||
template <BOOST_UNORDERED_EMPLACE_TEMPLATE>
|
||||
iterator emplace(BOOST_UNORDERED_EMPLACE_ARGS)
|
||||
{
|
||||
node_constructor a(this->node_alloc());
|
||||
a.construct_with_value(BOOST_UNORDERED_EMPLACE_FORWARD);
|
||||
|
||||
return iterator(emplace_impl(a));
|
||||
return iterator(emplace_impl(
|
||||
boost::unordered::detail::func::construct_value_generic(
|
||||
this->node_alloc(), BOOST_UNORDERED_EMPLACE_FORWARD)));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@@ -477,37 +426,37 @@ namespace boost { namespace unordered { namespace detail {
|
||||
// if hash function throws, or inserting > 1 element, basic exception
|
||||
// safety. Strong otherwise
|
||||
template <class I>
|
||||
typename boost::unordered::detail::enable_if_forward<I, void>::type
|
||||
insert_range(I i, I j)
|
||||
void insert_range(I i, I j, typename
|
||||
boost::unordered::detail::enable_if_forward<I, void*>::type = 0)
|
||||
{
|
||||
if(i == j) return;
|
||||
|
||||
std::size_t distance = boost::unordered::detail::distance(i, j);
|
||||
std::size_t distance = std::distance(i, j);
|
||||
if(distance == 1) {
|
||||
node_constructor a(this->node_alloc());
|
||||
a.construct_with_value2(*i);
|
||||
emplace_impl(a);
|
||||
emplace_impl(
|
||||
boost::unordered::detail::func::construct_value(
|
||||
this->node_alloc(), *i));
|
||||
}
|
||||
else {
|
||||
// Only require basic exception safety here
|
||||
this->reserve_for_insert(this->size_ + distance);
|
||||
|
||||
node_constructor a(this->node_alloc());
|
||||
for (; i != j; ++i) {
|
||||
a.construct_with_value2(*i);
|
||||
emplace_impl_no_rehash(a);
|
||||
emplace_impl_no_rehash(
|
||||
boost::unordered::detail::func::construct_value(
|
||||
this->node_alloc(), *i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class I>
|
||||
typename boost::unordered::detail::disable_if_forward<I, void>::type
|
||||
insert_range(I i, I j)
|
||||
void insert_range(I i, I j, typename
|
||||
boost::unordered::detail::disable_if_forward<I, void*>::type = 0)
|
||||
{
|
||||
node_constructor a(this->node_alloc());
|
||||
for (; i != j; ++i) {
|
||||
a.construct_with_value2(*i);
|
||||
emplace_impl(a);
|
||||
emplace_impl(
|
||||
boost::unordered::detail::func::construct_value(
|
||||
this->node_alloc(), *i));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -621,31 +570,65 @@ namespace boost { namespace unordered { namespace detail {
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// fill_buckets
|
||||
|
||||
template <class NodeCreator>
|
||||
static void fill_buckets(iterator n, table& dst,
|
||||
NodeCreator& creator)
|
||||
{
|
||||
link_pointer prev = dst.get_previous_start();
|
||||
void copy_buckets(table const& src) {
|
||||
this->create_buckets(this->bucket_count_);
|
||||
|
||||
while (n.node_) {
|
||||
for (iterator n = src.begin(); n.node_;) {
|
||||
std::size_t key_hash = n.node_->hash_;
|
||||
iterator group_end(n.node_->group_prev_->next_);
|
||||
|
||||
node_pointer first_node = creator.create(*n);
|
||||
node_pointer end = first_node;
|
||||
first_node->hash_ = key_hash;
|
||||
prev->next_ = first_node;
|
||||
++dst.size_;
|
||||
|
||||
iterator pos = this->add_node(
|
||||
boost::unordered::detail::func::construct_value(
|
||||
this->node_alloc(), *n), key_hash, iterator());
|
||||
for (++n; n != group_end; ++n)
|
||||
{
|
||||
end = creator.create(*n);
|
||||
end->hash_ = key_hash;
|
||||
add_after_node(end, first_node);
|
||||
++dst.size_;
|
||||
this->add_node(
|
||||
boost::unordered::detail::func::construct_value(
|
||||
this->node_alloc(), *n), key_hash, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
prev = place_in_bucket(dst, prev, end);
|
||||
void move_buckets(table const& src) {
|
||||
this->create_buckets(this->bucket_count_);
|
||||
|
||||
for (iterator n = src.begin(); n.node_;) {
|
||||
std::size_t key_hash = n.node_->hash_;
|
||||
iterator group_end(n.node_->group_prev_->next_);
|
||||
iterator pos = this->add_node(
|
||||
boost::unordered::detail::func::construct_value(
|
||||
this->node_alloc(), boost::move(*n)), key_hash, iterator());
|
||||
for (++n; n != group_end; ++n)
|
||||
{
|
||||
this->add_node(
|
||||
boost::unordered::detail::func::construct_value(
|
||||
this->node_alloc(), boost::move(*n)), key_hash, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void assign_buckets(table const& src) {
|
||||
node_holder<node_allocator> holder(*this);
|
||||
for (iterator n = src.begin(); n.node_;) {
|
||||
std::size_t key_hash = n.node_->hash_;
|
||||
iterator group_end(n.node_->group_prev_->next_);
|
||||
iterator pos = this->add_node(holder.copy_of(*n), key_hash, iterator());
|
||||
for (++n; n != group_end; ++n)
|
||||
{
|
||||
this->add_node(holder.copy_of(*n), key_hash, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void move_assign_buckets(table& src) {
|
||||
node_holder<node_allocator> holder(*this);
|
||||
for (iterator n = src.begin(); n.node_;) {
|
||||
std::size_t key_hash = n.node_->hash_;
|
||||
iterator group_end(n.node_->group_prev_->next_);
|
||||
iterator pos = this->add_node(holder.move_copy_of(*n), key_hash, iterator());
|
||||
for (++n; n != group_end; ++n)
|
||||
{
|
||||
this->add_node(holder.move_copy_of(*n), key_hash, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
|
||||
// Copyright (C) 2005-2016 Daniel James
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/unordered/unordered_map_fwd.hpp>
|
||||
#include <boost/unordered/detail/equivalent.hpp>
|
||||
#include <boost/unordered/detail/unique.hpp>
|
||||
|
||||
namespace boost { namespace unordered { namespace detail {
|
||||
template <typename A, typename K, typename M, typename H, typename P>
|
||||
struct map
|
||||
{
|
||||
typedef boost::unordered::detail::map<A, K, M, H, P> types;
|
||||
|
||||
typedef A allocator;
|
||||
typedef std::pair<K const, M> value_type;
|
||||
typedef H hasher;
|
||||
typedef P key_equal;
|
||||
typedef K key_type;
|
||||
|
||||
typedef boost::unordered::detail::allocator_traits<allocator>
|
||||
traits;
|
||||
typedef boost::unordered::detail::pick_node<allocator, value_type> pick;
|
||||
typedef typename pick::node node;
|
||||
typedef typename pick::bucket bucket;
|
||||
typedef typename pick::link_pointer link_pointer;
|
||||
|
||||
typedef boost::unordered::detail::table_impl<types> table;
|
||||
typedef boost::unordered::detail::map_extractor<key_type, value_type>
|
||||
extractor;
|
||||
|
||||
typedef typename boost::unordered::detail::pick_policy<K>::type policy;
|
||||
};
|
||||
|
||||
template <typename A, typename K, typename M, typename H, typename P>
|
||||
struct multimap
|
||||
{
|
||||
typedef boost::unordered::detail::multimap<A, K, M, H, P> types;
|
||||
|
||||
typedef A allocator;
|
||||
typedef std::pair<K const, M> value_type;
|
||||
typedef H hasher;
|
||||
typedef P key_equal;
|
||||
typedef K key_type;
|
||||
|
||||
typedef boost::unordered::detail::allocator_traits<allocator> traits;
|
||||
typedef boost::unordered::detail::pick_grouped_node<allocator,
|
||||
value_type> pick;
|
||||
typedef typename pick::node node;
|
||||
typedef typename pick::bucket bucket;
|
||||
typedef typename pick::link_pointer link_pointer;
|
||||
|
||||
typedef boost::unordered::detail::grouped_table_impl<types> table;
|
||||
typedef boost::unordered::detail::map_extractor<key_type, value_type>
|
||||
extractor;
|
||||
|
||||
typedef typename boost::unordered::detail::pick_policy<K>::type policy;
|
||||
};
|
||||
|
||||
}}}
|
||||
@@ -0,0 +1,57 @@
|
||||
|
||||
// Copyright (C) 2005-2016 Daniel James
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/unordered/unordered_set_fwd.hpp>
|
||||
#include <boost/unordered/detail/equivalent.hpp>
|
||||
#include <boost/unordered/detail/unique.hpp>
|
||||
|
||||
namespace boost { namespace unordered { namespace detail {
|
||||
template <typename A, typename T, typename H, typename P>
|
||||
struct set
|
||||
{
|
||||
typedef boost::unordered::detail::set<A, T, H, P> types;
|
||||
|
||||
typedef A allocator;
|
||||
typedef T value_type;
|
||||
typedef H hasher;
|
||||
typedef P key_equal;
|
||||
typedef T key_type;
|
||||
|
||||
typedef boost::unordered::detail::allocator_traits<allocator> traits;
|
||||
typedef boost::unordered::detail::pick_node<allocator, value_type> pick;
|
||||
typedef typename pick::node node;
|
||||
typedef typename pick::bucket bucket;
|
||||
typedef typename pick::link_pointer link_pointer;
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
template <typename A, typename T, typename H, typename P>
|
||||
struct multiset
|
||||
{
|
||||
typedef boost::unordered::detail::multiset<A, T, H, P> types;
|
||||
|
||||
typedef A allocator;
|
||||
typedef T value_type;
|
||||
typedef H hasher;
|
||||
typedef P key_equal;
|
||||
typedef T key_type;
|
||||
|
||||
typedef boost::unordered::detail::allocator_traits<allocator> traits;
|
||||
typedef boost::unordered::detail::pick_grouped_node<allocator,
|
||||
value_type> pick;
|
||||
typedef typename pick::node node;
|
||||
typedef typename pick::bucket bucket;
|
||||
typedef typename pick::link_pointer link_pointer;
|
||||
|
||||
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;
|
||||
};
|
||||
}}}
|
||||
@@ -13,28 +13,12 @@
|
||||
#endif
|
||||
|
||||
#include <boost/unordered/detail/buckets.hpp>
|
||||
#include <boost/unordered/detail/util.hpp>
|
||||
#include <boost/type_traits/aligned_storage.hpp>
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
#include <cmath>
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4127) // conditional expression is constant
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_UNORDERED_DEPRECATED_EQUALITY)
|
||||
|
||||
#if defined(__EDG__)
|
||||
#elif defined(_MSC_VER) || defined(__BORLANDC__) || defined(__DMC__)
|
||||
#pragma message("Warning: BOOST_UNORDERED_DEPRECATED_EQUALITY is no longer supported.")
|
||||
#elif defined(__GNUC__) || defined(__HP_aCC) || \
|
||||
defined(__SUNPRO_CC) || defined(__IBMCPP__)
|
||||
#warning "BOOST_UNORDERED_DEPRECATED_EQUALITY is no longer supported."
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
namespace boost { namespace unordered { namespace detail {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
@@ -80,70 +64,6 @@ namespace boost { namespace unordered { namespace detail {
|
||||
value_base& operator=(value_base const&);
|
||||
};
|
||||
|
||||
template <typename NodeAlloc>
|
||||
struct copy_nodes
|
||||
{
|
||||
typedef boost::unordered::detail::allocator_traits<NodeAlloc>
|
||||
node_allocator_traits;
|
||||
|
||||
node_constructor<NodeAlloc> constructor;
|
||||
|
||||
explicit copy_nodes(NodeAlloc& a) : constructor(a) {}
|
||||
|
||||
typename node_allocator_traits::pointer create(
|
||||
typename node_allocator_traits::value_type::value_type const& v)
|
||||
{
|
||||
constructor.construct_with_value2(v);
|
||||
return constructor.release();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename NodeAlloc>
|
||||
struct move_nodes
|
||||
{
|
||||
typedef boost::unordered::detail::allocator_traits<NodeAlloc>
|
||||
node_allocator_traits;
|
||||
|
||||
node_constructor<NodeAlloc> constructor;
|
||||
|
||||
explicit move_nodes(NodeAlloc& a) : constructor(a) {}
|
||||
|
||||
typename node_allocator_traits::pointer create(
|
||||
typename node_allocator_traits::value_type::value_type& v)
|
||||
{
|
||||
constructor.construct_with_value2(boost::move(v));
|
||||
return constructor.release();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Buckets>
|
||||
struct assign_nodes
|
||||
{
|
||||
node_holder<typename Buckets::node_allocator> holder;
|
||||
|
||||
explicit assign_nodes(Buckets& b) : holder(b) {}
|
||||
|
||||
typename Buckets::node_pointer create(
|
||||
typename Buckets::value_type const& v)
|
||||
{
|
||||
return holder.copy_of(v);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Buckets>
|
||||
struct move_assign_nodes
|
||||
{
|
||||
node_holder<typename Buckets::node_allocator> holder;
|
||||
|
||||
explicit move_assign_nodes(Buckets& b) : holder(b) {}
|
||||
|
||||
typename Buckets::node_pointer create(
|
||||
typename Buckets::value_type& v)
|
||||
{
|
||||
return holder.move_copy_of(v);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Types>
|
||||
struct table :
|
||||
boost::unordered::detail::functions<
|
||||
@@ -187,6 +107,8 @@ namespace boost { namespace unordered { namespace detail {
|
||||
bucket_pointer;
|
||||
typedef boost::unordered::detail::node_constructor<node_allocator>
|
||||
node_constructor;
|
||||
typedef boost::unordered::detail::node_tmp<node_allocator>
|
||||
node_tmp;
|
||||
|
||||
typedef boost::unordered::iterator_detail::
|
||||
iterator<node> iterator;
|
||||
@@ -403,9 +325,7 @@ namespace boost { namespace unordered { namespace detail {
|
||||
void init(table const& x)
|
||||
{
|
||||
if (x.size_) {
|
||||
create_buckets(bucket_count_);
|
||||
copy_nodes<node_allocator> node_creator(node_alloc());
|
||||
table_impl::fill_buckets(x.begin(), *this, node_creator);
|
||||
static_cast<table_impl*>(this)->copy_buckets(x);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -416,11 +336,7 @@ namespace boost { namespace unordered { namespace detail {
|
||||
}
|
||||
else if(x.size_) {
|
||||
// TODO: Could pick new bucket size?
|
||||
create_buckets(bucket_count_);
|
||||
|
||||
move_nodes<node_allocator> node_creator(node_alloc());
|
||||
node_holder<node_allocator> nodes(x);
|
||||
table_impl::fill_buckets(nodes.begin(), *this, node_creator);
|
||||
static_cast<table_impl*>(this)->move_buckets(x);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -429,34 +345,53 @@ namespace boost { namespace unordered { namespace detail {
|
||||
|
||||
void create_buckets(std::size_t new_count)
|
||||
{
|
||||
boost::unordered::detail::array_constructor<bucket_allocator>
|
||||
constructor(bucket_alloc());
|
||||
|
||||
// Creates an extra bucket to act as the start node.
|
||||
constructor.construct(bucket(), new_count + 1);
|
||||
std::size_t length = new_count + 1;
|
||||
bucket_pointer new_buckets = bucket_allocator_traits::allocate(
|
||||
bucket_alloc(), length);
|
||||
bucket_pointer constructed = new_buckets;
|
||||
|
||||
if (buckets_)
|
||||
{
|
||||
// Copy the nodes to the new buckets, including the dummy
|
||||
// node if there is one.
|
||||
(constructor.get() +
|
||||
static_cast<std::ptrdiff_t>(new_count))->next_ =
|
||||
(buckets_ + static_cast<std::ptrdiff_t>(
|
||||
bucket_count_))->next_;
|
||||
destroy_buckets();
|
||||
}
|
||||
else if (bucket::extra_node)
|
||||
{
|
||||
node_constructor a(node_alloc());
|
||||
a.construct();
|
||||
BOOST_TRY {
|
||||
bucket_pointer end = new_buckets
|
||||
+ static_cast<std::ptrdiff_t>(length);
|
||||
for(; constructed != end; ++constructed) {
|
||||
new ((void*) boost::addressof(*constructed)) bucket();
|
||||
}
|
||||
|
||||
(constructor.get() +
|
||||
static_cast<std::ptrdiff_t>(new_count))->next_ =
|
||||
a.release();
|
||||
if (buckets_)
|
||||
{
|
||||
// Copy the nodes to the new buckets, including the dummy
|
||||
// node if there is one.
|
||||
(new_buckets +
|
||||
static_cast<std::ptrdiff_t>(new_count))->next_ =
|
||||
(buckets_ + static_cast<std::ptrdiff_t>(
|
||||
bucket_count_))->next_;
|
||||
destroy_buckets();
|
||||
}
|
||||
else if (bucket::extra_node)
|
||||
{
|
||||
node_constructor a(node_alloc());
|
||||
a.create_node();
|
||||
|
||||
(new_buckets +
|
||||
static_cast<std::ptrdiff_t>(new_count))->next_ =
|
||||
a.release();
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(...) {
|
||||
for(bucket_pointer p = new_buckets; p != constructed; ++p) {
|
||||
boost::unordered::detail::func::destroy(
|
||||
boost::addressof(*p));
|
||||
}
|
||||
|
||||
bucket_allocator_traits::deallocate(bucket_alloc(),
|
||||
new_buckets, length);
|
||||
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
|
||||
bucket_count_ = new_count;
|
||||
buckets_ = constructor.release();
|
||||
buckets_ = new_buckets;
|
||||
recalculate_max_load();
|
||||
}
|
||||
|
||||
@@ -662,11 +597,7 @@ namespace boost { namespace unordered { namespace detail {
|
||||
clear_buckets();
|
||||
}
|
||||
|
||||
// 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);
|
||||
static_cast<table_impl*>(this)->assign_buckets(x);
|
||||
}
|
||||
|
||||
void assign(table const& x, true_type)
|
||||
@@ -691,9 +622,7 @@ 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);
|
||||
static_cast<table_impl*>(this)->copy_buckets(x);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -747,12 +676,7 @@ namespace boost { namespace unordered { namespace detail {
|
||||
clear_buckets();
|
||||
}
|
||||
|
||||
// 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);
|
||||
node_holder<node_allocator> nodes(x);
|
||||
table_impl::fill_buckets(nodes.begin(), *this, node_creator);
|
||||
static_cast<table_impl*>(this)->move_assign_buckets(x);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/unordered/detail/table.hpp>
|
||||
#include <boost/unordered/detail/extract_key.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <stdexcept>
|
||||
@@ -126,54 +125,6 @@ namespace boost { namespace unordered { namespace detail {
|
||||
typedef typename pick::link_pointer link_pointer;
|
||||
};
|
||||
|
||||
template <typename A, typename T, typename H, typename P>
|
||||
struct set
|
||||
{
|
||||
typedef boost::unordered::detail::set<A, T, H, P> types;
|
||||
|
||||
typedef A allocator;
|
||||
typedef T value_type;
|
||||
typedef H hasher;
|
||||
typedef P key_equal;
|
||||
typedef T key_type;
|
||||
|
||||
typedef boost::unordered::detail::allocator_traits<allocator> traits;
|
||||
typedef boost::unordered::detail::pick_node<allocator, value_type> pick;
|
||||
typedef typename pick::node node;
|
||||
typedef typename pick::bucket bucket;
|
||||
typedef typename pick::link_pointer link_pointer;
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
template <typename A, typename K, typename M, typename H, typename P>
|
||||
struct map
|
||||
{
|
||||
typedef boost::unordered::detail::map<A, K, M, H, P> types;
|
||||
|
||||
typedef A allocator;
|
||||
typedef std::pair<K const, M> value_type;
|
||||
typedef H hasher;
|
||||
typedef P key_equal;
|
||||
typedef K key_type;
|
||||
|
||||
typedef boost::unordered::detail::allocator_traits<allocator>
|
||||
traits;
|
||||
typedef boost::unordered::detail::pick_node<allocator, value_type> pick;
|
||||
typedef typename pick::node node;
|
||||
typedef typename pick::bucket bucket;
|
||||
typedef typename pick::link_pointer link_pointer;
|
||||
|
||||
typedef boost::unordered::detail::table_impl<types> table;
|
||||
typedef boost::unordered::detail::map_extractor<key_type, value_type>
|
||||
extractor;
|
||||
|
||||
typedef typename boost::unordered::detail::pick_policy<K>::type policy;
|
||||
};
|
||||
|
||||
template <typename Types>
|
||||
struct table_impl : boost::unordered::detail::table<Types>
|
||||
{
|
||||
@@ -190,6 +141,7 @@ namespace boost { namespace unordered { namespace detail {
|
||||
typedef typename table::key_equal key_equal;
|
||||
typedef typename table::key_type key_type;
|
||||
typedef typename table::node_constructor node_constructor;
|
||||
typedef typename table::node_tmp node_tmp;
|
||||
typedef typename table::extractor extractor;
|
||||
typedef typename table::iterator iterator;
|
||||
typedef typename table::c_iterator c_iterator;
|
||||
@@ -308,10 +260,9 @@ namespace boost { namespace unordered { namespace detail {
|
||||
// Emplace/Insert
|
||||
|
||||
inline iterator add_node(
|
||||
node_constructor& a,
|
||||
node_pointer n,
|
||||
std::size_t key_hash)
|
||||
{
|
||||
node_pointer n = a.release();
|
||||
n->hash_ = key_hash;
|
||||
|
||||
bucket_pointer b = this->get_bucket(this->hash_to_bucket(key_hash));
|
||||
@@ -340,23 +291,21 @@ namespace boost { namespace unordered { namespace detail {
|
||||
return iterator(n);
|
||||
}
|
||||
|
||||
inline iterator resize_and_add_node(node_pointer n, std::size_t key_hash)
|
||||
{
|
||||
node_tmp b(n, this->node_alloc());
|
||||
this->reserve_for_insert(this->size_ + 1);
|
||||
return this->add_node(b.release(), key_hash);
|
||||
}
|
||||
|
||||
value_type& operator[](key_type const& k)
|
||||
{
|
||||
std::size_t key_hash = this->hash(k);
|
||||
iterator pos = this->find_node(key_hash, k);
|
||||
|
||||
if (pos.node_) return *pos;
|
||||
|
||||
// Create the node before rehashing in case it throws an
|
||||
// exception (need strong safety in such a case).
|
||||
node_constructor a(this->node_alloc());
|
||||
a.construct_with_value(BOOST_UNORDERED_EMPLACE_ARGS3(
|
||||
boost::unordered::piecewise_construct,
|
||||
boost::make_tuple(k),
|
||||
boost::make_tuple()));
|
||||
|
||||
this->reserve_for_insert(this->size_ + 1);
|
||||
return *add_node(a, key_hash);
|
||||
return *this->resize_and_add_node(
|
||||
boost::unordered::detail::func::construct_pair(this->node_alloc(), k),
|
||||
key_hash);
|
||||
}
|
||||
|
||||
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
@@ -406,32 +355,17 @@ namespace boost { namespace unordered { namespace detail {
|
||||
{
|
||||
std::size_t key_hash = this->hash(k);
|
||||
iterator pos = this->find_node(key_hash, k);
|
||||
|
||||
if (pos.node_) return emplace_return(pos, false);
|
||||
|
||||
// Create the node before rehashing in case it throws an
|
||||
// exception (need strong safety in such a case).
|
||||
node_constructor a(this->node_alloc());
|
||||
a.construct_with_value(BOOST_UNORDERED_EMPLACE_FORWARD);
|
||||
|
||||
// reserve has basic exception safety if the hash function
|
||||
// throws, strong otherwise.
|
||||
this->reserve_for_insert(this->size_ + 1);
|
||||
return emplace_return(this->add_node(a, key_hash), true);
|
||||
}
|
||||
|
||||
emplace_return emplace_impl_with_node(node_constructor& a)
|
||||
{
|
||||
key_type const& k = this->get_key(a.value());
|
||||
std::size_t key_hash = this->hash(k);
|
||||
iterator pos = this->find_node(key_hash, k);
|
||||
|
||||
if (pos.node_) return emplace_return(pos, false);
|
||||
|
||||
// reserve has basic exception safety if the hash function
|
||||
// throws, strong otherwise.
|
||||
this->reserve_for_insert(this->size_ + 1);
|
||||
return emplace_return(this->add_node(a, key_hash), true);
|
||||
if (pos.node_) {
|
||||
return emplace_return(pos, false);
|
||||
}
|
||||
else {
|
||||
return emplace_return(
|
||||
this->resize_and_add_node(
|
||||
boost::unordered::detail::func::construct_value_generic(
|
||||
this->node_alloc(), BOOST_UNORDERED_EMPLACE_FORWARD),
|
||||
key_hash),
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
template <BOOST_UNORDERED_EMPLACE_TEMPLATE>
|
||||
@@ -439,9 +373,21 @@ namespace boost { namespace unordered { namespace detail {
|
||||
{
|
||||
// Don't have a key, so construct the node first in order
|
||||
// to be able to lookup the position.
|
||||
node_constructor a(this->node_alloc());
|
||||
a.construct_with_value(BOOST_UNORDERED_EMPLACE_FORWARD);
|
||||
return emplace_impl_with_node(a);
|
||||
node_tmp b(
|
||||
boost::unordered::detail::func::construct_value_generic(
|
||||
this->node_alloc(), BOOST_UNORDERED_EMPLACE_FORWARD),
|
||||
this->node_alloc());
|
||||
key_type const& k = this->get_key(b.node_->value());
|
||||
std::size_t key_hash = this->hash(k);
|
||||
iterator pos = this->find_node(key_hash, k);
|
||||
if (pos.node_) {
|
||||
return emplace_return(pos, false);
|
||||
}
|
||||
else {
|
||||
return emplace_return(
|
||||
this->resize_and_add_node(b.release(), key_hash),
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@@ -460,9 +406,7 @@ namespace boost { namespace unordered { namespace detail {
|
||||
template <class InputIt>
|
||||
void insert_range_impl(key_type const& k, InputIt i, InputIt j)
|
||||
{
|
||||
node_constructor a(this->node_alloc());
|
||||
|
||||
insert_range_impl2(a, k, i, j);
|
||||
insert_range_impl2(k, i, j);
|
||||
|
||||
while(++i != j) {
|
||||
// Note: can't use get_key as '*i' might not be value_type - it
|
||||
@@ -473,26 +417,25 @@ namespace boost { namespace unordered { namespace detail {
|
||||
// key here. Could be more efficient if '*i' is expensive. Could
|
||||
// be less efficient if copying the full value_type is
|
||||
// expensive.
|
||||
insert_range_impl2(a, extractor::extract(*i), i, j);
|
||||
insert_range_impl2(extractor::extract(*i), i, j);
|
||||
}
|
||||
}
|
||||
|
||||
template <class InputIt>
|
||||
void insert_range_impl2(node_constructor& a, key_type const& k,
|
||||
InputIt i, InputIt j)
|
||||
void insert_range_impl2(key_type const& k, InputIt i, InputIt j)
|
||||
{
|
||||
// No side effects in this initial code
|
||||
std::size_t key_hash = this->hash(k);
|
||||
iterator pos = this->find_node(key_hash, k);
|
||||
|
||||
if (!pos.node_) {
|
||||
a.construct_with_value2(*i);
|
||||
node_tmp b(
|
||||
boost::unordered::detail::func::construct_value(this->node_alloc(), *i),
|
||||
this->node_alloc());
|
||||
if(this->size_ + 1 > this->max_load_)
|
||||
this->reserve_for_insert(this->size_ +
|
||||
boost::unordered::detail::insert_size(i, j));
|
||||
|
||||
// Nothing after this point can throw.
|
||||
this->add_node(a, key_hash);
|
||||
this->add_node(b.release(), key_hash);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -502,8 +445,24 @@ namespace boost { namespace unordered { namespace detail {
|
||||
node_constructor a(this->node_alloc());
|
||||
|
||||
do {
|
||||
a.construct_with_value2(*i);
|
||||
emplace_impl_with_node(a);
|
||||
if (!a.node_) { a.create_node(); }
|
||||
boost::unordered::detail::func::call_construct(
|
||||
a.alloc_, a.node_->value_ptr(), *i);
|
||||
node_tmp b(a.release(), a.alloc_);
|
||||
|
||||
key_type const& k = this->get_key(b.node_->value());
|
||||
std::size_t key_hash = this->hash(k);
|
||||
iterator pos = this->find_node(key_hash, k);
|
||||
|
||||
if (pos.node_) {
|
||||
a.reclaim(b.release());
|
||||
}
|
||||
else {
|
||||
// reserve has basic exception safety if the hash function
|
||||
// throws, strong otherwise.
|
||||
this->reserve_for_insert(this->size_ + 1);
|
||||
this->add_node(b.release(), key_hash);
|
||||
}
|
||||
} while(++i != j);
|
||||
}
|
||||
|
||||
@@ -576,20 +535,39 @@ namespace boost { namespace unordered { namespace detail {
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// fill_buckets
|
||||
|
||||
template <class NodeCreator>
|
||||
static void fill_buckets(iterator n, table& dst,
|
||||
NodeCreator& creator)
|
||||
void copy_buckets(table const& src) {
|
||||
this->create_buckets(this->bucket_count_);
|
||||
|
||||
for(iterator n = src.begin(); n.node_; ++n) {
|
||||
this->add_node(
|
||||
boost::unordered::detail::func::construct_value(
|
||||
this->node_alloc(), *n), n.node_->hash_);
|
||||
}
|
||||
}
|
||||
|
||||
void move_buckets(table const& src) {
|
||||
this->create_buckets(this->bucket_count_);
|
||||
|
||||
for(iterator n = src.begin(); n.node_; ++n) {
|
||||
this->add_node(
|
||||
boost::unordered::detail::func::construct_value(
|
||||
this->node_alloc(), boost::move(*n)), n.node_->hash_);
|
||||
}
|
||||
}
|
||||
|
||||
void assign_buckets(table const& src)
|
||||
{
|
||||
link_pointer prev = dst.get_previous_start();
|
||||
node_holder<node_allocator> holder(*this);
|
||||
for(iterator n = src.begin(); n.node_; ++n) {
|
||||
this->add_node(holder.copy_of(*n), n.node_->hash_);
|
||||
}
|
||||
}
|
||||
|
||||
while (n.node_) {
|
||||
node_pointer node = creator.create(*n);
|
||||
node->hash_ = n.node_->hash_;
|
||||
prev->next_ = node;
|
||||
++dst.size_;
|
||||
++n;
|
||||
|
||||
prev = place_in_bucket(dst, prev);
|
||||
void move_assign_buckets(table& src)
|
||||
{
|
||||
node_holder<node_allocator> holder(*this);
|
||||
for(iterator n = src.begin(); n.node_; ++n) {
|
||||
this->add_node(holder.move_copy_of(*n), n.node_->hash_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -124,33 +124,16 @@ namespace boost { namespace unordered { namespace detail {
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// insert_size/initial_size
|
||||
|
||||
#if !defined(BOOST_NO_STD_DISTANCE)
|
||||
|
||||
using ::std::distance;
|
||||
|
||||
#else
|
||||
|
||||
template <class ForwardIterator>
|
||||
inline std::size_t distance(ForwardIterator i, ForwardIterator j) {
|
||||
std::size_t x;
|
||||
std::distance(i, j, x);
|
||||
return x;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template <class I>
|
||||
inline typename
|
||||
boost::unordered::detail::enable_if_forward<I, std::size_t>::type
|
||||
insert_size(I i, I j)
|
||||
inline std::size_t insert_size(I i, I j, typename
|
||||
boost::unordered::detail::enable_if_forward<I, void*>::type = 0)
|
||||
{
|
||||
return std::distance(i, j);
|
||||
}
|
||||
|
||||
template <class I>
|
||||
inline typename
|
||||
boost::unordered::detail::disable_if_forward<I, std::size_t>::type
|
||||
insert_size(I, I)
|
||||
inline std::size_t insert_size(I, I, typename
|
||||
boost::unordered::detail::disable_if_forward<I, void*>::type = 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -15,9 +15,7 @@
|
||||
#endif
|
||||
|
||||
#include <boost/unordered/unordered_map_fwd.hpp>
|
||||
#include <boost/unordered/detail/equivalent.hpp>
|
||||
#include <boost/unordered/detail/unique.hpp>
|
||||
#include <boost/unordered/detail/util.hpp>
|
||||
#include <boost/unordered/detail/map.hpp>
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/move/move.hpp>
|
||||
|
||||
|
||||
@@ -14,10 +14,7 @@
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/unordered/unordered_set_fwd.hpp>
|
||||
#include <boost/unordered/detail/equivalent.hpp>
|
||||
#include <boost/unordered/detail/unique.hpp>
|
||||
#include <boost/unordered/detail/util.hpp>
|
||||
#include <boost/unordered/detail/set.hpp>
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/move/move.hpp>
|
||||
|
||||
|
||||
+72
-2
@@ -5,5 +5,75 @@
|
||||
|
||||
import testing ;
|
||||
|
||||
build-project unordered ;
|
||||
build-project exception ;
|
||||
project unordered-test/unordered
|
||||
: requirements
|
||||
<warnings>all
|
||||
<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>clang:<cxxflags>"-pedantic -Wextra -Wno-long-long"
|
||||
;
|
||||
|
||||
#alias framework : /boost/test//boost_unit_test_framework ;
|
||||
alias framework : ;
|
||||
|
||||
test-suite unordered
|
||||
:
|
||||
[ run unordered/fwd_set_test.cpp ]
|
||||
[ run unordered/fwd_map_test.cpp ]
|
||||
[ run unordered/allocator_traits.cpp ]
|
||||
[ run unordered/minimal_allocator.cpp ]
|
||||
[ run unordered/compile_set.cpp ]
|
||||
[ run unordered/compile_map.cpp ]
|
||||
[ run unordered/noexcept_tests.cpp ]
|
||||
[ run unordered/link_test_1.cpp unordered/link_test_2.cpp ]
|
||||
[ run unordered/incomplete_test.cpp ]
|
||||
[ run unordered/simple_tests.cpp ]
|
||||
[ run unordered/equivalent_keys_tests.cpp ]
|
||||
[ run unordered/constructor_tests.cpp ]
|
||||
[ run unordered/copy_tests.cpp ]
|
||||
[ run unordered/move_tests.cpp ]
|
||||
[ run unordered/assign_tests.cpp ]
|
||||
[ run unordered/insert_tests.cpp ]
|
||||
[ run unordered/insert_stable_tests.cpp ]
|
||||
[ run unordered/unnecessary_copy_tests.cpp ]
|
||||
[ run unordered/erase_tests.cpp ]
|
||||
[ run unordered/erase_equiv_tests.cpp ]
|
||||
[ run unordered/find_tests.cpp ]
|
||||
[ run unordered/at_tests.cpp ]
|
||||
[ run unordered/bucket_tests.cpp ]
|
||||
[ run unordered/load_factor_tests.cpp ]
|
||||
[ run unordered/rehash_tests.cpp ]
|
||||
[ run unordered/equality_tests.cpp ]
|
||||
[ run unordered/swap_tests.cpp ]
|
||||
|
||||
[ run unordered/compile_set.cpp : :
|
||||
: <define>BOOST_UNORDERED_USE_MOVE
|
||||
: bmove_compile_set ]
|
||||
[ run unordered/compile_map.cpp : :
|
||||
: <define>BOOST_UNORDERED_USE_MOVE
|
||||
: bmove_compile_map ]
|
||||
[ run unordered/copy_tests.cpp : :
|
||||
: <define>BOOST_UNORDERED_USE_MOVE
|
||||
: bmove_copy ]
|
||||
[ run unordered/move_tests.cpp : :
|
||||
: <define>BOOST_UNORDERED_USE_MOVE
|
||||
: bmove_move ]
|
||||
[ run unordered/assign_tests.cpp : :
|
||||
: <define>BOOST_UNORDERED_USE_MOVE
|
||||
: bmove_assign ]
|
||||
;
|
||||
|
||||
test-suite unordered-exception
|
||||
:
|
||||
[ run exception/constructor_exception_tests.cpp framework ]
|
||||
[ run exception/copy_exception_tests.cpp framework ]
|
||||
[ run exception/assign_exception_tests.cpp framework ]
|
||||
[ run exception/insert_exception_tests.cpp framework ]
|
||||
[ run exception/erase_exception_tests.cpp framework ]
|
||||
[ run exception/rehash_exception_tests.cpp framework ]
|
||||
[ run exception/swap_exception_tests.cpp framework : : :
|
||||
<define>BOOST_UNORDERED_SWAP_METHOD=2 ]
|
||||
;
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
|
||||
# Copyright 2006-2008 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)
|
||||
|
||||
import testing ;
|
||||
|
||||
#alias framework : /boost/test//boost_unit_test_framework ;
|
||||
alias framework : ;
|
||||
|
||||
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"
|
||||
;
|
||||
|
||||
test-suite unordered-exception
|
||||
:
|
||||
[ run constructor_exception_tests.cpp framework ]
|
||||
[ run copy_exception_tests.cpp framework ]
|
||||
[ run assign_exception_tests.cpp framework ]
|
||||
[ run insert_exception_tests.cpp framework ]
|
||||
[ run erase_exception_tests.cpp framework ]
|
||||
[ run rehash_exception_tests.cpp framework ]
|
||||
[ run swap_exception_tests.cpp framework : : :
|
||||
<define>BOOST_UNORDERED_SWAP_METHOD=2 ]
|
||||
;
|
||||
@@ -38,21 +38,18 @@ struct self_assign_test2 : self_assign_base<T>
|
||||
template <class T>
|
||||
struct assign_base : public test::exception_base
|
||||
{
|
||||
const test::random_values<T> x_values, y_values;
|
||||
test::random_values<T> x_values, y_values;
|
||||
T x,y;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME T::hasher hasher;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::key_equal key_equal;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::allocator_type allocator_type;
|
||||
|
||||
assign_base(unsigned int count1, unsigned int count2, int tag1, int tag2,
|
||||
float mlf1 = 1.0, float mlf2 = 1.0) :
|
||||
x_values(count1),
|
||||
y_values(count2),
|
||||
x(x_values.begin(), x_values.end(), 0, hasher(tag1), key_equal(tag1),
|
||||
allocator_type(tag1)),
|
||||
y(y_values.begin(), y_values.end(), 0, hasher(tag2), key_equal(tag2),
|
||||
allocator_type(tag2))
|
||||
assign_base(int tag1, int tag2, float mlf1 = 1.0, float mlf2 = 1.0) :
|
||||
x_values(),
|
||||
y_values(),
|
||||
x(0, hasher(tag1), key_equal(tag1), allocator_type(tag1)),
|
||||
y(0, hasher(tag2), key_equal(tag2), allocator_type(tag2))
|
||||
{
|
||||
x.max_load_factor(mlf1);
|
||||
y.max_load_factor(mlf2);
|
||||
@@ -66,47 +63,80 @@ struct assign_base : public test::exception_base
|
||||
test::check_equivalent_keys(x1);
|
||||
|
||||
// If the container is empty at the point of the exception, the
|
||||
// internal structure is hidden, this exposes it.
|
||||
T& y = const_cast<T&>(x1);
|
||||
// internal structure is hidden, this exposes it, at the cost of
|
||||
// messing up the data.
|
||||
if (x_values.size()) {
|
||||
y.emplace(*x_values.begin());
|
||||
test::check_equivalent_keys(y);
|
||||
T& x2 = const_cast<T&>(x1);
|
||||
x2.emplace(*x_values.begin());
|
||||
test::check_equivalent_keys(x2);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct assign_test1 : assign_base<T>
|
||||
struct assign_values : assign_base<T>
|
||||
{
|
||||
assign_test1() : assign_base<T>(0, 0, 0, 0) {}
|
||||
assign_values(unsigned int count1, unsigned int count2,
|
||||
int tag1, int tag2, float mlf1 = 1.0, float mlf2 = 1.0) :
|
||||
assign_base<T>(tag1, tag2, mlf1, mlf2)
|
||||
{
|
||||
this->x_values.fill(count1);
|
||||
this->y_values.fill(count2);
|
||||
this->x.insert(this->x_values.begin(), this->x_values.end());
|
||||
this->y.insert(this->y_values.begin(), this->y_values.end());
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct assign_test2 : assign_base<T>
|
||||
struct assign_test1 : assign_values<T>
|
||||
{
|
||||
assign_test2() : assign_base<T>(60, 0, 0, 0) {}
|
||||
assign_test1() : assign_values<T>(0, 0, 0, 0) {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct assign_test3 : assign_base<T>
|
||||
struct assign_test2 : assign_values<T>
|
||||
{
|
||||
assign_test3() : assign_base<T>(0, 60, 0, 0) {}
|
||||
assign_test2() : assign_values<T>(60, 0, 0, 0) {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct assign_test4 : assign_base<T>
|
||||
struct assign_test3 : assign_values<T>
|
||||
{
|
||||
assign_test4() : assign_base<T>(10, 10, 1, 2) {}
|
||||
assign_test3() : assign_values<T>(0, 60, 0, 0) {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct assign_test5 : assign_base<T>
|
||||
struct assign_test4 : assign_values<T>
|
||||
{
|
||||
assign_test5() : assign_base<T>(5, 60, 0, 0, 1.0, 0.1) {}
|
||||
assign_test4() : assign_values<T>(10, 10, 1, 2) {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct assign_test5 : assign_values<T>
|
||||
{
|
||||
assign_test5() : assign_values<T>(5, 60, 0, 0, 1.0f, 0.1f) {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct equivalent_test1 : assign_base<T>
|
||||
{
|
||||
equivalent_test1() :
|
||||
assign_base<T>(0, 0)
|
||||
{
|
||||
test::random_values<T> x_values2(10);
|
||||
this->x_values.insert(x_values2.begin(), x_values2.end());
|
||||
this->x_values.insert(x_values2.begin(), x_values2.end());
|
||||
test::random_values<T> y_values2(10);
|
||||
this->y_values.insert(y_values2.begin(), y_values2.end());
|
||||
this->y_values.insert(y_values2.begin(), y_values2.end());
|
||||
this->x.insert(this->x_values.begin(), this->x_values.end());
|
||||
this->y.insert(this->y_values.begin(), this->y_values.end());
|
||||
}
|
||||
};
|
||||
|
||||
EXCEPTION_TESTS(
|
||||
(self_assign_test1)(self_assign_test2)
|
||||
(assign_test1)(assign_test2)(assign_test3)(assign_test4)(assign_test5),
|
||||
(assign_test1)(assign_test2)(assign_test3)(assign_test4)(assign_test5)
|
||||
(equivalent_test1),
|
||||
CONTAINER_SEQ)
|
||||
RUN_TESTS()
|
||||
|
||||
@@ -18,8 +18,8 @@ struct rehash_test_base : public test::exception_base
|
||||
{
|
||||
test::random_values<T> values;
|
||||
unsigned int n;
|
||||
rehash_test_base(unsigned int count = 100, unsigned int n = 0)
|
||||
: values(count), n(n)
|
||||
rehash_test_base(unsigned int count = 100, unsigned int n_ = 0)
|
||||
: values(count), n(n_)
|
||||
{}
|
||||
|
||||
typedef T data_type;
|
||||
|
||||
@@ -66,8 +66,8 @@ struct swap_base : public test::exception_base
|
||||
{}
|
||||
|
||||
struct data_type {
|
||||
data_type(T const& x, T const& y)
|
||||
: x(x), y(y) {}
|
||||
data_type(T const& x_, T const& y_)
|
||||
: x(x_), y(y_) {}
|
||||
|
||||
T x, y;
|
||||
};
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
#define BOOST_UNORDERED_TEST_HELPERS_INPUT_ITERATOR_HEADER
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/iterator.hpp>
|
||||
#include <boost/iterator/iterator_traits.hpp>
|
||||
#include <iterator>
|
||||
|
||||
namespace test
|
||||
{
|
||||
@@ -28,7 +28,7 @@ namespace test
|
||||
|
||||
template <class Iterator>
|
||||
struct input_iterator_adaptor
|
||||
: public boost::iterator<
|
||||
: public std::iterator<
|
||||
std::input_iterator_tag,
|
||||
BOOST_DEDUCED_TYPENAME boost::iterator_value<Iterator>::type,
|
||||
std::ptrdiff_t,
|
||||
@@ -72,7 +72,7 @@ namespace test
|
||||
|
||||
template <class Iterator>
|
||||
struct copy_iterator_adaptor
|
||||
: public boost::iterator<
|
||||
: public std::iterator<
|
||||
BOOST_DEDUCED_TYPENAME boost::iterator_category<Iterator>::type,
|
||||
BOOST_DEDUCED_TYPENAME boost::iterator_value<Iterator>::type,
|
||||
BOOST_DEDUCED_TYPENAME boost::iterator_difference<Iterator>::type,
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
#if !defined(UNORDERED_TEST_LIST_HEADER)
|
||||
#define UNORDERED_TEST_LIST_HEADER
|
||||
|
||||
#include <boost/iterator.hpp>
|
||||
#include <boost/limits.hpp>
|
||||
#include <iterator>
|
||||
#include <functional>
|
||||
|
||||
namespace test
|
||||
@@ -83,7 +83,7 @@ namespace test
|
||||
|
||||
template <typename T>
|
||||
class list_iterator
|
||||
: public boost::iterator<
|
||||
: public std::iterator<
|
||||
std::forward_iterator_tag, T,
|
||||
int, T*, T&>
|
||||
{
|
||||
@@ -109,7 +109,7 @@ namespace test
|
||||
|
||||
template <typename T>
|
||||
class list_const_iterator
|
||||
: public boost::iterator<
|
||||
: public std::iterator<
|
||||
std::forward_iterator_tag, T,
|
||||
int, T const*, T const&>
|
||||
{
|
||||
|
||||
@@ -103,8 +103,16 @@ namespace test
|
||||
struct random_values
|
||||
: public test::list<BOOST_DEDUCED_TYPENAME X::value_type>
|
||||
{
|
||||
random_values(int count, test::random_generator const& generator =
|
||||
random_values() {}
|
||||
|
||||
explicit random_values(int count, test::random_generator const& generator =
|
||||
test::default_generator)
|
||||
{
|
||||
fill(count, generator);
|
||||
}
|
||||
|
||||
void fill(int count, test::random_generator const& generator =
|
||||
test::default_generator)
|
||||
{
|
||||
test::unordered_generator<X> gen(generator);
|
||||
gen.fill(*this, count);
|
||||
|
||||
@@ -148,7 +148,7 @@ namespace test
|
||||
return ptr;
|
||||
}
|
||||
|
||||
pointer allocate(size_type n, void const* u)
|
||||
pointer allocate(size_type n, void const*)
|
||||
{
|
||||
pointer ptr(static_cast<T*>(::operator new(n * sizeof(T))));
|
||||
detail::tracker.track_allocate((void*) ptr, n, sizeof(T), tag_);
|
||||
|
||||
@@ -314,7 +314,7 @@ namespace exception
|
||||
//return pointer(static_cast<T*>(::operator new(n * sizeof(T))));
|
||||
}
|
||||
|
||||
pointer allocate(size_type n, void const* u)
|
||||
pointer allocate(size_type n, void const*)
|
||||
{
|
||||
T* ptr = 0;
|
||||
UNORDERED_SCOPE(allocator::allocate(size_type, const_pointer)) {
|
||||
@@ -494,7 +494,7 @@ namespace exception
|
||||
//return pointer(static_cast<T*>(::operator new(n * sizeof(T))));
|
||||
}
|
||||
|
||||
pointer allocate(size_type n, void const* u)
|
||||
pointer allocate(size_type n, void const*)
|
||||
{
|
||||
T* ptr = 0;
|
||||
UNORDERED_SCOPE(allocator2::allocate(size_type, const_pointer)) {
|
||||
|
||||
@@ -386,7 +386,7 @@ namespace minimal
|
||||
}
|
||||
|
||||
template <class Y>
|
||||
pointer allocate(size_type n, const_ptr<Y> u)
|
||||
pointer allocate(size_type n, const_ptr<Y>)
|
||||
{
|
||||
return pointer(static_cast<T*>(::operator new(n * sizeof(T))));
|
||||
}
|
||||
@@ -462,7 +462,7 @@ namespace minimal
|
||||
}
|
||||
|
||||
template <class Y>
|
||||
T* allocate(std::size_t n, const_ptr<Y> u) {
|
||||
T* allocate(std::size_t n, const_ptr<Y>) {
|
||||
return static_cast<T*>(::operator new(n * sizeof(T)));
|
||||
}
|
||||
|
||||
|
||||
@@ -347,7 +347,7 @@ namespace test
|
||||
return ptr;
|
||||
}
|
||||
|
||||
T* allocate(std::size_t n, void const* u)
|
||||
T* allocate(std::size_t n, void const*)
|
||||
{
|
||||
T* ptr(static_cast<T*>(::operator new(n * sizeof(T))));
|
||||
detail::tracker.track_allocate((void*) ptr, n, sizeof(T), tag_);
|
||||
@@ -573,7 +573,7 @@ namespace test
|
||||
return p;
|
||||
}
|
||||
|
||||
pointer allocate(size_type n, void const* u)
|
||||
pointer allocate(size_type n, void const*)
|
||||
{
|
||||
pointer ptr(static_cast<T*>(::operator new(n * sizeof(T))));
|
||||
detail::tracker.track_allocate((void*) ptr, n, sizeof(T), tag_);
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
|
||||
# Copyright 2006-2008 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)
|
||||
|
||||
import testing ;
|
||||
|
||||
project unordered-test/unordered
|
||||
: requirements
|
||||
<warnings>all
|
||||
<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"
|
||||
;
|
||||
|
||||
test-suite unordered
|
||||
:
|
||||
[ run fwd_set_test.cpp ]
|
||||
[ run fwd_map_test.cpp ]
|
||||
[ run allocator_traits.cpp ]
|
||||
[ 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 ]
|
||||
[ run equivalent_keys_tests.cpp ]
|
||||
[ run constructor_tests.cpp ]
|
||||
[ run copy_tests.cpp ]
|
||||
[ run move_tests.cpp ]
|
||||
[ run assign_tests.cpp ]
|
||||
[ run insert_tests.cpp ]
|
||||
[ run insert_stable_tests.cpp ]
|
||||
[ run unnecessary_copy_tests.cpp ]
|
||||
[ run erase_tests.cpp ]
|
||||
[ run erase_equiv_tests.cpp ]
|
||||
[ run find_tests.cpp ]
|
||||
[ run at_tests.cpp ]
|
||||
[ run bucket_tests.cpp ]
|
||||
[ run load_factor_tests.cpp ]
|
||||
[ run rehash_tests.cpp ]
|
||||
[ run equality_tests.cpp ]
|
||||
[ run swap_tests.cpp ]
|
||||
|
||||
[ run compile_set.cpp : :
|
||||
: <define>BOOST_UNORDERED_USE_MOVE
|
||||
: bmove_compile_set ]
|
||||
[ run compile_map.cpp : :
|
||||
: <define>BOOST_UNORDERED_USE_MOVE
|
||||
: bmove_compile_map ]
|
||||
[ run copy_tests.cpp : :
|
||||
: <define>BOOST_UNORDERED_USE_MOVE
|
||||
: bmove_copy ]
|
||||
[ run move_tests.cpp : :
|
||||
: <define>BOOST_UNORDERED_USE_MOVE
|
||||
: bmove_move ]
|
||||
[ run assign_tests.cpp : :
|
||||
: <define>BOOST_UNORDERED_USE_MOVE
|
||||
: bmove_assign ]
|
||||
;
|
||||
@@ -22,9 +22,9 @@
|
||||
T const* address(T const& r) { return &r; } \
|
||||
T* allocate(std::size_t n) \
|
||||
{ return static_cast<T*>(::operator new(n * sizeof(T))); } \
|
||||
T* allocate(std::size_t n, void const* u) \
|
||||
T* allocate(std::size_t n, void const*) \
|
||||
{ return static_cast<T*>(::operator new(n * sizeof(T))); } \
|
||||
void deallocate(T* p, std::size_t n) { ::operator delete((void*) p); } \
|
||||
void deallocate(T* p, std::size_t) { ::operator delete((void*) p); } \
|
||||
void construct(T* p, T const& t) { new(p) T(t); } \
|
||||
void destroy(T* p) { p->~T(); } \
|
||||
std::size_t max_size() const \
|
||||
@@ -44,9 +44,9 @@
|
||||
const_pointer address(T const& r) { return &r; } \
|
||||
pointer allocate(std::size_t n) \
|
||||
{ return pointer(::operator new(n * sizeof(T))); } \
|
||||
pointer allocate(std::size_t n, void const* u) \
|
||||
pointer allocate(std::size_t n, void const*) \
|
||||
{ return pointer(::operator new(n * sizeof(T))); } \
|
||||
void deallocate(pointer p, std::size_t n) \
|
||||
void deallocate(pointer p, std::size_t) \
|
||||
{ ::operator delete((void*) p); } \
|
||||
void construct(T* p, T const& t) { new(p) T(t); } \
|
||||
void destroy(T* p) { p->~T(); } \
|
||||
|
||||
@@ -16,7 +16,6 @@ UNORDERED_AUTO_TEST(at_tests) {
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Create Map" << std::endl;
|
||||
|
||||
boost::unordered_map<std::string, int> x;
|
||||
typedef boost::unordered_map<std::string, int>::iterator iterator;
|
||||
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Add elements" << std::endl;
|
||||
|
||||
|
||||
@@ -148,6 +148,7 @@ void unordered_destructible_test(X&)
|
||||
X* ptr = new X();
|
||||
X& a1 = *ptr;
|
||||
(&a1)->~X();
|
||||
::operator delete((void*)(&a1));
|
||||
|
||||
X a,b;
|
||||
X const a_const;
|
||||
|
||||
@@ -95,12 +95,16 @@ void erase_tests1(Container*, test::random_generator generator)
|
||||
BOOST_DEDUCED_TYPENAME Container::key_type
|
||||
key = test::get_key<Container>(*pos);
|
||||
std::size_t count = x.count(key);
|
||||
BOOST_TEST(count > 0);
|
||||
BOOST_TEST(next == x.erase(pos));
|
||||
--size;
|
||||
if(size > 0)
|
||||
BOOST_TEST(index == 0 ? next == x.begin() :
|
||||
next == boost::next(prev));
|
||||
BOOST_TEST(x.count(key) == count - 1);
|
||||
if (x.count(key) != count - 1) {
|
||||
std::cerr << count << " => " << x.count(key) << std::endl;
|
||||
}
|
||||
BOOST_TEST(x.size() == size);
|
||||
if (++iterations % 20 == 0) test::check_equivalent_keys(x);
|
||||
}
|
||||
@@ -180,12 +184,16 @@ void erase_tests1(Container*, test::random_generator generator)
|
||||
BOOST_DEDUCED_TYPENAME Container::key_type
|
||||
key = test::get_key<Container>(*pos);
|
||||
std::size_t count = x.count(key);
|
||||
BOOST_TEST(count > 0);
|
||||
x.quick_erase(pos);
|
||||
--size;
|
||||
if(size > 0)
|
||||
BOOST_TEST(index == 0 ? next == x.begin() :
|
||||
next == boost::next(prev));
|
||||
BOOST_TEST(x.count(key) == count - 1);
|
||||
if (x.count(key) != count - 1) {
|
||||
std::cerr << count << " => " << x.count(key) << std::endl;
|
||||
}
|
||||
BOOST_TEST(x.size() == size);
|
||||
if (++iterations % 20 == 0) test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
@@ -40,8 +40,10 @@ void find_tests1(X*, test::random_generator generator)
|
||||
iterator pos = x.find(key);
|
||||
BOOST_DEDUCED_TYPENAME X::const_iterator
|
||||
const_pos = x_const.find(key);
|
||||
BOOST_TEST(pos != x.end());
|
||||
BOOST_TEST(pos != x.end() &&
|
||||
x.key_eq()(key, test::get_key<X>(*pos)));
|
||||
BOOST_TEST(const_pos != x_const.end());
|
||||
BOOST_TEST(const_pos != x_const.end() &&
|
||||
x_const.key_eq()(key, test::get_key<X>(*const_pos)));
|
||||
|
||||
|
||||
@@ -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"
|
||||
@@ -599,7 +598,7 @@ UNORDERED_AUTO_TEST(insert_initializer_list_set)
|
||||
|
||||
boost::unordered_set<initialize_from_two_ints> set2;
|
||||
|
||||
#if BOOST_COMP_GNUC && BOOST_COMP_GNUC < BOOST_VERSION_NUMBER(4,5,0)
|
||||
#if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5))
|
||||
set2.insert({{1, 2}});
|
||||
#else
|
||||
set2.insert({1, 2});
|
||||
|
||||
@@ -18,7 +18,7 @@ struct SimpleAllocator
|
||||
{
|
||||
}
|
||||
|
||||
template <class T> SimpleAllocator(const SimpleAllocator<T>& other)
|
||||
template <class T> SimpleAllocator(const SimpleAllocator<T>&)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user