Boost has a library named Spirit that makes heavy use of TMP in order to facilitate the easy creation of parsers in a BNF like syntax. By default it is intended to work with standard library strings. I'm using it in a Qt based project, where QString
is the primary string type. How can I use boost::spirit
with QString
s?
There are two parts to making boost::spirit
and QString
cooperate; getting data in and getting data out. We'll start with the latter. As far as boost::spirit
is concerned, QString
is an unknown type. We must give it a few container traits so that it knows how to interact:
#include <boost/spirit/home/x3/support/traits/container_traits.hpp>
#include <QString>
namespace boost { namespace spirit { namespace x3 { namespace traits {
template<>
struct push_back_container<QString>
{
template<typename T>
static bool call(QString& c, T&& val)
{
c.push_back(std::move(val));
return true;
}
};
template<>
struct append_container<QString>
{
template<typename Iterator>
static bool call(QString& c, Iterator first, Iterator last)
{
c.append(first, std::distance(first, last));
return true;
}
};
template<>
struct is_empty_container<QString>
{
static bool call(QString const& c)
{
return c.isEmpty();
}
};
}}}}
Depending on your particular use case, you may also want to parse from QString
s. There is probably a way to teach boost::spirit
about QChar
(the iterable type of QString
), but I don't have the patience for that. The alternative is to create an iterator_adaptor
whose value type is uint32_t
, which is the type boost::spirit
uses to represent unicode values. Note you'll need to turn unicode support on ( #define BOOST_SPIRIT_X3_UNICODE
).
#include <boost/iterator/iterator_adaptor.hpp>
#include <QString>
template<typename QStringIterator>
class QStringSpiritUnicodeIteratorAdaptor : public boost::iterator_adaptor<
QStringSpiritUnicodeIteratorAdaptor<QStringIterator>,
QStringIterator, uint32_t, boost::forward_traversal_tag, uint32_t>
{
public:
using boost::iterator_adaptor<
QStringSpiritUnicodeIteratorAdaptor<QStringIterator>,
QStringIterator, uint32_t, boost::forward_traversal_tag,
uint32_t>::iterator_adaptor;
private:
friend class boost::iterator_core_access;
uint32_t dereference() const
{
return static_cast<uint32_t>(this->base_reference()->unicode());
}
};
using QStringSpiritUnicodeIterator =
QStringSpiritUnicodeIteratorAdaptor<QString::iterator>;
using QStringSpiritUnicodeConstIterator =
QStringSpiritUnicodeIteratorAdaptor<QString::const_iterator>;
This is used as follows:
QString text = "blah blah blah";
QStringSpiritUnicodeIterator begin(text.begin());
QStringSpiritUnicodeIterator end(text.end());
...::x3::phrase_parse(begin, end, ...);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.