mirror of
https://github.com/boostorg/unordered.git
synced 2025-07-31 03:47:16 +02:00
Unordered: More misc. cleanup.
Including removing node.hpp. [SVN r74775]
This commit is contained in:
@ -564,7 +564,7 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
template <class H, class P>
|
template <class H, class P>
|
||||||
class functions
|
class functions
|
||||||
{
|
{
|
||||||
friend class set_hash_functions<H, P>;
|
friend class boost::unordered::detail::set_hash_functions<H, P>;
|
||||||
functions& operator=(functions const&);
|
functions& operator=(functions const&);
|
||||||
|
|
||||||
typedef compressed<H, P> function_pair;
|
typedef compressed<H, P> function_pair;
|
||||||
|
@ -21,26 +21,26 @@ namespace unordered
|
|||||||
{
|
{
|
||||||
template <class K,
|
template <class K,
|
||||||
class T,
|
class T,
|
||||||
class H = hash<K>,
|
class H = boost::hash<K>,
|
||||||
class P = std::equal_to<K>,
|
class P = std::equal_to<K>,
|
||||||
class A = std::allocator<std::pair<const K, T> > >
|
class A = std::allocator<std::pair<const K, T> > >
|
||||||
class unordered_map;
|
class unordered_map;
|
||||||
|
|
||||||
template <class K,
|
template <class K,
|
||||||
class T,
|
class T,
|
||||||
class H = hash<K>,
|
class H = boost::hash<K>,
|
||||||
class P = std::equal_to<K>,
|
class P = std::equal_to<K>,
|
||||||
class A = std::allocator<std::pair<const K, T> > >
|
class A = std::allocator<std::pair<const K, T> > >
|
||||||
class unordered_multimap;
|
class unordered_multimap;
|
||||||
|
|
||||||
template <class T,
|
template <class T,
|
||||||
class H = hash<T>,
|
class H = boost::hash<T>,
|
||||||
class P = std::equal_to<T>,
|
class P = std::equal_to<T>,
|
||||||
class A = std::allocator<T> >
|
class A = std::allocator<T> >
|
||||||
class unordered_set;
|
class unordered_set;
|
||||||
|
|
||||||
template <class T,
|
template <class T,
|
||||||
class H = hash<T>,
|
class H = boost::hash<T>,
|
||||||
class P = std::equal_to<T>,
|
class P = std::equal_to<T>,
|
||||||
class A = std::allocator<T> >
|
class A = std::allocator<T> >
|
||||||
class unordered_multiset;
|
class unordered_multiset;
|
||||||
|
@ -1,364 +0,0 @@
|
|||||||
|
|
||||||
// Copyright (C) 2003-2004 Jeremy B. Maitin-Shepard.
|
|
||||||
// Copyright (C) 2005-2011 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)
|
|
||||||
|
|
||||||
// This contains the basic data structure, apart from the actual values. There's
|
|
||||||
// no construction or deconstruction here. So this only depends on the pointer
|
|
||||||
// type.
|
|
||||||
|
|
||||||
#ifndef BOOST_UNORDERED_DETAIL_NODE_HPP_INCLUDED
|
|
||||||
#define BOOST_UNORDERED_DETAIL_NODE_HPP_INCLUDED
|
|
||||||
|
|
||||||
#include <boost/unordered/detail/util.hpp>
|
|
||||||
|
|
||||||
#if BOOST_WORKAROUND(__BORLANDC__, <= 0X0582)
|
|
||||||
#define BOOST_UNORDERED_BORLAND_BOOL(x) (bool)(x)
|
|
||||||
#else
|
|
||||||
#define BOOST_UNORDERED_BORLAND_BOOL(x) x
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace boost { namespace unordered { namespace detail {
|
|
||||||
|
|
||||||
// Some forward declarations for buckets and tables
|
|
||||||
|
|
||||||
template <typename T> class table;
|
|
||||||
template <class A, bool Unique> class buckets;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// This section implements buckets and nodes. Here's a rough
|
|
||||||
// inheritance diagram, to show how they pull together.
|
|
||||||
//
|
|
||||||
// For unordered_set/unordered_map:
|
|
||||||
//
|
|
||||||
// bucket<A> value_base<allocator_traits<A>::value_type>
|
|
||||||
// | |
|
|
||||||
// +--------------+-------------+
|
|
||||||
// |
|
|
||||||
// ungrouped_node<A>
|
|
||||||
//
|
|
||||||
// For unordered_multiset/unordered_multimap:
|
|
||||||
//
|
|
||||||
// bucket<A> value_base<allocator_traits<A>::value_type>
|
|
||||||
// | |
|
|
||||||
// +--------------+-------------+
|
|
||||||
// |
|
|
||||||
// grouped_node<A>
|
|
||||||
|
|
||||||
// bucket
|
|
||||||
//
|
|
||||||
// bucket is used for both the buckets and as a base class for
|
|
||||||
// nodes. By using 'bucket_ptr' for 'node_ptr', 'next_' can point
|
|
||||||
// to either a bucket or a node. This is used later to implement a
|
|
||||||
// sentinel at the end of the bucket array.
|
|
||||||
|
|
||||||
template <class A>
|
|
||||||
class bucket
|
|
||||||
{
|
|
||||||
bucket& operator=(bucket const&);
|
|
||||||
public:
|
|
||||||
typedef typename ::boost::unordered::detail::rebind_wrap<A, bucket>::type
|
|
||||||
bucket_allocator;
|
|
||||||
typedef typename allocator_traits<bucket_allocator>::pointer bucket_ptr;
|
|
||||||
typedef bucket_ptr node_ptr;
|
|
||||||
|
|
||||||
node_ptr next_;
|
|
||||||
|
|
||||||
bucket() : next_() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
// The space used to store values in a node.
|
|
||||||
|
|
||||||
template <class ValueType>
|
|
||||||
struct value_base
|
|
||||||
{
|
|
||||||
typedef ValueType value_type;
|
|
||||||
typename ::boost::aligned_storage<
|
|
||||||
sizeof(value_type),
|
|
||||||
::boost::alignment_of<value_type>::value>::type data_;
|
|
||||||
|
|
||||||
void* address() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
value_type& value() {
|
|
||||||
return *(ValueType*) this;
|
|
||||||
}
|
|
||||||
value_type* value_ptr() {
|
|
||||||
return (ValueType*) this;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
value_base& operator=(value_base const&);
|
|
||||||
};
|
|
||||||
|
|
||||||
// In containers with equivalent keys (unordered_multimap and
|
|
||||||
// unordered_multiset) equivalent nodes are grouped together, in
|
|
||||||
// containers with unique keys (unordered_map and unordered_set)
|
|
||||||
// individual nodes are treated as groups of one. The following two
|
|
||||||
// classes implement the data structure.
|
|
||||||
|
|
||||||
// This is used for containers with unique keys. There are no groups
|
|
||||||
// so it doesn't add any extra members, and just treats individual
|
|
||||||
// nodes as groups of one.
|
|
||||||
|
|
||||||
template <class A>
|
|
||||||
struct ungrouped_node
|
|
||||||
: ::boost::unordered::detail::bucket<A>,
|
|
||||||
value_base<typename allocator_traits<A>::value_type>
|
|
||||||
{
|
|
||||||
typedef ::boost::unordered::detail::bucket<A> bucket;
|
|
||||||
typedef typename bucket::bucket_ptr bucket_ptr;
|
|
||||||
typedef typename bucket::node_ptr node_ptr;
|
|
||||||
typedef typename allocator_traits<A>::value_type value_type;
|
|
||||||
|
|
||||||
std::size_t hash_;
|
|
||||||
|
|
||||||
ungrouped_node() : bucket() {}
|
|
||||||
|
|
||||||
void init(node_ptr) {}
|
|
||||||
|
|
||||||
static node_ptr next_group(node_ptr ptr)
|
|
||||||
{
|
|
||||||
return ptr->next_;
|
|
||||||
}
|
|
||||||
|
|
||||||
static node_ptr next_group2(node_ptr ptr)
|
|
||||||
{
|
|
||||||
return ptr->next_;
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::size_t group_count(node_ptr n)
|
|
||||||
{
|
|
||||||
return !n ? 0 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void add_after_node(node_ptr n, node_ptr position)
|
|
||||||
{
|
|
||||||
n->next_ = position->next_;
|
|
||||||
position->next_ = position;
|
|
||||||
}
|
|
||||||
|
|
||||||
static node_ptr unlink_node(bucket& b, node_ptr n)
|
|
||||||
{
|
|
||||||
return unlink_nodes(b, n, n->next_);
|
|
||||||
}
|
|
||||||
|
|
||||||
static node_ptr unlink_nodes(bucket& b, node_ptr begin, node_ptr end)
|
|
||||||
{
|
|
||||||
node_ptr prev = b.next_;
|
|
||||||
while(prev->next_ != begin) prev = prev->next_;
|
|
||||||
prev->next_ = end;
|
|
||||||
return prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::size_t get_hash(node_ptr p)
|
|
||||||
{
|
|
||||||
return static_cast<ungrouped_node&>(*p).hash_;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void set_hash(node_ptr p, std::size_t hash)
|
|
||||||
{
|
|
||||||
static_cast<ungrouped_node&>(*p).hash_ = hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
static value_type& get_value(node_ptr p)
|
|
||||||
{
|
|
||||||
return static_cast<ungrouped_node&>(*p).value();
|
|
||||||
}
|
|
||||||
|
|
||||||
static value_type* get_value_ptr(node_ptr p)
|
|
||||||
{
|
|
||||||
return static_cast<ungrouped_node&>(*p).value_ptr();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// This is used for containers with equivalent keys. It implements a
|
|
||||||
// circular list running in the opposite direction to the linked
|
|
||||||
// list through the nodes.
|
|
||||||
|
|
||||||
template <class A>
|
|
||||||
struct grouped_node
|
|
||||||
: ::boost::unordered::detail::bucket<A>,
|
|
||||||
value_base<typename allocator_traits<A>::value_type>
|
|
||||||
{
|
|
||||||
typedef ::boost::unordered::detail::bucket<A> bucket;
|
|
||||||
typedef typename bucket::bucket_ptr bucket_ptr;
|
|
||||||
typedef typename bucket::node_ptr node_ptr;
|
|
||||||
typedef typename allocator_traits<A>::value_type value_type;
|
|
||||||
|
|
||||||
std::size_t hash_;
|
|
||||||
node_ptr group_prev_;
|
|
||||||
|
|
||||||
grouped_node() : bucket(), group_prev_() {}
|
|
||||||
void init(node_ptr n)
|
|
||||||
{
|
|
||||||
group_prev_ = n;
|
|
||||||
}
|
|
||||||
|
|
||||||
static node_ptr next_group(node_ptr ptr)
|
|
||||||
{
|
|
||||||
return get(ptr).group_prev_->next_;
|
|
||||||
}
|
|
||||||
|
|
||||||
static node_ptr next_group2(node_ptr ptr)
|
|
||||||
{
|
|
||||||
return get(ptr->next_).group_prev_;
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::size_t group_count(node_ptr ptr)
|
|
||||||
{
|
|
||||||
if (!ptr) return 0;
|
|
||||||
|
|
||||||
node_ptr start = ptr;
|
|
||||||
std::size_t size = 0;
|
|
||||||
do {
|
|
||||||
++size;
|
|
||||||
ptr = get(ptr).group_prev_;
|
|
||||||
} while(ptr != start);
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void add_after_node(node_ptr n, node_ptr pos)
|
|
||||||
{
|
|
||||||
n->next_ = get(pos).group_prev_->next_;
|
|
||||||
get(n).group_prev_ = get(pos).group_prev_;
|
|
||||||
get(pos).group_prev_->next_ = n;
|
|
||||||
get(pos).group_prev_ = n;
|
|
||||||
}
|
|
||||||
|
|
||||||
static node_ptr unlink_node(bucket& b, node_ptr n)
|
|
||||||
{
|
|
||||||
node_ptr next = n->next_;
|
|
||||||
node_ptr prev = get(n).group_prev_;
|
|
||||||
|
|
||||||
if(prev->next_ != n) {
|
|
||||||
// The node is at the beginning of a group.
|
|
||||||
|
|
||||||
// Find the previous node pointer:
|
|
||||||
prev = b.next_;
|
|
||||||
while(prev->next_ != n) {
|
|
||||||
prev = next_group2(prev);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove from group
|
|
||||||
if(BOOST_UNORDERED_BORLAND_BOOL(next) &&
|
|
||||||
get(next).group_prev_ == n)
|
|
||||||
{
|
|
||||||
get(next).group_prev_ = get(n).group_prev_;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(BOOST_UNORDERED_BORLAND_BOOL(next) &&
|
|
||||||
get(next).group_prev_ == n)
|
|
||||||
{
|
|
||||||
// The deleted node is not at the end of the group, so
|
|
||||||
// change the link from the next node.
|
|
||||||
get(next).group_prev_ = get(n).group_prev_;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// The deleted node is at the end of the group, so the
|
|
||||||
// first node in the group is pointing to it.
|
|
||||||
// Find that to change its pointer.
|
|
||||||
node_ptr x = get(n).group_prev_;
|
|
||||||
while(get(x).group_prev_ != n) {
|
|
||||||
x = get(x).group_prev_;
|
|
||||||
}
|
|
||||||
get(x).group_prev_ = get(n).group_prev_;
|
|
||||||
}
|
|
||||||
prev->next_ = next;
|
|
||||||
|
|
||||||
return prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
static node_ptr unlink_nodes(bucket& b, node_ptr begin, node_ptr end)
|
|
||||||
{
|
|
||||||
node_ptr prev = get(begin).group_prev_;
|
|
||||||
|
|
||||||
if(prev->next_ != begin) {
|
|
||||||
// The node is at the beginning of a group.
|
|
||||||
|
|
||||||
// Find the previous node pointer:
|
|
||||||
prev = b.next_;
|
|
||||||
while(prev->next_ != begin) prev = next_group2(prev);
|
|
||||||
|
|
||||||
if(BOOST_UNORDERED_BORLAND_BOOL(end)) split_group(end);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
node_ptr group1 = split_group(begin);
|
|
||||||
if(BOOST_UNORDERED_BORLAND_BOOL(end)) {
|
|
||||||
node_ptr group2 = split_group(end);
|
|
||||||
|
|
||||||
if(begin == group2) {
|
|
||||||
node_ptr end1 = get(group1).group_prev_;
|
|
||||||
node_ptr end2 = get(group2).group_prev_;
|
|
||||||
get(group1).group_prev_ = end2;
|
|
||||||
get(group2).group_prev_ = end1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
prev->next_ = end;
|
|
||||||
|
|
||||||
return prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Break a ciruclar list into two, with split as the beginning
|
|
||||||
// of the second group (if split is at the beginning then don't
|
|
||||||
// split).
|
|
||||||
static node_ptr split_group(node_ptr split)
|
|
||||||
{
|
|
||||||
// Find first node in group.
|
|
||||||
node_ptr first = split;
|
|
||||||
while(next_group(first) == first)
|
|
||||||
first = get(first).group_prev_;
|
|
||||||
|
|
||||||
if(first == split) return split;
|
|
||||||
|
|
||||||
node_ptr last = get(first).group_prev_;
|
|
||||||
get(first).group_prev_ = get(split).group_prev_;
|
|
||||||
get(split).group_prev_ = last;
|
|
||||||
|
|
||||||
return first;
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::size_t get_hash(node_ptr p) {
|
|
||||||
return static_cast<grouped_node&>(*p).hash_;
|
|
||||||
}
|
|
||||||
static void set_hash(node_ptr p, std::size_t hash) {
|
|
||||||
static_cast<grouped_node&>(*p).hash_ = hash;
|
|
||||||
}
|
|
||||||
static value_type& get_value(node_ptr p) {
|
|
||||||
return static_cast<grouped_node&>(*p).value();
|
|
||||||
}
|
|
||||||
static value_type* get_value_ptr(node_ptr p) {
|
|
||||||
return static_cast<grouped_node&>(*p).value_ptr();
|
|
||||||
}
|
|
||||||
|
|
||||||
static grouped_node& get(node_ptr ptr) {
|
|
||||||
return static_cast<grouped_node&>(*ptr);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// These two classes implement an easy way to pass around the node
|
|
||||||
// group policy classes without the messy template parameters.
|
|
||||||
// Whenever you see the template parameter 'G' it's one of these.
|
|
||||||
|
|
||||||
struct ungrouped
|
|
||||||
{
|
|
||||||
template <class A>
|
|
||||||
struct node {
|
|
||||||
typedef ungrouped_node<A> type;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct grouped
|
|
||||||
{
|
|
||||||
template <class A>
|
|
||||||
struct node {
|
|
||||||
typedef grouped_node<A> type;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
}}}
|
|
||||||
|
|
||||||
#endif
|
|
@ -22,9 +22,11 @@ namespace boost { namespace unordered { namespace iterator_detail {
|
|||||||
// all no throw
|
// all no throw
|
||||||
|
|
||||||
template <typename NodePointer, typename Value> struct iterator;
|
template <typename NodePointer, typename Value> struct iterator;
|
||||||
template <typename ConstNodePointer, typename NodePointer, typename Value> struct c_iterator;
|
template <typename ConstNodePointer, typename NodePointer,
|
||||||
|
typename Value> struct c_iterator;
|
||||||
template <typename NodePointer, typename Value> struct l_iterator;
|
template <typename NodePointer, typename Value> struct l_iterator;
|
||||||
template <typename ConstNodePointer, typename NodePointer, typename Value> struct cl_iterator;
|
template <typename ConstNodePointer, typename NodePointer,
|
||||||
|
typename Value> struct cl_iterator;
|
||||||
|
|
||||||
// Local Iterators
|
// Local Iterators
|
||||||
//
|
//
|
||||||
@ -37,7 +39,8 @@ namespace boost { namespace unordered { namespace iterator_detail {
|
|||||||
NodePointer, Value&>
|
NodePointer, Value&>
|
||||||
{
|
{
|
||||||
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
|
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
|
||||||
template <typename ConstNodePointer, typename NodePointer2, typename Value2>
|
template <typename ConstNodePointer, typename NodePointer2,
|
||||||
|
typename Value2>
|
||||||
friend struct boost::unordered::iterator_detail::cl_iterator;
|
friend struct boost::unordered::iterator_detail::cl_iterator;
|
||||||
private:
|
private:
|
||||||
#endif
|
#endif
|
||||||
@ -102,11 +105,12 @@ namespace boost { namespace unordered { namespace iterator_detail {
|
|||||||
|
|
||||||
cl_iterator() : ptr_() {}
|
cl_iterator() : ptr_() {}
|
||||||
|
|
||||||
cl_iterator(node_pointer x, std::size_t b, std::size_t c)
|
cl_iterator(node_pointer x, std::size_t b, std::size_t c) :
|
||||||
: ptr_(x), bucket_(b), bucket_count_(c) {}
|
ptr_(x), bucket_(b), bucket_count_(c) {}
|
||||||
|
|
||||||
cl_iterator(boost::unordered::iterator_detail::l_iterator<NodePointer, Value> const& x)
|
cl_iterator(boost::unordered::iterator_detail::l_iterator<
|
||||||
: ptr_(x.ptr_), bucket_(x.bucket_), bucket_count_(x.bucket_count_)
|
NodePointer, Value> const& x) :
|
||||||
|
ptr_(x.ptr_), bucket_(x.bucket_), bucket_count_(x.bucket_count_)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Value const&
|
Value const&
|
||||||
@ -147,7 +151,8 @@ namespace boost { namespace unordered { namespace iterator_detail {
|
|||||||
NodePointer, Value&>
|
NodePointer, Value&>
|
||||||
{
|
{
|
||||||
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
|
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
|
||||||
template <typename ConstNodePointer, typename NodePointer2, typename Value2>
|
template <typename ConstNodePointer, typename NodePointer2,
|
||||||
|
typename Value2>
|
||||||
friend struct boost::unordered::iterator_detail::c_iterator;
|
friend struct boost::unordered::iterator_detail::c_iterator;
|
||||||
private:
|
private:
|
||||||
#endif
|
#endif
|
||||||
@ -169,11 +174,14 @@ namespace boost { namespace unordered { namespace iterator_detail {
|
|||||||
}
|
}
|
||||||
|
|
||||||
iterator& operator++() {
|
iterator& operator++() {
|
||||||
node_ = node_ = static_cast<node_pointer>(node_->next_); return *this;
|
node_ = node_ = static_cast<node_pointer>(node_->next_);
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator operator++(int) {
|
iterator operator++(int) {
|
||||||
iterator tmp(node_); node_ = node_ = static_cast<node_pointer>(node_->next_); return tmp;
|
iterator tmp(node_);
|
||||||
|
node_ = node_ = static_cast<node_pointer>(node_->next_);
|
||||||
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(iterator const& x) const {
|
bool operator==(iterator const& x) const {
|
||||||
@ -191,7 +199,8 @@ namespace boost { namespace unordered { namespace iterator_detail {
|
|||||||
std::forward_iterator_tag, Value, std::ptrdiff_t,
|
std::forward_iterator_tag, Value, std::ptrdiff_t,
|
||||||
ConstNodePointer, Value const&>
|
ConstNodePointer, Value const&>
|
||||||
{
|
{
|
||||||
friend struct boost::unordered::iterator_detail::iterator<NodePointer, Value>;
|
friend struct boost::unordered::iterator_detail::iterator<
|
||||||
|
NodePointer, Value>;
|
||||||
|
|
||||||
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
|
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
|
||||||
template <typename K, typename T, typename H, typename P, typename A>
|
template <typename K, typename T, typename H, typename P, typename A>
|
||||||
@ -215,7 +224,8 @@ namespace boost { namespace unordered { namespace iterator_detail {
|
|||||||
|
|
||||||
explicit c_iterator(node_pointer const& x) : node_(x) {}
|
explicit c_iterator(node_pointer const& x) : node_(x) {}
|
||||||
|
|
||||||
c_iterator(boost::unordered::iterator_detail::iterator<NodePointer, Value> const& x) : node_(x.node_) {}
|
c_iterator(boost::unordered::iterator_detail::iterator<
|
||||||
|
NodePointer, Value> const& x) : node_(x.node_) {}
|
||||||
|
|
||||||
Value const& operator*() const {
|
Value const& operator*() const {
|
||||||
return node_->value();
|
return node_->value();
|
||||||
@ -226,11 +236,14 @@ namespace boost { namespace unordered { namespace iterator_detail {
|
|||||||
}
|
}
|
||||||
|
|
||||||
c_iterator& operator++() {
|
c_iterator& operator++() {
|
||||||
node_ = static_cast<node_pointer>(node_->next_); return *this;
|
node_ = static_cast<node_pointer>(node_->next_);
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
c_iterator operator++(int) {
|
c_iterator operator++(int) {
|
||||||
c_iterator tmp(node_); node_ = node_ = static_cast<node_pointer>(node_->next_); return tmp;
|
c_iterator tmp(node_);
|
||||||
|
node_ = node_ = static_cast<node_pointer>(node_->next_);
|
||||||
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
friend bool operator==(c_iterator const& x, c_iterator const& y) {
|
friend bool operator==(c_iterator const& x, c_iterator const& y) {
|
||||||
@ -248,7 +261,7 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
// convert double to std::size_t
|
// convert double to std::size_t
|
||||||
|
|
||||||
inline std::size_t double_to_size_t(double f)
|
inline std::size_t double_to_size(double f)
|
||||||
{
|
{
|
||||||
return f >= static_cast<double>(
|
return f >= static_cast<double>(
|
||||||
(std::numeric_limits<std::size_t>::max)()) ?
|
(std::numeric_limits<std::size_t>::max)()) ?
|
||||||
@ -320,10 +333,15 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
typedef typename buckets::node_pointer node_pointer;
|
typedef typename buckets::node_pointer node_pointer;
|
||||||
typedef typename buckets::const_node_pointer const_node_pointer;
|
typedef typename buckets::const_node_pointer const_node_pointer;
|
||||||
|
|
||||||
typedef boost::unordered::iterator_detail::iterator<node_pointer, value_type> iterator;
|
typedef boost::unordered::iterator_detail::
|
||||||
typedef boost::unordered::iterator_detail::c_iterator<const_node_pointer, node_pointer, value_type> c_iterator;
|
iterator<node_pointer, value_type> iterator;
|
||||||
typedef boost::unordered::iterator_detail::l_iterator<node_pointer, value_type> l_iterator;
|
typedef boost::unordered::iterator_detail::
|
||||||
typedef boost::unordered::iterator_detail::cl_iterator<const_node_pointer, node_pointer, value_type> cl_iterator;
|
c_iterator<const_node_pointer, node_pointer, value_type> c_iterator;
|
||||||
|
typedef boost::unordered::iterator_detail::
|
||||||
|
l_iterator<node_pointer, value_type> l_iterator;
|
||||||
|
typedef boost::unordered::iterator_detail::
|
||||||
|
cl_iterator<const_node_pointer, node_pointer, value_type>
|
||||||
|
cl_iterator;
|
||||||
|
|
||||||
// Members
|
// Members
|
||||||
|
|
||||||
@ -338,7 +356,7 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
// size < mlf_ * count
|
// size < mlf_ * count
|
||||||
return boost::unordered::detail::double_to_size_t(ceil(
|
return boost::unordered::detail::double_to_size(ceil(
|
||||||
static_cast<double>(this->mlf_) *
|
static_cast<double>(this->mlf_) *
|
||||||
static_cast<double>(this->max_bucket_count())
|
static_cast<double>(this->max_bucket_count())
|
||||||
)) - 1;
|
)) - 1;
|
||||||
@ -350,7 +368,7 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
|
|
||||||
// From 6.3.1/13:
|
// From 6.3.1/13:
|
||||||
// Only resize when size >= mlf_ * count
|
// Only resize when size >= mlf_ * count
|
||||||
return boost::unordered::detail::double_to_size_t(ceil(
|
return boost::unordered::detail::double_to_size(ceil(
|
||||||
static_cast<double>(this->mlf_) *
|
static_cast<double>(this->mlf_) *
|
||||||
static_cast<double>(this->bucket_count_)
|
static_cast<double>(this->bucket_count_)
|
||||||
));
|
));
|
||||||
@ -378,7 +396,7 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
// count > size / mlf_
|
// count > size / mlf_
|
||||||
|
|
||||||
return boost::unordered::detail::next_prime(
|
return boost::unordered::detail::next_prime(
|
||||||
boost::unordered::detail::double_to_size_t(floor(
|
boost::unordered::detail::double_to_size(floor(
|
||||||
static_cast<double>(size) /
|
static_cast<double>(size) /
|
||||||
static_cast<double>(mlf_))) + 1);
|
static_cast<double>(mlf_))) + 1);
|
||||||
}
|
}
|
||||||
@ -494,10 +512,12 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
move_assign_no_alloc(x);
|
move_assign_no_alloc(x);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
set_hash_functions<hasher, key_equal> new_func_this(*this, x);
|
boost::unordered::detail::set_hash_functions<hasher, key_equal>
|
||||||
|
new_func_this(*this, x);
|
||||||
|
|
||||||
if (x.size_) {
|
if (x.size_) {
|
||||||
buckets b(this->node_alloc(), x.min_buckets_for_size(x.size_));
|
buckets b(this->node_alloc(),
|
||||||
|
x.min_buckets_for_size(x.size_));
|
||||||
buckets tmp(x, move_tag());
|
buckets tmp(x, move_tag());
|
||||||
table_impl::move_buckets_to(tmp, b);
|
table_impl::move_buckets_to(tmp, b);
|
||||||
b.swap(*this);
|
b.swap(*this);
|
||||||
@ -514,7 +534,8 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
|
|
||||||
void move_assign_no_alloc(table& x)
|
void move_assign_no_alloc(table& x)
|
||||||
{
|
{
|
||||||
set_hash_functions<hasher, key_equal> new_func_this(*this, x);
|
boost::unordered::detail::set_hash_functions<hasher, key_equal>
|
||||||
|
new_func_this(*this, x);
|
||||||
// No throw from here.
|
// No throw from here.
|
||||||
this->move_buckets_from(x);
|
this->move_buckets_from(x);
|
||||||
this->mlf_ = x.mlf_;
|
this->mlf_ = x.mlf_;
|
||||||
@ -537,8 +558,10 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
template <typename Propagate>
|
template <typename Propagate>
|
||||||
void swap(table& x, Propagate p)
|
void swap(table& x, Propagate p)
|
||||||
{
|
{
|
||||||
set_hash_functions<hasher, key_equal> op1(*this, x);
|
boost::unordered::detail::set_hash_functions<hasher, key_equal>
|
||||||
set_hash_functions<hasher, key_equal> op2(x, *this);
|
op1(*this, x);
|
||||||
|
boost::unordered::detail::set_hash_functions<hasher, key_equal>
|
||||||
|
op2(x, *this);
|
||||||
// I think swap can throw if Propagate::value,
|
// I think swap can throw if Propagate::value,
|
||||||
// since the allocators' swap can throw. Not sure though.
|
// since the allocators' swap can throw. Not sure though.
|
||||||
this->buckets::swap(x, p);
|
this->buckets::swap(x, p);
|
||||||
@ -647,7 +670,7 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
min_buckets = next_prime((std::max)(min_buckets,
|
min_buckets = next_prime((std::max)(min_buckets,
|
||||||
boost::unordered::detail::double_to_size_t(floor(
|
boost::unordered::detail::double_to_size(floor(
|
||||||
static_cast<double>(this->size_) /
|
static_cast<double>(this->size_) /
|
||||||
static_cast<double>(mlf_))) + 1));
|
static_cast<double>(mlf_))) + 1));
|
||||||
|
|
||||||
|
@ -151,7 +151,8 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
|
|
||||||
template <class I>
|
template <class I>
|
||||||
inline std::size_t initial_size(I i, I j,
|
inline std::size_t initial_size(I i, I j,
|
||||||
std::size_t num_buckets = boost::unordered::detail::default_bucket_count)
|
std::size_t num_buckets =
|
||||||
|
boost::unordered::detail::default_bucket_count)
|
||||||
{
|
{
|
||||||
// TODO: Why +1?
|
// TODO: Why +1?
|
||||||
return (std::max)(
|
return (std::max)(
|
||||||
@ -189,15 +190,15 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
: boost::detail::if_true<
|
: boost::detail::if_true<
|
||||||
boost::is_empty<T>::value
|
boost::is_empty<T>::value
|
||||||
>:: BOOST_NESTED_TEMPLATE then<
|
>:: BOOST_NESTED_TEMPLATE then<
|
||||||
compressed_base<T, Index>,
|
boost::unordered::detail::compressed_base<T, Index>,
|
||||||
uncompressed_base<T, Index>
|
boost::unordered::detail::uncompressed_base<T, Index>
|
||||||
>
|
>
|
||||||
{};
|
{};
|
||||||
|
|
||||||
template <typename T1, typename T2>
|
template <typename T1, typename T2>
|
||||||
struct compressed
|
struct compressed
|
||||||
: private generate_base<T1, 1>::type,
|
: private boost::unordered::detail::generate_base<T1, 1>::type,
|
||||||
private generate_base<T2, 2>::type
|
private boost::unordered::detail::generate_base<T2, 2>::type
|
||||||
{
|
{
|
||||||
typedef typename generate_base<T1, 1>::type base1;
|
typedef typename generate_base<T1, 1>::type base1;
|
||||||
typedef typename generate_base<T2, 2>::type base2;
|
typedef typename generate_base<T2, 2>::type base2;
|
||||||
|
@ -258,7 +258,8 @@ namespace unordered
|
|||||||
)).first); \
|
)).first); \
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT, BOOST_UNORDERED_EMPLACE, _)
|
BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT,
|
||||||
|
BOOST_UNORDERED_EMPLACE, _)
|
||||||
|
|
||||||
#undef BOOST_UNORDERED_EMPLACE
|
#undef BOOST_UNORDERED_EMPLACE
|
||||||
|
|
||||||
@ -536,7 +537,8 @@ namespace unordered
|
|||||||
|
|
||||||
// Assign
|
// Assign
|
||||||
|
|
||||||
unordered_multimap& operator=(BOOST_COPY_ASSIGN_REF(unordered_multimap) x)
|
unordered_multimap& operator=(
|
||||||
|
BOOST_COPY_ASSIGN_REF(unordered_multimap) x)
|
||||||
{
|
{
|
||||||
table_.assign(x.table_);
|
table_.assign(x.table_);
|
||||||
return *this;
|
return *this;
|
||||||
@ -649,7 +651,8 @@ namespace unordered
|
|||||||
))); \
|
))); \
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT, BOOST_UNORDERED_EMPLACE, _)
|
BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT,
|
||||||
|
BOOST_UNORDERED_EMPLACE, _)
|
||||||
|
|
||||||
#undef BOOST_UNORDERED_EMPLACE
|
#undef BOOST_UNORDERED_EMPLACE
|
||||||
|
|
||||||
|
@ -256,7 +256,8 @@ namespace unordered
|
|||||||
)).first); \
|
)).first); \
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT, BOOST_UNORDERED_EMPLACE, _)
|
BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT,
|
||||||
|
BOOST_UNORDERED_EMPLACE, _)
|
||||||
|
|
||||||
#undef BOOST_UNORDERED_EMPLACE
|
#undef BOOST_UNORDERED_EMPLACE
|
||||||
|
|
||||||
@ -298,7 +299,8 @@ namespace unordered
|
|||||||
return this->emplace_hint(hint, x);
|
return this->emplace_hint(hint, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator insert(const_iterator hint, BOOST_UNORDERED_RV_REF(value_type) x)
|
iterator insert(const_iterator hint,
|
||||||
|
BOOST_UNORDERED_RV_REF(value_type) x)
|
||||||
{
|
{
|
||||||
return this->emplace_hint(hint, boost::move(x));
|
return this->emplace_hint(hint, boost::move(x));
|
||||||
}
|
}
|
||||||
@ -518,7 +520,8 @@ namespace unordered
|
|||||||
|
|
||||||
// Assign
|
// Assign
|
||||||
|
|
||||||
unordered_multiset& operator=(BOOST_COPY_ASSIGN_REF(unordered_multiset) x)
|
unordered_multiset& operator=(
|
||||||
|
BOOST_COPY_ASSIGN_REF(unordered_multiset) x)
|
||||||
{
|
{
|
||||||
table_.assign(x.table_);
|
table_.assign(x.table_);
|
||||||
return *this;
|
return *this;
|
||||||
@ -631,7 +634,8 @@ namespace unordered
|
|||||||
))); \
|
))); \
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT, BOOST_UNORDERED_EMPLACE, _)
|
BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT,
|
||||||
|
BOOST_UNORDERED_EMPLACE, _)
|
||||||
|
|
||||||
#undef BOOST_UNORDERED_EMPLACE
|
#undef BOOST_UNORDERED_EMPLACE
|
||||||
|
|
||||||
@ -673,7 +677,8 @@ namespace unordered
|
|||||||
return this->emplace_hint(hint, x);
|
return this->emplace_hint(hint, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator insert(const_iterator hint, BOOST_UNORDERED_RV_REF(value_type) x)
|
iterator insert(const_iterator hint,
|
||||||
|
BOOST_UNORDERED_RV_REF(value_type) x)
|
||||||
{
|
{
|
||||||
return this->emplace_hint(hint, boost::move(x));
|
return this->emplace_hint(hint, boost::move(x));
|
||||||
}
|
}
|
||||||
@ -1190,7 +1195,8 @@ namespace unordered
|
|||||||
|
|
||||||
#if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST)
|
#if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST)
|
||||||
template <class T, class H, class P, class A>
|
template <class T, class H, class P, class A>
|
||||||
void unordered_multiset<T,H,P,A>::insert(std::initializer_list<value_type> list)
|
void unordered_multiset<T,H,P,A>::insert(
|
||||||
|
std::initializer_list<value_type> list)
|
||||||
{
|
{
|
||||||
table_.insert_range(list.begin(), list.end());
|
table_.insert_range(list.begin(), list.end());
|
||||||
}
|
}
|
||||||
@ -1212,7 +1218,8 @@ namespace unordered
|
|||||||
|
|
||||||
template <class T, class H, class P, class A>
|
template <class T, class H, class P, class A>
|
||||||
typename unordered_multiset<T,H,P,A>::iterator
|
typename unordered_multiset<T,H,P,A>::iterator
|
||||||
unordered_multiset<T,H,P,A>::erase(const_iterator first, const_iterator last)
|
unordered_multiset<T,H,P,A>::erase(
|
||||||
|
const_iterator first, const_iterator last)
|
||||||
{
|
{
|
||||||
return iterator(table_.erase_range(first.node_, last.node_));
|
return iterator(table_.erase_range(first.node_, last.node_));
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user