Boost.IostreamsのFilter作成!

Filterはデータに対して何らかの処理をするために使います。
作成したいコンセプトのクラスを継承し、それに対応するメンバを定義することで、簡単に作ることができます。

ここではデータを逆順に出力するFilterを作成します。

#include <iostream>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/device/back_inserter.hpp>
#include <boost/iostreams/pipeline.hpp>

class ReverseOutputFilter
    : public boost::iostreams::multichar_output_filter{
public:
    template<class Sink>
    std::streamsize write(
        Sink& snk, const char* s, std::streamsize n){
        std::streamsize rest = n;
        while(rest != 0){
            const char c = *(s + rest - 1);
            if(boost::iostreams::put(snk, c)){ break; }

            --rest;
        }

        return n - rest;
    }
};
BOOST_IOSTREAMS_PIPABLE(ReverseOutputFilter, 0);

int main(){
    namespace io = boost::iostreams;

    std::string result;
    io::filtering_ostream out(
        ReverseOutputFilter() | io::back_inserter(result));
    out << "Example String";
    out.flush();

    std::cout << result << std::endl;

    return 0;
}


Output:

gnirtS elpmaxE


multichar_output_filterを継承しました。これで、一度に文字列を処理し、出力するためのFilterを作成できます。
メンバには関数writeを定義します。
Filterからの出力には、boost::iostreams::put、もしくはboost::iostrems::writeを使用します。

ついでに、BOOST_IOSTREAMS_PIPABLEを使って、FilterをPipableにしました。*1
これで|演算子を使ってfiltering_ostreamにFilterやDeviceをセットすることができます。

*1:少しわかりにくいのですが、第2引数はクラスのテンプレート引数の数です