
From: "Hartmut Kaiser" <hartmut.kaiser@gmail.com>
1. Employ operator<< and operator>> for user-defined types.
Spirit supports that out of the box in two ways.
a) it has the 'stream' primitive utilizing the user type supplied operator>>() and operator<<() for parsing/generating. I.e.
user_type u; spirit::qi::parse(str, spirit::stream, u); spirit::karma::generate(std::back_inserter(str), spirit::stream, u);
Hartmut, 'parse' does str->user_type and 'generate' does user_type-
str, right?
Yep, exactly. And 'stream' is a placeholder.
Is it (the support for conversions and user types) anywhere in the documentation?
The documentation for Spirit 2 is still in the process of being written. Parts of it are in place, but not all of it. Joel and I are working on it to have it ready for BoostCon.
If it all that easy, I'll wrap it up into the API of my liking and we'll use it instead of lexical_cast. The whole 'convert' saga seems for nothing. Given how long this lexical_cast/convert discussion's been dragging on I feel you might spend some time educating more people (besides me) how to deploy Spirit for mundane taks like conversion. How do you handle failed conversion?
The functions qi::parse() and karma::generate() simply return a bool indicating success, the manipulators qi::match() and karma::format() integrate with the IO stream facilities (i.e. set the ios::bad flag or throw).
Where do I do to learn Spirit? The docs seem preoccupied with big stuff.
Did you look at the Spirit2 docs (http://www.boost.org/doc/libs/1_38_0/libs/spirit/doc/html/index.html)? I think they start slow, even if they do not explicitly cover conversion. A good source of information you will find by looking at the examples and tests in the repository.
[rant] As a side note I just love to see "spirit::qi::parse...spirit::stream" given some've could not stand my humble "convert::to" and "convert::from". I am sure they gonna love yours. LOL.
Understood. Spirits interface is not optimized for simplicity, though. It's meant to cover the whole thing (parsing/generation), so it's a bit too verbose for 'simple' conversion tasks. That's why I'm all in favor of having a simple interface. But, IMHO, such an interface needs to be downwards compatible just to avoid having two different DSEL for the same purpose in Boost. Any suggestion on that is highly welcome. It might just be that you need to allow Spirits placeholder types to be used for the convert<> function template parameters (in addition to the buildins like int, long, etc): For int's: convert<int>::to() convert<int>::from() which uses optimal conversion functions; and for user types (uses operator<<() and operator>>()): convert<spirit::tag::stream>::to() convert<spirit::tag::stream>::from() (spirit::stream is an instance of spirit::tag::stream). The idea would be to use Spirit directly if you need more powerful constructs like sequences and convert for conversion of single items. Regards Hartmut