boost/unordered/detail/allocator_helpers.hpp
// Copyright 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) // A couple of templates to make using allocators easier. #ifndef BOOST_UNORDERED_DETAIL_ALLOCATOR_UTILITIES_HPP_INCLUDED #define BOOST_UNORDERED_DETAIL_ALLOCATOR_UTILITIES_HPP_INCLUDED #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif #include <boost/config.hpp> #if (defined(BOOST_NO_STD_ALLOCATOR) || defined(BOOST_DINKUMWARE_STDLIB)) \ && !defined(__BORLANDC__) # define BOOST_UNORDERED_USE_ALLOCATOR_UTILITIES #endif #if defined(BOOST_UNORDERED_USE_ALLOCATOR_UTILITIES) # include <boost/detail/allocator_utilities.hpp> #endif namespace boost { namespace unordered_detail { // rebind_wrap // // Rebind allocators. For some problematic libraries, use rebind_to // from <boost/detail/allocator_utilities.hpp>. #if defined(BOOST_UNORDERED_USE_ALLOCATOR_UTILITIES) template <class Alloc, class T> struct rebind_wrap : ::boost::detail::allocator::rebind_to<Alloc, T> {}; #else template <class Alloc, class T> struct rebind_wrap { typedef BOOST_DEDUCED_TYPENAME Alloc::BOOST_NESTED_TEMPLATE rebind<T>::other type; }; #endif // allocator_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 <class Allocator> struct allocator_array_constructor { typedef BOOST_DEDUCED_TYPENAME Allocator::pointer pointer; Allocator& alloc_; pointer ptr_; pointer constructed_; std::size_t length_; allocator_array_constructor(Allocator& a) : alloc_(a), ptr_(), constructed_(), length_(0) { constructed_ = pointer(); ptr_ = pointer(); } ~allocator_array_constructor() { if (ptr_) { for(pointer p = ptr_; p != constructed_; ++p) alloc_.destroy(p); alloc_.deallocate(ptr_, length_); } } template <class V> void construct(V const& v, std::size_t l) { BOOST_ASSERT(!ptr_); length_ = l; ptr_ = alloc_.allocate(length_); pointer end = ptr_ + static_cast<std::ptrdiff_t>(length_); for(constructed_ = ptr_; constructed_ != end; ++constructed_) alloc_.construct(constructed_, v); } pointer get() const { return ptr_; } pointer release() { pointer p(ptr_); ptr_ = pointer(); return p; } private: allocator_array_constructor(allocator_array_constructor const&); allocator_array_constructor& operator=( allocator_array_constructor const&); }; }} #if defined(BOOST_UNORDERED_USE_ALLOCATOR_UTILITIES) # undef BOOST_UNORDERED_USE_ALLOCATOR_UTILITIES #endif #endif