I'm trying to parse a Wavefront OBJ file. If line describes a vertex, i try to split it, take XYZ-coordinates, and assign them to a tuple. For example, if the line is "v -0.000581696 -0.734665 -0.623267 1.0", the result must be {-0.000581696, -0.734665, -0.623267}.
The code is as follows:
const auto vertex = ranges::views::split(line, " "sv) |
ranges::views::tail | // ignore "v "
ranges::views::take(3) | // ignore 4th value if exists
ranges::views::transform([](const std::string &value) { return std::stof(value); }) | // convert string to float
ranges::to<std::tuple<float, float, float>>();
However, the compiler gives me this error:
error C2678: binary '|': no operator found which takes a left-hand operand of type 'ranges::take_view<ranges::tail_view<ranges::split_view<ranges::ref_view<std::string>,std::basic_string_view<char,std::char_traits<char>>>>>' (or there is no acceptable conversion)
What am I doing wrong and how do I fix it?
EDIT: Inserting ranges::views::transform([](const auto &view) { return view | ranges::to<std::string>; }) between take and transform solved the string conversion part, but using to<std::tuple> still leads to an error
error C2678: binary '|': no operator found which takes a left-hand operand of type 'ranges::transform_view<ranges::transform_view<ranges::take_view<ranges::tail_view<ranges::split_view<ranges::ref_view<std::string>,std::basic_string_view<char,std::char_traits<char>>>>>,Arg>,`anonymous-namespace'::readWavefrontObj::<lambda_2>>' (or there is no acceptable conversion)
So far, I could only convert this to vector<float>. Is conversion to a tuple even possible?
ranges::to requires the type have an (Iterator, Iterator) constructor, which std::tuple doesn't have.
You'll have to explicitly take the first 3 elements, e.g.
template <std::random_access_range R>
std::array<float, 3> to_array(R r) {
assert(ranges::size(r) >= 3);
return { r[0], r[1], r[2] };
}
const auto vertex = to_array(ranges::views::split(line, " "sv) |
ranges::views::tail | // ignore "v "
ranges::views::transform([](const std::string &value) { return std::stof(value); })); // transform is lazy, so it doesn't matter what else is on line
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With