Files
boost_unordered/include/boost/unordered/detail/structure.hpp
Daniel James 386d9f28d7 Initial checkin of new version of Boost.Unordered.
- More template use, less preprocessor use.
 - Removed some of the Visual C++ 6 workarounds.
 - Reduced memory use of the main object.
 - Split into smaller headers.

[SVN r55878]
2009-08-30 16:42:28 +00:00

221 lines
6.4 KiB
C++

// Copyright (C) 2003-2004 Jeremy B. Maitin-Shepard.
// Copyright (C) 2005-2009 Daniel James
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// This contains the basic data structure, apart from the actual values. There's
// no construction or deconstruction here. So this only depends on the pointer
// type.
#ifndef BOOST_UNORDERED_DETAIL_STRUCTURE_HPP_INCLUDED
#define BOOST_UNORDERED_DETAIL_STRUCTURE_HPP_INCLUDED
#include <boost/unordered/detail/node.hpp>
namespace boost { namespace unordered_detail {
////////////////////////////////////////////////////////////////////////////
// hash_structure implementation
template <class A, class G>
void hash_structure<A, G>::swap(hash_structure<A, G>& other)
{
std::swap(buckets_, other.buckets_);
std::swap(cached_begin_bucket_, other.cached_begin_bucket_);
std::swap(size_, other.size_);
std::swap(bucket_count_, other.bucket_count_);
}
template <class A, class G>
std::size_t hash_structure<A, G>::bucket_count() const
{
return bucket_count_;
}
template <class A, class G>
std::size_t hash_structure<A, G>::bucket_from_hash(std::size_t hashed) const
{
return hashed % bucket_count_;
}
template <class A, class G>
BOOST_DEDUCED_TYPENAME hash_structure<A, G>::bucket_ptr
hash_structure<A, G>::bucket_ptr_from_hash(std::size_t hashed) const
{
return buckets_ + static_cast<std::ptrdiff_t>(
bucket_from_hash(hashed));
}
template <class A, class G>
BOOST_DEDUCED_TYPENAME hash_structure<A, G>::bucket_ptr
hash_structure<A, G>::buckets_begin() const
{
return buckets_;
}
template <class A, class G>
BOOST_DEDUCED_TYPENAME hash_structure<A, G>::bucket_ptr
hash_structure<A, G>::buckets_end() const
{
return buckets_ + static_cast<std::ptrdiff_t>(bucket_count_);
}
template <class A, class G>
std::size_t hash_structure<A, G>::bucket_size(std::size_t index) const
{
bucket_ptr ptr = (buckets_ + static_cast<std::ptrdiff_t>(index))->next_;
std::size_t count = 0;
while(ptr) {
++count;
ptr = next_node(ptr);
}
return count;
}
// Link a node
template <class A, class G>
void hash_structure<A, G>::link_node(node_ptr n, node_ptr position)
{
node_base::add_after_node(n, position);
++size_;
}
template <class A, class G>
void hash_structure<A, G>::link_node_in_bucket(node_ptr n, bucket_ptr bucket)
{
node_base::add_to_bucket(n, *bucket);
++size_;
if(bucket < cached_begin_bucket_) cached_begin_bucket_ = bucket;
}
template <class A, class G>
void hash_structure<A, G>::unlink_node(bucket_ptr bucket, node_ptr pos)
{
--size_;
node_base::unlink_node(*bucket, pos);
}
template <class A, class G>
void hash_structure<A, G>::unlink_nodes(
bucket_ptr bucket, node_ptr begin, node_ptr end)
{
size_ -= node_count(begin, end);
node_base::unlink_nodes(*bucket, begin, end);
}
template <class A, class G>
void hash_structure<A, G>::unlink_nodes(bucket_ptr bucket, node_ptr end)
{
size_ -= node_count(bucket->next_, end);
node_base::unlink_nodes(*bucket, end);
}
template <class A, class G>
std::size_t hash_structure<A, G>::unlink_group(node_ptr* pos)
{
std::size_t count = node_base::group_count(*pos);
size_ -= count;
node_base::unlink_group(pos);
return count;
}
template <class A, class G>
void hash_structure<A, G>::link_group(
node_ptr n, bucket_ptr bucket, std::size_t count)
{
node_base::add_group_to_bucket(n, *bucket);
size_ += count;
if(bucket < cached_begin_bucket_) cached_begin_bucket_ = bucket;
}
template <class A, class G>
BOOST_DEDUCED_TYPENAME hash_structure<A, G>::bucket_ptr
hash_structure<A, G>::get_bucket(std::size_t n) const
{
return buckets_ + static_cast<std::ptrdiff_t>(n);
}
template <class A, class G>
BOOST_DEDUCED_TYPENAME hash_structure<A, G>::node_ptr
hash_structure<A, G>::bucket_begin(std::size_t n) const
{
return (buckets_ + static_cast<std::ptrdiff_t>(n))->next_;
}
template <class A, class G>
BOOST_DEDUCED_TYPENAME hash_structure<A, G>::node_ptr
hash_structure<A, G>::bucket_end(std::size_t) const
{
return node_ptr();
}
// recompute_begin_bucket
//
// After an erase cached_begin_bucket_ might be left pointing to
// an empty bucket, so this is called to update it
//
// no throw
template <class A, class G>
void hash_structure<A, G>::recompute_begin_bucket(bucket_ptr b)
{
BOOST_ASSERT(!(b < cached_begin_bucket_));
if(b == cached_begin_bucket_)
{
if (size_ != 0) {
while (!cached_begin_bucket_->next_)
++cached_begin_bucket_;
} else {
cached_begin_bucket_ = buckets_end();
}
}
}
// This is called when a range has been erased
//
// no throw
template <class A, class G>
void hash_structure<A, G>::recompute_begin_bucket(bucket_ptr b1, bucket_ptr b2)
{
BOOST_ASSERT(!(b1 < cached_begin_bucket_) && !(b2 < b1));
BOOST_ASSERT(BOOST_UNORDERED_BORLAND_BOOL(b2->next_));
if(b1 == cached_begin_bucket_ && !b1->next_)
cached_begin_bucket_ = b2;
}
// no throw
template <class A, class G>
inline float hash_structure<A, G>::load_factor() const
{
BOOST_ASSERT(bucket_count_ != 0);
return static_cast<float>(size_)
/ static_cast<float>(bucket_count_);
}
////////////////////////////////////////////////////////////////////////////
// hash_iterator_base implementation
template <class BucketPtr>
inline void hash_iterator_base<BucketPtr>::increment(node_ptr node) {
while(!node) {
++bucket_;
node = bucket_->next_;
}
node_ = node;
}
template <class BucketPtr>
inline void hash_iterator_base<BucketPtr>::increment()
{
increment(next_node(node_));
}
}}
#endif