16RELOCO_BEGIN_UNSAFE_BUFFER_USAGE
34 span<std::byte> buffer RELOCO_LIFETIMEBOUND RELOCO_LIFETIME_CAPTURE_BY_THIS) noexcept
43 RELOCO_BEGIN_UNSAFE_CODE
44 explicit scratch_allocator(span<char> buffer RELOCO_LIFETIMEBOUND RELOCO_LIFETIME_CAPTURE_BY_THIS) noexcept
45 : m_buf(
reinterpret_cast<std::byte *
>(buffer.data()), buffer.size()) {}
56 RELOCO_BEGIN_UNSAFE_CODE
59 if (count == 0 || count > available() /
sizeof(T)) {
63 const size_t size = count *
sizeof(T);
64 std::byte *current_ptr = m_buf.data() + m_pos;
65 const uintptr_t addr =
reinterpret_cast<uintptr_t
>(current_ptr);
66 const size_t alignment_offset =
static_cast<size_t>((
alignof(T) - (addr %
alignof(T))) %
alignof(T));
68 if (alignment_offset > available() || size > available() - alignment_offset) {
72 m_pos += alignment_offset + size;
73 return static_cast<T *
>(
static_cast<void *
>(current_ptr + alignment_offset));
88 template <
typename T,
typename... Args>
90 static_assert(std::is_trivially_destructible_v<T>,
"scratch_allocator only permits trivially destructible types");
92 T *storage = allocate<T>();
93 if (storage ==
nullptr) {
96 return ::new (
static_cast<void *
>(storage)) T(std::forward<Args>(args)...);
113 [[nodiscard]]
constexpr span<std::byte>
remaining_span() const noexcept RELOCO_LIFETIMEBOUND {
114 if (m_pos >= m_buf.size()) {
117 return {m_buf.data() + m_pos, m_buf.size() - m_pos};
123 constexpr void reset() noexcept { m_pos = 0; }
125 [[nodiscard]]
constexpr size_t size() const noexcept {
return m_pos; }
126 [[nodiscard]]
constexpr size_t capacity() const noexcept {
return m_buf.size(); }
127 [[nodiscard]]
constexpr size_t available() const noexcept {
128 return (m_pos < m_buf.size()) ? (m_buf.size() - m_pos) : 0;
132 span<std::byte> m_buf;
138RELOCO_END_UNSAFE_BUFFER_USAGE
Zero-allocation bump allocator for scratch buffers.
Definition scratch_allocator.hpp:27
constexpr scratch_allocator(span< std::byte > buffer RELOCO_LIFETIMEBOUND RELOCO_LIFETIME_CAPTURE_BY_THIS) noexcept
Constructs a scratch allocator over a provided byte span.
Definition scratch_allocator.hpp:33
RELOCO_END_UNSAFE_CODE RELOCO_BEGIN_UNSAFE_CODE RELOCO_ASSUME_ALIGNED(alignof(T)) T *allocate(size_t count
Reserves aligned storage for objects without constructing them.
constexpr size_t size() const noexcept
Definition scratch_allocator.hpp:125
constexpr void reset() noexcept
Resets the allocator back to the beginning of the buffer.
Definition scratch_allocator.hpp:123
constexpr span< std::byte > remaining_span() const noexcept RELOCO_LIFETIMEBOUND
Returns a span over the remaining unallocated space.
Definition scratch_allocator.hpp:113
RELOCO_END_UNSAFE_CODE RELOCO_BEGIN_UNSAFE_CODE typename Args RELOCO_ASSUME_ALIGNED(alignof(T)) T *create(Args &&...args) noexcept RELOCO_LIFETIMEBOUND
Definition scratch_allocator.hpp:89
constexpr scratch_allocator rest() const noexcept RELOCO_LIFETIMEBOUND
Creates and returns a new scratch_allocator owning the remaining unallocated space.
Definition scratch_allocator.hpp:106
constexpr size_t available() const noexcept
Definition scratch_allocator.hpp:127
constexpr size_t capacity() const noexcept
Definition scratch_allocator.hpp:126
RELOCO_BEGIN_UNSAFE_CODE scratch_allocator(span< char > buffer RELOCO_LIFETIMEBOUND RELOCO_LIFETIME_CAPTURE_BY_THIS) noexcept
Constructs a scratch allocator over a provided character span.
Definition scratch_allocator.hpp:44
Compiler, language-version, and optional-library feature detection.
#define MICROFMT_API_CLASS
Definition compat.hpp:181
RELOCO_END_UNSAFE_CODE
Definition remote_object.hpp:132
Single re-export of every `reloco` type and annotation microfmt builds on.