Edit: /usr/include/boost/align/aligned_allocator_adaptor.hpp (5107B)
/*
Copyright 2014-2016 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_ALIGN_ALIGNED_ALLOCATOR_ADAPTOR_HPP
#define BOOST_ALIGN_ALIGNED_ALLOCATOR_ADAPTOR_HPP
#include
#include
#include
#include
#include
#include
#include
#include
#include
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
#include
#endif
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
#include
#endif
namespace boost {
namespace alignment {
template
class aligned_allocator_adaptor
: public Allocator {
BOOST_STATIC_ASSERT(detail::is_alignment_constant::value);
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
typedef std::allocator_traits traits;
typedef typename traits::template rebind_alloc char_alloc;
typedef typename traits::template rebind_traits char_traits;
typedef typename char_traits::pointer char_ptr;
#else
typedef typename Allocator::template rebind::other char_alloc;
typedef typename char_alloc::pointer char_ptr;
#endif
public:
typedef typename Allocator::value_type value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef void* void_pointer;
typedef const void* const_void_pointer;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
private:
template
struct min_align {
enum {
value = detail::max_size::value>::value
};
};
public:
template
struct rebind {
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
typedef aligned_allocator_adaptor, Alignment> other;
#else
typedef aligned_allocator_adaptor::other, Alignment> other;
#endif
};
aligned_allocator_adaptor()
: Allocator() { }
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template
explicit aligned_allocator_adaptor(A&& alloc) BOOST_NOEXCEPT
: Allocator(std::forward(alloc)) { }
#else
template
explicit aligned_allocator_adaptor(const A& alloc) BOOST_NOEXCEPT
: Allocator(alloc) { }
#endif
template
aligned_allocator_adaptor(const aligned_allocator_adaptor& other) BOOST_NOEXCEPT
: Allocator(other.base()) { }
Allocator& base() BOOST_NOEXCEPT {
return static_cast(*this);
}
const Allocator& base() const BOOST_NOEXCEPT {
return static_cast(*this);
}
pointer allocate(size_type size) {
enum {
m = min_align::value
};
std::size_t s = size * sizeof(value_type);
std::size_t n = s + m - 1;
char_alloc a(base());
char_ptr p = a.allocate(sizeof p + n);
void* r = boost::to_address(p) + sizeof p;
(void)boost::alignment::align(m, s, r, n);
::new(static_cast(static_cast(r) - 1)) char_ptr(p);
return static_cast(r);
}
pointer allocate(size_type size, const_void_pointer hint) {
enum {
m = min_align::value
};
std::size_t s = size * sizeof(value_type);
std::size_t n = s + m - 1;
char_ptr h = char_ptr();
if (hint) {
h = *(static_cast(hint) - 1);
}
char_alloc a(base());
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
char_ptr p = char_traits::allocate(a, sizeof p + n, h);
#else
char_ptr p = a.allocate(sizeof p + n, h);
#endif
void* r = boost::to_address(p) + sizeof p;
(void)boost::alignment::align(m, s, r, n);
::new(static_cast(static_cast(r) - 1)) char_ptr(p);
return static_cast(r);
}
void deallocate(pointer ptr, size_type size) {
enum {
m = min_align::value
};
char_ptr* p = reinterpret_cast(ptr) - 1;
char_ptr r = *p;
p->~char_ptr();
char_alloc a(base());
a.deallocate(r, sizeof r + size * sizeof(value_type) + m - 1);
}
};
template
inline bool
operator==(const aligned_allocator_adaptor& a,
const aligned_allocator_adaptor& b) BOOST_NOEXCEPT
{
return a.base() == b.base();
}
template
inline bool
operator!=(const aligned_allocator_adaptor& a,
const aligned_allocator_adaptor& b) BOOST_NOEXCEPT
{
return !(a == b);
}
} /* alignment */
} /* boost */
#endif