forked from OctaForge/libostd
fully generic stream range (works on any type of stream)
This commit is contained in:
parent
5beecdf370
commit
e0574308a0
|
@ -9,6 +9,7 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <locale>
|
#include <locale>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "ostd/platform.hh"
|
#include "ostd/platform.hh"
|
||||||
#include "ostd/types.hh"
|
#include "ostd/types.hh"
|
||||||
|
@ -157,42 +158,47 @@ struct stream_range<T, true>: input_range<stream_range<T>> {
|
||||||
using difference_type = stream_off_t;
|
using difference_type = stream_off_t;
|
||||||
|
|
||||||
stream_range() = delete;
|
stream_range() = delete;
|
||||||
stream_range(stream &s): p_stream(&s), p_size(s.size()) {}
|
stream_range(stream &s): p_stream(&s) {}
|
||||||
stream_range(stream_range const &r): p_stream(r.p_stream), p_size(r.p_size) {}
|
stream_range(stream_range const &r): p_stream(r.p_stream) {}
|
||||||
|
|
||||||
bool empty() const {
|
bool empty() const {
|
||||||
|
if (!p_item.has_value()) {
|
||||||
try {
|
try {
|
||||||
auto pos = p_stream->tell();
|
p_item = p_stream->get<T>();
|
||||||
return (p_size - pos) < stream_off_t(sizeof(T));
|
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void pop_front() {
|
void pop_front() {
|
||||||
T val;
|
if (p_item.has_value()) {
|
||||||
p_stream->read_bytes(&val, sizeof(T));
|
p_item = std::nullopt;
|
||||||
|
} else {
|
||||||
|
p_stream->get<T>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
T front() const {
|
T front() const {
|
||||||
T val;
|
if (p_item.has_value()) {
|
||||||
p_stream->read_bytes(&val, sizeof(T));
|
return p_item.value();
|
||||||
p_stream->seek(-sizeof(T), stream_seek::CUR);
|
} else {
|
||||||
return val;
|
return (p_item = p_stream->get<T>()).value();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool equals_front(stream_range const &s) const {
|
bool equals_front(stream_range const &s) const {
|
||||||
return p_stream->tell() == s.p_stream->tell();
|
return p_stream == s.p_stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
void put(T val) {
|
void put(T val) {
|
||||||
p_stream->write_bytes(&val, sizeof(T));
|
p_stream->put(val);
|
||||||
p_size += sizeof(T);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
stream *p_stream;
|
stream *p_stream;
|
||||||
stream_off_t p_size;
|
mutable std::optional<T> p_item;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|
Loading…
Reference in a new issue