eliaskosunen/scnlib

Capture matches in tuple

neel opened this issue · 1 comments

neel commented

Currently there is not way of capturing matches into a tuple directly.
The scan function takes references of variables and then assigns a value to it.

If there is a possibility of usage like the following then it will be useful in many scenarios.

std::tuple<std::uint32_t, std::string> tuple;
auto result = scn::scan("123 foo", "{} {}", tuple);

I am trying to do this using std::apply , but even with that I need to specify the arguments in the scan<...>

std::tuple<std::uint32_t, std::string> tuple;
auto result = scn::make_result("123 foo");
std::tuple<decltype(result.range()), std::string> subject_format(result.range(), "{} {}");
auto args = std::tuple_cat(subject_format, tuple);
result = std::apply(scn::scan<decltype(result.range()), std::string, std::uint32_t, std::string>, args);

It would be nice if there was a simpler way of doing this.

This is somewhat more easily achievable in v2, where the interface is more closely linked with tuples, and where you're able to pass a tuple to scn::scan for it to use:

std::tuple<std::uint32_t, std::string> tuple;

// Normally with v2 scn::scan, you'd give the types to scan as template params
//     auto result = scn::scan<T, U>("input", "{} {}");
// Here, when given a tuple, they are automatically deduced
// The tuple is passed in by move, and then returned out inside `result`
auto result = scn::scan("123 foo", "{} {}", std::move(tuple));
// Access tuple with read values with result->values()

It's not quite what you're asking, since the tuple is returned and not written to by-reference, but that's probably a little too incompatible with the v2 interface.

Since the default behavior in v2 is also just returning a tuple, that's also a possibility, if it satisfies your requirements:

auto result = scn::scan<std::uint32_t, std::string>("123 foo", "{} {}");
// Acess tuple<uint32, string> with result->values()

In v1, if assigning from the result of scan_result isn't an option, I think your best bet may be close to what you have there. scn::scan(..., tuple) would be ambiguous as to whether you're scanning a tuple, or its elements, even though scanning a tuple isn't currently defined.