3#include <StormByte/buffer/typedefs.hxx>
19namespace StormByte::Buffer {
39 inline
Generic(const DataType& data) noexcept: m_buffer(data) {}
45 inline Generic(DataType&& data)
noexcept: m_buffer(std::move(data)) {}
83 template<std::ranges::input_range Src>
84 requires (!std::is_class_v<std::remove_cv_t<std::ranges::range_value_t<Src>>>) &&
85 requires(std::ranges::range_value_t<Src> v) {
static_cast<std::byte
>(v); }
88 if constexpr (
requires { std::ranges::size(src); }) {
89 auto s = std::ranges::size(src);
90 if (s > 0) out.reserve(
static_cast<typename DataType::size_type
>(s));
92 std::transform(std::ranges::begin(src), std::ranges::end(src), std::back_inserter(out),
93 [] (
auto&& e)
noexcept {
return static_cast<std::byte
>(e); });
97 template<std::ranges::input_range Src>
98 requires (!std::is_class_v<std::remove_cv_t<std::ranges::range_value_t<Src>>>) &&
99 requires(std::ranges::range_value_t<Src> v) {
static_cast<std::byte
>(v); }
100 static DataType DataConvert(Src&& src)
noexcept {
101 using Dec = std::remove_cvref_t<Src>;
102 if constexpr (std::same_as<Dec, DataType>) {
103 return std::move(src);
106 if constexpr (
requires { std::ranges::size(src); }) {
107 auto s = std::ranges::size(src);
108 if (s > 0) out.reserve(
static_cast<typename DataType::size_type
>(s));
110 std::transform(std::ranges::begin(src), std::ranges::end(src), std::back_inserter(out),
111 [] (
auto&& e)
noexcept {
return static_cast<std::byte
>(e); });
121 if (!sv.empty()) out.reserve(
static_cast<typename DataType::size_type
>(sv.size()));
122 std::transform(sv.begin(), sv.end(), std::back_inserter(out), [] (
char c)
noexcept { return static_cast<std::byte>(c); });
130 if (!s)
return DataType{};
131 return DataConvert(std::string_view(s));
194 virtual std::
size_t AvailableBytes() const noexcept = 0;
200 virtual
void Clean() noexcept = 0;
208 virtual
void Clear() noexcept = 0;
214 virtual const DataType& Data() const noexcept {
223 virtual bool Drop(
const std::size_t& count)
noexcept = 0;
230 virtual bool Empty() const noexcept = 0;
238 virtual
bool EoF() const noexcept = 0;
247 inline virtual
bool Extract(const std::
size_t& count, DataType& outBuffer) noexcept = 0;
255 inline
bool Extract(DataType& outBuffer) noexcept {
256 return Extract(0, outBuffer);
273 return Extract(0, outBuffer);
312 virtual
bool Peek(const std::
size_t& count, DataType& outBuffer) const noexcept = 0;
331 virtual
bool Peek(const std::
size_t& count,
WriteOnly& outBuffer) const noexcept = 0;
339 virtual
bool Read(const std::
size_t& count, DataType& outBuffer) const noexcept = 0;
346 inline
bool Read(DataType& outBuffer) const noexcept {
347 return Read(0, outBuffer);
356 virtual bool Read(
const std::size_t& count,
WriteOnly& outBuffer)
const noexcept = 0;
364 return Read(0, outBuffer);
389 virtual void Seek(
const std::ptrdiff_t& offset,
const Position& mode)
const noexcept = 0;
396 virtual std::size_t
Size() const noexcept = 0;
456 virtual
bool IsWritable() const noexcept = 0;
467 virtual
bool Write(const std::
size_t& count, const DataType& data) noexcept = 0;
485 bool Write(std::string_view sv) noexcept {
487 if (!sv.empty()) tmp.reserve(
static_cast<typename DataType::size_type
>(sv.size()));
488 std::transform(sv.begin(), sv.end(), std::back_inserter(tmp), [] (
char e)
noexcept { return static_cast<std::byte>(e); });
489 return Write(
static_cast<std::size_t
>(tmp.size()), std::move(tmp));
495 bool Write(
const char* s)
noexcept {
496 if (!s)
return Write(DataType{});
497 return Write(std::string_view(s));
503 bool Write(
const std::size_t& count, std::string_view sv)
noexcept {
504 size_t to_write = (count == 0) ?
static_cast<size_t>(sv.size()) : std::min(count,
static_cast<std::size_t
>(sv.size()));
506 if (to_write > 0) tmp.reserve(
static_cast<typename DataType::size_type
>(to_write));
507 std::transform(sv.begin(), sv.begin() + to_write, std::back_inserter(tmp), [] (
char e)
noexcept { return static_cast<std::byte>(e); });
508 return Write(
static_cast<std::size_t
>(to_write), std::move(tmp));
514 bool Write(
const std::size_t& count,
const char* s)
noexcept {
515 if (!s)
return Write(count, DataType{});
516 return Write(count, std::string_view(s));
522 template<std::
size_t N>
523 bool Write(
const char (&s)[N])
noexcept {
525 if (N == 0)
return Write(DataType{});
526 return Write(std::string_view(s, (N > 0) ? (N - 1) : 0));
539 template<std::ranges::input_range R>
540 requires (!std::is_class_v<std::remove_cv_t<std::ranges::range_value_t<R>>>) &&
541 requires(std::ranges::range_value_t<R> v) {
static_cast<std::byte
>(v); }
544 if constexpr (
requires(DataType& d,
typename DataType::size_type n) { d.reserve(n); }) {
545 auto dist = std::ranges::distance(r);
546 if (dist > 0) tmp.reserve(
static_cast<typename DataType::size_type
>(dist));
548 std::transform(std::ranges::begin(r), std::ranges::end(r), std::back_inserter(tmp),
549 [] (
auto&& e)
noexcept {
return static_cast<std::byte
>(e); });
550 return Write(
static_cast<std::size_t
>(tmp.size()), std::move(tmp));
564 template<std::ranges::input_range Rw>
565 requires (!std::is_class_v<std::remove_cv_t<std::ranges::range_value_t<Rw>>>) &&
566 requires(std::ranges::range_value_t<Rw> v) {
static_cast<std::byte
>(v); }
567 bool Write(
const std::size_t& count,
const Rw& r)
noexcept {
568 if (count == 0)
return Write(r);
570 if constexpr (
requires(DataType& d,
typename DataType::size_type n) { d.reserve(n); }) {
571 auto dist = std::ranges::distance(r);
572 if (dist > 0) tmp.reserve(
static_cast<typename DataType::size_type
>(std::min(dist,
static_cast<decltype(dist)
>(count))));
574 auto it = std::ranges::begin(r);
575 auto end = std::ranges::end(r);
576 std::size_t written = 0;
577 for (; it != end && written < count; ++it, ++written) {
578 tmp.push_back(
static_cast<std::byte
>(*it));
580 return Write(
static_cast<std::size_t
>(written), std::move(tmp));
594 template<std::ranges::input_range Rrw>
595 requires (!std::is_class_v<std::remove_cv_t<std::ranges::range_value_t<Rrw>>>) &&
596 requires(std::ranges::range_value_t<Rrw> v) {
static_cast<std::byte
>(v); }
597 bool Write(
const std::size_t& count, Rrw&& r)
noexcept {
598 using Dec = std::remove_cvref_t<Rrw>;
599 if (count == 0)
return Write(std::forward<Rrw>(r));
600 if constexpr (std::same_as<Dec, DataType>) {
602 DataType tmp = std::move(r);
603 if (tmp.size() > count) tmp.resize(count);
604 return Write(
static_cast<std::size_t
>(tmp.size()), std::move(tmp));
607 if constexpr (
requires(DataType& d,
typename DataType::size_type n) { d.reserve(n); }) {
608 auto dist = std::ranges::distance(r);
609 if (dist > 0) tmp.reserve(
static_cast<typename DataType::size_type
>(std::min(dist,
static_cast<decltype(dist)
>(count))));
611 auto it = std::ranges::begin(r);
612 auto end = std::ranges::end(r);
613 std::size_t written = 0;
614 for (; it != end && written < count; ++it, ++written) {
615 tmp.push_back(
static_cast<std::byte
>(*it));
617 return Write(
static_cast<std::size_t
>(written), std::move(tmp));
630 template<std::ranges::input_range Rr>
631 requires (!std::is_class_v<std::remove_cv_t<std::ranges::range_value_t<Rr>>>) &&
632 requires(std::ranges::range_value_t<Rr> v) {
static_cast<std::byte
>(v); }
634 using Dec = std::remove_cvref_t<Rr>;
635 if constexpr (std::same_as<Dec, DataType>) {
637 return Write(
static_cast<std::size_t
>(r.size()), std::move(r));
640 if constexpr (
requires(DataType& d,
typename DataType::size_type n) { d.reserve(n); }) {
641 auto dist = std::ranges::distance(r);
642 if (dist > 0) tmp.reserve(
static_cast<typename DataType::size_type
>(dist));
644 std::transform(std::ranges::begin(r), std::ranges::end(r), std::back_inserter(tmp),
645 [] (
auto&& e)
noexcept {
return static_cast<std::byte
>(e); });
646 return Write(
static_cast<std::size_t
>(tmp.size()), std::move(tmp));
664 template<std::input_iterator I, std::sentinel_for<I> S>
665 requires (!std::is_class_v<std::remove_cv_t<std::iter_value_t<I>>>) &&
666 requires(std::iter_value_t<I> v) {
static_cast<std::byte
>(v); }
667 bool Write(I first, S last)
noexcept {
669 std::transform(first, last, std::back_inserter(tmp), [] (
auto&& e)
noexcept {
return static_cast<std::byte
>(e); });
670 return Write(
static_cast<std::size_t
>(tmp.size()), std::move(tmp));
686 template<std::input_iterator I2, std::sentinel_for<I2> S2>
687 requires (!std::is_class_v<std::remove_cv_t<std::iter_value_t<I2>>>) &&
688 requires(std::iter_value_t<I2> v) {
static_cast<std::byte
>(v); }
689 bool Write(
const std::size_t& count, I2 first, S2 last)
noexcept {
690 if (count == 0)
return Write(first, last);
692 std::size_t written = 0;
693 for (; first != last && written < count; ++first, ++written) {
694 tmp.push_back(
static_cast<std::byte
>(*first));
696 return Write(
static_cast<std::size_t
>(written), std::move(tmp));
708 virtual bool Write(
const std::size_t& count, DataType&& data)
noexcept = 0;
719 virtual bool Write(
const std::size_t& count,
const ReadOnly& data)
noexcept = 0;
730 return Write(data.AvailableBytes(), data);
753 return Write(data.AvailableBytes(), std::move(data));
Generic class to maintain common API guarantees across buffer types.
Definition generic.hxx:28
Generic(DataType &&data) noexcept
Construct Generic with initial data using move semantics.
Definition generic.hxx:45
Generic(const Generic &) noexcept=default
Copy construct deleted.
static DataType DataConvert(const Src &src) noexcept
Convert various source types into the library DataType.
Definition generic.hxx:86
Generic(Generic &&) noexcept=default
Move construct deleted.
static DataType DataConvert(const char *s) noexcept
Convert a null-terminated C string to DataType.
Definition generic.hxx:129
Generic() noexcept=default
Construct Generic.
static DataType DataConvert(std::string_view sv) noexcept
Convert a std::string_view to DataType.
Definition generic.hxx:119
Generic class providing a buffer that can be read but not written to.
Definition generic.hxx:146
ReadOnly(ReadOnly &&) noexcept=default
Move construct deleted.
virtual bool IsReadable() const noexcept=0
Check if the buffer is readable.
virtual void ExtractUntilEoF(WriteOnly &outBuffer) noexcept=0
Read all bytes until end-of-file into a WriteOnly buffer.
virtual bool Extract(const std::size_t &count, WriteOnly &outBuffer) noexcept=0
Destructive read that removes data from the buffer into a FIFO.
ReadOnly(const DataType &data) noexcept
Construct ReadOnly.
Definition generic.hxx:157
virtual bool Empty() const noexcept=0
Check if the buffer is empty.
virtual void ExtractUntilEoF(DataType &outBuffer) noexcept=0
Read all bytes until end-of-file into an existing buffer.
ReadOnly(const ReadOnly &) noexcept=default
Copy construct deleted.
virtual bool Read(const std::size_t &count, WriteOnly &outBuffer) const noexcept=0
Read bytes into a WriteOnly buffer.
virtual bool Drop(const std::size_t &count) noexcept=0
Drop bytes in the buffer.
virtual std::size_t Size() const noexcept=0
Get the current number of bytes stored in the buffer.
bool Read(WriteOnly &outBuffer) const noexcept
Read bytes into a WriteOnly buffer.
Definition generic.hxx:363
virtual void Seek(const std::ptrdiff_t &offset, const Position &mode) const noexcept=0
Move the read position for non-destructive reads.
ReadOnly() noexcept
Construct ReadOnly.
Definition generic.hxx:151
bool Extract(WriteOnly &outBuffer) noexcept
Destructive read that removes all data from the buffer into a FIFO.
Definition generic.hxx:272
virtual void ReadUntilEoF(DataType &outBuffer) const noexcept=0
Read all bytes until end-of-file into an existing buffer.
ReadOnly(DataType &&data) noexcept
Construct ReadOnly with initial data using move semantics.
Definition generic.hxx:163
virtual void ReadUntilEoF(WriteOnly &outBuffer) const noexcept=0
Read all bytes until end-of-file into a WriteOnly buffer.
Generic class providing a buffer that can be both read from and written to.
Definition generic.hxx:765
ReadWrite() noexcept
Construct ReadWrite.
Definition generic.hxx:770
ReadWrite(DataType &&data) noexcept
Construct ReadWrite with initial data using move semantics.
Definition generic.hxx:782
ReadWrite(const ReadWrite &other) noexcept=default
Copy construct deleted.
ReadWrite(ReadWrite &&other) noexcept=default
Move construct deleted.
ReadWrite(const DataType &data) noexcept
Construct ReadWrite.
Definition generic.hxx:776
virtual ~ReadWrite() noexcept=default
Virtual destructor.
Generic class providing a buffer that can be written to but not read from.
Definition generic.hxx:408
WriteOnly(const WriteOnly &)=default
Copy construct deleted.
bool Write(const R &r) noexcept
Write all elements from an input range to the buffer.
Definition generic.hxx:542
bool Write(const std::size_t &count, I2 first, S2 last) noexcept
Write up-to count bytes from an iterator pair (0 => all available).
Definition generic.hxx:689
bool Write(const std::size_t &count, const char *s) noexcept
Write up-to count bytes from a C string pointer (null-terminated).
Definition generic.hxx:514
bool Write(const char *s) noexcept
Write from a C string pointer (null-terminated). Uses std::string_view.
Definition generic.hxx:495
bool Write(I first, S last) noexcept
Write from iterator pair whose value_type is convertible to std::byte.
Definition generic.hxx:667
WriteOnly(DataType &&data) noexcept
Construct WriteOnly with initial data using move semantics.
Definition generic.hxx:425
WriteOnly(const DataType &data) noexcept
Construct WriteOnly.
Definition generic.hxx:419
bool Write(const std::size_t &count, std::string_view sv) noexcept
Write up-to count bytes from a string view (0 => all available).
Definition generic.hxx:503
virtual bool Write(const std::size_t &count, ReadOnly &&data) noexcept=0
Move bytes from a vector to the buffer.
bool Write(const char(&s)[N]) noexcept
Write from a string literal (array) and avoid copying the trailing NUL.
Definition generic.hxx:523
virtual bool Write(const std::size_t &count, DataType &&data) noexcept=0
Move bytes from a vector to the buffer.
bool Write(ReadOnly &&data) noexcept
Move bytes from a vector to the buffer.
Definition generic.hxx:752
virtual bool Write(const std::size_t &count, const ReadOnly &data) noexcept=0
Write bytes from a vector to the buffer.
bool Write(const ReadOnly &data) noexcept
Write bytes from a vector to the buffer.
Definition generic.hxx:729
WriteOnly() noexcept
Construct WriteOnly.
Definition generic.hxx:413
bool Write(const std::size_t &count, const Rw &r) noexcept
Write up-to count elements from an input range.
Definition generic.hxx:567
WriteOnly(WriteOnly &&) noexcept=default
Move construct deleted.
bool Write(Rr &&r) noexcept
Write from an rvalue input range.
Definition generic.hxx:633
bool Write(const std::size_t &count, Rrw &&r) noexcept
Write up-to count elements from an rvalue range.
Definition generic.hxx:597