I need to deserialize a std::vector<boost::variant<..>>
with decoration supplied by other objects.
One of the things the "decoration" enables is a empty entry in the vector. I have hit a brick wall in my real implementation. However, I have managed to shrink wrap it. 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);
}
The offending changes, which attempt to implement a "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 out the karma::generate
step, std::cout
is a valid expression (Boost::variant OutputStreamable
). Spirit requires that generators be given types which are OutputStreamable
(spirit::karma OutputStreamable
) and the variant above should be OutputStreamable
since I have made the undefined
typeOutputStreamable
as a no-op.
What gives ? :(
I'm really beginning to question weather the C++ template mechanism is worth it when using libraries with > 2 levels of template indirection. Perhaps I should go back to straight-c.
Edit 1:
Ok, Clang gave me a sensible first
error...
error: no type named 'properties' in 'boost::spirit::karma::no_auto_mapping_exists'
Now I got to figure out how to map undefined as a no-op to get a clean conversion. This spirit documentation entry (and this in specific) describes what I need to look into. Is there a generic undefined type provided by spirit or one defined in boost, that spirit already maps as a no-op ?
Edit 2:
std::vector<boost::optional<boost::variant<..>>>
is beginning to look quite appealing since spirit provides type-deduction for them.