Remove the grouped node stuff

This commit is contained in:
Daniel James
2017-04-27 18:22:43 +01:00
parent 94a3a9baf9
commit ea64f2e46e
9 changed files with 3 additions and 268 deletions

View File

@ -38,14 +38,6 @@ matrix:
env: |
label="clang 32 bit";
user_config="using clang : : clang++ -m32 -Werror --std=c++03 ;"
- compiler: gcc
env: |
label="gcc C++03 interopable1";
user_config="using gcc : : g++-4.8 -fsanitize=address -Werror --std=c++03 -DBOOST_UNORDERED_INTEROPERABLE_NODES=1 ;"
- compiler: clang
env: |
label="gcc C++11 interopable2";
user_config="using clang : : clang++ -fsanitize=address -Werror --std=c++03 -DBOOST_UNORDERED_INTEROPERABLE_NODES=2 ;"
before_script:
- cd ${TRAVIS_BUILD_DIR}

View File

@ -66,19 +66,6 @@
#define BOOST_UNORDERED_EMPLACE_LIMIT 10
#endif
// BOOST_UNORDERED_INTEROPERABLE_NODES - Use the same node type for
// containers with unique and equivalent keys.
//
// 0 = Use different nodes
// 1 = Use ungrouped nodes everywhere
// 2 = Use grouped nodes everywhere
//
// Might add an extra value to use grouped nodes everywhere later.
#if !defined(BOOST_UNORDERED_INTEROPERABLE_NODES)
#define BOOST_UNORDERED_INTEROPERABLE_NODES 0
#endif
// BOOST_UNORDERED_USE_ALLOCATOR_TRAITS - Pick which version of
// allocator_traits to use.
//
@ -190,10 +177,6 @@ template <typename A, typename T> struct node;
template <typename T> struct ptr_node;
template <typename N> struct node_algo;
template <typename A, typename T> struct grouped_node;
template <typename T> struct grouped_ptr_node;
template <typename N> struct grouped_node_algo;
static const float minimum_max_load_factor = 1e-3f;
static const std::size_t default_bucket_count = 11;
@ -4565,210 +4548,6 @@ template <typename A, typename T> struct pick_node
typedef typename pick::link_pointer link_pointer;
typedef boost::unordered::detail::node_algo<node> node_algo;
};
////////////////////////////////////////////////////////////////////////
// Grouped nodes
template <typename A, typename T>
struct grouped_node : boost::unordered::detail::value_base<T>
{
typedef typename ::boost::unordered::detail::rebind_wrap<A,
grouped_node<A, T> >::type allocator;
typedef typename ::boost::unordered::detail::allocator_traits<
allocator>::pointer node_pointer;
typedef node_pointer link_pointer;
typedef typename ::boost::unordered::detail::rebind_wrap<A,
bucket<node_pointer> >::type bucket_allocator;
typedef typename ::boost::unordered::detail::allocator_traits<
bucket_allocator>::pointer bucket_pointer;
link_pointer next_;
node_pointer group_prev_;
std::size_t hash_;
grouped_node() : next_(), group_prev_(), hash_(0) {}
void init(node_pointer self) { group_prev_ = self; }
private:
grouped_node& operator=(grouped_node const&);
};
template <typename T>
struct grouped_ptr_node : boost::unordered::detail::ptr_bucket
{
typedef T value_type;
typedef boost::unordered::detail::ptr_bucket bucket_base;
typedef grouped_ptr_node<T>* node_pointer;
typedef ptr_bucket* link_pointer;
typedef ptr_bucket* bucket_pointer;
node_pointer group_prev_;
std::size_t hash_;
boost::unordered::detail::value_base<T> value_base_;
grouped_ptr_node() : bucket_base(), group_prev_(0), hash_(0) {}
void init(node_pointer self) { group_prev_ = self; }
void* address() { return value_base_.address(); }
value_type& value() { return value_base_.value(); }
value_type* value_ptr() { return value_base_.value_ptr(); }
private:
grouped_ptr_node& operator=(grouped_ptr_node const&);
};
template <typename N> struct grouped_node_algo
{
typedef typename N::node_pointer node_pointer;
typedef typename N::link_pointer link_pointer;
typedef typename N::bucket_pointer bucket_pointer;
static node_pointer next_node(link_pointer n)
{
return static_cast<node_pointer>(n->next_);
}
static node_pointer next_for_find(node_pointer n)
{
return static_cast<node_pointer>(n->group_prev_->next_);
}
static link_pointer next_for_erase(link_pointer prev)
{
return static_cast<node_pointer>(prev->next_)->group_prev_;
}
static node_pointer last_for_rehash(link_pointer prev)
{
return static_cast<node_pointer>(prev->next_)->group_prev_;
}
// The 'void*' arguments are pointers to the table, which we
// will ignore, but without groups they could be used to
// access the various functions for dealing with values and keys.
static node_pointer next_group(node_pointer n, void const*)
{
return static_cast<node_pointer>(n->group_prev_->next_);
}
static std::size_t count(node_pointer n, void const*)
{
std::size_t x = 0;
node_pointer it = n;
do {
it = it->group_prev_;
++x;
} while (it != n);
return x;
}
// Adds node 'n' to the group containing 'pos'.
// If 'pos' is the first node in group, add to the end of the group,
// otherwise add before 'pos'. Other versions will probably behave
// differently.
static inline void add_to_node(node_pointer n, node_pointer pos)
{
n->next_ = pos->group_prev_->next_;
n->group_prev_ = pos->group_prev_;
pos->group_prev_->next_ = n;
pos->group_prev_ = n;
}
static inline node_pointer extract_first_node(link_pointer prev)
{
node_pointer n = next_node(prev);
if (n->group_prev_ != n) {
node_pointer next = next_node(n);
next->group_prev_ = n->group_prev_;
n->group_prev_ = n;
}
prev->next_ = n->next_;
return n;
}
// Split the groups containing 'i' and 'j' so that they can
// be safely erased/extracted.
static link_pointer split_groups(node_pointer i, node_pointer j)
{
node_pointer prev = i->group_prev_;
if (prev->next_ != i)
prev = node_pointer();
if (j) {
node_pointer first = j;
while (first != i && first->group_prev_->next_ == first) {
first = first->group_prev_;
}
boost::swap(first->group_prev_, j->group_prev_);
if (first == i)
return prev;
}
if (prev) {
node_pointer first = prev;
while (first->group_prev_->next_ == first) {
first = first->group_prev_;
}
boost::swap(first->group_prev_, i->group_prev_);
}
return prev;
}
};
// If the allocator uses raw pointers use grouped_ptr_node
// Otherwise use grouped_node.
template <typename A, typename T, typename NodePtr, typename BucketPtr>
struct pick_grouped_node2
{
typedef boost::unordered::detail::grouped_node<A, T> node;
typedef typename boost::unordered::detail::allocator_traits<
typename boost::unordered::detail::rebind_wrap<A, node>::type>::pointer
node_pointer;
typedef boost::unordered::detail::bucket<node_pointer> bucket;
typedef node_pointer link_pointer;
};
template <typename A, typename T>
struct pick_grouped_node2<A, T, boost::unordered::detail::grouped_ptr_node<T>*,
boost::unordered::detail::ptr_bucket*>
{
typedef boost::unordered::detail::grouped_ptr_node<T> node;
typedef boost::unordered::detail::ptr_bucket bucket;
typedef bucket* link_pointer;
};
template <typename A, typename T> struct pick_grouped_node
{
typedef typename boost::remove_const<T>::type nonconst;
typedef boost::unordered::detail::allocator_traits<
typename boost::unordered::detail::rebind_wrap<A,
boost::unordered::detail::grouped_ptr_node<nonconst> >::type>
tentative_node_traits;
typedef boost::unordered::detail::allocator_traits<
typename boost::unordered::detail::rebind_wrap<A,
boost::unordered::detail::ptr_bucket>::type>
tentative_bucket_traits;
typedef pick_grouped_node2<A, nonconst,
typename tentative_node_traits::pointer,
typename tentative_bucket_traits::pointer>
pick;
typedef typename pick::node node;
typedef typename pick::bucket bucket;
typedef typename pick::link_pointer link_pointer;
typedef boost::unordered::detail::grouped_node_algo<node> node_algo;
};
}
}
}

View File

@ -23,11 +23,7 @@ template <typename A, typename K, typename M, typename H, typename P> struct map
typedef boost::unordered::detail::allocator_traits<value_allocator>
value_allocator_traits;
#if BOOST_UNORDERED_INTEROPERABLE_NODES != 2
typedef boost::unordered::detail::pick_node<A, value_type> pick;
#else
typedef boost::unordered::detail::pick_grouped_node<A, value_type> pick;
#endif
typedef typename pick::node node;
typedef typename pick::bucket bucket;
typedef typename pick::link_pointer link_pointer;
@ -69,11 +65,7 @@ struct multimap
typedef boost::unordered::detail::allocator_traits<value_allocator>
value_allocator_traits;
#if BOOST_UNORDERED_INTEROPERABLE_NODES != 1
typedef boost::unordered::detail::pick_grouped_node<A, value_type> pick;
#else
typedef boost::unordered::detail::pick_node<A, value_type> pick;
#endif
typedef typename pick::node node;
typedef typename pick::bucket bucket;
typedef typename pick::link_pointer link_pointer;

View File

@ -23,11 +23,7 @@ template <typename A, typename T, typename H, typename P> struct set
typedef boost::unordered::detail::allocator_traits<value_allocator>
value_allocator_traits;
#if BOOST_UNORDERED_INTEROPERABLE_NODES != 2
typedef boost::unordered::detail::pick_node<A, value_type> pick;
#else
typedef boost::unordered::detail::pick_grouped_node<A, value_type> pick;
#endif
typedef typename pick::node node;
typedef typename pick::bucket bucket;
typedef typename pick::link_pointer link_pointer;
@ -68,11 +64,7 @@ template <typename A, typename T, typename H, typename P> struct multiset
typedef boost::unordered::detail::allocator_traits<value_allocator>
value_allocator_traits;
#if BOOST_UNORDERED_INTEROPERABLE_NODES != 1
typedef boost::unordered::detail::pick_grouped_node<A, value_type> pick;
#else
typedef boost::unordered::detail::pick_node<A, value_type> pick;
#endif
typedef typename pick::node node;
typedef typename pick::bucket bucket;
typedef typename pick::link_pointer link_pointer;

View File

@ -740,14 +740,12 @@ template <class K, class T, class H, class P, class A> class unordered_map
void merge(boost::unordered_map<K, T, H2, P2, A>&& source);
#endif
#if BOOST_UNORDERED_INTEROPERABLE_NODES
template <typename H2, typename P2>
void merge(boost::unordered_multimap<K, T, H2, P2, A>& source);
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template <typename H2, typename P2>
void merge(boost::unordered_multimap<K, T, H2, P2, A>&& source);
#endif
#endif
// observers
@ -1277,14 +1275,12 @@ template <class K, class T, class H, class P, class A> class unordered_multimap
void merge(boost::unordered_multimap<K, T, H2, P2, A>&& source);
#endif
#if BOOST_UNORDERED_INTEROPERABLE_NODES
template <typename H2, typename P2>
void merge(boost::unordered_map<K, T, H2, P2, A>& source);
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template <typename H2, typename P2>
void merge(boost::unordered_map<K, T, H2, P2, A>&& source);
#endif
#endif
// observers
@ -1644,7 +1640,6 @@ void unordered_map<K, T, H, P, A>::merge(
}
#endif
#if BOOST_UNORDERED_INTEROPERABLE_NODES
template <class K, class T, class H, class P, class A>
template <typename H2, typename P2>
void unordered_map<K, T, H, P, A>::merge(
@ -1662,7 +1657,6 @@ void unordered_map<K, T, H, P, A>::merge(
table_.merge_unique(source.table_);
}
#endif
#endif
// observers
@ -2152,7 +2146,6 @@ void unordered_multimap<K, T, H, P, A>::merge(
}
#endif
#if BOOST_UNORDERED_INTEROPERABLE_NODES
template <class K, class T, class H, class P, class A>
template <typename H2, typename P2>
void unordered_multimap<K, T, H, P, A>::merge(
@ -2174,7 +2167,6 @@ void unordered_multimap<K, T, H, P, A>::merge(
}
}
#endif
#endif
// lookup

View File

@ -457,14 +457,12 @@ template <class T, class H, class P, class A> class unordered_set
void merge(boost::unordered_set<T, H2, P2, A>&& source);
#endif
#if BOOST_UNORDERED_INTEROPERABLE_NODES
template <typename H2, typename P2>
void merge(boost::unordered_multiset<T, H2, P2, A>& source);
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template <typename H2, typename P2>
void merge(boost::unordered_multiset<T, H2, P2, A>&& source);
#endif
#endif
// observers
@ -962,14 +960,12 @@ template <class T, class H, class P, class A> class unordered_multiset
void merge(boost::unordered_multiset<T, H2, P2, A>&& source);
#endif
#if BOOST_UNORDERED_INTEROPERABLE_NODES
template <typename H2, typename P2>
void merge(boost::unordered_set<T, H2, P2, A>& source);
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template <typename H2, typename P2>
void merge(boost::unordered_set<T, H2, P2, A>&& source);
#endif
#endif
// observers
@ -1322,7 +1318,6 @@ void unordered_set<T, H, P, A>::merge(
}
#endif
#if BOOST_UNORDERED_INTEROPERABLE_NODES
template <class T, class H, class P, class A>
template <typename H2, typename P2>
void unordered_set<T, H, P, A>::merge(
@ -1340,7 +1335,6 @@ void unordered_set<T, H, P, A>::merge(
table_.merge_unique(source.table_);
}
#endif
#endif
// lookup
@ -1732,7 +1726,6 @@ void unordered_multiset<T, H, P, A>::merge(
}
#endif
#if BOOST_UNORDERED_INTEROPERABLE_NODES
template <class T, class H, class P, class A>
template <typename H2, typename P2>
void unordered_multiset<T, H, P, A>::merge(
@ -1754,7 +1747,6 @@ void unordered_multiset<T, H, P, A>::merge(
}
}
#endif
#endif
// lookup

View File

@ -93,8 +93,6 @@ static inline void run_tests()
<< BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT << "\n" \
<< "BOOST_UNORDERED_EMPLACE_LIMIT: " \
<< BOOST_UNORDERED_EMPLACE_LIMIT << "\n" \
<< "BOOST_UNORDERED_INTEROPERABLE_NODES: " \
<< BOOST_UNORDERED_INTEROPERABLE_NODES << "\n" \
<< "BOOST_UNORDERED_USE_ALLOCATOR_TRAITS: " \
<< BOOST_UNORDERED_USE_ALLOCATOR_TRAITS << "\n" \
<< "BOOST_UNORDERED_CXX11_CONSTRUCTION: " \

View File

@ -47,9 +47,9 @@ std::size_t hash_value(insert_stable::member const& x)
}
}
// This is now only supported when using grouped nodes. I can't see any
// efficient way to do it otherwise.
#if !BOOST_UNORDERED_INTEROPERABLE_NODES
// This is no longer supported, as there's no longer an efficient way to get to
// the end of a group of equivalent nodes.
#if 0
UNORDERED_AUTO_TEST(stable_insert_test1)
{

View File

@ -99,7 +99,6 @@ UNORDERED_AUTO_TEST(merge_multiset)
test::check_equivalent_keys(y);
}
#if BOOST_UNORDERED_INTEROPERABLE_NODES
UNORDERED_AUTO_TEST(merge_set_and_multiset)
{
boost::unordered_set<int> x;
@ -139,7 +138,6 @@ UNORDERED_AUTO_TEST(merge_set_and_multiset)
test::check_equivalent_keys(x);
test::check_equivalent_keys(y);
}
#endif
template <class X> void merge_empty_test(X*, test::random_generator generator)
{