170 lines
3.4 KiB
C++
170 lines
3.4 KiB
C++
|
/*
|
||
|
Copyright 2019 Glen Joseph Fernandes
|
||
|
(glenjofe@gmail.com)
|
||
|
|
||
|
Distributed under the Boost Software License, Version 1.0.
|
||
|
(http://www.boost.org/LICENSE_1_0.txt)
|
||
|
*/
|
||
|
#ifndef BOOST_CORE_ALLOC_CONSTRUCT_HPP
|
||
|
#define BOOST_CORE_ALLOC_CONSTRUCT_HPP
|
||
|
|
||
|
#include <boost/core/noinit_adaptor.hpp>
|
||
|
|
||
|
namespace boost {
|
||
|
|
||
|
template<class A, class T>
|
||
|
inline void
|
||
|
alloc_destroy(A& a, T* p)
|
||
|
{
|
||
|
boost::allocator_destroy(a, p);
|
||
|
}
|
||
|
|
||
|
template<class A, class T>
|
||
|
inline void
|
||
|
alloc_destroy_n(A& a, T* p, std::size_t n)
|
||
|
{
|
||
|
while (n > 0) {
|
||
|
boost::allocator_destroy(a, p + --n);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
template<class A, class T>
|
||
|
inline void
|
||
|
alloc_destroy(noinit_adaptor<A>&, T* p)
|
||
|
{
|
||
|
p->~T();
|
||
|
}
|
||
|
|
||
|
template<class A, class T>
|
||
|
inline void
|
||
|
alloc_destroy_n(noinit_adaptor<A>&, T* p, std::size_t n)
|
||
|
{
|
||
|
while (n > 0) {
|
||
|
p[--n].~T();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
namespace detail {
|
||
|
|
||
|
template<class A, class T>
|
||
|
class alloc_destroyer {
|
||
|
public:
|
||
|
alloc_destroyer(A& a, T* p) BOOST_NOEXCEPT
|
||
|
: a_(a),
|
||
|
p_(p),
|
||
|
n_(0) { }
|
||
|
|
||
|
~alloc_destroyer() {
|
||
|
boost::alloc_destroy_n(a_, p_, n_);
|
||
|
}
|
||
|
|
||
|
std::size_t& size() BOOST_NOEXCEPT {
|
||
|
return n_;
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
alloc_destroyer(const alloc_destroyer&);
|
||
|
alloc_destroyer& operator=(const alloc_destroyer&);
|
||
|
|
||
|
A& a_;
|
||
|
T* p_;
|
||
|
std::size_t n_;
|
||
|
};
|
||
|
|
||
|
} /* detail */
|
||
|
|
||
|
template<class A, class T>
|
||
|
inline void
|
||
|
alloc_construct(A& a, T* p)
|
||
|
{
|
||
|
boost::allocator_construct(a, p);
|
||
|
}
|
||
|
|
||
|
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||
|
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||
|
template<class A, class T, class U, class... V>
|
||
|
inline void
|
||
|
alloc_construct(A& a, T* p, U&& u, V&&... v)
|
||
|
{
|
||
|
boost::allocator_construct(a, p, std::forward<U>(u),
|
||
|
std::forward<V>(v)...);
|
||
|
}
|
||
|
#else
|
||
|
template<class A, class T, class U>
|
||
|
inline void
|
||
|
alloc_construct(A& a, T* p, U&& u)
|
||
|
{
|
||
|
boost::allocator_construct(a, p, std::forward<U>(u));
|
||
|
}
|
||
|
#endif
|
||
|
#else
|
||
|
template<class A, class T, class U>
|
||
|
inline void
|
||
|
alloc_construct(A& a, T* p, const U& u)
|
||
|
{
|
||
|
boost::allocator_construct(a, p, u);
|
||
|
}
|
||
|
|
||
|
template<class A, class T, class U>
|
||
|
inline void
|
||
|
alloc_construct(A& a, T* p, U& u)
|
||
|
{
|
||
|
boost::allocator_construct(a, p, u);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
template<class A, class T>
|
||
|
inline void
|
||
|
alloc_construct_n(A& a, T* p, std::size_t n)
|
||
|
{
|
||
|
detail::alloc_destroyer<A, T> hold(a, p);
|
||
|
for (std::size_t& i = hold.size(); i < n; ++i) {
|
||
|
boost::allocator_construct(a, p + i);
|
||
|
}
|
||
|
hold.size() = 0;
|
||
|
}
|
||
|
|
||
|
template<class A, class T>
|
||
|
inline void
|
||
|
alloc_construct_n(A& a, T* p, std::size_t n, const T* l, std::size_t m)
|
||
|
{
|
||
|
detail::alloc_destroyer<A, T> hold(a, p);
|
||
|
for (std::size_t& i = hold.size(); i < n; ++i) {
|
||
|
boost::allocator_construct(a, p + i, l[i % m]);
|
||
|
}
|
||
|
hold.size() = 0;
|
||
|
}
|
||
|
|
||
|
template<class A, class T, class I>
|
||
|
inline void
|
||
|
alloc_construct_n(A& a, T* p, std::size_t n, I b)
|
||
|
{
|
||
|
detail::alloc_destroyer<A, T> hold(a, p);
|
||
|
for (std::size_t& i = hold.size(); i < n; void(++i), void(++b)) {
|
||
|
boost::allocator_construct(a, p + i, *b);
|
||
|
}
|
||
|
hold.size() = 0;
|
||
|
}
|
||
|
|
||
|
template<class A, class T>
|
||
|
inline void
|
||
|
alloc_construct(noinit_adaptor<A>&, T* p)
|
||
|
{
|
||
|
::new(static_cast<void*>(p)) T;
|
||
|
}
|
||
|
|
||
|
template<class A, class T>
|
||
|
inline void
|
||
|
alloc_construct_n(noinit_adaptor<A>& a, T* p, std::size_t n)
|
||
|
{
|
||
|
detail::alloc_destroyer<noinit_adaptor<A>, T> hold(a, p);
|
||
|
for (std::size_t& i = hold.size(); i < n; ++i) {
|
||
|
::new(static_cast<void*>(p + i)) T;
|
||
|
}
|
||
|
hold.size() = 0;
|
||
|
}
|
||
|
|
||
|
} /* boost */
|
||
|
|
||
|
#endif
|