端末に色つきテキストを出力する

iomanip の setw(5) みたいなノリで,出力する文字に色をつける方法を考える.

  cout<<ioscc::green<<"GREEN"<<endl;

のようにすれば,緑色で GREEN が表示されるようにしたい. std::endl で色がリセットされる.
で,書いてみたのが以下のコード.

#include <iostream>

namespace ioscc
{
  enum TColorCode {red=1, blue, green};
  const char *_sesc    = "\033[";
  const char *_sreset  = "0m";
  const char *_sred    = "31;1m";
  const char *_sblue   = "34;1m";
  const char *_sgreen  = "32;1m";
};

struct _colored_stream
{
  std::ostream &os;
};

inline _colored_stream operator<< (std::ostream &os, ioscc::TColorCode ccode)
{
  switch (ccode)
  {
    case ioscc::red    : os<<ioscc::_sesc<<ioscc::_sred;   break;
    case ioscc::blue   : os<<ioscc::_sesc<<ioscc::_sblue;  break;
    case ioscc::green  : os<<ioscc::_sesc<<ioscc::_sgreen; break;
  }
  _colored_stream colos={os};
  return colos;
}

template <typename T>
_colored_stream operator<< (_colored_stream os, const T     &rhs)
{
  os.os << rhs;
  return os;
};
template <>
_colored_stream operator<< (_colored_stream os, const ioscc::TColorCode &ccode)
{
  os.os << ioscc::_sesc<<ioscc::_sreset;
  os.os << ccode;
  return os;
};
_colored_stream operator<< (_colored_stream os, std::ostream& (*__pf)(std::ostream&))
{
  os.os << ioscc::_sesc<<ioscc::_sreset;
  __pf(os.os);
  return os;
};

こんな感じで使う (iomanip を include しておく必要がある):

  cout<<ioscc::red<<setw(10)<<"赤"<<ioscc::blue<<setw(10)<<"青"<<endl;
  cout<<ioscc::green<<"GREEN"<<ioscc::blue<<" BLUE"<<flush;
  cout<<" DEFAULT"<<endl;
  cout<<ioscc::green<<setprecision(20)<<3.14159265358979323846l<<endl;

すると,


GREEN BLUE DEFAULT
3.1415926535897932385

こんなふうに表示される.