83 RELOCO_BEGIN_UNSAFE_CODE
84 explicit map_writer(
sink out)
noexcept RELOCO_RETURN_TYPESTATE(unconsumed) : out_(std::move(out)) {
86 out_.put(
static_cast<char>(detail::MT_MAP | 31));
90 ~map_writer()
noexcept { end(); }
92 map_writer(
const map_writer &) =
delete;
93 map_writer &operator=(
const map_writer &) =
delete;
94 map_writer(map_writer &&other)
noexcept RELOCO_RETURN_TYPESTATE(unconsumed)
95 : out_(std::move(other.out_)), closed_(other.closed_) {
100 map_writer &as_known() &
noexcept RELOCO_CALLABLE_WHEN(
"unconsumed",
"unknown") RELOCO_RETURN_TYPESTATE(unconsumed) {
101 RELOCO_ASSERT(!closed_,
"Attempt to reuse consumed state");
107 map_writer &key(microfmt::string_view k) &
noexcept RELOCO_CALLABLE_WHEN(
"unconsumed") {
108 detail::encode_header(out_, detail::MT_TEXT, k.size());
113 map_writer &key(uint32_t int_key) &
noexcept RELOCO_CALLABLE_WHEN(
"unconsumed") {
114 detail::encode_header(out_, detail::MT_UNSIGNED, int_key);
119 map_writer &kv(microfmt::string_view k, microfmt::string_view val) &
noexcept RELOCO_CALLABLE_WHEN(
"unconsumed") {
121 detail::encode_header(out_, detail::MT_TEXT, val.size());
127 RELOCO_BEGIN_UNSAFE_CODE
128 map_writer &kv(microfmt::string_view k,
const char *val) &
noexcept RELOCO_CALLABLE_WHEN(
"unconsumed") {
130 if (val ==
nullptr) {
131 out_.put(
static_cast<char>(detail::MT_SIMPLE | 22));
133 detail::encode_header(out_, detail::MT_TEXT, microfmt::string_view(val).size());
140 template <std::
size_t N>
141 map_writer &kv(microfmt::string_view k,
const char (&val)[N]) &
noexcept RELOCO_CALLABLE_WHEN(
"unconsumed") {
142 return kv(k, microfmt::string_view(val, N - 1));
145 map_writer &kv(microfmt::string_view k, span<const uint8_t>
bytes) &
noexcept RELOCO_CALLABLE_WHEN(
"unconsumed") {
147 detail::encode_header(out_, detail::MT_BYTES,
bytes.size());
148 for (uint8_t b :
bytes)
149 out_.put(
static_cast<char>(b));
154 RELOCO_BEGIN_UNSAFE_CODE
155 map_writer &kv(microfmt::string_view k,
bool val) &
noexcept RELOCO_CALLABLE_WHEN(
"unconsumed") {
157 out_.put(
static_cast<char>(detail::MT_SIMPLE | (val ? 21 : 20)));
163 RELOCO_BEGIN_UNSAFE_CODE
164 map_writer &kv(microfmt::string_view k, std::nullptr_t) &
noexcept RELOCO_CALLABLE_WHEN(
"unconsumed") {
166 out_.put(
static_cast<char>(detail::MT_SIMPLE | 22));
171 template <
typename T,
172 typename std::enable_if<std::is_integral<T>::value && !std::is_same<T, bool>::value,
int>::type = 0>
173 map_writer &kv(microfmt::string_view k, T val) &
noexcept RELOCO_CALLABLE_WHEN(
"unconsumed") {
175 if constexpr (std::is_signed_v<T>) {
177 detail::encode_header(out_, detail::MT_NEGATIVE,
static_cast<uint64_t
>(-1 - val));
179 detail::encode_header(out_, detail::MT_UNSIGNED,
static_cast<uint64_t
>(val));
182 detail::encode_header(out_, detail::MT_UNSIGNED,
static_cast<uint64_t
>(val));
188 template <
typename T,
189 typename std::enable_if<std::is_integral<T>::value && !std::is_same<T, bool>::value,
int>::type = 0>
190 map_writer &kv(uint32_t k, T val) &
noexcept RELOCO_CALLABLE_WHEN(
"unconsumed") {
192 if constexpr (std::is_signed_v<T>) {
194 detail::encode_header(out_, detail::MT_NEGATIVE,
static_cast<uint64_t
>(-1 - val));
196 detail::encode_header(out_, detail::MT_UNSIGNED,
static_cast<uint64_t
>(val));
199 detail::encode_header(out_, detail::MT_UNSIGNED,
static_cast<uint64_t
>(val));
204 [[nodiscard]] map_writer nested_map(microfmt::string_view k)
noexcept RELOCO_CALLABLE_WHEN(
"unconsumed")
205 RELOCO_RETURN_TYPESTATE(unconsumed) {
207 return map_writer(out_);
210 [[nodiscard]] array_writer nested_array(microfmt::string_view k)
noexcept RELOCO_CALLABLE_WHEN(
"unconsumed")
211 RELOCO_RETURN_TYPESTATE(unconsumed);
213 void end()
noexcept RELOCO_CALLABLE_WHEN(
"unconsumed",
"consumed") RELOCO_SET_TYPESTATE(consumed) {
215 out_.put(
static_cast<char>(detail::BREAK_BYTE));