33 using char_type = CharT;
34 using traits_type = Traits;
35 using int_type =
typename Traits::int_type;
36 using pos_type =
typename Traits::pos_type;
37 using off_type =
typename Traits::off_type;
41 explicit basic_spanbuf(std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) noexcept
45 std::span<CharT> buffer, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) noexcept
46 : mode_{mode}, buffer_{buffer} {
58 std::basic_streambuf<CharT, Traits>* setbuf(CharT* buffer, std::streamsize size)
override {
59 this->span(std::span{buffer,
static_cast<std::size_t
>(size)});
64 [[nodiscard]] std::span<CharT> span()
const noexcept {
68 void span(std::span<CharT> buffer)
noexcept {
71 if ((mode_ & std::ios_base::in) == std::ios_base::in) {
72 this->setg(buffer_.data(), buffer_.data(), buffer_.data() + buffer_.size());
75 if ((mode_ & std::ios_base::out) == std::ios_base::out) {
76 this->setp(buffer_.data(), buffer_.data() + buffer_.size());
78 (mode_ & std::ios_base::ate) == std::ios_base::ate ?
static_cast<std::int32_t
>(buffer_.size()) : 0);
83 pos_type seekoff(off_type offset, std::ios_base::seekdir direction, std::ios_base::openmode mode)
override {
85 case std::ios_base::beg:
86 return seekpos(pos_type{offset}, mode);
87 case std::ios_base::cur:
90 if ((mode & (std::ios_base::in | std::ios_base::out)) == (std::ios_base::in | std::ios_base::out)) {
94 if ((mode & std::ios_base::in) == std::ios_base::in) {
95 return seekpos(this->gptr() + offset - this->eback(), std::ios_base::in);
98 if ((mode & std::ios_base::out) == std::ios_base::out) {
99 return seekpos(this->pptr() + offset - this->pbase(), std::ios_base::out);
103 case std::ios_base::end:
104 return seekpos(pos_type{
static_cast<off_type
>(buffer_.size()) + offset}, mode);
109 return std::basic_streambuf<CharT, Traits>::seekoff(offset, direction, mode);
112 pos_type seekpos(pos_type pos, std::ios_base::openmode mode)
override {
114 if (pos < 0 || pos >= buffer_.size()) {
115 return std::basic_streambuf<CharT, Traits>::seekpos(pos, mode);
118 if ((mode_ & std::ios_base::in) == std::ios_base::in && (mode & std::ios_base::in) == std::ios_base::in) {
119 this->setg(buffer_.data(), buffer_.data() + pos, buffer_.data() + buffer_.size());
122 if ((mode_ & std::ios_base::out) == std::ios_base::out
123 && (mode & std::ios_base::out) == std::ios_base::out) {
124 this->setp(buffer_.data(), buffer_.data() + buffer_.size());
125 this->pbump(
static_cast<std::int32_t
>(pos));
132 std::ios_base::openmode mode_;
133 std::span<CharT> buffer_;