766cc4c9b7
The concept of ForwardIterator is flawed because it mixed 2 sets of concepts (value access and traversal) into 1 package. http://www.boost.org/doc/libs/1_65_1/libs/iterator/doc/new-iter-concepts.html It requires value_type (const)& as return type when dereference is applied, which is not mandatory in spirit parsing. A return type which is convertible to value_type is good enough. ReadableIteratorConcept and ForwardTraversalConcept should be what we need for the iterator check. For example, the iterator of the range returned by boost::adaptors::transform(std::string, func) is normally not a ForwardIterator. But it fulfills ReadableIteratorConcept and ForwardTraversalConcept and should be able to be parsed by spirit.
53 lines
1.7 KiB
C++
53 lines
1.7 KiB
C++
/*=============================================================================
|
|
Copyright (c) 2001-2017 Joel de Guzman
|
|
Copyright (c) 2017 think-cell GmbH
|
|
|
|
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
=============================================================================*/
|
|
#include <boost/detail/lightweight_test.hpp>
|
|
#include <boost/spirit/home/qi.hpp>
|
|
#include <boost/range/adaptor/transformed.hpp>
|
|
|
|
#include <iostream>
|
|
#include <string>
|
|
#include <functional>
|
|
|
|
namespace {
|
|
char transform_func(char c) {
|
|
return c < 'a' || 'z' < c ? c : static_cast<char>(c - 'a' + 'A');
|
|
}
|
|
}
|
|
|
|
int main()
|
|
{
|
|
using boost::adaptors::transform;
|
|
using boost::spirit::qi::raw;
|
|
using boost::spirit::qi::eps;
|
|
using boost::spirit::qi::eoi;
|
|
using boost::spirit::qi::upper;
|
|
using boost::spirit::qi::repeat;
|
|
using boost::spirit::qi::parse;
|
|
|
|
std::string input = "abcde";
|
|
boost::transformed_range<char(*)(char), std::string> const rng = transform(input, transform_func);
|
|
|
|
{
|
|
std::string str;
|
|
BOOST_TEST((parse(boost::begin(rng), boost::end(rng), +upper >> eoi, str)));
|
|
BOOST_TEST(("ABCDE"==str));
|
|
}
|
|
|
|
{
|
|
boost::iterator_range<boost::range_iterator<boost::transformed_range<char(*)(char), std::string> const>::type> str;
|
|
BOOST_TEST((parse(boost::begin(rng), boost::end(rng), raw[+upper >> eoi], str)));
|
|
BOOST_TEST((boost::equal(std::string("ABCDE"), str)));
|
|
}
|
|
|
|
{
|
|
BOOST_TEST((parse(boost::begin(rng), boost::end(rng), (repeat(6)[upper] | repeat(5)[upper]) >> eoi)));
|
|
}
|
|
|
|
return boost::report_errors();
|
|
}
|