Sprout.Weed で複数の文字列をパースする場合に文字列が連結されるのを回避する

さて、

homu:mado


のような『:』区切りの構文をパースする場合、

namespace weed = sprout::weed;
static constexpr auto parser = *weed::lim<4>(weed::char_ - ':') >> ":" >> *weed::lim<4>(weed::char_);


のようなパーサを記述すると思います。
しかし、このパーサでは文字列が連結されて結果が返ってきます。

static constexpr auto parser = *weed::lim<4>(weed::char_ - ':') >> ":" >> *weed::lim<4>(weed::char_);
static_assert(parse("homu:mado", parser), "");
static_assert(parse("homu:mado", parser) == "homumado", "");


これを回避するために weed::as_tuple を使用します。

[ソース]

#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 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(){
    using sprout::make_tuple;
    namespace w = sprout::weed;

    static constexpr auto item = w::as_tuple[*w::lim<4>(w::char_ - ':')];
    static_assert(parse("homu:mado", item >> ':' >> item), "");
    static_assert(parse("homu:mado", item >> ':' >> item) == make_tuple("homu", "mado"), "");
    
    return 0;
}

[コンパイラ]

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