fork download
  1. #include <iostream>
  2. #include <array>
  3. #include <functional>
  4. #include <algorithm>
  5.  
  6. class formatting_streambuf: public std::streambuf
  7. {
  8. typedef std::function<std::string(const std::string&)> formatter_t;
  9. public:
  10. formatting_streambuf(std::streambuf* buf, const formatter_t& formatter) : buffer_{}, buf_(buf), formatter_(formatter)
  11. {
  12. setp(buffer_.begin(), buffer_.end() - 1);
  13. }
  14. protected:
  15. virtual int overflow(int_type c = traits_type::eof()) override
  16. {
  17. *pptr() = traits_type::to_char_type(c);
  18. format();
  19. return traits_type::not_eof(c);
  20. }
  21.  
  22. virtual int sync() override
  23. {
  24. format();
  25. return 0;
  26. }
  27. private:
  28. void format()
  29. {
  30. const std::string value(buffer_.begin(), pptr() - buffer_.begin());
  31. const std::string formatted = formatter_(value);
  32. buf_->sputn(formatted.c_str(), formatted.size());
  33. setp(buffer_.begin(), buffer_.end());
  34. }
  35.  
  36. std::array<char, 1024> buffer_;
  37. std::streambuf* buf_;
  38. formatter_t formatter_;
  39. };
  40.  
  41. class formatting_ostream : public std::ostream
  42. {
  43. typedef std::function<std::string(const std::string&)> formatter_t;
  44. public:
  45. formatting_ostream(std::ostream& stream, const formatter_t& formatter) :
  46. stream_(stream), old_buf_(stream_.rdbuf()), streambuf_(old_buf_, formatter)
  47. {
  48. init(&streambuf_);
  49. }
  50. private:
  51. std::ostream& stream_;
  52. std::streambuf* old_buf_;
  53. formatting_streambuf streambuf_;
  54. };
  55.  
  56. class source
  57. {
  58. public:
  59. source(std::ostream& stream) : stream_(stream)
  60. {
  61. }
  62.  
  63. void print()
  64. {
  65. stream_ << "HeLlO" << std::endl;
  66. }
  67. private:
  68. std::ostream& stream_;
  69. };
  70.  
  71. int main()
  72. {
  73. auto to_lower = [](const std::string& v) -> std::string
  74. {
  75. std::string result;
  76. std::transform(v.begin(), v.end(), std::back_inserter(result), tolower);
  77. return result;
  78. };
  79. formatting_ostream stream(std::cout, to_lower);
  80. source s(stream);
  81. s.print();
  82. s.print();
  83.  
  84. source ss(std::cout);
  85. ss.print();
  86. }
Success #stdin #stdout 0s 3236KB
stdin
Standard input is empty
stdout
hello
hello
HeLlO