yohhoyの日記

技術的メモをしていきたい日記

tee ostream

UNIX tee(2)コマンド っぽく動作するostream。ストリーム出力すると予めバインドした2個の出力ストリームに同データを転送する。

std::ofstream ofs("log.txt");
tee_ostream tee(std::cout, ofs);  // teeストリーム作成

tee << "tee emulation" << std::endl;  // 標準出力 および "log.txt"へ出力

実装:

#include <ostream>

template <class E, class T = std::char_traits<E> >
class basic_tee_streambuf : public std::basic_streambuf<E, T> {
  typedef std::basic_streambuf<E, T> sbuf_type;
  typedef typename sbuf_type::int_type int_type;

  sbuf_type& sbuf1_;
  sbuf_type& sbuf2_;

  virtual int_type overflow(int_type ch)
  {
    sbuf1_.sputc(ch);
    sbuf2_.sputc(ch);
    return ch;
  }

public:
  basic_tee_streambuf(sbuf_type& sbuf1, sbuf_type& sbuf2)
    : sbuf1_(sbuf1), sbuf2_(sbuf2)
  {
    this->setp(0, 0);
  }
};

template <class E, class T = std::char_traits<E> >
class basic_tee_ostream : public std::basic_ostream<E, T> {
  typedef std::basic_ostream<E, T> ostream_type;
public:
  basic_tee_ostream(ostream_type& os1, ostream_type& os2)
    : ostream_type(new basic_tee_streambuf<E, T>(*os1.rdbuf(), *os2.rdbuf())) {}
  ~basic_tee_ostream()
  {
    delete this->rdbuf();
  }
};

typedef basic_tee_ostream<char> tee_ostream;
typedef basic_tee_ostream<wchar_t> tee_wostream;

Boost.Iostreams が利用可能ならboost::tee_deviceでよいかも。

関連URL