WIP: Migrate packing to pass context object.

This commit is contained in:
Kurt Sassenrath 2023-12-28 15:51:13 -08:00
parent a027d6b946
commit cb2b5b47b0

View File

@ -66,17 +66,37 @@ public:
, curr_(std::begin(buff_))
, end_(std::end(buff_)) {}
struct context {
decltype(std::begin(BufferType{})) out;
decltype(std::begin(BufferType{})) end;
constexpr auto remaining() noexcept {
return std::ranges::distance(out, end);
}
template <packable_type T>
constexpr tl::expected<tl::monostate, error> pack(T&& v) noexcept {
using diff_type =
std::iterator_traits<decltype(curr_)>::difference_type;
auto rem = remaining();
decltype(rem) needed = builtin_packer<T>::total_size(v);
if (needed > rem) {
return tl::make_unexpected(error::out_of_space);
} else {
builtin_packer<T>::pack(v, *this);
return tl::monostate{};
}
}
};
template <packable_type T>
constexpr tl::expected<tl::monostate, error> pack(T&& v) noexcept {
using diff_type =
std::iterator_traits<decltype(curr_)>::difference_type;
diff_type const space_needed = builtin_packer<T>::total_size(v);
if (space_needed > std::distance(curr_, end_)) {
return tl::make_unexpected(error::out_of_space);
} else {
curr_ = builtin_packer<T>::pack(v, curr_);
return tl::monostate{};
}
context ctx{curr_, end_};
// If packing is successful, it updates iterators.
return ctx.pack(std::forward<T>(v)).map([&]{
curr_ = ctx.out;
end_ = ctx.end;
});
}
constexpr auto tell() const noexcept {