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:
Daniel James
2016-08-14 20:55:40 +01:00
parent 93a33ba15f
commit e92f7d86c1
2 changed files with 43 additions and 93 deletions

View File

@ -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

View File

@ -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();
}