33 #if __GNUC__ == 4 && __GNUC_MINOR__ <= 8
34 using max_align_t = ::max_align_t;
36 using max_align_t = std::max_align_t;
39 template <std::
size_t N, std::
size_t alignment = alignof(max_align_t)>
42 alignas(alignment)
char buf_[N];
46 ~arena() {ptr_ =
nullptr;}
47 arena() noexcept : ptr_(buf_) {}
48 arena(
const arena&) =
delete;
49 arena& operator=(
const arena&) =
delete;
51 template <std::
size_t ReqAlign>
char* allocate(std::size_t n);
52 void deallocate(
char* p, std::size_t n) noexcept;
54 static constexpr std::size_t size() noexcept {
return N;}
55 std::size_t used() const noexcept {
return static_cast<std::size_t
>(ptr_ - buf_);}
56 void reset() noexcept {ptr_ = buf_;}
61 align_up(std::size_t n) noexcept
62 {
return (n + (alignment-1)) & ~(alignment-1);}
65 pointer_in_buffer(
char* p) noexcept
66 {
return buf_ <= p && p <= buf_ + N;}
69 template <std::
size_t N, std::
size_t alignment>
70 template <std::
size_t ReqAlign>
72 arena<N, alignment>::allocate(std::size_t n)
74 static_assert(ReqAlign <= alignment,
"alignment is too small for this arena");
75 assert(pointer_in_buffer(ptr_) &&
"short_alloc has outlived arena");
76 auto const aligned_n = align_up(n);
77 if (
static_cast<decltype(aligned_n)
>(buf_ + N - ptr_) >= aligned_n)
84 static_assert(alignment <=
alignof(max_align_t),
"you've chosen an "
85 "alignment that is larger than alignof(max_align_t), and "
86 "cannot be guaranteed by normal operator new");
87 return static_cast<char*
>(::operator
new(n));
90 template <std::
size_t N, std::
size_t alignment>
92 arena<N, alignment>::deallocate(
char* p, std::size_t n) noexcept
94 assert(pointer_in_buffer(ptr_) &&
"short_alloc has outlived arena");
95 if (pointer_in_buffer(p))
102 ::operator
delete(p);
105 template <
class T, std::
size_t N, std::
size_t Align = alignof(max_align_t)>
109 using value_type = T;
110 static auto constexpr alignment = Align;
111 static auto constexpr size = N;
112 using arena_type = arena<size, alignment>;
118 short_alloc(
const short_alloc&) =
default;
119 short_alloc& operator=(
const short_alloc&) =
delete;
121 short_alloc(arena_type& a) noexcept : a_(a)
123 static_assert(size % alignment == 0,
124 "size N needs to be a multiple of alignment Align");
127 short_alloc(
const short_alloc<U, N, alignment>& a) noexcept
130 template <
class _Up>
struct rebind {
using other = short_alloc<_Up, N, alignment>;};
132 T* allocate(std::size_t n)
134 return reinterpret_cast<T*
>(a_.template allocate<alignof(T)>(n*
sizeof(T)));
136 void deallocate(T* p, std::size_t n) noexcept
138 a_.deallocate(
reinterpret_cast<char*
>(p), n*
sizeof(T));
141 template <
class T1, std::size_t N1, std::size_t A1,
142 class U, std::size_t M, std::size_t A2>
145 operator==(
const short_alloc<T1, N1, A1>& x,
const short_alloc<U, M, A2>& y) noexcept;
147 template <
class U, std::
size_t M, std::
size_t A>
friend class short_alloc;
150 template <
class T, std::
size_t N, std::
size_t A1,
class U, std::
size_t M, std::
size_t A2>
153 operator==(
const short_alloc<T, N, A1>& x,
const short_alloc<U, M, A2>& y) noexcept
155 return N == M && A1 == A2 && &x.a_ == &y.a_;
158 template <
class T, std::
size_t N, std::
size_t A1,
class U, std::
size_t M, std::
size_t A2>
161 operator!=(
const short_alloc<T, N, A1>& x,
const short_alloc<U, M, A2>& y) noexcept
168 #endif // SHORT_ALLOC_H