forked from boostorg/unordered
Remove the grouped node stuff
This commit is contained in:
@ -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}
|
||||
|
@ -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;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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: " \
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
Reference in New Issue
Block a user