парсинг из std :: string в boost :: string_view с использованием boost :: spirit :: x3

В моем мой предыдущий вопрос было высказано предположение, что производительность моего boost::spirit::x3 синтаксический анализатор может быть улучшен путем анализа в boost::string_view с использованием raw директивы.

Тем не менее, я испытываю трудности с его сборкой.
Вот что я узнал:

  • До x3нужно было специализироваться assign_to_attribute_from_iterators (см. например этот так ответ) чтобы справиться с raw директивы.

  • x3 теперь использует move_to вместо этого свободная функция (см., например, этот так ответ).

Поэтому я добавил move_to перегрузка, которая работает, если я анализирую с char*:

#include <iostream>
#include <string>

#include <boost/utility/string_view.hpp>

namespace boost {
namespace spirit { namespace x3 { namespace traits {

template <typename It>
void move_to(It b, It e, boost::string_view& v)
{
v = boost::string_view(b, std::size_t(std::distance(b,e)));
}

} } }

} // namespace boost

#include <boost/spirit/home/x3.hpp>

namespace parser
{
namespace x3 = boost::spirit::x3;
using x3::char_;
using x3::raw;

const auto str  = raw[ +~char_('_')] >> '_';
}

int main()
{
std::string input = "hello world_";

boost::string_view str;
parse(input.data(), input.data()+input.size(), parser::str, str);

std::cout << str;
}

живой пример

Тем не менее, это не компиляции:

1) Если я разбираю с помощью std::string::const_iterator

parse(input.cbegin(), input.cend(), parser::str, str);

Конструктор boost::string_view либо ожидает const char* или std::string&,

main.cpp:12:16: error: no matching function for call to 'boost::basic_string_view<char, std::char_traits<char> >::basic_string_view(__gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >&, std::size_t)'
v = boost::string_view(b, std::size_t(std::distance(b,e)));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

живой пример

Как я могу создать экземпляр boost::string_view от std::string::const_iterator?

2) Если boost/spirit/home/x3.hpp включен до move_to перегрузка

живой пример

Почему моя перегрузка не выбрана? Разве это не лучшая перегрузка, чем любая из тех, которые определены в boost/spirit/home/x3/support/traits/move_to.hpp?
Как я могу убедиться, что моя перегрузка выбрана независимо от порядка включения?

2

Решение

Я бы просто написал, что вы хотите:

v = boost::string_view(&*b, std::distance(b,e));

Возможно, вы захотите проверить, что хранилище является смежным — как проверка концепции для вашего входного диапазона. В этом отношении, возможно, было бы яснее также потребовать, чтобы итератор имел произвольный доступ, и записать:

v = boost::string_view(&*b, e-b);

Any это требование для string_view в любом случае

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]