repr 0.1
Reconstructable string representations and more
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages Concepts
buffer.h
Go to the documentation of this file.
#pragma once
#include <cstring>
#include <iosfwd>
#include <string>
#include <string_view>
#include <utility>
namespace librepr::detail {
struct StringBuffer {
StringBuffer() = default;
// We can hopefully avoid reallocations
// by doing this ahead of time.
buffer.reserve(in.size() * 2);
}
void write(const char* beg, const char* end) {
LIBREPR_ASSERT(end >= beg, "Invalid write. (end < beg)");
auto& target = (cursor == std::string::npos) ? buffer : inplace_buffer;
if(auto len = (end - beg); len > 0) {
auto lpos = target.size();
target.resize(lpos + len);
std::memcpy(target.data() + lpos, beg, len);
}
}
auto* beg = sv.data();
this->write(beg, beg + sv.size());
}
LIBREPR_HINT_INLINE void write(char c) {
auto& target = (cursor == std::string::npos) ? buffer : inplace_buffer;
target.push_back(c);
}
flush();
// buf.shrink_to_fit();
return std::move(buffer);
}
explicit operator std::string() {
flush();
return buffer;
}
return &buffer;
}
buf.write(sv);
return buf;
}
friend StringBuffer& operator<<(StringBuffer& buf, char c){
buf.write(c);
return buf;
}
buf.flush();
return stream << buf.buffer;
}
return buffer.size() + inplace_buffer.size();
}
void set_cursor(std::size_t index = std::string::npos) {
flush();
cursor = index;
}
void flush() {
if (!inplace_buffer.empty()) {
// flush inplace buffer if it's not empty
buffer.insert(cursor, inplace_buffer);
inplace_buffer.clear();
}
}
private:
std::string buffer{};
std::string inplace_buffer{};
std::size_t cursor{std::string::npos};
};
} // namespace librepr::detail