GIVEN:
A class MyStream
derived of std::basic_istream<>
contains a pointer subject
to a std::basic_istream<>
object. It shall respond to tellg()
and read()
with modified content from the corresponding responses of subject
.
template <class T> MyStream :
public std::basic_istream<typename T::char_type, typename T::traits_type> {
std::basic::istream<...>* subject;
...
};
PROBLEM: The functions tellg()
, seekg()
and read()
as well as the status-flag functions are not virtual.
QUESTION: How can a MyStream
object pass tell, seek, and read to subject, forward the response to the caller and modifiy the status flags so that they correspond to the flags of subject
?
Use something like this:
template <typename T> struct MyStream : public std::basic_istream<typename T::char_type, typename T::traits_type> {
struct rdbuf_impl : public std::basic_streambuf<typename T::char_type, typename T::traits_type> {
// overwrite what you need
std::basic::istream<...>* subject;
// for tellg passthru (an example)
pos_type seekoff( off_type off, std::ios_base::seekdir dir,
std::ios_base::openmode which = ios_base::in | ios_base::out ) overwrite {
return subject->pubseekoff(off, dir, which);
}
};
MyStream(std::basic::istream<...>* subject) {
auto v = new rdbuf_impl(subject);
rdbuf(v); // set associated stream buffer 'v' in 'this'.
}
};
EDIT:
Let's consider tellg
method. Looking at definition of class basic_istream::tellg
(https://en.cppreference.com/w/cpp/io/basic_istream/tellg) - it is written, that tellg
will call rdbuf()->pubseekoff(0, std::ios_base::cur, std::ios_base::in)
. Documentation for basic_streambuf::pubseekof
(https://en.cppreference.com/w/cpp/io/basic_streambuf/pubseekoff) mentions, that it will call seekoff(off, dir, which)
. seekoff
is virtual in basic_streambuf
class and you can overwrite it.