Boost-spirit-karma and advanced "concept" related to auto generators
I need to deserialize std::vector<boost::variant<..>> with the decoration supplied by other objects.
One of the things that “embellishment” includes is a blank entry in the vector. I hit a brick wall in my real implementation. However, I managed to collapse it. The code that compiles:
#include <string> #include <boost/spirit/include/karma.hpp> #include <boost/variant.hpp> #include <boost/cstdint.hpp> namespace karma = boost::spirit::karma; typedef boost::variant<boost::int32_t, boost::int64_t> custom_variant; int main() { using karma::generate; custom_variant v; std::string temp; std::back_insert_iterator<std::string> x(temp); std::cout << v; karma::generate(x, karma::auto_, v); } Breaking changes that attempt to implement the "undefined" type along with the required concept.
#include <string> #include <boost/spirit/include/karma.hpp> #include <boost/variant.hpp> #include <boost/cstdint.hpp> namespace karma = boost::spirit::karma; struct undefined{}; std::ostream & operator<<(std::ostream & out, undefined const & undefined) { return out; } typedef boost::variant<undefined,boost::int32_t, boost::int64_t> custom_variant; int main() { using karma::generate; custom_variant v; std::string temp; std::back_insert_iterator<std::string> x(temp); std::cout << v; karma::generate(x, karma::auto_, v); } If I comment on the karma::generate step, std::cout is a valid expression (Boost :: variant OutputStreamable ). The spirit requires that the generators are set to OutputStreamable (spirit :: karma OutputStreamable ) OutputStreamable , and the option above should be OutputStreamable , since I made the type undefined OutputStreamable as no-op.
What gives?: (
I am really starting to doubt that the C ++ template engine is worth using the s> 2 libraries with levels of template access. Perhaps I should return to the straight path.
Change 1:
Ok, Klang gave me a reasonable mistake first ...
error: no type named 'properties' in 'boost::spirit::karma::no_auto_mapping_exists'
Now I need to figure out how to match undefined as no-op to get a pure conversion. This record of spirit documentation (and this in particular) describes what I need to look into. Is there a generic undefined type provided by the spirit or one defined in boost, this spirit is already displayed as no-op?
Edit 2:
std::vector<boost::optional<boost::variant<..>>> starts to look pretty attractive, because the spirit provides a deduction type for them.
I would suggest using spirit::unused_type for this purpose, since it is already “known” for Spirit and has a predefined operator<<() (but any other type will do) - not that you really need this operator for Karma in the first turn.
In addition, you need to provide the create_generator specialization (as you suspected):
namespace boost { namespace spirit { namespace traits { template <> struct create_generator<spirit::unused_type> { typedef spirit::karma::eps_type type; static type call() { return spirit::karma::eps; } }; }}} which will display unused_type in karma::eps . This seems to be exactly what you need, since eps eats the attribute without generating anything, it always does. If you go this route, you will not need to use optional<> .