9#include "../microfmt.hpp"
12#include <memory_resource>
24using vector = std::pmr::vector<char>;
32template <
typename...
Args>
39 auto *
str =
static_cast<std::pmr::string *
>(ctx);
40 str->append(
sv.data(),
sv.size());
54template <
typename...
Args>
61 auto *
vec =
static_cast<std::pmr::vector<char> *
>(ctx);
88 : mr_(
other.mr_), current_chunk_(
other.current_chunk_), size_(
other.size_), current_cap_(
other.current_cap_) {
89 other.current_chunk_ =
nullptr;
91 other.current_cap_ = 0;
98 current_chunk_ =
other.current_chunk_;
100 current_cap_ =
other.current_cap_;
101 other.current_chunk_ =
nullptr;
103 other.current_cap_ = 0;
109 return sink{
this, [](
void *ctx, microfmt::string_view
sv)
noexcept {
static_cast<arena_sink *
>(ctx)->
write(
sv); }};
113 if (size_ >= current_cap_) {
116 RELOCO_ASSERT(size_ < current_cap_,
"Array access out of bounds");
118 current_chunk_->data[size_++] =
c;
122 void write(microfmt::string_view
sv)
noexcept {
129 return microfmt::string_view(current_chunk_->data, size_);
136 chunk *previous =
nullptr;
137 std::size_t capacity = 0;
142 [[nodiscard]]
static std::size_t allocation_size(std::size_t capacity)
noexcept {
143 return sizeof(chunk) -
sizeof(
char) + capacity;
146 void allocate_chunk(std::size_t capacity)
noexcept {
147 void *storage = mr_->allocate(allocation_size(capacity),
alignof(chunk));
148 current_chunk_ = ::new (storage) chunk{current_chunk_, capacity, {}};
149 current_cap_ = capacity;
153 void grow() noexcept {
154 const std::size_t new_capacity = current_cap_ * 2;
155 chunk *previous_chunk = current_chunk_;
156 const std::size_t previous_size = size_;
157 allocate_chunk(new_capacity);
158 RELOCO_BEGIN_UNSAFE_BUFFER_USAGE;
159 for (std::size_t i = 0; i < previous_size; ++i) {
160 current_chunk_->data[i] = previous_chunk->data[i];
162 RELOCO_END_UNSAFE_BUFFER_USAGE;
163 size_ = previous_size;
166 void release_chunks() noexcept {
167 while (current_chunk_ !=
nullptr) {
168 chunk *previous = current_chunk_->previous;
169 const std::size_t capacity = current_chunk_->capacity;
170 current_chunk_->~chunk();
171 mr_->deallocate(current_chunk_, allocation_size(capacity),
alignof(chunk));
172 current_chunk_ = previous;
176 value_ptr<std::pmr::memory_resource> mr_;
177 chunk *current_chunk_{
nullptr};
178 std::size_t size_{0};
179 std::size_t current_cap_{0};
Definition pmr_sink.hpp:74
arena_sink & operator=(const arena_sink &)=delete
arena_sink(std::pmr::memory_resource *mr RELOCO_LIFETIMEBOUND, std::size_t initial_chunk_size=128) noexcept
Definition pmr_sink.hpp:76
arena_sink(arena_sink &&other) noexcept
Definition pmr_sink.hpp:87
void put(char c) noexcept
Definition pmr_sink.hpp:112
arena_sink & operator=(arena_sink &&other) noexcept
Definition pmr_sink.hpp:94
void write(microfmt::string_view sv) noexcept
Definition pmr_sink.hpp:122
microfmt::string_view view() const noexcept RELOCO_LIFETIMEBOUND
Definition pmr_sink.hpp:128
arena_sink(const arena_sink &)=delete
~arena_sink() noexcept
Definition pmr_sink.hpp:83
sink as_sink() noexcept RELOCO_LIFETIMEBOUND
Definition pmr_sink.hpp:108
#define MICROFMT_API_CLASS
Definition compat.hpp:181
Definition pmr_sink.hpp:17
std::pmr::vector< char > vector
Definition pmr_sink.hpp:24
std::pmr::string string
Definition pmr_sink.hpp:23
RELOCO_BEGIN_UNSAFE_CODE std::pmr::string format(std::pmr::memory_resource *mr, microfmt::string_view fmt_str, const Args &...args)
Definition pmr_sink.hpp:35
RELOCO_END_UNSAFE_CODE RELOCO_BEGIN_UNSAFE_CODE std::pmr::vector< char > format_vector(std::pmr::memory_resource *mr, microfmt::string_view fmt_str, const Args &...args)
Definition pmr_sink.hpp:57
reloco::sink sink
Type-erased, zero-allocation output sink.
Definition microfmt.hpp:46
RELOCO_CONSTEXPR20 void format_to(const sink &out, microfmt::string_view fmt, const Args &...args) noexcept
Definition microfmt.hpp:1766
constexpr auto vec(const T(&arr)[N]) noexcept
Definition math.hpp:28
RELOCO_END_UNSAFE_CODE
Definition remote_object.hpp:132