9#include "../microfmt.hpp"
22 static_assert(Capacity > 0,
"Capacity must be greater than 0");
23 static_assert((Capacity & (Capacity - 1)) == 0,
"Capacity must be a power of 2 for fast bitmask wrapping");
36 [[nodiscard]]
sink as_sink() & noexcept RELOCO_LIFETIMEBOUND {
38 [](
void *ctx, microfmt::string_view sv)
noexcept {
static_cast<ring_buffer_sink *
>(ctx)->
write(sv); }};
45 void put(
char c)
noexcept {
46 const size_t pos = head_.fetch_add(1, std::memory_order_relaxed);
47 buffer_[pos & Mask] = c;
48 count_.fetch_add(1, std::memory_order_relaxed);
51 void write(microfmt::string_view sv)
noexcept {
61 [[nodiscard]]
size_t size() const noexcept {
62 const size_t c = count_.load(std::memory_order_relaxed);
63 return c > Capacity ? Capacity : c;
66 [[nodiscard]]
constexpr size_t capacity() const noexcept {
return Capacity; }
67 [[nodiscard]]
bool empty() const noexcept {
return size() == 0; }
68 [[nodiscard]]
bool full() const noexcept {
return count_.load(std::memory_order_relaxed) >= Capacity; }
71 head_.store(0, std::memory_order_relaxed);
72 count_.store(0, std::memory_order_relaxed);
86 const size_t total_written = count_.load(std::memory_order_relaxed);
87 if (total_written == 0) {
91 if (total_written <= Capacity) {
93 return {microfmt::string_view(buffer_.data(), total_written), {}};
97 const size_t tail = head_.load(std::memory_order_relaxed) & Mask;
98 const size_t first_len = Capacity - tail;
99 const size_t second_len = tail;
101 RELOCO_BEGIN_UNSAFE_BUFFER_USAGE;
103 return {microfmt::string_view(buffer_.data() + tail, first_len), microfmt::string_view(buffer_.data(), second_len)};
105 RELOCO_END_UNSAFE_BUFFER_USAGE;
110 const auto slices =
view();
111 if (!slices.first.empty()) {
112 target.write(slices.first);
114 if (!slices.second.empty()) {
115 target.write(slices.second);
120 static constexpr size_t Mask = Capacity - 1;
122 alignas(
void *) microfmt::array<char, Capacity> buffer_{};
123 std::atomic<size_t> head_{0};
124 std::atomic<size_t> count_{0};
Definition ring_buffer_sink.hpp:21
void dump_to(const sink &target) const noexcept
Definition ring_buffer_sink.hpp:109
bool full() const noexcept
Definition ring_buffer_sink.hpp:68
void write(microfmt::string_view sv) noexcept
Definition ring_buffer_sink.hpp:51
size_t size() const noexcept
Definition ring_buffer_sink.hpp:61
void put(char c) noexcept
Definition ring_buffer_sink.hpp:45
bool empty() const noexcept
Definition ring_buffer_sink.hpp:67
constexpr size_t capacity() const noexcept
Definition ring_buffer_sink.hpp:66
dump_slices view() const noexcept RELOCO_LIFETIMEBOUND
Definition ring_buffer_sink.hpp:85
sink as_sink() &noexcept RELOCO_LIFETIMEBOUND
Definition ring_buffer_sink.hpp:36
constexpr ring_buffer_sink() noexcept=default
void reset() noexcept
Definition ring_buffer_sink.hpp:70
reloco::sink sink
Type-erased, zero-allocation output sink.
Definition microfmt.hpp:46
Definition ring_buffer_sink.hpp:79
microfmt::string_view first
Definition ring_buffer_sink.hpp:80
microfmt::string_view second
Definition ring_buffer_sink.hpp:81