Sprout.Weed でコンパイル時にファイルパスをパース

やってみました。
__FILE__ とかがコンパイル時にパースできますね。
果たして必要になるときが来るのだろか…。

[ソース]

#define SPROUT_CONFIG_SUPPORT_TEMPORARY_CONTAINER_ITERATION
#include <sprout/weed.hpp>
#include <sprout/tuple/array.hpp>
#include <iostream>

template<typename Parsed>
struct parsed_holder{
    constexpr
    operator bool() const{
        return parsed.success();
    }
    
    constexpr decltype(std::declval<Parsed>().attr())
    attr(){
        return parsed.attr();
    }

    template<typename T>
    constexpr bool
    operator ==(T&& t) const{
        return parsed.attr() == t;
    }
    Parsed parsed;
};

template<typename Char, std::size_t N, typename Parser>
constexpr auto
parse(Char const(&str)[N], Parser&& parser)
->parsed_holder<decltype(
    sprout::weed::parse(str, str+N-1, sprout::forward<Parser>(parser))
)>{
    return { sprout::weed::parse(str, str+N-1, sprout::forward<Parser>(parser)) };
}


int
main(){
    namespace w = sprout::weed;
    
    static constexpr auto string_max = 12;
    static constexpr auto nest_max = 8;
    static constexpr auto dir = *w::lim<string_max>(w::char_ - '/' - w::eoi);
    static constexpr auto tail = dir >> w::eoi;
    static constexpr auto path_parser = (*w::lim<nest_max>(w::as_tuple[dir >> '/']) - tail) >> tail;

    {
        // ../main.cpp
        static_assert(parse(__FILE__, path_parser), "");

        static constexpr auto result = parse(__FILE__, path_parser);
        static constexpr auto result_dirs = sprout::get<0>(result.attr());
        static constexpr auto result_tail = sprout::get<1>(result.attr());
        static_assert(result_tail == "main.cpp", "");
    }

    {
        static constexpr char data[] = "D:/LLVM/llvm/include/llvm/Constant.h";
        static_assert(parse(data, path_parser), "");

        static constexpr auto result = parse(data, path_parser);
        static constexpr auto result_dirs = sprout::get<0>(result.attr());
        static constexpr auto result_tail = sprout::get<1>(result.attr());
        static_assert(sprout::get<0>(result_dirs[0]) == "D:", "");
        static_assert(sprout::get<0>(result_dirs[1]) == "LLVM", "");
        static_assert(sprout::get<0>(result_dirs[2]) == "llvm", "");
        static_assert(sprout::get<0>(result_dirs[3]) == "include", "");
        static_assert(sprout::get<0>(result_dirs[4]) == "llvm", "");
        static_assert(result_tail == "Constant.h", "");
    }

    return 0;
}

[コンパイラ]

  • g++ (GCC) 4.7.0 20111210 (experimental)