boost::filesystem を使ってディレクトリ直下の全てのディレクトリ・ファイルを列挙

#define BOOST_FILESYSTEM_VERSION 3    // filesystem で日本語を使用する場合に定義

#include <iostream>

#include <boost/filesystem.hpp>

#include <boost/range.hpp>
#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm/for_each.hpp>
#include <boost/range/join.hpp>

#include <pstade/oven/any_range.hpp>


// ディレクトリ内のファイル・ディレクトリの範囲
std::pair<
    boost::filesystem::directory_iterator,
    boost::filesystem::directory_iterator
>
directory_range(const boost::filesystem::path& p){
    using boost::filesystem::directory_iterator;
    return std::make_pair(directory_iterator(p), directory_iterator());
}

// ディレクトリ直下のファイル・ディレクトリの範囲
pstade::oven::any_range<boost::filesystem::path, boost::single_pass_traversal_tag>
directory_all_range(const boost::filesystem::path& path){
    
    namespace fs = boost::filesystem;
    namespace oven = pstade::oven;
    
    oven::any_range<fs::path, boost::single_pass_traversal_tag> result(directory_range(path));
    
    boost::for_each(directory_range(path), [&result](const fs::path& p){
        if( boost::filesystem::is_directory(p) ){
            result = boost::join(result, directory_all_range(p));
        }
    });
    
    return result;
}

int
main(){
    namespace fs = boost::filesystem;
    
    // カレントディレクトリ直下のファイル・ディレクトリを全て表示
    boost::for_each(directory_all_range(fs::current_path()), [](fs::path p){
        std::cout << p.filename() << std::endl;
    });

    return 0;
}

これがやりたかったんやー。
そんな訳でディレクトリ直下の全てのディレクトリ・ファイルの範囲を取得しています。
any_range の部分でエラーが出たり、結合がうまくいかなかったり、レンジが吹っ飛んだりして結構大変でした…。
テンプレートのエラーはやっぱり分かりづらいでござる。
眠気MAXなのですごく怪しいですが、ひとまずこれで動きました。
ディレクトリの深さに限界があるような気がするけど。
レンジ難しいよレンジ。


[boost/pstade]
ver 1.44.0 / ver 1.04.3
[参照]
http://www.kmonos.net/alang/boost/classes/filesystem.html
http://d.hatena.ne.jp/faith_and_brave/20100104/