Files
boost_unordered/include/boost/unordered/detail/buckets.hpp
Daniel James 06b0b1d31c Merge some documentation changes and inspect fixes.
Merged revisions 55370,55729,56440,56570-56571,56603,56697-56699 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r55370 | danieljames | 2009-08-02 19:18:14 +0100 (Sun, 02 Aug 2009) | 1 line
  
  Pass through more elements in doxygen2boostbook. Refs #3309.
........
  r55729 | danieljames | 2009-08-23 11:07:25 +0100 (Sun, 23 Aug 2009) | 3 lines
  
  Add depencies on doxygen documentation to standalone documentation targets.
  
  This seems to be needed for building pdfs.
........
  r56440 | danieljames | 2009-09-27 20:11:39 +0100 (Sun, 27 Sep 2009) | 1 line
  
  Fix silly error in doxygen test file.
........
  r56570 | danieljames | 2009-10-04 11:37:36 +0100 (Sun, 04 Oct 2009) | 1 line
  
  Clean up some unordered TODOs.
........
  r56571 | danieljames | 2009-10-04 11:37:56 +0100 (Sun, 04 Oct 2009) | 1 line
  
  Detab.
........
  r56603 | danieljames | 2009-10-05 22:29:39 +0100 (Mon, 05 Oct 2009) | 1 line
  
  Various inspect fixes.
........
  r56697 | danieljames | 2009-10-10 14:00:28 +0100 (Sat, 10 Oct 2009) | 1 line
  
  Add forwarding html file for accumulators.
........
  r56698 | danieljames | 2009-10-10 14:01:14 +0100 (Sat, 10 Oct 2009) | 1 line
  
  Missing newline.
........
  r56699 | danieljames | 2009-10-10 14:01:30 +0100 (Sat, 10 Oct 2009) | 1 line
  
  Add copyright to boostbook reference xml.
........


[SVN r56702]
2009-10-10 14:53:46 +00:00

177 lines
5.3 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)
#ifndef BOOST_UNORDERED_DETAIL_MANAGER_HPP_INCLUDED
#define BOOST_UNORDERED_DETAIL_MANAGER_HPP_INCLUDED
#include <boost/config.hpp>
#include <boost/assert.hpp>
#include <boost/unordered/detail/node.hpp>
namespace boost { namespace unordered_detail {
////////////////////////////////////////////////////////////////////////////
// Buckets
template <class A, class G>
inline BOOST_DEDUCED_TYPENAME hash_buckets<A, G>::bucket_ptr
hash_buckets<A, G>::get_bucket(std::size_t num) const
{
return buckets_ + static_cast<std::ptrdiff_t>(num);
}
template <class A, class G>
inline BOOST_DEDUCED_TYPENAME hash_buckets<A, G>::bucket_ptr
hash_buckets<A, G>::bucket_ptr_from_hash(std::size_t hashed) const
{
return get_bucket(hashed % bucket_count_);
}
template <class A, class G>
std::size_t hash_buckets<A, G>::bucket_size(std::size_t index) const
{
if(!buckets_) return 0;
bucket_ptr ptr = get_bucket(index)->next_;
std::size_t count = 0;
while(ptr) {
++count;
ptr = ptr->next_;
}
return count;
}
template <class A, class G>
inline BOOST_DEDUCED_TYPENAME hash_buckets<A, G>::node_ptr
hash_buckets<A, G>::bucket_begin(std::size_t num) const
{
return buckets_ ? get_bucket(num)->next_ : node_ptr();
}
////////////////////////////////////////////////////////////////////////////
// Delete
template <class A, class G>
inline void hash_buckets<A, G>::delete_node(node_ptr b)
{
node* raw_ptr = static_cast<node*>(&*b);
boost::unordered_detail::destroy(&raw_ptr->value());
real_node_ptr n(node_alloc().address(*raw_ptr));
node_alloc().destroy(n);
node_alloc().deallocate(n, 1);
}
template <class A, class G>
inline void hash_buckets<A, G>::clear_bucket(bucket_ptr b)
{
node_ptr node_it = b->next_;
b->next_ = node_ptr();
while(node_it) {
node_ptr node_to_delete = node_it;
node_it = node_it->next_;
delete_node(node_to_delete);
}
}
template <class A, class G>
inline void hash_buckets<A, G>::delete_buckets()
{
bucket_ptr end = this->get_bucket(this->bucket_count_);
for(bucket_ptr begin = this->buckets_; begin != end; ++begin) {
clear_bucket(begin);
}
// Destroy the buckets (including the sentinel bucket).
++end;
for(bucket_ptr begin = this->buckets_; begin != end; ++begin) {
bucket_alloc().destroy(begin);
}
bucket_alloc().deallocate(this->buckets_, this->bucket_count_ + 1);
this->buckets_ = bucket_ptr();
}
template <class A, class G>
inline std::size_t hash_buckets<A, G>::delete_nodes(
node_ptr begin, node_ptr end)
{
std::size_t count = 0;
while(begin != end) {
node_ptr n = begin;
begin = begin->next_;
delete_node(n);
++count;
}
return count;
}
////////////////////////////////////////////////////////////////////////////
// Constructors and Destructors
template <class A, class G>
inline hash_buckets<A, G>::hash_buckets(
node_allocator const& a, std::size_t bucket_count)
: buckets_(),
bucket_count_(bucket_count),
allocators_(a,a)
{
}
template <class A, class G>
inline hash_buckets<A, G>::~hash_buckets()
{
if(this->buckets_) { this->delete_buckets(); }
}
template <class A, class G>
inline void hash_buckets<A, G>::create_buckets()
{
// The array constructor will clean up in the event of an
// exception.
allocator_array_constructor<bucket_allocator>
constructor(bucket_alloc());
// Creates an extra bucket to act as a sentinel.
constructor.construct(bucket(), this->bucket_count_ + 1);
// Set up the sentinel (node_ptr cast)
bucket_ptr sentinel = constructor.get() +
static_cast<ptrdiff_t>(this->bucket_count_);
sentinel->next_ = sentinel;
// Only release the buckets once everything is successfully
// done.
this->buckets_ = constructor.release();
}
////////////////////////////////////////////////////////////////////////////
// Constructors and Destructors
// no throw
template <class A, class G>
inline void hash_buckets<A, G>::move(hash_buckets& other)
{
BOOST_ASSERT(node_alloc() == other.node_alloc());
if(this->buckets_) { this->delete_buckets(); }
this->buckets_ = other.buckets_;
this->bucket_count_ = other.bucket_count_;
other.buckets_ = bucket_ptr();
other.bucket_count_ = 0;
}
template <class A, class G>
inline void hash_buckets<A, G>::swap(hash_buckets<A, G>& other)
{
BOOST_ASSERT(node_alloc() == other.node_alloc());
std::swap(buckets_, other.buckets_);
std::swap(bucket_count_, other.bucket_count_);
}
}}
#endif