
Basically, this looks OK to me as well. I would like to see it made more automatic and more inline with what other serializations uses. On one level, this is merely a cosmetic issue. On the other level, its about leverage of user interface patterns. Ideally, I would like to see usage something as simple as: Struct X { variant<int, char, unsigned long> x template<class Archive, class T> void serialize(Archive &ar, T& t, unsigned int version){ ar & x; } }; A couple of questions though a) would it not be interesting for variant to return an integer corresponding to is current type? unsigned variant::get_type_index(); b) and the reverse variant::set_type_index(unsigned int ti); // of course this destroys any variable stored therein I would hope this might be implementable. My experience with mpl suggests that it might be. In this case the serialization would be a dream come true. so we could something like: template<class Archive, class T> void save(Archive &ar, const T & v){ usigned int ti = x.get_type_index(); ar << ti apply_visitor( bind( variant_saver(), ref(ar), _1 ), v ); } template<class Archive, class T> void load(Archive &ar, T & v, unsigned int version){ unsigned int ti; ar >> ti; v.set_type_index(ti); apply_visitor( bind( variant_loader(), ref(ar), _1 ), v ); } This would be an example were the type interface can be expanded to better support any serialization implementation without compromising the original design. Just a thought. Robert Ramey "Peter Dimov" <pdimov@mmltd.net> wrote in message news:004401c4d0ad$24160900$6501a8c0@pdimov2...
Richard Peters wrote:
Hello,
I'm looking for a way to serialize a variant. I see two possibly difficult things that I don't know how to accomplish: 1) In order to be able to retrieve a variant from an archive, the type of the value held by the variant must be stored. 2) When retrieving the data from an archive, once the type is read, a value of that type must be extracted from the archive and assigned to the variant. Has anybody tried this before, is this as difficult as it looks? Any help would be greatly appreciated.
I would expect the external representation of a variant<T1, ..., Tn> to be:
int index; Ti ti;
where index denotes the type and is returned by varant<>::which().
Assuming a variant<int, string> for simplicity, the save pseudocode should be something like:
int index = v.which(); ar << v;
switch( v ) { case 0: ar << get<int>( v ); break; case 1: ar << get<string>( v ); break; }
You can rewrite it generically in terms of apply_visitor:
struct variant_saver { typedef void result_type;
template<class A, class T> void operator( A & a, T const & t ) const { a << t; } };
apply_visitor( bind( variant_saver(), ref(ar), _1 ), v );
Disclaimer: I haven't compiled any of this. ;-)
Loading should be the reverse operation:
int index; ar >> index;
switch( index ) { case 0: { int t; ar << t; v = t; break; } case 1: { string t; ar << t; v = t; break; } }
This, of course, belongs in variant.hpp. Don't let our shared_ptr debates fool you. :-)
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost