Note that this code compiles without error with spirit x3 from boost v1.69, for which this code was originally developed. The error originates at the x3::parse() line, but with this template noise I have no idea what the compiler is actually trying to tell me or why spirit x3 1.84 has this error while 1.69 doesn't. g++ 13.2 in c++17 mode:
#include <boost/spirit/home/x3.hpp>
#include <algorithm>
#include <iomanip>
#include <iterator>
#include <stdexcept>
namespace x3 = boost::spirit::x3;
namespace {
using x3::char_;
using x3::lit;
using x3::no_skip;
const auto escaped =
lit('"') >> *((char_ - '"') | lit('"') >> char_('"')) >> lit('"');
const auto non_escaped =
*(char_ - (lit(',') | lit('"') | lit('\r') | lit('\n')));
const auto field = escaped | non_escaped;
const auto record = (field % ',') >> (lit("\r\n") | lit('\n') | !char_);
} //namespace
namespace utils {
std::vector<std::string> parse_csv(std::string_view input,
std::string_view& remainder)
{
std::vector<std::string> result;
auto first { std::begin(input) };
if (!x3::parse(first, std::end(input), record, result)) {
throw std::runtime_error{"CSV parse failure"};
}
remainder = input.substr(std::distance(std::begin(input), first));
return result;
}
}
After paring down what I hope is many lines of error messages not salient to the point:
/data3/jbuster/boost-build/install/xgcc/boost/1.84/include/boost/spirit/home/x3/support/traits/move_to.hpp:164:9: note: template argument deduction/substitution failed:
/data3/jbuster/boost-build/install/xgcc/boost/1.84/include/boost/spirit/home/x3/support/traits/move_to.hpp:196:24: note: deduced conflicting types for parameter ‘Iterator’ (‘char’ and ‘std::__cxx11::basic_string<char>’)
196 | detail::move_to(src, dest, typename attribute_category<Dest>::type());
| ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/data3/jbuster/boost-build/install/xgcc/boost/1.84/include/boost/spirit/home/x3/support/traits/move_to.hpp:168:9: note: candidate: ‘template<class Iterator, class Dest> void boost::spirit::x3::traits::detail::move_to(Iterator, Iterator, Dest&, boost::spirit::x3::traits::container_attribute)’
168 | move_to(Iterator first, Iterator last, Dest& dest, container_attribute)
| ^~~~~~~
/data3/jbuster/boost-build/install/xgcc/boost/1.84/include/boost/spirit/home/x3/support/traits/move_to.hpp:168:9: note: template argument deduction/substitution failed:
/data3/jbuster/boost-build/install/xgcc/boost/1.84/include/boost/spirit/home/x3/support/traits/move_to.hpp:196:24: note: deduced conflicting types for parameter ‘Iterator’ (‘char’ and ‘std::__cxx11::basic_string<char>’)
196 | detail::move_to(src, dest, typename attribute_category<Dest>::type());
| ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/data3/jbuster/boost-build/install/xgcc/boost/1.84/include/boost/spirit/home/x3/support/traits/move_to.hpp:180:9: note: candidate: ‘template<class Iterator, class Dest> typename boost::enable_if<boost::spirit::x3::traits::is_size_one_sequence<Dest> >::type boost::spirit::x3::traits::detail::move_to(Iterator, Iterator, Dest&, boost::spirit::x3::traits::tuple_attribute)’
180 | move_to(Iterator first, Iterator last, Dest& dest, tuple_attribute)
| ^~~~~~~
/data3/jbuster/boost-build/install/xgcc/boost/1.84/include/boost/spirit/home/x3/support/traits/move_to.hpp:180:9: note: template argument deduction/substitution failed:
/data3/jbuster/boost-build/install/xgcc/boost/1.84/include/boost/spirit/home/x3/support/traits/move_to.hpp:196:24: note: deduced conflicting types for parameter ‘Iterator’ (‘char’ and ‘std::__cxx11::basic_string<char>’)
196 | detail::move_to(src, dest, typename attribute_category<Dest>::type());
| ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/data3/jbuster/boost-build/install/xgcc/boost/1.84/include/boost/spirit/home/x3/support/traits/move_to.hpp:187:9: note: candidate: ‘template<class Iterator> void boost::spirit::x3::traits::detail::move_to(Iterator, Iterator, boost::iterator_range<T>&, boost::spirit::x3::traits::range_attribute)’
187 | move_to(Iterator first, Iterator last, boost::iterator_range<Iterator>& rng, range_attribute)
| ^~~~~~~
/data3/jbuster/boost-build/install/xgcc/boost/1.84/include/boost/spirit/home/x3/support/traits/move_to.hpp:187:9: note: template argument deduction/substitution failed:
/data3/jbuster/boost-build/install/xgcc/boost/1.84/include/boost/spirit/home/x3/support/traits/move_to.hpp:196:24: note: deduced conflicting types for parameter ‘Iterator’ (‘char’ and ‘std::__cxx11::basic_string<char>’)
196 | detail::move_to(src, dest, typename attribute_category<Dest>::type());
| ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The attribute synthesis/compatibility rules for X3 have been in flux. In this particular area (string synthesis) I've seen some improvements but also "random behaviour changes".
This is all fine since the X3 interface is (still) documented as "experimental".
Help the attribute synthesis a little, changing
to
Here's a demo with test cases and many many simplifications/improvements along the way:
Live On Coliru
Printing the expectable
BONUS
Parse a whole file at once:
Live On Coliru
Printing
¹ e.g. the case where
raw[p] >> raw[p]suddenly becomes compatible with astd::stringbound attribute reference; I'm not sure I concur