generic StreamRange (defaulting to char)

master
Daniel Kolesa 2015-06-27 01:02:28 +01:00
parent a840b20ea3
commit 715a608b3a
1 changed files with 16 additions and 12 deletions

View File

@ -25,6 +25,7 @@ enum class StreamSeek {
set = SEEK_SET set = SEEK_SET
}; };
template<typename T = char, bool = octa::IsPod<T>::value>
struct StreamRange; struct StreamRange;
struct Stream { struct Stream {
@ -54,11 +55,13 @@ struct Stream {
virtual octa::Size read(char *, octa::Size) { return 0; } virtual octa::Size read(char *, octa::Size) { return 0; }
virtual octa::Size write(const char *, octa::Size) { return 0; } virtual octa::Size write(const char *, octa::Size) { return 0; }
StreamRange iter(); template<typename T = char>
StreamRange<T> iter();
}; };
struct StreamRange: InputRange< template<typename T>
Stream, octa::InputRangeTag, char, char, octa::Size, StreamOffset struct StreamRange<T, true>: InputRange<
Stream, octa::InputRangeTag, T, T, octa::Size, StreamOffset
> { > {
StreamRange(Stream &s): p_stream(&s) {} StreamRange(Stream &s): p_stream(&s) {}
StreamRange(const StreamRange &r): p_stream(r.p_stream) {} StreamRange(const StreamRange &r): p_stream(r.p_stream) {}
@ -67,13 +70,13 @@ struct StreamRange: InputRange<
bool pop_front() { bool pop_front() {
if (empty()) return false; if (empty()) return false;
char val; T val;
return !!p_stream->read(&val, 1); return !!p_stream->read(&val, sizeof(T));
} }
char front() const { T front() const {
char val; T val;
p_stream->seek(-p_stream->read(&val, 1), StreamSeek::cur); p_stream->seek(-p_stream->read(&val, sizeof(T)), StreamSeek::cur);
return val; return val;
} }
@ -81,16 +84,17 @@ struct StreamRange: InputRange<
return p_stream->tell() == s.p_stream->tell(); return p_stream->tell() == s.p_stream->tell();
} }
void put(const char &val) { void put(T val) {
p_stream->write(&val, 1); p_stream->write(&val, sizeof(T));
} }
private: private:
Stream *p_stream; Stream *p_stream;
}; };
inline StreamRange Stream::iter() { template<typename T>
return StreamRange(*this); inline StreamRange<T> Stream::iter() {
return StreamRange<T>(*this);
} }
enum class StreamMode { enum class StreamMode {