Search code examples
c++boostboost-spirit-qi

qi::parse boost change begin iterator


Do function below change iterator which first point to s.begin() and after point to s.begin() + 1? I'm right?

#include <boost/spirit/include/qi.hpp>
#include <string>
#include <iostream>

using namespace boost::spirit;

int main()
{
    std::string s;
    std::getline(std::cin, s);
    auto it = s.begin();
    bool match = qi::parse(it, s.end(), ascii::digit);
    std::cout << std::boolalpha << match << '\n';
    if (it != s.end())
        std::cout << std::string{ it, s.end() } << '\n';
}

INPUT:

1Kar

OUTPUT:

Kar


Solution

  • Yes, you're right if the parser(the expr parameter below) succeeds. This is what happens with the input 1Kar. You're using the following:

    //boost/spirit/home/qi/parse.hpp
    template <typename Iterator, typename Expr>
    inline bool
    parse(Iterator& first, Iterator last, Expr const& expr);
    

    Reference: Iterator Based Parser API.

    The first iterator is passed by a lvalue reference and on a successful parse it is repositioned to the rightmost position consumed by the parser. The iterator is moved if none of the parse components have been failed, for example:

    //Input: 1Kar
    qi::parse(it, s.end(), ascii::digit >> ascii::digit); //Fail
    assert(it == s.begin());
    
    //Input: 1Kar
    qi::parse(it, s.end(), ascii::digit); //Ok
    assert(it == std::next(s.begin()));