fork download
  1. #include <iostream>
  2. #include <set>
  3. #include <algorithm>
  4.  
  5. template<typename CharT = char,
  6. typename CharTraits = std::char_traits<CharT> >
  7. class Logger : public std::basic_ostream<CharT, CharTraits>,
  8. private std::basic_streambuf<CharT, CharTraits>
  9. {
  10. typedef std::basic_streambuf<CharT, CharTraits> streambuf_type;
  11. typedef std::basic_ostream<CharT, CharTraits> ostream_type;
  12.  
  13. std::set<streambuf_type*> mStreambufs;
  14.  
  15. public:
  16.  
  17. typedef CharT char_type;
  18. typedef CharTraits traits_type;
  19.  
  20. typedef typename std::set<streambuf_type*>::iterator iterator;
  21. typedef typename std::set<streambuf_type*>::const_iterator const_iterator;
  22.  
  23. Logger():
  24. ostream_type{this} {}
  25.  
  26. iterator begin() { return mStreambufs.begin(); }
  27. iterator end() { return mStreambufs.end(); }
  28. const_iterator begin() const { return mStreambufs.cbegin(); }
  29. const_iterator end() const { return mStreambufs.cend(); }
  30.  
  31. std::pair<iterator, bool> add( streambuf_type* ptr ) { return mStreambufs.insert(ptr); }
  32. std::pair<iterator, bool> add( ostream_type& ptr ) { return add(ptr.rdbuf()); }
  33.  
  34. void erase( iterator i ) { mStreambufs.erase(i); }
  35.  
  36. protected:
  37.  
  38. virtual typename traits_type::int_type overflow( typename traits_type::int_type c = traits_type::eof() ) override
  39. {
  40. typename traits_type::int_type rval = traits_type::not_eof(c);
  41.  
  42. if( !traits_type::eq_int_type( rval, c ) ) /// EOF - no characters to be written. Return success.
  43. return rval;
  44.  
  45. for( auto ptr : *this )
  46. if( traits_type::eq_int_type( ptr->sputc( traits_type::to_char_type(c) ), traits_type::eof() ) )
  47. rval = traits_type::eof(); // if one streambuf returns a value indicating failure, all other streambufs are done and EOF is returned.
  48.  
  49. return rval;
  50. }
  51. };
  52.  
  53. #include <fstream>
  54.  
  55. int main()
  56. {
  57. Logger<> logger;
  58. logger.add( std::cout );
  59.  
  60. logger << "Hallo Welt!\nWie gehts?" << std::endl;
  61. }
Success #stdin #stdout 0s 3032KB
stdin
Standard input is empty
stdout
Hallo Welt!
Wie gehts?