mirror of
https://github.com/boostorg/unordered.git
synced 2025-07-30 03:17:15 +02:00
Unordered: Use iterators in more of the implementation methods.
[SVN r77834]
This commit is contained in:
@ -19,6 +19,7 @@
|
|||||||
#include <boost/swap.hpp>
|
#include <boost/swap.hpp>
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
#include <boost/limits.hpp>
|
#include <boost/limits.hpp>
|
||||||
|
#include <boost/iterator.hpp>
|
||||||
|
|
||||||
#if defined(BOOST_MSVC)
|
#if defined(BOOST_MSVC)
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
@ -32,6 +33,8 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
struct ptr_bucket;
|
struct ptr_bucket;
|
||||||
template <typename A, typename Bucket, typename Node, typename Policy>
|
template <typename A, typename Bucket, typename Node, typename Policy>
|
||||||
struct buckets;
|
struct buckets;
|
||||||
|
template <typename Types> struct table_impl;
|
||||||
|
template <typename Types> struct grouped_table_impl;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
@ -180,6 +183,272 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
|
|
||||||
enum { extra_node = false };
|
enum { extra_node = false };
|
||||||
};
|
};
|
||||||
|
}}}
|
||||||
|
|
||||||
|
namespace boost { namespace unordered { namespace iterator_detail {
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Iterators
|
||||||
|
//
|
||||||
|
// all no throw
|
||||||
|
|
||||||
|
template <typename NodePointer, typename Value> struct iterator;
|
||||||
|
template <typename ConstNodePointer, typename NodePointer,
|
||||||
|
typename Value> struct c_iterator;
|
||||||
|
template <typename NodePointer, typename Value, typename Policy>
|
||||||
|
struct l_iterator;
|
||||||
|
template <typename ConstNodePointer, typename NodePointer,
|
||||||
|
typename Value, typename Policy> struct cl_iterator;
|
||||||
|
|
||||||
|
// Local Iterators
|
||||||
|
//
|
||||||
|
// all no throw
|
||||||
|
|
||||||
|
template <typename NodePointer, typename Value, typename Policy>
|
||||||
|
struct l_iterator
|
||||||
|
: public boost::iterator<
|
||||||
|
std::forward_iterator_tag, Value, std::ptrdiff_t,
|
||||||
|
NodePointer, Value&>
|
||||||
|
{
|
||||||
|
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
|
||||||
|
template <typename ConstNodePointer, typename NodePointer2,
|
||||||
|
typename Value2, typename Policy2>
|
||||||
|
friend struct boost::unordered::iterator_detail::cl_iterator;
|
||||||
|
private:
|
||||||
|
#endif
|
||||||
|
typedef NodePointer node_pointer;
|
||||||
|
typedef boost::unordered::iterator_detail::iterator<NodePointer, Value>
|
||||||
|
iterator;
|
||||||
|
node_pointer ptr_;
|
||||||
|
std::size_t bucket_;
|
||||||
|
std::size_t bucket_count_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
l_iterator() : ptr_() {}
|
||||||
|
|
||||||
|
l_iterator(iterator x, std::size_t b, std::size_t c)
|
||||||
|
: ptr_(x.node_), bucket_(b), bucket_count_(c) {}
|
||||||
|
|
||||||
|
Value& operator*() const {
|
||||||
|
return ptr_->value();
|
||||||
|
}
|
||||||
|
|
||||||
|
Value* operator->() const {
|
||||||
|
return ptr_->value_ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
l_iterator& operator++() {
|
||||||
|
ptr_ = static_cast<node_pointer>(ptr_->next_);
|
||||||
|
if (ptr_ && Policy::to_bucket(bucket_count_, ptr_->hash_)
|
||||||
|
!= bucket_)
|
||||||
|
ptr_ = node_pointer();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
l_iterator operator++(int) {
|
||||||
|
l_iterator tmp(*this);
|
||||||
|
++(*this);
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(l_iterator x) const {
|
||||||
|
return ptr_ == x.ptr_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(l_iterator x) const {
|
||||||
|
return ptr_ != x.ptr_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename ConstNodePointer, typename NodePointer, typename Value,
|
||||||
|
typename Policy>
|
||||||
|
struct cl_iterator
|
||||||
|
: public boost::iterator<
|
||||||
|
std::forward_iterator_tag, Value, std::ptrdiff_t,
|
||||||
|
ConstNodePointer, Value const&>
|
||||||
|
{
|
||||||
|
friend struct boost::unordered::iterator_detail::l_iterator
|
||||||
|
<NodePointer, Value, Policy>;
|
||||||
|
private:
|
||||||
|
|
||||||
|
typedef NodePointer node_pointer;
|
||||||
|
typedef boost::unordered::iterator_detail::iterator<NodePointer, Value>
|
||||||
|
iterator;
|
||||||
|
node_pointer ptr_;
|
||||||
|
std::size_t bucket_;
|
||||||
|
std::size_t bucket_count_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
cl_iterator() : ptr_() {}
|
||||||
|
|
||||||
|
cl_iterator(iterator x, std::size_t b, std::size_t c) :
|
||||||
|
ptr_(x.node_), bucket_(b), bucket_count_(c) {}
|
||||||
|
|
||||||
|
cl_iterator(boost::unordered::iterator_detail::l_iterator<
|
||||||
|
NodePointer, Value, Policy> const& x) :
|
||||||
|
ptr_(x.ptr_), bucket_(x.bucket_), bucket_count_(x.bucket_count_)
|
||||||
|
{}
|
||||||
|
|
||||||
|
Value const&
|
||||||
|
operator*() const {
|
||||||
|
return ptr_->value();
|
||||||
|
}
|
||||||
|
|
||||||
|
Value const* operator->() const {
|
||||||
|
return ptr_->value_ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
cl_iterator& operator++() {
|
||||||
|
ptr_ = static_cast<node_pointer>(ptr_->next_);
|
||||||
|
if (ptr_ && Policy::to_bucket(bucket_count_, ptr_->hash_)
|
||||||
|
!= bucket_)
|
||||||
|
ptr_ = node_pointer();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
cl_iterator operator++(int) {
|
||||||
|
cl_iterator tmp(*this);
|
||||||
|
++(*this);
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator==(cl_iterator const& x, cl_iterator const& y) {
|
||||||
|
return x.ptr_ == y.ptr_;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator!=(cl_iterator const& x, cl_iterator const& y) {
|
||||||
|
return x.ptr_ != y.ptr_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename NodePointer, typename Value>
|
||||||
|
struct iterator
|
||||||
|
: public boost::iterator<
|
||||||
|
std::forward_iterator_tag, Value, std::ptrdiff_t,
|
||||||
|
NodePointer, Value&>
|
||||||
|
{
|
||||||
|
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
|
||||||
|
template <typename, typename, typename>
|
||||||
|
friend struct boost::unordered::iterator_detail::c_iterator;
|
||||||
|
template <typename, typename, typename>
|
||||||
|
friend struct boost::unordered::iterator_detail::l_iterator;
|
||||||
|
template <typename, typename, typename, typename>
|
||||||
|
friend struct boost::unordered::iterator_detail::cl_iterator;
|
||||||
|
template <typename>
|
||||||
|
friend struct boost::unordered::detail::table;
|
||||||
|
template <typename, typename, typename, typename>
|
||||||
|
friend struct boost::unordered::detail::buckets;
|
||||||
|
template <typename>
|
||||||
|
friend struct boost::unordered::detail::table_impl;
|
||||||
|
template <typename>
|
||||||
|
friend struct boost::unordered::detail::grouped_table_impl;
|
||||||
|
private:
|
||||||
|
#endif
|
||||||
|
typedef NodePointer node_pointer;
|
||||||
|
node_pointer node_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
iterator() : node_() {}
|
||||||
|
|
||||||
|
explicit iterator(node_pointer const& x) : node_(x) {}
|
||||||
|
|
||||||
|
Value& operator*() const {
|
||||||
|
return node_->value();
|
||||||
|
}
|
||||||
|
|
||||||
|
Value* operator->() const {
|
||||||
|
return &node_->value();
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator& operator++() {
|
||||||
|
node_ = static_cast<node_pointer>(node_->next_);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator operator++(int) {
|
||||||
|
iterator tmp(node_);
|
||||||
|
node_ = static_cast<node_pointer>(node_->next_);
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(iterator const& x) const {
|
||||||
|
return node_ == x.node_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(iterator const& x) const {
|
||||||
|
return node_ != x.node_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename ConstNodePointer, typename NodePointer, typename Value>
|
||||||
|
struct c_iterator
|
||||||
|
: public boost::iterator<
|
||||||
|
std::forward_iterator_tag, Value, std::ptrdiff_t,
|
||||||
|
ConstNodePointer, Value const&>
|
||||||
|
{
|
||||||
|
friend struct boost::unordered::iterator_detail::iterator<
|
||||||
|
NodePointer, Value>;
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
|
||||||
|
template <typename>
|
||||||
|
friend struct boost::unordered::detail::table;
|
||||||
|
template <typename, typename, typename, typename>
|
||||||
|
friend struct boost::unordered::detail::buckets;
|
||||||
|
template <typename>
|
||||||
|
friend struct boost::unordered::detail::table_impl;
|
||||||
|
template <typename>
|
||||||
|
friend struct boost::unordered::detail::grouped_table_impl;
|
||||||
|
|
||||||
|
private:
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef NodePointer node_pointer;
|
||||||
|
typedef boost::unordered::iterator_detail::iterator<NodePointer, Value>
|
||||||
|
iterator;
|
||||||
|
node_pointer node_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
c_iterator() : node_() {}
|
||||||
|
|
||||||
|
explicit c_iterator(node_pointer const& x) : node_(x) {}
|
||||||
|
|
||||||
|
c_iterator(boost::unordered::iterator_detail::iterator<
|
||||||
|
NodePointer, Value> const& x) : node_(x.node_) {}
|
||||||
|
|
||||||
|
Value const& operator*() const {
|
||||||
|
return node_->value();
|
||||||
|
}
|
||||||
|
|
||||||
|
Value const* operator->() const {
|
||||||
|
return &node_->value();
|
||||||
|
}
|
||||||
|
|
||||||
|
c_iterator& operator++() {
|
||||||
|
node_ = static_cast<node_pointer>(node_->next_);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
c_iterator operator++(int) {
|
||||||
|
c_iterator tmp(node_);
|
||||||
|
node_ = static_cast<node_pointer>(node_->next_);
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator==(c_iterator const& x, c_iterator const& y) {
|
||||||
|
return x.node_ == y.node_;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator!=(c_iterator const& x, c_iterator const& y) {
|
||||||
|
return x.node_ != y.node_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}}}
|
||||||
|
|
||||||
|
namespace boost { namespace unordered { namespace detail {
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
@ -302,6 +571,16 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
typedef boost::unordered::detail::node_constructor<node_allocator>
|
typedef boost::unordered::detail::node_constructor<node_allocator>
|
||||||
node_constructor;
|
node_constructor;
|
||||||
|
|
||||||
|
typedef boost::unordered::iterator_detail::
|
||||||
|
iterator<node_pointer, value_type> iterator;
|
||||||
|
typedef boost::unordered::iterator_detail::
|
||||||
|
c_iterator<const_node_pointer, node_pointer, value_type> c_iterator;
|
||||||
|
typedef boost::unordered::iterator_detail::
|
||||||
|
l_iterator<node_pointer, value_type, policy> l_iterator;
|
||||||
|
typedef boost::unordered::iterator_detail::
|
||||||
|
cl_iterator<const_node_pointer, node_pointer, value_type, policy>
|
||||||
|
cl_iterator;
|
||||||
|
|
||||||
// Members
|
// Members
|
||||||
|
|
||||||
bucket_pointer buckets_;
|
bucket_pointer buckets_;
|
||||||
@ -354,16 +633,17 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
return this->get_bucket(bucket_index)->next_;
|
return this->get_bucket(bucket_index)->next_;
|
||||||
}
|
}
|
||||||
|
|
||||||
node_pointer get_start() const
|
iterator get_start() const
|
||||||
{
|
{
|
||||||
return static_cast<node_pointer>(this->get_previous_start()->next_);
|
return iterator(static_cast<node_pointer>(
|
||||||
|
this->get_previous_start()->next_));
|
||||||
}
|
}
|
||||||
|
|
||||||
node_pointer get_start(std::size_t bucket_index) const
|
iterator get_start(std::size_t bucket_index) const
|
||||||
{
|
{
|
||||||
previous_pointer prev = this->get_previous_start(bucket_index);
|
previous_pointer prev = this->get_previous_start(bucket_index);
|
||||||
return prev ? static_cast<node_pointer>(prev->next_) :
|
return prev ? iterator(static_cast<node_pointer>(prev->next_)) :
|
||||||
node_pointer();
|
iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
float load_factor() const
|
float load_factor() const
|
||||||
@ -376,15 +656,15 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
std::size_t bucket_size(std::size_t index) const
|
std::size_t bucket_size(std::size_t index) const
|
||||||
{
|
{
|
||||||
if (!this->size_) return 0;
|
if (!this->size_) return 0;
|
||||||
node_pointer ptr = this->get_start(index);
|
iterator it = this->get_start(index);
|
||||||
if (!ptr) return 0;
|
if (!it.node_) return 0;
|
||||||
|
|
||||||
std::size_t count = 0;
|
std::size_t count = 0;
|
||||||
while(ptr &&
|
while(it.node_ && policy::to_bucket(
|
||||||
policy::to_bucket(this->bucket_count_, ptr->hash_) == index)
|
this->bucket_count_, it.node_->hash_) == index)
|
||||||
{
|
{
|
||||||
++count;
|
++count;
|
||||||
ptr = static_cast<node_pointer>(ptr->next_);
|
++it;
|
||||||
}
|
}
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
@ -480,21 +760,22 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
// Delete/destruct
|
// Delete/destruct
|
||||||
|
|
||||||
inline void delete_node(node_pointer n)
|
inline void delete_node(c_iterator n)
|
||||||
{
|
{
|
||||||
boost::unordered::detail::destroy(n->value_ptr());
|
boost::unordered::detail::destroy(n.node_->value_ptr());
|
||||||
node_allocator_traits::destroy(node_alloc(), boost::addressof(*n));
|
node_allocator_traits::destroy(node_alloc(),
|
||||||
node_allocator_traits::deallocate(node_alloc(), n, 1);
|
boost::addressof(*n.node_));
|
||||||
|
node_allocator_traits::deallocate(node_alloc(), n.node_, 1);
|
||||||
--size_;
|
--size_;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t delete_nodes(node_pointer begin, node_pointer end)
|
std::size_t delete_nodes(c_iterator begin, c_iterator end)
|
||||||
{
|
{
|
||||||
std::size_t count = 0;
|
std::size_t count = 0;
|
||||||
|
|
||||||
while(begin != end) {
|
while(begin != end) {
|
||||||
node_pointer n = begin;
|
c_iterator n = begin;
|
||||||
begin = static_cast<node_pointer>(begin->next_);
|
++begin;
|
||||||
delete_node(n);
|
delete_node(n);
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
@ -522,7 +803,7 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
while(prev->next_) {
|
while(prev->next_) {
|
||||||
node_pointer n = static_cast<node_pointer>(prev->next_);
|
node_pointer n = static_cast<node_pointer>(prev->next_);
|
||||||
prev->next_ = n->next_;
|
prev->next_ = n->next_;
|
||||||
delete_node(n);
|
delete_node(iterator(n));
|
||||||
}
|
}
|
||||||
|
|
||||||
delete_extra_node(prev);
|
delete_extra_node(prev);
|
||||||
@ -552,7 +833,7 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
while(prev->next_) {
|
while(prev->next_) {
|
||||||
node_pointer n = static_cast<node_pointer>(prev->next_);
|
node_pointer n = static_cast<node_pointer>(prev->next_);
|
||||||
prev->next_ = n->next_;
|
prev->next_ = n->next_;
|
||||||
delete_node(n);
|
delete_node(iterator(n));
|
||||||
}
|
}
|
||||||
|
|
||||||
bucket_pointer end = this->get_bucket(this->bucket_count_);
|
bucket_pointer end = this->get_bucket(this->bucket_count_);
|
||||||
|
@ -186,6 +186,7 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
typedef typename table::node_constructor node_constructor;
|
typedef typename table::node_constructor node_constructor;
|
||||||
typedef typename table::extractor extractor;
|
typedef typename table::extractor extractor;
|
||||||
typedef typename table::iterator iterator;
|
typedef typename table::iterator iterator;
|
||||||
|
typedef typename table::c_iterator c_iterator;
|
||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
@ -219,48 +220,48 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
// Accessors
|
// Accessors
|
||||||
|
|
||||||
template <class Key, class Pred>
|
template <class Key, class Pred>
|
||||||
node_pointer find_node_impl(
|
iterator find_node_impl(
|
||||||
std::size_t hash,
|
std::size_t hash,
|
||||||
Key const& k,
|
Key const& k,
|
||||||
Pred const& eq) const
|
Pred const& eq) const
|
||||||
{
|
{
|
||||||
std::size_t bucket_index =
|
std::size_t bucket_index =
|
||||||
policy::to_bucket(this->bucket_count_, hash);
|
policy::to_bucket(this->bucket_count_, hash);
|
||||||
node_pointer n = this->get_start(bucket_index);
|
iterator n = this->get_start(bucket_index);
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
if (!n) return n;
|
if (!n.node_) return n;
|
||||||
|
|
||||||
std::size_t node_hash = n->hash_;
|
std::size_t node_hash = n.node_->hash_;
|
||||||
if (hash == node_hash)
|
if (hash == node_hash)
|
||||||
{
|
{
|
||||||
if (eq(k, this->get_key(n->value())))
|
if (eq(k, this->get_key(*n)))
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (policy::to_bucket(this->bucket_count_, node_hash)
|
if (policy::to_bucket(this->bucket_count_, node_hash)
|
||||||
!= bucket_index)
|
!= bucket_index)
|
||||||
return node_pointer();
|
return iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
n = static_cast<node_pointer>(
|
n = iterator(static_cast<node_pointer>(
|
||||||
static_cast<node_pointer>(n->group_prev_)->next_);
|
static_cast<node_pointer>(n.node_->group_prev_)->next_));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t count(key_type const& k) const
|
std::size_t count(key_type const& k) const
|
||||||
{
|
{
|
||||||
node_pointer n = this->find_node(k);
|
iterator n = this->find_node(k);
|
||||||
if (!n) return 0;
|
if (!n.node_) return 0;
|
||||||
|
|
||||||
std::size_t count = 0;
|
std::size_t count = 0;
|
||||||
node_pointer it = n;
|
node_pointer it = n.node_;
|
||||||
do {
|
do {
|
||||||
it = static_cast<node_pointer>(it->group_prev_);
|
it = static_cast<node_pointer>(it->group_prev_);
|
||||||
++count;
|
++count;
|
||||||
} while(it != n);
|
} while(it != n.node_);
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
@ -268,12 +269,12 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
std::pair<iterator, iterator>
|
std::pair<iterator, iterator>
|
||||||
equal_range(key_type const& k) const
|
equal_range(key_type const& k) const
|
||||||
{
|
{
|
||||||
node_pointer n = this->find_node(k);
|
iterator n = this->find_node(k);
|
||||||
return std::make_pair(
|
return std::make_pair(
|
||||||
iterator(n), iterator(n ?
|
n, n.node_ ? iterator(
|
||||||
static_cast<node_pointer>(
|
static_cast<node_pointer>(
|
||||||
static_cast<node_pointer>(n->group_prev_)->next_) :
|
static_cast<node_pointer>(n.node_->group_prev_)->next_
|
||||||
n));
|
)) : n);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Equality
|
// Equality
|
||||||
@ -283,14 +284,14 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
if(this->size_ != other.size_) return false;
|
if(this->size_ != other.size_) return false;
|
||||||
if(!this->size_) return true;
|
if(!this->size_) return true;
|
||||||
|
|
||||||
for(node_pointer n1 = this->get_start(); n1;)
|
for(iterator n1 = this->get_start(); n1.node_;)
|
||||||
{
|
{
|
||||||
node_pointer n2 = other.find_matching_node(n1);
|
iterator n2 = other.find_matching_node(n1);
|
||||||
if (!n2) return false;
|
if (!n2.node_) return false;
|
||||||
node_pointer end1 = static_cast<node_pointer>(
|
iterator end1(static_cast<node_pointer>(
|
||||||
static_cast<node_pointer>(n1->group_prev_)->next_);
|
static_cast<node_pointer>(n1.node_->group_prev_)->next_));
|
||||||
node_pointer end2 = static_cast<node_pointer>(
|
iterator end2(static_cast<node_pointer>(
|
||||||
static_cast<node_pointer>(n2->group_prev_)->next_);
|
static_cast<node_pointer>(n2.node_->group_prev_)->next_));
|
||||||
if (!group_equals(n1, end1, n2, end2)) return false;
|
if (!group_equals(n1, end1, n2, end2)) return false;
|
||||||
n1 = end1;
|
n1 = end1;
|
||||||
}
|
}
|
||||||
@ -300,25 +301,24 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
|
|
||||||
#if !defined(BOOST_UNORDERED_DEPRECATED_EQUALITY)
|
#if !defined(BOOST_UNORDERED_DEPRECATED_EQUALITY)
|
||||||
|
|
||||||
static bool group_equals(node_pointer n1, node_pointer end1,
|
static bool group_equals(iterator n1, iterator end1,
|
||||||
node_pointer n2, node_pointer end2)
|
iterator n2, iterator end2)
|
||||||
{
|
{
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
if (n1->value() != n2->value())
|
if (*n1 != *n2) break;
|
||||||
break;
|
|
||||||
|
|
||||||
n1 = static_cast<node_pointer>(n1->next_);
|
++n1;
|
||||||
n2 = static_cast<node_pointer>(n2->next_);
|
++n2;
|
||||||
|
|
||||||
if (n1 == end1) return n2 == end2;
|
if (n1 == end1) return n2 == end2;
|
||||||
if (n2 == end2) return false;
|
if (n2 == end2) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(node_pointer n1a = n1, n2a = n2;;)
|
for(iterator n1a = n1, n2a = n2;;)
|
||||||
{
|
{
|
||||||
n1a = static_cast<node_pointer>(n1a->next_);
|
++n1a;
|
||||||
n2a = static_cast<node_pointer>(n2a->next_);
|
++n2a;
|
||||||
|
|
||||||
if (n1a == end1)
|
if (n1a == end1)
|
||||||
{
|
{
|
||||||
@ -329,50 +329,50 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
if (n2a == end2) return false;
|
if (n2a == end2) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
node_pointer start = n1;
|
iterator start = n1;
|
||||||
for(;n1 != end1; n1 = static_cast<node_pointer>(n1->next_))
|
for(;n1 != end1; ++n1)
|
||||||
{
|
{
|
||||||
value_type const& v = n1->value();
|
value_type const& v = *n1;
|
||||||
if (find(start, n1, v)) continue;
|
if (find(start, n1, v)) continue;
|
||||||
std::size_t matches = count_equal(n2, end2, v);
|
std::size_t matches = count_equal(n2, end2, v);
|
||||||
if (!matches || matches != 1 + count_equal(
|
if (!matches) return false;
|
||||||
static_cast<node_pointer>(n1->next_), end1, v))
|
iterator next = n1;
|
||||||
return false;
|
++next;
|
||||||
|
if (matches != 1 + count_equal(next, end1, v)) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool find(node_pointer n, node_pointer end, value_type const& v)
|
static bool find(iterator n, iterator end, value_type const& v)
|
||||||
{
|
{
|
||||||
for(;n != end; n = static_cast<node_pointer>(n->next_))
|
for(;n != end; ++n)
|
||||||
if (n->value() == v)
|
if (*n == v)
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::size_t count_equal(node_pointer n, node_pointer end,
|
static std::size_t count_equal(iterator n, iterator end,
|
||||||
value_type const& v)
|
value_type const& v)
|
||||||
{
|
{
|
||||||
std::size_t count = 0;
|
std::size_t count = 0;
|
||||||
for(;n != end; n = static_cast<node_pointer>(n->next_))
|
for(;n != end; ++n)
|
||||||
if (n->value() == v) ++count;
|
if (*n == v) ++count;
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
static bool group_equals(node_pointer n1, node_pointer end1,
|
static bool group_equals(iterator n1, iterator end1,
|
||||||
node_pointer n2, node_pointer end2)
|
iterator n2, iterator end2)
|
||||||
{
|
{
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
if(!extractor::compare_mapped(
|
if(!extractor::compare_mapped(*n1, *n2))
|
||||||
n1->value(), n2->value()))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
n1 = static_cast<node_pointer>(n1->next_);
|
++n1;
|
||||||
n2 = static_cast<node_pointer>(n2->next_);
|
++n2;
|
||||||
|
|
||||||
if (n1 == end1) return n2 == end2;
|
if (n1 == end1) return n2 == end2;
|
||||||
if (n2 == end2) return false;
|
if (n2 == end2) return false;
|
||||||
@ -394,15 +394,15 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
pos->group_prev_ = static_cast<link_pointer>(n);
|
pos->group_prev_ = static_cast<link_pointer>(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline node_pointer add_node(
|
inline iterator add_node(
|
||||||
node_constructor& a,
|
node_constructor& a,
|
||||||
std::size_t hash,
|
std::size_t hash,
|
||||||
node_pointer pos)
|
iterator pos)
|
||||||
{
|
{
|
||||||
node_pointer n = a.release();
|
node_pointer n = a.release();
|
||||||
n->hash_ = hash;
|
n->hash_ = hash;
|
||||||
if(pos) {
|
if (pos.node_) {
|
||||||
this->add_after_node(n, pos);
|
this->add_after_node(n, pos.node_);
|
||||||
if (n->next_) {
|
if (n->next_) {
|
||||||
std::size_t next_bucket = policy::to_bucket(
|
std::size_t next_bucket = policy::to_bucket(
|
||||||
this->bucket_count_,
|
this->bucket_count_,
|
||||||
@ -438,14 +438,14 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
++this->size_;
|
++this->size_;
|
||||||
return n;
|
return iterator(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
node_pointer emplace_impl(node_constructor& a)
|
iterator emplace_impl(node_constructor& a)
|
||||||
{
|
{
|
||||||
key_type const& k = this->get_key(a.value());
|
key_type const& k = this->get_key(a.value());
|
||||||
std::size_t hash = this->hash(k);
|
std::size_t hash = this->hash(k);
|
||||||
node_pointer position = this->find_node(hash, k);
|
iterator position = this->find_node(hash, k);
|
||||||
|
|
||||||
// reserve has basic exception safety if the hash function
|
// reserve has basic exception safety if the hash function
|
||||||
// throws, strong otherwise.
|
// throws, strong otherwise.
|
||||||
@ -457,8 +457,7 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
{
|
{
|
||||||
key_type const& k = this->get_key(a.value());
|
key_type const& k = this->get_key(a.value());
|
||||||
std::size_t hash = this->hash(k);
|
std::size_t hash = this->hash(k);
|
||||||
this->add_node(a, hash,
|
this->add_node(a, hash, this->find_node(hash, k));
|
||||||
this->find_node(hash, k));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(BOOST_NO_RVALUE_REFERENCES)
|
#if defined(BOOST_NO_RVALUE_REFERENCES)
|
||||||
@ -562,37 +561,38 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
node_pointer end = static_cast<node_pointer>(end1);
|
node_pointer end = static_cast<node_pointer>(end1);
|
||||||
prev->next_ = end1;
|
prev->next_ = end1;
|
||||||
this->fix_buckets(bucket, prev, end);
|
this->fix_buckets(bucket, prev, end);
|
||||||
return this->delete_nodes(pos, end);
|
return this->delete_nodes(c_iterator(pos), c_iterator(end));
|
||||||
}
|
}
|
||||||
|
|
||||||
node_pointer erase(node_pointer r)
|
iterator erase(c_iterator r)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(r);
|
BOOST_ASSERT(r.node_);
|
||||||
node_pointer next = static_cast<node_pointer>(r->next_);
|
iterator next(r.node_);
|
||||||
|
++next;
|
||||||
|
|
||||||
bucket_pointer bucket = this->get_bucket(
|
bucket_pointer bucket = this->get_bucket(
|
||||||
policy::to_bucket(this->bucket_count_, r->hash_));
|
policy::to_bucket(this->bucket_count_, r.node_->hash_));
|
||||||
previous_pointer prev = unlink_node(*bucket, r);
|
previous_pointer prev = unlink_node(*bucket, r.node_);
|
||||||
|
|
||||||
this->fix_buckets(bucket, prev, next);
|
this->fix_buckets(bucket, prev, next.node_);
|
||||||
|
|
||||||
this->delete_node(r);
|
this->delete_node(r);
|
||||||
|
|
||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
|
||||||
node_pointer erase_range(node_pointer r1, node_pointer r2)
|
iterator erase_range(c_iterator r1, c_iterator r2)
|
||||||
{
|
{
|
||||||
if (r1 == r2) return r2;
|
if (r1 == r2) return iterator(r2.node_);
|
||||||
|
|
||||||
std::size_t bucket_index =
|
std::size_t bucket_index =
|
||||||
policy::to_bucket(this->bucket_count_, r1->hash_);
|
policy::to_bucket(this->bucket_count_, r1.node_->hash_);
|
||||||
previous_pointer prev = unlink_nodes(
|
previous_pointer prev = unlink_nodes(
|
||||||
*this->get_bucket(bucket_index), r1, r2);
|
*this->get_bucket(bucket_index), r1.node_, r2.node_);
|
||||||
this->fix_buckets_range(bucket_index, prev, r1, r2);
|
this->fix_buckets_range(bucket_index, prev, r1.node_, r2.node_);
|
||||||
this->delete_nodes(r1, r2);
|
this->delete_nodes(r1, r2);
|
||||||
|
|
||||||
return r2;
|
return iterator(r2.node_);
|
||||||
}
|
}
|
||||||
|
|
||||||
static previous_pointer unlink_node(bucket& b, node_pointer n)
|
static previous_pointer unlink_node(bucket& b, node_pointer n)
|
||||||
@ -709,17 +709,18 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
|
|
||||||
node_constructor a(dst.node_alloc());
|
node_constructor a(dst.node_alloc());
|
||||||
|
|
||||||
node_pointer n = src.get_start();
|
iterator n = src.get_start();
|
||||||
previous_pointer prev = dst.get_previous_start();
|
previous_pointer prev = dst.get_previous_start();
|
||||||
|
|
||||||
while(n) {
|
while (n.node_) {
|
||||||
std::size_t hash = n->hash_;
|
std::size_t hash = n.node_->hash_;
|
||||||
node_pointer group_end =
|
iterator group_end(
|
||||||
static_cast<node_pointer>(
|
static_cast<node_pointer>(
|
||||||
static_cast<node_pointer>(n->group_prev_)->next_);
|
static_cast<node_pointer>(n.node_->group_prev_)->next_
|
||||||
|
));
|
||||||
|
|
||||||
a.construct_node();
|
a.construct_node();
|
||||||
a.construct_value2(n->value());
|
a.construct_value2(*n);
|
||||||
|
|
||||||
node_pointer first_node = a.release();
|
node_pointer first_node = a.release();
|
||||||
node_pointer end = first_node;
|
node_pointer end = first_node;
|
||||||
@ -727,11 +728,10 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
prev->next_ = static_cast<link_pointer>(first_node);
|
prev->next_ = static_cast<link_pointer>(first_node);
|
||||||
++dst.size_;
|
++dst.size_;
|
||||||
|
|
||||||
for(n = static_cast<node_pointer>(n->next_); n != group_end;
|
for (++n; n != group_end; ++n)
|
||||||
n = static_cast<node_pointer>(n->next_))
|
|
||||||
{
|
{
|
||||||
a.construct_node();
|
a.construct_node();
|
||||||
a.construct_value2(n->value());
|
a.construct_value2(*n);
|
||||||
end = a.release();
|
end = a.release();
|
||||||
end->hash_ = hash;
|
end->hash_ = hash;
|
||||||
add_after_node(end, first_node);
|
add_after_node(end, first_node);
|
||||||
@ -756,17 +756,18 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
|
|
||||||
node_constructor a(dst.node_alloc());
|
node_constructor a(dst.node_alloc());
|
||||||
|
|
||||||
node_pointer n = src.get_start();
|
iterator n = src.get_start();
|
||||||
previous_pointer prev = dst.get_previous_start();
|
previous_pointer prev = dst.get_previous_start();
|
||||||
|
|
||||||
while(n) {
|
while (n.node_) {
|
||||||
std::size_t hash = n->hash_;
|
std::size_t hash = n.node_->hash_;
|
||||||
node_pointer group_end =
|
iterator group_end(
|
||||||
static_cast<node_pointer>(
|
static_cast<node_pointer>(
|
||||||
static_cast<node_pointer>(n->group_prev_)->next_);
|
static_cast<node_pointer>(n.node_->group_prev_)->next_
|
||||||
|
));
|
||||||
|
|
||||||
a.construct_node();
|
a.construct_node();
|
||||||
a.construct_value2(boost::move(n->value()));
|
a.construct_value2(boost::move(*n));
|
||||||
|
|
||||||
node_pointer first_node = a.release();
|
node_pointer first_node = a.release();
|
||||||
node_pointer end = first_node;
|
node_pointer end = first_node;
|
||||||
@ -774,11 +775,10 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
prev->next_ = static_cast<link_pointer>(first_node);
|
prev->next_ = static_cast<link_pointer>(first_node);
|
||||||
++dst.size_;
|
++dst.size_;
|
||||||
|
|
||||||
for(n = static_cast<node_pointer>(n->next_); n != group_end;
|
for(++n; n != group_end; ++n)
|
||||||
n = static_cast<node_pointer>(n->next_))
|
|
||||||
{
|
{
|
||||||
a.construct_node();
|
a.construct_node();
|
||||||
a.construct_value2(boost::move(n->value()));
|
a.construct_value2(boost::move(*n));
|
||||||
end = a.release();
|
end = a.release();
|
||||||
end->hash_ = hash;
|
end->hash_ = hash;
|
||||||
add_after_node(end, first_node);
|
add_after_node(end, first_node);
|
||||||
|
@ -11,255 +11,8 @@
|
|||||||
#include <boost/unordered/detail/util.hpp>
|
#include <boost/unordered/detail/util.hpp>
|
||||||
#include <boost/type_traits/aligned_storage.hpp>
|
#include <boost/type_traits/aligned_storage.hpp>
|
||||||
#include <boost/type_traits/alignment_of.hpp>
|
#include <boost/type_traits/alignment_of.hpp>
|
||||||
#include <boost/iterator.hpp>
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
namespace boost { namespace unordered { namespace iterator_detail {
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Iterators
|
|
||||||
//
|
|
||||||
// all no throw
|
|
||||||
|
|
||||||
template <typename NodePointer, typename Value> struct iterator;
|
|
||||||
template <typename ConstNodePointer, typename NodePointer,
|
|
||||||
typename Value> struct c_iterator;
|
|
||||||
template <typename NodePointer, typename Value, typename Policy>
|
|
||||||
struct l_iterator;
|
|
||||||
template <typename ConstNodePointer, typename NodePointer,
|
|
||||||
typename Value, typename Policy> struct cl_iterator;
|
|
||||||
|
|
||||||
// Local Iterators
|
|
||||||
//
|
|
||||||
// all no throw
|
|
||||||
|
|
||||||
template <typename NodePointer, typename Value, typename Policy>
|
|
||||||
struct l_iterator
|
|
||||||
: public boost::iterator<
|
|
||||||
std::forward_iterator_tag, Value, std::ptrdiff_t,
|
|
||||||
NodePointer, Value&>
|
|
||||||
{
|
|
||||||
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
|
|
||||||
template <typename ConstNodePointer, typename NodePointer2,
|
|
||||||
typename Value2, typename Policy2>
|
|
||||||
friend struct boost::unordered::iterator_detail::cl_iterator;
|
|
||||||
private:
|
|
||||||
#endif
|
|
||||||
typedef NodePointer node_pointer;
|
|
||||||
node_pointer ptr_;
|
|
||||||
std::size_t bucket_;
|
|
||||||
std::size_t bucket_count_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
l_iterator() : ptr_() {}
|
|
||||||
|
|
||||||
l_iterator(node_pointer x, std::size_t b, std::size_t c)
|
|
||||||
: ptr_(x), bucket_(b), bucket_count_(c) {}
|
|
||||||
|
|
||||||
Value& operator*() const {
|
|
||||||
return ptr_->value();
|
|
||||||
}
|
|
||||||
|
|
||||||
Value* operator->() const {
|
|
||||||
return ptr_->value_ptr();
|
|
||||||
}
|
|
||||||
|
|
||||||
l_iterator& operator++() {
|
|
||||||
ptr_ = static_cast<node_pointer>(ptr_->next_);
|
|
||||||
if (ptr_ && Policy::to_bucket(bucket_count_, ptr_->hash_)
|
|
||||||
!= bucket_)
|
|
||||||
ptr_ = node_pointer();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
l_iterator operator++(int) {
|
|
||||||
l_iterator tmp(*this);
|
|
||||||
++(*this);
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(l_iterator x) const {
|
|
||||||
return ptr_ == x.ptr_;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator!=(l_iterator x) const {
|
|
||||||
return ptr_ != x.ptr_;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ConstNodePointer, typename NodePointer, typename Value,
|
|
||||||
typename Policy>
|
|
||||||
struct cl_iterator
|
|
||||||
: public boost::iterator<
|
|
||||||
std::forward_iterator_tag, Value, std::ptrdiff_t,
|
|
||||||
ConstNodePointer, Value const&>
|
|
||||||
{
|
|
||||||
friend struct boost::unordered::iterator_detail::l_iterator
|
|
||||||
<NodePointer, Value, Policy>;
|
|
||||||
private:
|
|
||||||
|
|
||||||
typedef NodePointer node_pointer;
|
|
||||||
node_pointer ptr_;
|
|
||||||
std::size_t bucket_;
|
|
||||||
std::size_t bucket_count_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
cl_iterator() : ptr_() {}
|
|
||||||
|
|
||||||
cl_iterator(node_pointer x, std::size_t b, std::size_t c) :
|
|
||||||
ptr_(x), bucket_(b), bucket_count_(c) {}
|
|
||||||
|
|
||||||
cl_iterator(boost::unordered::iterator_detail::l_iterator<
|
|
||||||
NodePointer, Value, Policy> const& x) :
|
|
||||||
ptr_(x.ptr_), bucket_(x.bucket_), bucket_count_(x.bucket_count_)
|
|
||||||
{}
|
|
||||||
|
|
||||||
Value const&
|
|
||||||
operator*() const {
|
|
||||||
return ptr_->value();
|
|
||||||
}
|
|
||||||
|
|
||||||
Value const* operator->() const {
|
|
||||||
return ptr_->value_ptr();
|
|
||||||
}
|
|
||||||
|
|
||||||
cl_iterator& operator++() {
|
|
||||||
ptr_ = static_cast<node_pointer>(ptr_->next_);
|
|
||||||
if (ptr_ && Policy::to_bucket(bucket_count_, ptr_->hash_)
|
|
||||||
!= bucket_)
|
|
||||||
ptr_ = node_pointer();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
cl_iterator operator++(int) {
|
|
||||||
cl_iterator tmp(*this);
|
|
||||||
++(*this);
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
friend bool operator==(cl_iterator const& x, cl_iterator const& y) {
|
|
||||||
return x.ptr_ == y.ptr_;
|
|
||||||
}
|
|
||||||
|
|
||||||
friend bool operator!=(cl_iterator const& x, cl_iterator const& y) {
|
|
||||||
return x.ptr_ != y.ptr_;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename NodePointer, typename Value>
|
|
||||||
struct iterator
|
|
||||||
: public boost::iterator<
|
|
||||||
std::forward_iterator_tag, Value, std::ptrdiff_t,
|
|
||||||
NodePointer, Value&>
|
|
||||||
{
|
|
||||||
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
|
|
||||||
template <typename ConstNodePointer, typename NodePointer2,
|
|
||||||
typename Value2>
|
|
||||||
friend struct boost::unordered::iterator_detail::c_iterator;
|
|
||||||
private:
|
|
||||||
#endif
|
|
||||||
typedef NodePointer node_pointer;
|
|
||||||
node_pointer node_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
iterator() : node_() {}
|
|
||||||
|
|
||||||
explicit iterator(node_pointer const& x) : node_(x) {}
|
|
||||||
|
|
||||||
Value& operator*() const {
|
|
||||||
return node_->value();
|
|
||||||
}
|
|
||||||
|
|
||||||
Value* operator->() const {
|
|
||||||
return &node_->value();
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator& operator++() {
|
|
||||||
node_ = static_cast<node_pointer>(node_->next_);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator operator++(int) {
|
|
||||||
iterator tmp(node_);
|
|
||||||
node_ = static_cast<node_pointer>(node_->next_);
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(iterator const& x) const {
|
|
||||||
return node_ == x.node_;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator!=(iterator const& x) const {
|
|
||||||
return node_ != x.node_;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ConstNodePointer, typename NodePointer, typename Value>
|
|
||||||
struct c_iterator
|
|
||||||
: public boost::iterator<
|
|
||||||
std::forward_iterator_tag, Value, std::ptrdiff_t,
|
|
||||||
ConstNodePointer, Value const&>
|
|
||||||
{
|
|
||||||
friend struct boost::unordered::iterator_detail::iterator<
|
|
||||||
NodePointer, Value>;
|
|
||||||
|
|
||||||
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
|
|
||||||
template <typename K, typename T, typename H, typename P, typename A>
|
|
||||||
friend class boost::unordered::unordered_map;
|
|
||||||
template <typename K, typename T, typename H, typename P, typename A>
|
|
||||||
friend class boost::unordered::unordered_multimap;
|
|
||||||
template <typename T, typename H, typename P, typename A>
|
|
||||||
friend class boost::unordered::unordered_set;
|
|
||||||
template <typename T, typename H, typename P, typename A>
|
|
||||||
friend class boost::unordered::unordered_multiset;
|
|
||||||
|
|
||||||
private:
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef NodePointer node_pointer;
|
|
||||||
node_pointer node_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
c_iterator() : node_() {}
|
|
||||||
|
|
||||||
explicit c_iterator(node_pointer const& x) : node_(x) {}
|
|
||||||
|
|
||||||
c_iterator(boost::unordered::iterator_detail::iterator<
|
|
||||||
NodePointer, Value> const& x) : node_(x.node_) {}
|
|
||||||
|
|
||||||
Value const& operator*() const {
|
|
||||||
return node_->value();
|
|
||||||
}
|
|
||||||
|
|
||||||
Value const* operator->() const {
|
|
||||||
return &node_->value();
|
|
||||||
}
|
|
||||||
|
|
||||||
c_iterator& operator++() {
|
|
||||||
node_ = static_cast<node_pointer>(node_->next_);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
c_iterator operator++(int) {
|
|
||||||
c_iterator tmp(node_);
|
|
||||||
node_ = static_cast<node_pointer>(node_->next_);
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
friend bool operator==(c_iterator const& x, c_iterator const& y) {
|
|
||||||
return x.node_ == y.node_;
|
|
||||||
}
|
|
||||||
|
|
||||||
friend bool operator!=(c_iterator const& x, c_iterator const& y) {
|
|
||||||
return x.node_ != y.node_;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}}}
|
|
||||||
|
|
||||||
namespace boost { namespace unordered { namespace detail {
|
namespace boost { namespace unordered { namespace detail {
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
@ -340,15 +93,7 @@ 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::
|
typedef typename table::iterator iterator;
|
||||||
iterator<node_pointer, value_type> iterator;
|
|
||||||
typedef boost::unordered::iterator_detail::
|
|
||||||
c_iterator<const_node_pointer, node_pointer, value_type> c_iterator;
|
|
||||||
typedef boost::unordered::iterator_detail::
|
|
||||||
l_iterator<node_pointer, value_type, policy> l_iterator;
|
|
||||||
typedef boost::unordered::iterator_detail::
|
|
||||||
cl_iterator<const_node_pointer, node_pointer, value_type, policy>
|
|
||||||
cl_iterator;
|
|
||||||
|
|
||||||
// Members
|
// Members
|
||||||
|
|
||||||
@ -465,9 +210,9 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
|
|
||||||
// Iterators
|
// Iterators
|
||||||
|
|
||||||
node_pointer begin() const {
|
iterator begin() const {
|
||||||
return !this->buckets_ ?
|
return !this->buckets_ ?
|
||||||
node_pointer() : this->get_start();
|
iterator() : this->get_start();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assignment
|
// Assignment
|
||||||
@ -601,33 +346,33 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
// Find Node
|
// Find Node
|
||||||
|
|
||||||
template <typename Key, typename Hash, typename Pred>
|
template <typename Key, typename Hash, typename Pred>
|
||||||
node_pointer generic_find_node(
|
iterator generic_find_node(
|
||||||
Key const& k,
|
Key const& k,
|
||||||
Hash const& hash_function,
|
Hash const& hash_function,
|
||||||
Pred const& eq) const
|
Pred const& eq) const
|
||||||
{
|
{
|
||||||
if (!this->size_) return node_pointer();
|
if (!this->size_) return iterator();
|
||||||
return static_cast<table_impl const*>(this)->
|
return static_cast<table_impl const*>(this)->
|
||||||
find_node_impl(policy::apply_hash(hash_function, k), k, eq);
|
find_node_impl(policy::apply_hash(hash_function, k), k, eq);
|
||||||
}
|
}
|
||||||
|
|
||||||
node_pointer find_node(
|
iterator find_node(
|
||||||
std::size_t hash,
|
std::size_t hash,
|
||||||
key_type const& k) const
|
key_type const& k) const
|
||||||
{
|
{
|
||||||
if (!this->size_) return node_pointer();
|
if (!this->size_) return iterator();
|
||||||
return static_cast<table_impl const*>(this)->
|
return static_cast<table_impl const*>(this)->
|
||||||
find_node_impl(hash, k, this->key_eq());
|
find_node_impl(hash, k, this->key_eq());
|
||||||
}
|
}
|
||||||
|
|
||||||
node_pointer find_node(key_type const& k) const
|
iterator find_node(key_type const& k) const
|
||||||
{
|
{
|
||||||
if (!this->size_) return node_pointer();
|
if (!this->size_) return iterator();
|
||||||
return static_cast<table_impl const*>(this)->
|
return static_cast<table_impl const*>(this)->
|
||||||
find_node_impl(this->hash(k), k, this->key_eq());
|
find_node_impl(this->hash(k), k, this->key_eq());
|
||||||
}
|
}
|
||||||
|
|
||||||
node_pointer find_matching_node(node_pointer n) const
|
iterator find_matching_node(iterator n) const
|
||||||
{
|
{
|
||||||
// TODO: Does this apply to C++11?
|
// TODO: Does this apply to C++11?
|
||||||
//
|
//
|
||||||
@ -635,7 +380,7 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
// when different hash functions are used. So I can't use the hash
|
// when different hash functions are used. So I can't use the hash
|
||||||
// value from the node here.
|
// value from the node here.
|
||||||
|
|
||||||
return find_node(get_key(n->value()));
|
return find_node(get_key(*n));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reserve and rehash
|
// Reserve and rehash
|
||||||
|
@ -182,6 +182,7 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
typedef typename table::node_constructor node_constructor;
|
typedef typename table::node_constructor node_constructor;
|
||||||
typedef typename table::extractor extractor;
|
typedef typename table::extractor extractor;
|
||||||
typedef typename table::iterator iterator;
|
typedef typename table::iterator iterator;
|
||||||
|
typedef typename table::c_iterator c_iterator;
|
||||||
|
|
||||||
typedef std::pair<iterator, bool> emplace_return;
|
typedef std::pair<iterator, bool> emplace_return;
|
||||||
|
|
||||||
@ -217,46 +218,46 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
// Accessors
|
// Accessors
|
||||||
|
|
||||||
template <class Key, class Pred>
|
template <class Key, class Pred>
|
||||||
node_pointer find_node_impl(
|
iterator find_node_impl(
|
||||||
std::size_t hash,
|
std::size_t hash,
|
||||||
Key const& k,
|
Key const& k,
|
||||||
Pred const& eq) const
|
Pred const& eq) const
|
||||||
{
|
{
|
||||||
std::size_t bucket_index =
|
std::size_t bucket_index =
|
||||||
policy::to_bucket(this->bucket_count_, hash);
|
policy::to_bucket(this->bucket_count_, hash);
|
||||||
node_pointer n = this->get_start(bucket_index);
|
iterator n = this->get_start(bucket_index);
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
if (!n) return n;
|
if (!n.node_) return n;
|
||||||
|
|
||||||
std::size_t node_hash = n->hash_;
|
std::size_t node_hash = n.node_->hash_;
|
||||||
if (hash == node_hash)
|
if (hash == node_hash)
|
||||||
{
|
{
|
||||||
if (eq(k, this->get_key(n->value())))
|
if (eq(k, this->get_key(*n)))
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (policy::to_bucket(this->bucket_count_, node_hash)
|
if (policy::to_bucket(this->bucket_count_, node_hash)
|
||||||
!= bucket_index)
|
!= bucket_index)
|
||||||
return node_pointer();
|
return iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
n = static_cast<node_pointer>(n->next_);
|
++n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t count(key_type const& k) const
|
std::size_t count(key_type const& k) const
|
||||||
{
|
{
|
||||||
return this->find_node(k) ? 1 : 0;
|
return this->find_node(k).node_ ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
value_type& at(key_type const& k) const
|
value_type& at(key_type const& k) const
|
||||||
{
|
{
|
||||||
if (this->size_) {
|
if (this->size_) {
|
||||||
node_pointer it = this->find_node(k);
|
iterator it = this->find_node(k);
|
||||||
if (it) return it->value();
|
if (it.node_) return *it;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::throw_exception(
|
boost::throw_exception(
|
||||||
@ -266,9 +267,10 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
std::pair<iterator, iterator>
|
std::pair<iterator, iterator>
|
||||||
equal_range(key_type const& k) const
|
equal_range(key_type const& k) const
|
||||||
{
|
{
|
||||||
node_pointer n = this->find_node(k);
|
iterator n = this->find_node(k);
|
||||||
return std::make_pair(iterator(n),
|
iterator n2 = n;
|
||||||
iterator(n ? static_cast<node_pointer>(n->next_) : n));
|
if (n2.node_) ++n2;
|
||||||
|
return std::make_pair(n, n2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// equals
|
// equals
|
||||||
@ -278,17 +280,15 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
if(this->size_ != other.size_) return false;
|
if(this->size_ != other.size_) return false;
|
||||||
if(!this->size_) return true;
|
if(!this->size_) return true;
|
||||||
|
|
||||||
for(node_pointer n1 = this->get_start(); n1;
|
for(iterator n1 = this->get_start(); n1.node_; ++n1)
|
||||||
n1 = static_cast<node_pointer>(n1->next_))
|
|
||||||
{
|
{
|
||||||
node_pointer n2 = other.find_matching_node(n1);
|
iterator n2 = other.find_matching_node(n1);
|
||||||
|
|
||||||
#if !defined(BOOST_UNORDERED_DEPRECATED_EQUALITY)
|
#if !defined(BOOST_UNORDERED_DEPRECATED_EQUALITY)
|
||||||
if(!n2 || n1->value() != n2->value())
|
if (!n2.node_ || *n1 != *n2)
|
||||||
return false;
|
return false;
|
||||||
#else
|
#else
|
||||||
if(!n2 || !extractor::compare_mapped(
|
if (!n2.node_ || !extractor::compare_mapped(*n1, *n2))
|
||||||
n1->value(), n2->value()))
|
|
||||||
return false;
|
return false;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -298,7 +298,7 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
|
|
||||||
// Emplace/Insert
|
// Emplace/Insert
|
||||||
|
|
||||||
inline node_pointer add_node(
|
inline iterator add_node(
|
||||||
node_constructor& a,
|
node_constructor& a,
|
||||||
std::size_t hash)
|
std::size_t hash)
|
||||||
{
|
{
|
||||||
@ -329,7 +329,7 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
}
|
}
|
||||||
|
|
||||||
++this->size_;
|
++this->size_;
|
||||||
return n;
|
return iterator(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
value_type& operator[](key_type const& k)
|
value_type& operator[](key_type const& k)
|
||||||
@ -337,9 +337,9 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
typedef typename value_type::second_type mapped_type;
|
typedef typename value_type::second_type mapped_type;
|
||||||
|
|
||||||
std::size_t hash = this->hash(k);
|
std::size_t hash = this->hash(k);
|
||||||
node_pointer pos = this->find_node(hash, k);
|
iterator pos = this->find_node(hash, k);
|
||||||
|
|
||||||
if (pos) return pos->value();
|
if (pos.node_) return *pos;
|
||||||
|
|
||||||
// Create the node before rehashing in case it throws an
|
// Create the node before rehashing in case it throws an
|
||||||
// exception (need strong safety in such a case).
|
// exception (need strong safety in such a case).
|
||||||
@ -357,7 +357,7 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
this->reserve_for_insert(this->size_ + 1);
|
this->reserve_for_insert(this->size_ + 1);
|
||||||
return add_node(a, hash)->value();
|
return *add_node(a, hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(BOOST_NO_RVALUE_REFERENCES)
|
#if defined(BOOST_NO_RVALUE_REFERENCES)
|
||||||
@ -365,7 +365,7 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
boost::unordered::detail::please_ignore_this_overload> const&)
|
boost::unordered::detail::please_ignore_this_overload> const&)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(false);
|
BOOST_ASSERT(false);
|
||||||
return emplace_return(iterator(this->begin()), false);
|
return emplace_return(this->begin(), false);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -398,9 +398,9 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
BOOST_UNORDERED_EMPLACE_ARGS)
|
BOOST_UNORDERED_EMPLACE_ARGS)
|
||||||
{
|
{
|
||||||
std::size_t hash = this->hash(k);
|
std::size_t hash = this->hash(k);
|
||||||
node_pointer pos = this->find_node(hash, k);
|
iterator pos = this->find_node(hash, k);
|
||||||
|
|
||||||
if (pos) return emplace_return(iterator(pos), false);
|
if (pos.node_) return emplace_return(pos, false);
|
||||||
|
|
||||||
// Create the node before rehashing in case it throws an
|
// Create the node before rehashing in case it throws an
|
||||||
// exception (need strong safety in such a case).
|
// exception (need strong safety in such a case).
|
||||||
@ -411,21 +411,21 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
// reserve has basic exception safety if the hash function
|
// reserve has basic exception safety if the hash function
|
||||||
// throws, strong otherwise.
|
// throws, strong otherwise.
|
||||||
this->reserve_for_insert(this->size_ + 1);
|
this->reserve_for_insert(this->size_ + 1);
|
||||||
return emplace_return(iterator(this->add_node(a, hash)), true);
|
return emplace_return(this->add_node(a, hash), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
emplace_return emplace_impl_with_node(node_constructor& a)
|
emplace_return emplace_impl_with_node(node_constructor& a)
|
||||||
{
|
{
|
||||||
key_type const& k = this->get_key(a.value());
|
key_type const& k = this->get_key(a.value());
|
||||||
std::size_t hash = this->hash(k);
|
std::size_t hash = this->hash(k);
|
||||||
node_pointer pos = this->find_node(hash, k);
|
iterator pos = this->find_node(hash, k);
|
||||||
|
|
||||||
if (pos) return emplace_return(iterator(pos), false);
|
if (pos.node_) return emplace_return(pos, false);
|
||||||
|
|
||||||
// reserve has basic exception safety if the hash function
|
// reserve has basic exception safety if the hash function
|
||||||
// throws, strong otherwise.
|
// throws, strong otherwise.
|
||||||
this->reserve_for_insert(this->size_ + 1);
|
this->reserve_for_insert(this->size_ + 1);
|
||||||
return emplace_return(iterator(this->add_node(a, hash)), true);
|
return emplace_return(this->add_node(a, hash), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <BOOST_UNORDERED_EMPLACE_TEMPLATE>
|
template <BOOST_UNORDERED_EMPLACE_TEMPLATE>
|
||||||
@ -495,9 +495,9 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
{
|
{
|
||||||
// No side effects in this initial code
|
// No side effects in this initial code
|
||||||
std::size_t hash = this->hash(k);
|
std::size_t hash = this->hash(k);
|
||||||
node_pointer pos = this->find_node(hash, k);
|
iterator pos = this->find_node(hash, k);
|
||||||
|
|
||||||
if (!pos) {
|
if (!pos.node_) {
|
||||||
a.construct_node();
|
a.construct_node();
|
||||||
a.construct_value2(*i);
|
a.construct_value2(*i);
|
||||||
|
|
||||||
@ -558,37 +558,38 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
node_pointer end = static_cast<node_pointer>(pos->next_);
|
node_pointer end = static_cast<node_pointer>(pos->next_);
|
||||||
prev->next_ = pos->next_;
|
prev->next_ = pos->next_;
|
||||||
this->fix_buckets(bucket, prev, end);
|
this->fix_buckets(bucket, prev, end);
|
||||||
return this->delete_nodes(pos, end);
|
return this->delete_nodes(c_iterator(pos), c_iterator(end));
|
||||||
}
|
}
|
||||||
|
|
||||||
node_pointer erase(node_pointer r)
|
iterator erase(c_iterator r)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(r);
|
BOOST_ASSERT(r.node_);
|
||||||
node_pointer next = static_cast<node_pointer>(r->next_);
|
iterator next(r.node_);
|
||||||
|
++next;
|
||||||
|
|
||||||
bucket_pointer bucket = this->get_bucket(
|
bucket_pointer bucket = this->get_bucket(
|
||||||
policy::to_bucket(this->bucket_count_, r->hash_));
|
policy::to_bucket(this->bucket_count_, r.node_->hash_));
|
||||||
previous_pointer prev = unlink_node(*bucket, r);
|
previous_pointer prev = unlink_node(*bucket, r.node_);
|
||||||
|
|
||||||
this->fix_buckets(bucket, prev, next);
|
this->fix_buckets(bucket, prev, next.node_);
|
||||||
|
|
||||||
this->delete_node(r);
|
this->delete_node(r);
|
||||||
|
|
||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
|
||||||
node_pointer erase_range(node_pointer r1, node_pointer r2)
|
iterator erase_range(c_iterator r1, c_iterator r2)
|
||||||
{
|
{
|
||||||
if (r1 == r2) return r2;
|
if (r1 == r2) return iterator(r2.node_);
|
||||||
|
|
||||||
std::size_t bucket_index =
|
std::size_t bucket_index =
|
||||||
policy::to_bucket(this->bucket_count_, r1->hash_);
|
policy::to_bucket(this->bucket_count_, r1.node_->hash_);
|
||||||
previous_pointer prev = unlink_nodes(
|
previous_pointer prev = unlink_nodes(
|
||||||
*this->get_bucket(bucket_index), r1, r2);
|
*this->get_bucket(bucket_index), r1.node_, r2.node_);
|
||||||
this->fix_buckets_range(bucket_index, prev, r1, r2);
|
this->fix_buckets_range(bucket_index, prev, r1.node_, r2.node_);
|
||||||
this->delete_nodes(r1, r2);
|
this->delete_nodes(r1, r2);
|
||||||
|
|
||||||
return r2;
|
return iterator(r2.node_);
|
||||||
}
|
}
|
||||||
|
|
||||||
static previous_pointer unlink_node(bucket& b, node_pointer n)
|
static previous_pointer unlink_node(bucket& b, node_pointer n)
|
||||||
@ -621,18 +622,18 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
|
|
||||||
node_constructor a(dst.node_alloc());
|
node_constructor a(dst.node_alloc());
|
||||||
|
|
||||||
node_pointer n = src.get_start();
|
iterator n = src.get_start();
|
||||||
previous_pointer prev = dst.get_previous_start();
|
previous_pointer prev = dst.get_previous_start();
|
||||||
|
|
||||||
while(n) {
|
while(n.node_) {
|
||||||
a.construct_node();
|
a.construct_node();
|
||||||
a.construct_value2(n->value());
|
a.construct_value2(*n);
|
||||||
|
|
||||||
node_pointer node = a.release();
|
node_pointer node = a.release();
|
||||||
node->hash_ = n->hash_;
|
node->hash_ = n.node_->hash_;
|
||||||
prev->next_ = static_cast<link_pointer>(node);
|
prev->next_ = static_cast<link_pointer>(node);
|
||||||
++dst.size_;
|
++dst.size_;
|
||||||
n = static_cast<node_pointer>(n->next_);
|
++n;
|
||||||
|
|
||||||
prev = place_in_bucket(dst, prev);
|
prev = place_in_bucket(dst, prev);
|
||||||
}
|
}
|
||||||
@ -652,18 +653,18 @@ namespace boost { namespace unordered { namespace detail {
|
|||||||
|
|
||||||
node_constructor a(dst.node_alloc());
|
node_constructor a(dst.node_alloc());
|
||||||
|
|
||||||
node_pointer n = src.get_start();
|
iterator n = src.get_start();
|
||||||
previous_pointer prev = dst.get_previous_start();
|
previous_pointer prev = dst.get_previous_start();
|
||||||
|
|
||||||
while(n) {
|
while (n.node_) {
|
||||||
a.construct_node();
|
a.construct_node();
|
||||||
a.construct_value2(boost::move(n->value()));
|
a.construct_value2(boost::move(*n));
|
||||||
|
|
||||||
node_pointer node = a.release();
|
node_pointer node = a.release();
|
||||||
node->hash_ = n->hash_;
|
node->hash_ = n.node_->hash_;
|
||||||
prev->next_ = static_cast<link_pointer>(node);
|
prev->next_ = static_cast<link_pointer>(node);
|
||||||
++dst.size_;
|
++dst.size_;
|
||||||
n = static_cast<node_pointer>(n->next_);
|
++n;
|
||||||
|
|
||||||
prev = place_in_bucket(dst, prev);
|
prev = place_in_bucket(dst, prev);
|
||||||
}
|
}
|
||||||
|
@ -203,12 +203,12 @@ namespace unordered
|
|||||||
|
|
||||||
iterator begin()
|
iterator begin()
|
||||||
{
|
{
|
||||||
return iterator(table_.begin());
|
return table_.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
const_iterator begin() const
|
const_iterator begin() const
|
||||||
{
|
{
|
||||||
return const_iterator(table_.begin());
|
return table_.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator end()
|
iterator end()
|
||||||
@ -223,7 +223,7 @@ namespace unordered
|
|||||||
|
|
||||||
const_iterator cbegin() const
|
const_iterator cbegin() const
|
||||||
{
|
{
|
||||||
return const_iterator(table_.begin());
|
return table_.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
const_iterator cend() const
|
const_iterator cend() const
|
||||||
@ -689,12 +689,12 @@ namespace unordered
|
|||||||
|
|
||||||
iterator begin()
|
iterator begin()
|
||||||
{
|
{
|
||||||
return iterator(table_.begin());
|
return table_.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
const_iterator begin() const
|
const_iterator begin() const
|
||||||
{
|
{
|
||||||
return const_iterator(table_.begin());
|
return table_.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator end()
|
iterator end()
|
||||||
@ -709,7 +709,7 @@ namespace unordered
|
|||||||
|
|
||||||
const_iterator cbegin() const
|
const_iterator cbegin() const
|
||||||
{
|
{
|
||||||
return const_iterator(table_.begin());
|
return table_.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
const_iterator cend() const
|
const_iterator cend() const
|
||||||
@ -1141,7 +1141,7 @@ namespace unordered
|
|||||||
typename unordered_map<K,T,H,P,A>::iterator
|
typename unordered_map<K,T,H,P,A>::iterator
|
||||||
unordered_map<K,T,H,P,A>::erase(const_iterator position)
|
unordered_map<K,T,H,P,A>::erase(const_iterator position)
|
||||||
{
|
{
|
||||||
return iterator(table_.erase(position.node_));
|
return table_.erase(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class K, class T, class H, class P, class A>
|
template <class K, class T, class H, class P, class A>
|
||||||
@ -1156,7 +1156,7 @@ namespace unordered
|
|||||||
unordered_map<K,T,H,P,A>::erase(
|
unordered_map<K,T,H,P,A>::erase(
|
||||||
const_iterator first, const_iterator last)
|
const_iterator first, const_iterator last)
|
||||||
{
|
{
|
||||||
return iterator(table_.erase_range(first.node_, last.node_));
|
return table_.erase_range(first, last);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class K, class T, class H, class P, class A>
|
template <class K, class T, class H, class P, class A>
|
||||||
@ -1214,14 +1214,14 @@ namespace unordered
|
|||||||
typename unordered_map<K,T,H,P,A>::iterator
|
typename unordered_map<K,T,H,P,A>::iterator
|
||||||
unordered_map<K,T,H,P,A>::find(const key_type& k)
|
unordered_map<K,T,H,P,A>::find(const key_type& k)
|
||||||
{
|
{
|
||||||
return iterator(table_.find_node(k));
|
return table_.find_node(k);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class K, class T, class H, class P, class A>
|
template <class K, class T, class H, class P, class A>
|
||||||
typename unordered_map<K,T,H,P,A>::const_iterator
|
typename unordered_map<K,T,H,P,A>::const_iterator
|
||||||
unordered_map<K,T,H,P,A>::find(const key_type& k) const
|
unordered_map<K,T,H,P,A>::find(const key_type& k) const
|
||||||
{
|
{
|
||||||
return const_iterator(table_.find_node(k));
|
return table_.find_node(k);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class K, class T, class H, class P, class A>
|
template <class K, class T, class H, class P, class A>
|
||||||
@ -1233,7 +1233,7 @@ namespace unordered
|
|||||||
CompatibleHash const& hash,
|
CompatibleHash const& hash,
|
||||||
CompatiblePredicate const& eq)
|
CompatiblePredicate const& eq)
|
||||||
{
|
{
|
||||||
return iterator(table_.generic_find_node(k, hash, eq));
|
return table_.generic_find_node(k, hash, eq);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class K, class T, class H, class P, class A>
|
template <class K, class T, class H, class P, class A>
|
||||||
@ -1245,7 +1245,7 @@ namespace unordered
|
|||||||
CompatibleHash const& hash,
|
CompatibleHash const& hash,
|
||||||
CompatiblePredicate const& eq) const
|
CompatiblePredicate const& eq) const
|
||||||
{
|
{
|
||||||
return const_iterator(table_.generic_find_node(k, hash, eq));
|
return table_.generic_find_node(k, hash, eq);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class K, class T, class H, class P, class A>
|
template <class K, class T, class H, class P, class A>
|
||||||
@ -1468,7 +1468,7 @@ namespace unordered
|
|||||||
typename unordered_multimap<K,T,H,P,A>::iterator
|
typename unordered_multimap<K,T,H,P,A>::iterator
|
||||||
unordered_multimap<K,T,H,P,A>::erase(const_iterator position)
|
unordered_multimap<K,T,H,P,A>::erase(const_iterator position)
|
||||||
{
|
{
|
||||||
return iterator(table_.erase(position.node_));
|
return table_.erase(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class K, class T, class H, class P, class A>
|
template <class K, class T, class H, class P, class A>
|
||||||
@ -1483,7 +1483,7 @@ namespace unordered
|
|||||||
unordered_multimap<K,T,H,P,A>::erase(
|
unordered_multimap<K,T,H,P,A>::erase(
|
||||||
const_iterator first, const_iterator last)
|
const_iterator first, const_iterator last)
|
||||||
{
|
{
|
||||||
return iterator(table_.erase_range(first.node_, last.node_));
|
return table_.erase_range(first, last);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class K, class T, class H, class P, class A>
|
template <class K, class T, class H, class P, class A>
|
||||||
@ -1520,14 +1520,14 @@ namespace unordered
|
|||||||
typename unordered_multimap<K,T,H,P,A>::iterator
|
typename unordered_multimap<K,T,H,P,A>::iterator
|
||||||
unordered_multimap<K,T,H,P,A>::find(const key_type& k)
|
unordered_multimap<K,T,H,P,A>::find(const key_type& k)
|
||||||
{
|
{
|
||||||
return iterator(table_.find_node(k));
|
return table_.find_node(k);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class K, class T, class H, class P, class A>
|
template <class K, class T, class H, class P, class A>
|
||||||
typename unordered_multimap<K,T,H,P,A>::const_iterator
|
typename unordered_multimap<K,T,H,P,A>::const_iterator
|
||||||
unordered_multimap<K,T,H,P,A>::find(const key_type& k) const
|
unordered_multimap<K,T,H,P,A>::find(const key_type& k) const
|
||||||
{
|
{
|
||||||
return const_iterator(table_.find_node(k));
|
return table_.find_node(k);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class K, class T, class H, class P, class A>
|
template <class K, class T, class H, class P, class A>
|
||||||
@ -1539,7 +1539,7 @@ namespace unordered
|
|||||||
CompatibleHash const& hash,
|
CompatibleHash const& hash,
|
||||||
CompatiblePredicate const& eq)
|
CompatiblePredicate const& eq)
|
||||||
{
|
{
|
||||||
return iterator(table_.generic_find_node(k, hash, eq));
|
return table_.generic_find_node(k, hash, eq);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class K, class T, class H, class P, class A>
|
template <class K, class T, class H, class P, class A>
|
||||||
@ -1551,7 +1551,7 @@ namespace unordered
|
|||||||
CompatibleHash const& hash,
|
CompatibleHash const& hash,
|
||||||
CompatiblePredicate const& eq) const
|
CompatiblePredicate const& eq) const
|
||||||
{
|
{
|
||||||
return const_iterator(table_.generic_find_node(k, hash, eq));
|
return table_.generic_find_node(k, hash, eq);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class K, class T, class H, class P, class A>
|
template <class K, class T, class H, class P, class A>
|
||||||
|
@ -201,12 +201,12 @@ namespace unordered
|
|||||||
|
|
||||||
iterator begin()
|
iterator begin()
|
||||||
{
|
{
|
||||||
return iterator(table_.begin());
|
return table_.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
const_iterator begin() const
|
const_iterator begin() const
|
||||||
{
|
{
|
||||||
return const_iterator(table_.begin());
|
return table_.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator end()
|
iterator end()
|
||||||
@ -221,7 +221,7 @@ namespace unordered
|
|||||||
|
|
||||||
const_iterator cbegin() const
|
const_iterator cbegin() const
|
||||||
{
|
{
|
||||||
return const_iterator(table_.begin());
|
return table_.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
const_iterator cend() const
|
const_iterator cend() const
|
||||||
@ -1116,7 +1116,7 @@ namespace unordered
|
|||||||
typename unordered_set<T,H,P,A>::iterator
|
typename unordered_set<T,H,P,A>::iterator
|
||||||
unordered_set<T,H,P,A>::erase(const_iterator position)
|
unordered_set<T,H,P,A>::erase(const_iterator position)
|
||||||
{
|
{
|
||||||
return iterator(table_.erase(position.node_));
|
return table_.erase(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class H, class P, class A>
|
template <class T, class H, class P, class A>
|
||||||
@ -1131,7 +1131,7 @@ namespace unordered
|
|||||||
unordered_set<T,H,P,A>::erase(
|
unordered_set<T,H,P,A>::erase(
|
||||||
const_iterator first, const_iterator last)
|
const_iterator first, const_iterator last)
|
||||||
{
|
{
|
||||||
return iterator(table_.erase_range(first.node_, last.node_));
|
return table_.erase_range(first, last);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class H, class P, class A>
|
template <class T, class H, class P, class A>
|
||||||
@ -1168,7 +1168,7 @@ namespace unordered
|
|||||||
typename unordered_set<T,H,P,A>::const_iterator
|
typename unordered_set<T,H,P,A>::const_iterator
|
||||||
unordered_set<T,H,P,A>::find(const key_type& k) const
|
unordered_set<T,H,P,A>::find(const key_type& k) const
|
||||||
{
|
{
|
||||||
return const_iterator(table_.find_node(k));
|
return table_.find_node(k);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class H, class P, class A>
|
template <class T, class H, class P, class A>
|
||||||
@ -1180,7 +1180,7 @@ namespace unordered
|
|||||||
CompatibleHash const& hash,
|
CompatibleHash const& hash,
|
||||||
CompatiblePredicate const& eq) const
|
CompatiblePredicate const& eq) const
|
||||||
{
|
{
|
||||||
return const_iterator(table_.generic_find_node(k, hash, eq));
|
return table_.generic_find_node(k, hash, eq);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class H, class P, class A>
|
template <class T, class H, class P, class A>
|
||||||
@ -1394,7 +1394,7 @@ namespace unordered
|
|||||||
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 position)
|
unordered_multiset<T,H,P,A>::erase(const_iterator position)
|
||||||
{
|
{
|
||||||
return iterator(table_.erase(position.node_));
|
return table_.erase(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class H, class P, class A>
|
template <class T, class H, class P, class A>
|
||||||
@ -1409,7 +1409,7 @@ namespace unordered
|
|||||||
unordered_multiset<T,H,P,A>::erase(
|
unordered_multiset<T,H,P,A>::erase(
|
||||||
const_iterator first, const_iterator last)
|
const_iterator first, const_iterator last)
|
||||||
{
|
{
|
||||||
return iterator(table_.erase_range(first.node_, last.node_));
|
return table_.erase_range(first, last);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class H, class P, class A>
|
template <class T, class H, class P, class A>
|
||||||
@ -1446,7 +1446,7 @@ namespace unordered
|
|||||||
typename unordered_multiset<T,H,P,A>::const_iterator
|
typename unordered_multiset<T,H,P,A>::const_iterator
|
||||||
unordered_multiset<T,H,P,A>::find(const key_type& k) const
|
unordered_multiset<T,H,P,A>::find(const key_type& k) const
|
||||||
{
|
{
|
||||||
return const_iterator(table_.find_node(k));
|
return table_.find_node(k);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class H, class P, class A>
|
template <class T, class H, class P, class A>
|
||||||
@ -1458,7 +1458,7 @@ namespace unordered
|
|||||||
CompatibleHash const& hash,
|
CompatibleHash const& hash,
|
||||||
CompatiblePredicate const& eq) const
|
CompatiblePredicate const& eq) const
|
||||||
{
|
{
|
||||||
return const_iterator(table_.generic_find_node(k, hash, eq));
|
return table_.generic_find_node(k, hash, eq);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class H, class P, class A>
|
template <class T, class H, class P, class A>
|
||||||
|
Reference in New Issue
Block a user