Sprout.Weed の parse をラップしてみた

テストしやすいようにちょっとラップしてみました。

[ソース]

#define SPROUT_CONFIG_SUPPORT_TEMPORARY_CONTAINER_ITERATION
#include <sprout/weed.hpp>


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

template<typename String, typename Parser>
constexpr auto
parse(String const& str, Parser&& parser)
->parsed_holder<decltype(
    sprout::weed::parse(str.begin(), str.end(), sprout::forward<Parser>(parser))
)>{
    return { sprout::weed::parse(str.begin(), str.end(), sprout::forward<Parser>(parser)) };
}

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


int
main(){
    namespace w = sprout::weed;
    
    static_assert(parse("1234", w::int_), "");
    static_assert(parse("1234", w::int_) == 1234ll, "");
    static_assert(!parse("c", w::int_), "");
    static_assert(parse("c", w::int_) == false, "");

    static constexpr auto parser = w::int_ >> ':' >> w::int_;
    static constexpr auto str = sprout::to_string("12:34");

    static constexpr auto check_result = sprout::make_array<long long int>(12, 34);
    static_assert( parse(str, parser) == check_result, "");

    return 0;
}

んーこんな感じですかね。
サッと使う分には特に問題はないかな?
constexpr optional があればもうちょっと簡単になりそう。

[コンパイラ]

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