forked from boostorg/unordered
Remove 'local_iterator_base'.
Merged revisions 42153-42156 via svnmerge from https://svn.boost.org/svn/boost/branches/unordered/dev ........ r42153 | danieljames | 2007-12-18 22:51:31 +0000 (Tue, 18 Dec 2007) | 2 lines Remove 'local_iterator_base'. It isn't really needed. ........ r42155 | danieljames | 2007-12-18 22:58:12 +0000 (Tue, 18 Dec 2007) | 1 line Add a helper function for creating null pointers. ........ r42156 | danieljames | 2007-12-18 23:14:49 +0000 (Tue, 18 Dec 2007) | 3 lines Check that I'm using link_ptr & bucket_ptr correctly (they should be distinct types with an explicit conversion from bucket_ptr to link_ptr). ........ [SVN r42189]
This commit is contained in:
@@ -42,6 +42,9 @@ namespace boost {
|
|||||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||||
template <class T>
|
template <class T>
|
||||||
inline void reset(T& x) { x = T(); }
|
inline void reset(T& x) { x = T(); }
|
||||||
|
|
||||||
|
template <class Ptr>
|
||||||
|
inline Ptr null_ptr() { return Ptr(); }
|
||||||
#else
|
#else
|
||||||
template <class T>
|
template <class T>
|
||||||
inline void reset_impl(T& x, ...) { x = T(); }
|
inline void reset_impl(T& x, ...) { x = T(); }
|
||||||
@@ -49,6 +52,9 @@ namespace boost {
|
|||||||
inline void reset_impl(T*& x, int) { x = 0; }
|
inline void reset_impl(T*& x, int) { x = 0; }
|
||||||
template <class T>
|
template <class T>
|
||||||
inline void reset(T& x) { reset_impl(x); }
|
inline void reset(T& x) { reset_impl(x); }
|
||||||
|
|
||||||
|
template <class Ptr>
|
||||||
|
inline Ptr null_ptr() { Ptr x; reset(x); return x; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Work around for Microsoft's ETI bug.
|
// Work around for Microsoft's ETI bug.
|
||||||
|
@@ -53,8 +53,28 @@ namespace boost {
|
|||||||
typedef BOOST_DEDUCED_TYPENAME allocator_pointer<node_allocator>::type node_ptr;
|
typedef BOOST_DEDUCED_TYPENAME allocator_pointer<node_allocator>::type node_ptr;
|
||||||
typedef BOOST_DEDUCED_TYPENAME allocator_pointer<bucket_allocator>::type bucket_ptr;
|
typedef BOOST_DEDUCED_TYPENAME allocator_pointer<bucket_allocator>::type bucket_ptr;
|
||||||
typedef BOOST_DEDUCED_TYPENAME allocator_reference<value_allocator>::type reference;
|
typedef BOOST_DEDUCED_TYPENAME allocator_reference<value_allocator>::type reference;
|
||||||
typedef bucket_ptr link_ptr;
|
typedef BOOST_DEDUCED_TYPENAME allocator_reference<bucket_allocator>::type bucket_reference;
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
typedef bucket_ptr link_ptr;
|
||||||
|
#else
|
||||||
|
// This alternative version of link_ptr is used to check that the
|
||||||
|
// implementation is type safe wrt bucket_ptr and link_ptr.
|
||||||
|
//
|
||||||
|
// It's a sort of strict typedef.
|
||||||
|
|
||||||
|
struct link_ptr {
|
||||||
|
link_ptr() : ptr_() { BOOST_HASH_MSVC_RESET_PTR(ptr_); }
|
||||||
|
explicit link_ptr(bucket_ptr p) : ptr_(p) {}
|
||||||
|
bucket_reference operator*() const { return *ptr_; }
|
||||||
|
bucket* operator->() const { return &*ptr_; }
|
||||||
|
operator bool() const { return ptr_; }
|
||||||
|
bool operator==(link_ptr const& x) const { return ptr_ == x.ptr_; }
|
||||||
|
bool operator!=(link_ptr const& x) const { return ptr_ != x.ptr_; }
|
||||||
|
private:
|
||||||
|
bucket_ptr ptr_;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
// Hash Bucket
|
// Hash Bucket
|
||||||
//
|
//
|
||||||
// all no throw
|
// all no throw
|
||||||
@@ -256,31 +276,31 @@ namespace boost {
|
|||||||
return static_cast<node&>(*p).value_;
|
return static_cast<node&>(*p).value_;
|
||||||
}
|
}
|
||||||
|
|
||||||
class local_iterator_base
|
class iterator_base
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
bucket_ptr bucket_;
|
||||||
link_ptr node_;
|
link_ptr node_;
|
||||||
|
|
||||||
local_iterator_base()
|
iterator_base()
|
||||||
: node_()
|
: bucket_(), node_()
|
||||||
{
|
{
|
||||||
|
BOOST_HASH_MSVC_RESET_PTR(bucket_);
|
||||||
BOOST_HASH_MSVC_RESET_PTR(node_);
|
BOOST_HASH_MSVC_RESET_PTR(node_);
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit local_iterator_base(link_ptr n)
|
explicit iterator_base(bucket_ptr b)
|
||||||
: node_(n) {}
|
: bucket_(b), node_(b->next_) {}
|
||||||
|
|
||||||
bool not_finished() const
|
iterator_base(bucket_ptr b, link_ptr n)
|
||||||
{
|
: bucket_(b), node_(n) {}
|
||||||
return node_ ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(local_iterator_base const& x) const
|
bool operator==(iterator_base const& x) const
|
||||||
{
|
{
|
||||||
return node_ == x.node_;
|
return node_ == x.node_;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(local_iterator_base const& x) const
|
bool operator!=(iterator_base const& x) const
|
||||||
{
|
{
|
||||||
return node_ != x.node_;
|
return node_ != x.node_;
|
||||||
}
|
}
|
||||||
@@ -290,59 +310,14 @@ namespace boost {
|
|||||||
return get_value(node_);
|
return get_value(node_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void increment()
|
|
||||||
{
|
|
||||||
BOOST_ASSERT(node_);
|
|
||||||
node_ = node_->next_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void next_group()
|
|
||||||
{
|
|
||||||
node_ = BOOST_UNORDERED_TABLE_DATA::next_group(node_);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class iterator_base
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
bucket_ptr bucket_;
|
|
||||||
local_iterator_base local_;
|
|
||||||
|
|
||||||
iterator_base()
|
|
||||||
: bucket_(), local_() {}
|
|
||||||
|
|
||||||
explicit iterator_base(bucket_ptr b)
|
|
||||||
: bucket_(b), local_(b->next_) {}
|
|
||||||
|
|
||||||
iterator_base(bucket_ptr b, link_ptr n)
|
|
||||||
: bucket_(b), local_(n) {}
|
|
||||||
|
|
||||||
iterator_base(bucket_ptr b, local_iterator_base const& it)
|
|
||||||
: bucket_(b), local_(it) {}
|
|
||||||
|
|
||||||
bool operator==(iterator_base const& x) const
|
|
||||||
{
|
|
||||||
return local_ == x.local_;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator!=(iterator_base const& x) const
|
|
||||||
{
|
|
||||||
return local_ != x.local_;
|
|
||||||
}
|
|
||||||
|
|
||||||
reference operator*() const
|
|
||||||
{
|
|
||||||
return *local_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void increment()
|
void increment()
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(bucket_);
|
BOOST_ASSERT(bucket_);
|
||||||
local_.increment();
|
node_ = node_->next_;
|
||||||
|
|
||||||
while (!local_.node_) {
|
while (!node_) {
|
||||||
++bucket_;
|
++bucket_;
|
||||||
local_ = local_iterator_base(bucket_->next_);
|
node_ = bucket_->next_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -462,41 +437,40 @@ namespace boost {
|
|||||||
return iterator_base(buckets_ + bucket_count_);
|
return iterator_base(buckets_ + bucket_count_);
|
||||||
}
|
}
|
||||||
|
|
||||||
local_iterator_base begin(size_type n) const
|
link_ptr begin(size_type n) const
|
||||||
{
|
{
|
||||||
return local_iterator_base(buckets_[n].next_);
|
return buckets_[n].next_;
|
||||||
}
|
}
|
||||||
|
|
||||||
local_iterator_base end(size_type) const
|
link_ptr end(size_type) const
|
||||||
{
|
{
|
||||||
return local_iterator_base();
|
return unordered_detail::null_ptr<link_ptr>();
|
||||||
}
|
}
|
||||||
|
|
||||||
local_iterator_base begin(bucket_ptr b) const
|
link_ptr begin(bucket_ptr b) const
|
||||||
{
|
{
|
||||||
return local_iterator_base(b->next_);
|
return b->next_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bucket Size
|
// Bucket Size
|
||||||
|
|
||||||
// no throw
|
// no throw
|
||||||
size_type node_count(local_iterator_base it) const
|
size_type node_count(link_ptr it) const
|
||||||
{
|
{
|
||||||
size_type count = 0;
|
size_type count = 0;
|
||||||
while(it.not_finished()) {
|
while(BOOST_HASH_BORLAND_BOOL(it)) {
|
||||||
++count;
|
++count;
|
||||||
it.increment();
|
it = it->next_;
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_type node_count(local_iterator_base it1,
|
size_type node_count(link_ptr it1, link_ptr it2) const
|
||||||
local_iterator_base it2) const
|
|
||||||
{
|
{
|
||||||
size_type count = 0;
|
size_type count = 0;
|
||||||
while(it1 != it2) {
|
while(it1 != it2) {
|
||||||
++count;
|
++count;
|
||||||
it1.increment();
|
it1 = it1->next_;
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
@@ -507,10 +481,9 @@ namespace boost {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if BOOST_UNORDERED_HASH_EQUIVALENT
|
#if BOOST_UNORDERED_HASH_EQUIVALENT
|
||||||
size_type group_count(local_iterator_base first_node) const
|
size_type group_count(link_ptr it) const
|
||||||
{
|
{
|
||||||
size_type count = 0;
|
size_type count = 0;
|
||||||
link_ptr it = first_node.node_;
|
|
||||||
link_ptr first = it;
|
link_ptr first = it;
|
||||||
do {
|
do {
|
||||||
++count;
|
++count;
|
||||||
@@ -519,7 +492,7 @@ namespace boost {
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
size_type group_count(local_iterator_base) const
|
size_type group_count(link_ptr) const
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -534,7 +507,7 @@ namespace boost {
|
|||||||
#if BOOST_UNORDERED_HASH_EQUIVALENT
|
#if BOOST_UNORDERED_HASH_EQUIVALENT
|
||||||
static link_ptr* get_for_erase(iterator_base r)
|
static link_ptr* get_for_erase(iterator_base r)
|
||||||
{
|
{
|
||||||
link_ptr n = r.local_.node_;
|
link_ptr n = r.node_;
|
||||||
|
|
||||||
// If the element isn't the first in its group, then
|
// If the element isn't the first in its group, then
|
||||||
// the link to it will be found in the previous element
|
// the link to it will be found in the previous element
|
||||||
@@ -551,7 +524,7 @@ namespace boost {
|
|||||||
#else
|
#else
|
||||||
static link_ptr* get_for_erase(iterator_base r)
|
static link_ptr* get_for_erase(iterator_base r)
|
||||||
{
|
{
|
||||||
link_ptr n = r.local_.node_;
|
link_ptr n = r.node_;
|
||||||
link_ptr* it = &r.bucket_->next_;
|
link_ptr* it = &r.bucket_->next_;
|
||||||
while(*it != n) it = &(*it)->next_;
|
while(*it != n) it = &(*it)->next_;
|
||||||
return it;
|
return it;
|
||||||
@@ -566,10 +539,10 @@ namespace boost {
|
|||||||
// no throw
|
// no throw
|
||||||
|
|
||||||
#if BOOST_UNORDERED_HASH_EQUIVALENT
|
#if BOOST_UNORDERED_HASH_EQUIVALENT
|
||||||
void link_node(link_ptr n, local_iterator_base pos)
|
void link_node(link_ptr n, link_ptr pos)
|
||||||
{
|
{
|
||||||
node& node_ref = get_node(n);
|
node& node_ref = get_node(n);
|
||||||
node& pos_ref = get_node(pos.node_);
|
node& pos_ref = get_node(pos);
|
||||||
node_ref.next_ = pos_ref.group_prev_->next_;
|
node_ref.next_ = pos_ref.group_prev_->next_;
|
||||||
node_ref.group_prev_ = pos_ref.group_prev_;
|
node_ref.group_prev_ = pos_ref.group_prev_;
|
||||||
pos_ref.group_prev_->next_ = n;
|
pos_ref.group_prev_->next_ = n;
|
||||||
@@ -577,7 +550,7 @@ namespace boost {
|
|||||||
++size_;
|
++size_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void link_node(link_ptr n, bucket_ptr base)
|
void link_node_in_bucket(link_ptr n, bucket_ptr base)
|
||||||
{
|
{
|
||||||
node& node_ref = get_node(n);
|
node& node_ref = get_node(n);
|
||||||
node_ref.next_ = base->next_;
|
node_ref.next_ = base->next_;
|
||||||
@@ -597,7 +570,7 @@ namespace boost {
|
|||||||
if(base < cached_begin_bucket_) cached_begin_bucket_ = base;
|
if(base < cached_begin_bucket_) cached_begin_bucket_ = base;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void link_node(link_ptr n, bucket_ptr base)
|
void link_node_in_bucket(link_ptr n, bucket_ptr base)
|
||||||
{
|
{
|
||||||
n->next_ = base->next_;
|
n->next_ = base->next_;
|
||||||
base->next_ = n;
|
base->next_ = n;
|
||||||
@@ -607,7 +580,7 @@ namespace boost {
|
|||||||
|
|
||||||
void link_group(link_ptr n, bucket_ptr base, size_type)
|
void link_group(link_ptr n, bucket_ptr base, size_type)
|
||||||
{
|
{
|
||||||
link_node(n, base);
|
link_node_in_bucket(n, base);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -615,7 +588,7 @@ namespace boost {
|
|||||||
void unlink_node(iterator_base it)
|
void unlink_node(iterator_base it)
|
||||||
{
|
{
|
||||||
link_ptr* pos = get_for_erase(it);
|
link_ptr* pos = get_for_erase(it);
|
||||||
node* n = &get_node(it.local_.node_);
|
node* n = &get_node(it.node_);
|
||||||
link_ptr next = n->next_;
|
link_ptr next = n->next_;
|
||||||
|
|
||||||
if(n->group_prev_ == *pos) {
|
if(n->group_prev_ == *pos) {
|
||||||
@@ -644,7 +617,7 @@ namespace boost {
|
|||||||
|
|
||||||
size_type unlink_group(link_ptr* pos)
|
size_type unlink_group(link_ptr* pos)
|
||||||
{
|
{
|
||||||
size_type count = group_count(local_iterator_base(*pos));
|
size_type count = group_count(*pos);
|
||||||
size_ -= count;
|
size_ -= count;
|
||||||
link_ptr last = last_in_group(*pos);
|
link_ptr last = last_in_group(*pos);
|
||||||
*pos = last->next_;
|
*pos = last->next_;
|
||||||
@@ -671,31 +644,28 @@ namespace boost {
|
|||||||
link_ptr* it = get_for_erase(n);
|
link_ptr* it = get_for_erase(n);
|
||||||
split_group(*it);
|
split_group(*it);
|
||||||
unordered_detail::reset(*it);
|
unordered_detail::reset(*it);
|
||||||
size_ -= node_count(n.local_);
|
size_ -= node_count(n.node_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void unlink_nodes(iterator_base begin, iterator_base end)
|
void unlink_nodes(iterator_base begin, iterator_base end)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(begin.bucket_ == end.bucket_);
|
BOOST_ASSERT(begin.bucket_ == end.bucket_);
|
||||||
local_iterator_base local_end = end.local_;
|
size_ -= node_count(begin.node_, end.node_);
|
||||||
|
|
||||||
size_ -= node_count(begin.local_, local_end);
|
|
||||||
link_ptr* it = get_for_erase(begin);
|
link_ptr* it = get_for_erase(begin);
|
||||||
split_group(*it, local_end.node_);
|
split_group(*it, end.node_);
|
||||||
*it = local_end.node_;
|
*it = end.node_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void unlink_nodes(bucket_ptr base, iterator_base end)
|
void unlink_nodes(bucket_ptr base, iterator_base end)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(base == end.bucket_);
|
BOOST_ASSERT(base == end.bucket_);
|
||||||
|
|
||||||
local_iterator_base local_end = end.local_;
|
split_group(end.node_);
|
||||||
split_group(local_end.node_);
|
|
||||||
|
|
||||||
link_ptr ptr(base->next_);
|
link_ptr ptr(base->next_);
|
||||||
base->next_ = local_end.node_;
|
base->next_ = end.node_;
|
||||||
|
|
||||||
size_ -= node_count(local_iterator_base(ptr), local_end);
|
size_ -= node_count(ptr, end.node_);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if BOOST_UNORDERED_HASH_EQUIVALENT
|
#if BOOST_UNORDERED_HASH_EQUIVALENT
|
||||||
@@ -707,7 +677,7 @@ namespace boost {
|
|||||||
// If split is at the beginning of the group then there's
|
// If split is at the beginning of the group then there's
|
||||||
// nothing to split.
|
// nothing to split.
|
||||||
if(prev_in_group(split)->next_ != split)
|
if(prev_in_group(split)->next_ != split)
|
||||||
return link_ptr();
|
return unordered_detail::null_ptr<link_ptr>();
|
||||||
|
|
||||||
// Find the start of the group.
|
// Find the start of the group.
|
||||||
link_ptr start = split;
|
link_ptr start = split;
|
||||||
@@ -763,7 +733,7 @@ namespace boost {
|
|||||||
link_ptr n = construct_node(v);
|
link_ptr n = construct_node(v);
|
||||||
|
|
||||||
// Rest is no throw
|
// Rest is no throw
|
||||||
link_node(n, base);
|
link_node_in_bucket(n, base);
|
||||||
return iterator_base(base, n);
|
return iterator_base(base, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -774,39 +744,38 @@ namespace boost {
|
|||||||
link_ptr n = construct_node(v);
|
link_ptr n = construct_node(v);
|
||||||
|
|
||||||
// Rest is no throw
|
// Rest is no throw
|
||||||
link_node(n, position.local_);
|
link_node(n, position.node_);
|
||||||
return iterator_base(position.bucket_, n);
|
return iterator_base(position.bucket_, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator_base create_node(value_type const& v,
|
iterator_base create_node(value_type const& v,
|
||||||
bucket_ptr base, local_iterator_base position)
|
bucket_ptr base, link_ptr position)
|
||||||
{
|
{
|
||||||
// throws, strong exception-safety:
|
// throws, strong exception-safety:
|
||||||
link_ptr n = construct_node(v);
|
link_ptr n = construct_node(v);
|
||||||
|
|
||||||
// Rest is no throw
|
// Rest is no throw
|
||||||
if(position.not_finished())
|
if(BOOST_HASH_BORLAND_BOOL(position))
|
||||||
link_node(n, position);
|
link_node(n, position);
|
||||||
else
|
else
|
||||||
link_node(n, base);
|
link_node_in_bucket(n, base);
|
||||||
|
|
||||||
return iterator_base(base, n);
|
return iterator_base(base, n);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if BOOST_UNORDERED_HASH_EQUIVALENT
|
#if BOOST_UNORDERED_HASH_EQUIVALENT
|
||||||
void copy_group(local_iterator_base it, bucket_ptr dst)
|
void copy_group(link_ptr it, bucket_ptr dst)
|
||||||
{
|
{
|
||||||
local_iterator_base end = it;
|
link_ptr end = next_group(it);
|
||||||
end.next_group();
|
iterator_base pos = create_node(get_value(it), dst);
|
||||||
iterator_base pos = create_node(*it, dst);
|
for(it = it->next_; it != end; it = it->next_)
|
||||||
for(it.increment(); it != end; it.increment())
|
create_node(get_value(it), pos);
|
||||||
create_node(*it, pos);
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void copy_group(local_iterator_base it, bucket_ptr dst)
|
void copy_group(link_ptr it, bucket_ptr dst)
|
||||||
{
|
{
|
||||||
create_node(*it, dst);
|
create_node(get_value(it), dst);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -884,7 +853,7 @@ namespace boost {
|
|||||||
iterator_base next = r;
|
iterator_base next = r;
|
||||||
next.increment();
|
next.increment();
|
||||||
unlink_node(r);
|
unlink_node(r);
|
||||||
allocators_.destroy(r.local_.node_);
|
allocators_.destroy(r.node_);
|
||||||
// r has been invalidated but its bucket is still valid
|
// r has been invalidated but its bucket is still valid
|
||||||
recompute_begin_bucket(r.bucket_, next.bucket_);
|
recompute_begin_bucket(r.bucket_, next.bucket_);
|
||||||
return next;
|
return next;
|
||||||
@@ -898,7 +867,7 @@ namespace boost {
|
|||||||
|
|
||||||
if (r1.bucket_ == r2.bucket_) {
|
if (r1.bucket_ == r2.bucket_) {
|
||||||
unlink_nodes(r1, r2);
|
unlink_nodes(r1, r2);
|
||||||
delete_nodes(r1.local_.node_, r2.local_.node_);
|
delete_nodes(r1.node_, r2.node_);
|
||||||
|
|
||||||
// No need to call recompute_begin_bucket because
|
// No need to call recompute_begin_bucket because
|
||||||
// the nodes are only deleted from one bucket, which
|
// the nodes are only deleted from one bucket, which
|
||||||
@@ -909,17 +878,17 @@ namespace boost {
|
|||||||
BOOST_ASSERT(r1.bucket_ < r2.bucket_);
|
BOOST_ASSERT(r1.bucket_ < r2.bucket_);
|
||||||
|
|
||||||
unlink_nodes(r1);
|
unlink_nodes(r1);
|
||||||
delete_to_bucket_end(r1.local_.node_);
|
delete_to_bucket_end(r1.node_);
|
||||||
|
|
||||||
for(bucket_ptr i = r1.bucket_ + 1; i != r2.bucket_; ++i) {
|
for(bucket_ptr i = r1.bucket_ + 1; i != r2.bucket_; ++i) {
|
||||||
size_ -= node_count(local_iterator_base(i->next_));
|
size_ -= node_count(i->next_);
|
||||||
clear_bucket(i);
|
clear_bucket(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(r2 != end()) {
|
if(r2 != end()) {
|
||||||
link_ptr first = r2.bucket_->next_;
|
link_ptr first = r2.bucket_->next_;
|
||||||
unlink_nodes(r2.bucket_, r2);
|
unlink_nodes(r2.bucket_, r2);
|
||||||
delete_nodes(first, r2.local_.node_);
|
delete_nodes(first, r2.node_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// r1 has been invalidated but its bucket is still
|
// r1 has been invalidated but its bucket is still
|
||||||
@@ -1019,7 +988,6 @@ namespace boost {
|
|||||||
|
|
||||||
// iterators
|
// iterators
|
||||||
|
|
||||||
typedef BOOST_DEDUCED_TYPENAME data::local_iterator_base local_iterator_base;
|
|
||||||
typedef BOOST_DEDUCED_TYPENAME data::iterator_base iterator_base;
|
typedef BOOST_DEDUCED_TYPENAME data::iterator_base iterator_base;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -1489,11 +1457,11 @@ namespace boost {
|
|||||||
// no throw:
|
// no throw:
|
||||||
for(bucket_ptr i = src.cached_begin_bucket_; i != end; ++i) {
|
for(bucket_ptr i = src.cached_begin_bucket_; i != end; ++i) {
|
||||||
// no throw:
|
// no throw:
|
||||||
for(local_iterator_base it = src.begin(i);
|
for(link_ptr it = src.begin(i);
|
||||||
it.not_finished(); it.next_group()) {
|
BOOST_HASH_BORLAND_BOOL(it); it = data::next_group(it)) {
|
||||||
// hash function can throw.
|
// hash function can throw.
|
||||||
bucket_ptr dst_bucket = dst.buckets_ +
|
bucket_ptr dst_bucket = dst.buckets_ +
|
||||||
dst.index_from_hash(hf(extract_key(*it)));
|
dst.index_from_hash(hf(extract_key(data::get_value(it))));
|
||||||
// throws, strong
|
// throws, strong
|
||||||
dst.copy_group(it, dst_bucket);
|
dst.copy_group(it, dst_bucket);
|
||||||
}
|
}
|
||||||
@@ -1519,7 +1487,7 @@ namespace boost {
|
|||||||
size_type hash_value = hash_function()(k);
|
size_type hash_value = hash_function()(k);
|
||||||
bucket_ptr bucket = this->buckets_
|
bucket_ptr bucket = this->buckets_
|
||||||
+ this->index_from_hash(hash_value);
|
+ this->index_from_hash(hash_value);
|
||||||
local_iterator_base position = find_iterator(bucket, k);
|
link_ptr position = find_iterator(bucket, k);
|
||||||
|
|
||||||
// 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).
|
||||||
@@ -1535,12 +1503,12 @@ namespace boost {
|
|||||||
|
|
||||||
link_ptr n = a.release();
|
link_ptr n = a.release();
|
||||||
|
|
||||||
// I'm relying on local_iterator_base not being invalidated by
|
// I'm relying on link_ptr not being invalidated by
|
||||||
// the rehash here.
|
// the rehash here.
|
||||||
if(position.not_finished())
|
if(BOOST_HASH_BORLAND_BOOL(position))
|
||||||
this->link_node(n, position);
|
this->link_node(n, position);
|
||||||
else
|
else
|
||||||
this->link_node(n, bucket);
|
this->link_node_in_bucket(n, bucket);
|
||||||
|
|
||||||
return iterator_base(bucket, n);
|
return iterator_base(bucket, n);
|
||||||
}
|
}
|
||||||
@@ -1561,9 +1529,9 @@ namespace boost {
|
|||||||
// Find the first node in the group - so that the node
|
// Find the first node in the group - so that the node
|
||||||
// will be inserted at the end of the group.
|
// will be inserted at the end of the group.
|
||||||
|
|
||||||
local_iterator_base start(it.local_);
|
link_ptr start(it.node_);
|
||||||
while(this->prev_in_group(start.node_)->next_ == start.node_)
|
while(this->prev_in_group(start)->next_ == start)
|
||||||
start.node_ = this->prev_in_group(start.node_);
|
start = this->prev_in_group(start);
|
||||||
|
|
||||||
// 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).
|
||||||
@@ -1607,12 +1575,12 @@ namespace boost {
|
|||||||
|
|
||||||
key_type const& k = extract_key(a.get()->value_);
|
key_type const& k = extract_key(a.get()->value_);
|
||||||
bucket_ptr bucket = get_bucket(k);
|
bucket_ptr bucket = get_bucket(k);
|
||||||
local_iterator_base position = find_iterator(bucket, k);
|
link_ptr position = find_iterator(bucket, k);
|
||||||
|
|
||||||
if(position.not_finished())
|
if(BOOST_HASH_BORLAND_BOOL(position))
|
||||||
this->link_node(a.release(), position);
|
this->link_node(a.release(), position);
|
||||||
else
|
else
|
||||||
this->link_node(a.release(), bucket);
|
this->link_node_in_bucket(a.release(), bucket);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1650,10 +1618,10 @@ namespace boost {
|
|||||||
|
|
||||||
size_type hash_value = hash_function()(k);
|
size_type hash_value = hash_function()(k);
|
||||||
bucket_ptr bucket = this->buckets_ + this->index_from_hash(hash_value);
|
bucket_ptr bucket = this->buckets_ + this->index_from_hash(hash_value);
|
||||||
local_iterator_base pos = find_iterator(bucket, k);
|
link_ptr pos = find_iterator(bucket, k);
|
||||||
|
|
||||||
if (pos.not_finished())
|
if (BOOST_HASH_BORLAND_BOOL(pos))
|
||||||
return *pos;
|
return data::get_value(pos);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Side effects only in this block.
|
// Side effects only in this block.
|
||||||
@@ -1671,9 +1639,9 @@ namespace boost {
|
|||||||
// Nothing after this point can throw.
|
// Nothing after this point can throw.
|
||||||
|
|
||||||
link_ptr n = a.release();
|
link_ptr n = a.release();
|
||||||
this->link_node(n, bucket);
|
this->link_node_in_bucket(n, bucket);
|
||||||
|
|
||||||
return *local_iterator_base(n);
|
return data::get_value(n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1687,9 +1655,9 @@ namespace boost {
|
|||||||
key_type const& k = extract_key(v);
|
key_type const& k = extract_key(v);
|
||||||
size_type hash_value = hash_function()(k);
|
size_type hash_value = hash_function()(k);
|
||||||
bucket_ptr bucket = this->buckets_ + this->index_from_hash(hash_value);
|
bucket_ptr bucket = this->buckets_ + this->index_from_hash(hash_value);
|
||||||
local_iterator_base pos = find_iterator(bucket, k);
|
link_ptr pos = find_iterator(bucket, k);
|
||||||
|
|
||||||
if (pos.not_finished()) {
|
if (BOOST_HASH_BORLAND_BOOL(pos)) {
|
||||||
// Found an existing key, return it (no throw).
|
// Found an existing key, return it (no throw).
|
||||||
return std::pair<iterator_base, bool>(
|
return std::pair<iterator_base, bool>(
|
||||||
iterator_base(bucket, pos), false);
|
iterator_base(bucket, pos), false);
|
||||||
@@ -1711,7 +1679,7 @@ namespace boost {
|
|||||||
// Nothing after this point can throw.
|
// Nothing after this point can throw.
|
||||||
|
|
||||||
link_ptr n = a.release();
|
link_ptr n = a.release();
|
||||||
this->link_node(n, bucket);
|
this->link_node_in_bucket(n, bucket);
|
||||||
|
|
||||||
return std::pair<iterator_base, bool>(
|
return std::pair<iterator_base, bool>(
|
||||||
iterator_base(bucket, n), true);
|
iterator_base(bucket, n), true);
|
||||||
@@ -1764,9 +1732,9 @@ namespace boost {
|
|||||||
size_type hash_value = hash_function()(extract_key(*i));
|
size_type hash_value = hash_function()(extract_key(*i));
|
||||||
bucket_ptr bucket = this->buckets_
|
bucket_ptr bucket = this->buckets_
|
||||||
+ this->index_from_hash(hash_value);
|
+ this->index_from_hash(hash_value);
|
||||||
local_iterator_base pos = find_iterator(bucket, extract_key(*i));
|
link_ptr pos = find_iterator(bucket, extract_key(*i));
|
||||||
|
|
||||||
if (!pos.not_finished()) {
|
if (!BOOST_HASH_BORLAND_BOOL(pos)) {
|
||||||
// Doesn't already exist, add to bucket.
|
// Doesn't already exist, add to bucket.
|
||||||
// Side effects only in this block.
|
// Side effects only in this block.
|
||||||
|
|
||||||
@@ -1784,7 +1752,7 @@ namespace boost {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Nothing after this point can throw.
|
// Nothing after this point can throw.
|
||||||
this->link_node(a.release(), bucket);
|
this->link_node_in_bucket(a.release(), bucket);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1821,8 +1789,8 @@ namespace boost {
|
|||||||
// strong exception safety, no side effects
|
// strong exception safety, no side effects
|
||||||
size_type count(key_type const& k) const
|
size_type count(key_type const& k) const
|
||||||
{
|
{
|
||||||
local_iterator_base it = find_iterator(k); // throws, strong
|
link_ptr it = find_iterator(k); // throws, strong
|
||||||
return it.not_finished() ? this->group_count(it) : 0;
|
return BOOST_HASH_BORLAND_BOOL(it) ? this->group_count(it) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// find
|
// find
|
||||||
@@ -1831,9 +1799,9 @@ namespace boost {
|
|||||||
iterator_base find(key_type const& k) const
|
iterator_base find(key_type const& k) const
|
||||||
{
|
{
|
||||||
bucket_ptr bucket = get_bucket(k);
|
bucket_ptr bucket = get_bucket(k);
|
||||||
local_iterator_base it = find_iterator(bucket, k);
|
link_ptr it = find_iterator(bucket, k);
|
||||||
|
|
||||||
if (it.not_finished())
|
if (BOOST_HASH_BORLAND_BOOL(it))
|
||||||
return iterator_base(bucket, it);
|
return iterator_base(bucket, it);
|
||||||
else
|
else
|
||||||
return this->end();
|
return this->end();
|
||||||
@@ -1842,10 +1810,10 @@ namespace boost {
|
|||||||
value_type& at(key_type const& k) const
|
value_type& at(key_type const& k) const
|
||||||
{
|
{
|
||||||
bucket_ptr bucket = get_bucket(k);
|
bucket_ptr bucket = get_bucket(k);
|
||||||
local_iterator_base it = find_iterator(bucket, k);
|
link_ptr it = find_iterator(bucket, k);
|
||||||
|
|
||||||
if (it.not_finished())
|
if (BOOST_HASH_BORLAND_BOOL(it))
|
||||||
return *it;
|
return data::get_value(it);
|
||||||
else
|
else
|
||||||
throw std::out_of_range("Unable to find key in unordered_map.");
|
throw std::out_of_range("Unable to find key in unordered_map.");
|
||||||
}
|
}
|
||||||
@@ -1856,10 +1824,10 @@ namespace boost {
|
|||||||
std::pair<iterator_base, iterator_base> equal_range(key_type const& k) const
|
std::pair<iterator_base, iterator_base> equal_range(key_type const& k) const
|
||||||
{
|
{
|
||||||
bucket_ptr bucket = get_bucket(k);
|
bucket_ptr bucket = get_bucket(k);
|
||||||
local_iterator_base it = find_iterator(bucket, k);
|
link_ptr it = find_iterator(bucket, k);
|
||||||
if (it.not_finished()) {
|
if (BOOST_HASH_BORLAND_BOOL(it)) {
|
||||||
iterator_base first(iterator_base(bucket, it));
|
iterator_base first(iterator_base(bucket, it));
|
||||||
iterator_base second(iterator_base(bucket, this->last_in_group(it.node_)));
|
iterator_base second(iterator_base(bucket, this->last_in_group(it)));
|
||||||
second.increment();
|
second.increment();
|
||||||
return std::pair<iterator_base, iterator_base>(first, second);
|
return std::pair<iterator_base, iterator_base>(first, second);
|
||||||
}
|
}
|
||||||
@@ -1878,18 +1846,18 @@ namespace boost {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// strong exception safety, no side effects
|
// strong exception safety, no side effects
|
||||||
local_iterator_base find_iterator(key_type const& k) const
|
link_ptr find_iterator(key_type const& k) const
|
||||||
{
|
{
|
||||||
return find_iterator(get_bucket(k), k);
|
return find_iterator(get_bucket(k), k);
|
||||||
}
|
}
|
||||||
|
|
||||||
// strong exception safety, no side effects
|
// strong exception safety, no side effects
|
||||||
local_iterator_base find_iterator(bucket_ptr bucket,
|
link_ptr find_iterator(bucket_ptr bucket,
|
||||||
key_type const& k) const
|
key_type const& k) const
|
||||||
{
|
{
|
||||||
local_iterator_base it = this->begin(bucket);
|
link_ptr it = this->begin(bucket);
|
||||||
while (it.not_finished() && !equal(k, *it))
|
while (BOOST_HASH_BORLAND_BOOL(it) && !equal(k, data::get_value(it)))
|
||||||
it.next_group();
|
it = data::next_group(it);
|
||||||
|
|
||||||
return it;
|
return it;
|
||||||
}
|
}
|
||||||
@@ -1898,8 +1866,8 @@ namespace boost {
|
|||||||
link_ptr* find_for_erase(bucket_ptr bucket, key_type const& k) const
|
link_ptr* find_for_erase(bucket_ptr bucket, key_type const& k) const
|
||||||
{
|
{
|
||||||
link_ptr* it = &bucket->next_;
|
link_ptr* it = &bucket->next_;
|
||||||
while(BOOST_HASH_BORLAND_BOOL(*it) && !equal(k, this->get_value(*it)))
|
while(BOOST_HASH_BORLAND_BOOL(*it) && !equal(k, data::get_value(*it)))
|
||||||
it = &this->next_group(*it);
|
it = &data::next_group(*it);
|
||||||
|
|
||||||
return it;
|
return it;
|
||||||
}
|
}
|
||||||
@@ -1930,24 +1898,27 @@ namespace boost {
|
|||||||
typedef BOOST_DEDUCED_TYPENAME allocator_value_type<Alloc>::type value_type;
|
typedef BOOST_DEDUCED_TYPENAME allocator_value_type<Alloc>::type value_type;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef BOOST_DEDUCED_TYPENAME BOOST_UNORDERED_TABLE_DATA<Alloc>::local_iterator_base base;
|
typedef BOOST_UNORDERED_TABLE_DATA<Alloc> data;
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME data::link_ptr ptr;
|
||||||
typedef BOOST_UNORDERED_CONST_LOCAL_ITERATOR<Alloc> const_local_iterator;
|
typedef BOOST_UNORDERED_CONST_LOCAL_ITERATOR<Alloc> const_local_iterator;
|
||||||
|
|
||||||
friend class BOOST_UNORDERED_CONST_LOCAL_ITERATOR<Alloc>;
|
friend class BOOST_UNORDERED_CONST_LOCAL_ITERATOR<Alloc>;
|
||||||
base base_;
|
ptr ptr_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BOOST_UNORDERED_LOCAL_ITERATOR() : base_() {}
|
BOOST_UNORDERED_LOCAL_ITERATOR() : ptr_() {
|
||||||
explicit BOOST_UNORDERED_LOCAL_ITERATOR(base x) : base_(x) {}
|
BOOST_HASH_MSVC_RESET_PTR(ptr_);
|
||||||
|
}
|
||||||
|
explicit BOOST_UNORDERED_LOCAL_ITERATOR(ptr x) : ptr_(x) {}
|
||||||
BOOST_DEDUCED_TYPENAME allocator_reference<Alloc>::type operator*() const
|
BOOST_DEDUCED_TYPENAME allocator_reference<Alloc>::type operator*() const
|
||||||
{ return *base_; }
|
{ return data::get_value(ptr_); }
|
||||||
value_type* operator->() const { return &*base_; }
|
value_type* operator->() const { return &data::get_value(ptr_); }
|
||||||
BOOST_UNORDERED_LOCAL_ITERATOR& operator++() { base_.increment(); return *this; }
|
BOOST_UNORDERED_LOCAL_ITERATOR& operator++() { ptr_ = ptr_->next_; return *this; }
|
||||||
BOOST_UNORDERED_LOCAL_ITERATOR operator++(int) { BOOST_UNORDERED_LOCAL_ITERATOR tmp(base_); base_.increment(); return tmp; }
|
BOOST_UNORDERED_LOCAL_ITERATOR operator++(int) { BOOST_UNORDERED_LOCAL_ITERATOR tmp(ptr_); ptr_ = ptr_->next_; return tmp; }
|
||||||
bool operator==(BOOST_UNORDERED_LOCAL_ITERATOR x) const { return base_ == x.base_; }
|
bool operator==(BOOST_UNORDERED_LOCAL_ITERATOR x) const { return ptr_ == x.ptr_; }
|
||||||
bool operator==(const_local_iterator x) const { return base_ == x.base_; }
|
bool operator==(const_local_iterator x) const { return ptr_ == x.ptr_; }
|
||||||
bool operator!=(BOOST_UNORDERED_LOCAL_ITERATOR x) const { return base_ != x.base_; }
|
bool operator!=(BOOST_UNORDERED_LOCAL_ITERATOR x) const { return ptr_ != x.ptr_; }
|
||||||
bool operator!=(const_local_iterator x) const { return base_ != x.base_; }
|
bool operator!=(const_local_iterator x) const { return ptr_ != x.ptr_; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Alloc>
|
template <typename Alloc>
|
||||||
@@ -1963,24 +1934,27 @@ namespace boost {
|
|||||||
typedef BOOST_DEDUCED_TYPENAME allocator_value_type<Alloc>::type value_type;
|
typedef BOOST_DEDUCED_TYPENAME allocator_value_type<Alloc>::type value_type;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef BOOST_DEDUCED_TYPENAME BOOST_UNORDERED_TABLE_DATA<Alloc>::local_iterator_base base;
|
typedef BOOST_UNORDERED_TABLE_DATA<Alloc> data;
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME data::link_ptr ptr;
|
||||||
typedef BOOST_UNORDERED_LOCAL_ITERATOR<Alloc> local_iterator;
|
typedef BOOST_UNORDERED_LOCAL_ITERATOR<Alloc> local_iterator;
|
||||||
friend class BOOST_UNORDERED_LOCAL_ITERATOR<Alloc>;
|
friend class BOOST_UNORDERED_LOCAL_ITERATOR<Alloc>;
|
||||||
base base_;
|
ptr ptr_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BOOST_UNORDERED_CONST_LOCAL_ITERATOR() : base_() {}
|
BOOST_UNORDERED_CONST_LOCAL_ITERATOR() : ptr_() {
|
||||||
explicit BOOST_UNORDERED_CONST_LOCAL_ITERATOR(base x) : base_(x) {}
|
BOOST_HASH_MSVC_RESET_PTR(ptr_);
|
||||||
BOOST_UNORDERED_CONST_LOCAL_ITERATOR(local_iterator x) : base_(x.base_) {}
|
}
|
||||||
|
explicit BOOST_UNORDERED_CONST_LOCAL_ITERATOR(ptr x) : ptr_(x) {}
|
||||||
|
BOOST_UNORDERED_CONST_LOCAL_ITERATOR(local_iterator x) : ptr_(x.ptr_) {}
|
||||||
BOOST_DEDUCED_TYPENAME allocator_const_reference<Alloc>::type
|
BOOST_DEDUCED_TYPENAME allocator_const_reference<Alloc>::type
|
||||||
operator*() const { return *base_; }
|
operator*() const { return data::get_value(ptr_); }
|
||||||
value_type const* operator->() const { return &*base_; }
|
value_type const* operator->() const { return &data::get_value(ptr_); }
|
||||||
BOOST_UNORDERED_CONST_LOCAL_ITERATOR& operator++() { base_.increment(); return *this; }
|
BOOST_UNORDERED_CONST_LOCAL_ITERATOR& operator++() { ptr_ = ptr_->next_; return *this; }
|
||||||
BOOST_UNORDERED_CONST_LOCAL_ITERATOR operator++(int) { BOOST_UNORDERED_CONST_LOCAL_ITERATOR tmp(base_); base_.increment(); return tmp; }
|
BOOST_UNORDERED_CONST_LOCAL_ITERATOR operator++(int) { BOOST_UNORDERED_CONST_LOCAL_ITERATOR tmp(ptr_); ptr_ = ptr_->next_; return tmp; }
|
||||||
bool operator==(local_iterator x) const { return base_ == x.base_; }
|
bool operator==(local_iterator x) const { return ptr_ == x.ptr_; }
|
||||||
bool operator==(BOOST_UNORDERED_CONST_LOCAL_ITERATOR x) const { return base_ == x.base_; }
|
bool operator==(BOOST_UNORDERED_CONST_LOCAL_ITERATOR x) const { return ptr_ == x.ptr_; }
|
||||||
bool operator!=(local_iterator x) const { return base_ != x.base_; }
|
bool operator!=(local_iterator x) const { return ptr_ != x.ptr_; }
|
||||||
bool operator!=(BOOST_UNORDERED_CONST_LOCAL_ITERATOR x) const { return base_ != x.base_; }
|
bool operator!=(BOOST_UNORDERED_CONST_LOCAL_ITERATOR x) const { return ptr_ != x.ptr_; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// iterators
|
// iterators
|
||||||
|
Reference in New Issue
Block a user