#include #include #include #include #include namespace io = boost::iostreams; template > class basic_istream_device { void operator=(const basic_istream_device &); std::basic_streambuf & buffer; public: typedef C char_type; typedef io::source_tag category; basic_istream_device(std::basic_streambuf & buffer) : buffer(buffer) {} std::streamsize read(char_type* s, std::streamsize n) { std::streamsize result = buffer.sgetn(s, n); return result ? result : -1; } }; template > class basic_ostream_device { void operator=(const basic_ostream_device &); std::basic_streambuf & buffer; public: typedef C char_type; typedef io::sink_tag category; basic_ostream_device(std::basic_streambuf & buffer) : buffer(buffer) {} std::streamsize write(const char_type* s, std::streamsize n) { return buffer.sputn(s, n); } }; template > class basic_iostream_device { void operator=(const basic_iostream_device &); std::basic_streambuf & buffer; public: typedef C char_type; typedef io::bidirectional_device_tag category; // The following definition makes the compiler fail: // struct category : io::device_tag, io::input, io::output {}; basic_iostream_device(std::basic_streambuf & buffer) : buffer(buffer) {} std::streamsize read(char_type* s, std::streamsize n) { std::streamsize result = buffer.sgetn(s, n); return result ? result : -1; } std::streamsize write(const char_type* s, std::streamsize n) { return buffer.sputn(s, n); } }; typedef basic_ostream_device ostream_device; typedef basic_iostream_device iostream_device; int main() { std::stringstream buffer; buffer << "raw "; { // The following declaration makes the program succeed: // io::stream > wrapper(*buffer.rdbuf()); io::stream > wrapper(*buffer.rdbuf()); wrapper << L"and converted"; } std::cout << buffer.str() << std::endl; return 0; }