forked from boostorg/unordered
Remove array_constructor.
I was using SFINAE for everything because some old compilers had issues. But that's hopefully in the distant past now.
This commit is contained in:
@ -31,6 +31,7 @@
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/utility/addressof.hpp>
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
#include <boost/detail/select_type.hpp>
|
||||
#include <boost/swap.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
@ -1248,76 +1249,6 @@ namespace boost { namespace unordered { namespace detail { namespace func {
|
||||
}
|
||||
}}}}
|
||||
|
||||
namespace boost { namespace unordered { namespace detail {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// array_constructor
|
||||
//
|
||||
// Allocate and construct an array in an exception safe manner, and
|
||||
// clean up if an exception is thrown before the container takes charge
|
||||
// of it.
|
||||
|
||||
template <typename Allocator>
|
||||
struct array_constructor
|
||||
{
|
||||
typedef boost::unordered::detail::allocator_traits<Allocator> traits;
|
||||
typedef typename traits::pointer pointer;
|
||||
|
||||
Allocator& alloc_;
|
||||
pointer ptr_;
|
||||
pointer constructed_;
|
||||
std::size_t length_;
|
||||
|
||||
array_constructor(Allocator& a)
|
||||
: alloc_(a), ptr_(), constructed_(), length_(0)
|
||||
{
|
||||
constructed_ = pointer();
|
||||
ptr_ = pointer();
|
||||
}
|
||||
|
||||
~array_constructor() {
|
||||
if (ptr_) {
|
||||
for(pointer p = ptr_; p != constructed_; ++p) {
|
||||
boost::unordered::detail::func::destroy(
|
||||
boost::addressof(*p));
|
||||
}
|
||||
|
||||
traits::deallocate(alloc_, ptr_, length_);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
void construct(V const& v, std::size_t l)
|
||||
{
|
||||
BOOST_ASSERT(!ptr_);
|
||||
length_ = l;
|
||||
ptr_ = traits::allocate(alloc_, length_);
|
||||
pointer end = ptr_ + static_cast<std::ptrdiff_t>(length_);
|
||||
for(constructed_ = ptr_; constructed_ != end; ++constructed_) {
|
||||
new ((void*) boost::addressof(*constructed_)) V(v);
|
||||
}
|
||||
}
|
||||
|
||||
pointer get() const
|
||||
{
|
||||
return ptr_;
|
||||
}
|
||||
|
||||
pointer release()
|
||||
{
|
||||
pointer p(ptr_);
|
||||
ptr_ = pointer();
|
||||
return p;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
array_constructor(array_constructor const&);
|
||||
array_constructor& operator=(array_constructor const&);
|
||||
};
|
||||
}}}
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
@ -345,34 +345,53 @@ namespace boost { namespace unordered { namespace detail {
|
||||
|
||||
void create_buckets(std::size_t new_count)
|
||||
{
|
||||
boost::unordered::detail::array_constructor<bucket_allocator>
|
||||
constructor(bucket_alloc());
|
||||
|
||||
// Creates an extra bucket to act as the start node.
|
||||
constructor.construct(bucket(), new_count + 1);
|
||||
std::size_t length = new_count + 1;
|
||||
bucket_pointer new_buckets = bucket_allocator_traits::allocate(
|
||||
bucket_alloc(), length);
|
||||
bucket_pointer constructed = new_buckets;
|
||||
|
||||
if (buckets_)
|
||||
{
|
||||
// Copy the nodes to the new buckets, including the dummy
|
||||
// node if there is one.
|
||||
(constructor.get() +
|
||||
static_cast<std::ptrdiff_t>(new_count))->next_ =
|
||||
(buckets_ + static_cast<std::ptrdiff_t>(
|
||||
bucket_count_))->next_;
|
||||
destroy_buckets();
|
||||
}
|
||||
else if (bucket::extra_node)
|
||||
{
|
||||
node_constructor a(node_alloc());
|
||||
a.create_node();
|
||||
BOOST_TRY {
|
||||
bucket_pointer end = new_buckets
|
||||
+ static_cast<std::ptrdiff_t>(length);
|
||||
for(; constructed != end; ++constructed) {
|
||||
new ((void*) boost::addressof(*constructed)) bucket();
|
||||
}
|
||||
|
||||
(constructor.get() +
|
||||
static_cast<std::ptrdiff_t>(new_count))->next_ =
|
||||
a.release();
|
||||
if (buckets_)
|
||||
{
|
||||
// Copy the nodes to the new buckets, including the dummy
|
||||
// node if there is one.
|
||||
(new_buckets +
|
||||
static_cast<std::ptrdiff_t>(new_count))->next_ =
|
||||
(buckets_ + static_cast<std::ptrdiff_t>(
|
||||
bucket_count_))->next_;
|
||||
destroy_buckets();
|
||||
}
|
||||
else if (bucket::extra_node)
|
||||
{
|
||||
node_constructor a(node_alloc());
|
||||
a.create_node();
|
||||
|
||||
(new_buckets +
|
||||
static_cast<std::ptrdiff_t>(new_count))->next_ =
|
||||
a.release();
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(...) {
|
||||
for(bucket_pointer p = new_buckets; p != constructed; ++p) {
|
||||
boost::unordered::detail::func::destroy(
|
||||
boost::addressof(*p));
|
||||
}
|
||||
|
||||
bucket_allocator_traits::deallocate(bucket_alloc(),
|
||||
new_buckets, length);
|
||||
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
|
||||
bucket_count_ = new_count;
|
||||
buckets_ = constructor.release();
|
||||
buckets_ = new_buckets;
|
||||
recalculate_max_load();
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user