How to change the default enums serialization in Boost.Serialization
Hi, By default in Boost.Serialization, enum types are serialized as a 32-bit integer. But I need to serialize some enum types as different width integer. I've tried to specialize the boost::serialization::serialize method, but it seems it doesn't work for enums. Here is my attempt: #include <iostream> #include <boost/archive/binary_oarchive.hpp> #include <boost/asio.hpp> enum MyEnum_t { HELLO, BYE }; namespace boost { namespace serialization { template< class Archive > void save(Archive & ar, const MyEnum_t & t, unsigned int version) { unsigned char c = (unsigned char) t; ar & c; } template< class Archive > void load(Archive & ar, MyEnum_t & t, unsigned int version) { unsigned char c; ar & c; t = (MyEnum_t) c; } } // namespace serialization } // namespace boost BOOST_SERIALIZATION_SPLIT_FREE(MyEnum_t) int main(int argc, const char *argv[]) { boost::asio::streambuf buf; boost::archive::binary_oarchive pboa(buf); buf.consume(buf.size()); // Ignore headers MyEnum_t me = HELLO; pboa << me; std::cout << buf.size() << std::endl; // buf.size() = 4, but I want 1 return 0; } Thanks in advance, Andrés -- Andrés Senac González andres@senac.es, andres.senac@um.es +(34) 627550280
Andrés Senac wrote:
Hi, By default in Boost.Serialization, enum types are serialized as a 32-bit integer. But I need to serialize some enum types as different width integer. I've tried to specialize the boost::serialization::serialize method, but it seems it doesn't work for enums. Here is my attempt:
#include <iostream> #include <boost/archive/binary_oarchive.hpp> #include <boost/asio.hpp>
enum MyEnum_t { HELLO, BYE };
namespace boost { namespace serialization { template< class Archive > void save(Archive & ar, const MyEnum_t & t, unsigned int version) { unsigned char c = (unsigned char) t; ar & c; } template< class Archive > void load(Archive & ar, MyEnum_t & t, unsigned int version) { unsigned char c; ar & c; t = (MyEnum_t) c; } } // namespace serialization } // namespace boost BOOST_SERIALIZATION_SPLIT_FREE(MyEnum_t)
int main(int argc, const char *argv[]) { boost::asio::streambuf buf; boost::archive::binary_oarchive pboa(buf); buf.consume(buf.size()); // Ignore headers MyEnum_t me = HELLO; pboa << me; std::cout << buf.size() << std::endl; // buf.size() = 4, but I want 1 return 0; }
Thanks in advance, Andrés
Consider making a wrapper for you enum - like this; struct enum_wrapper { unsigned char m_value; enum_wrapper(unsigned int value) : m_value(value) { assert(value <= 255); } template<class Archive> void save(Archive &ar, unsigned int version){ ar << m_value; } void load ... } then you can use .... enum { a b .. } e; ar & enum_wrapper(e); .. Robert Ramey
Thanks! Finally, I've made a wrapper as you suggest, but using different integer widths for different enum types, like this: template < typename T > struct enum_wrapper { T m_value; enum_wrapper(T t) : m_value(t) { } template < typename Archive > void serialize(Archive& ar, unsigned int version) { ar & m_value; } }; template < typename T > struct serialize_enum_as // redefined to use different integer types { typedef unsigned char type; }; template< typename Enum > enum_wrapper< typename serialize_enum_as< Enum >::type > create_wrapper(Enum e) { return enum_wrapper< typename serialize_enum_as< Enum >::type >(e); } .... ar & create_wrapper(e); Regards, Andrés 2011/10/4 Robert Ramey <ramey@rrsd.com>
** Andrés Senac wrote:
Hi, By default in Boost.Serialization, enum types are serialized as a 32-bit integer. But I need to serialize some enum types as different width integer. I've tried to specialize the boost::serialization::serialize method, but it seems it doesn't work for enums. Here is my attempt:
#include <iostream> #include <boost/archive/binary_oarchive.hpp> #include <boost/asio.hpp>
enum MyEnum_t { HELLO, BYE };
namespace boost { namespace serialization { template< class Archive > void save(Archive & ar, const MyEnum_t & t, unsigned int version) { unsigned char c = (unsigned char) t; ar & c; } template< class Archive > void load(Archive & ar, MyEnum_t & t, unsigned int version) { unsigned char c; ar & c; t = (MyEnum_t) c; } } // namespace serialization } // namespace boost BOOST_SERIALIZATION_SPLIT_FREE(MyEnum_t)
int main(int argc, const char *argv[]) { boost::asio::streambuf buf; boost::archive::binary_oarchive pboa(buf); buf.consume(buf.size()); // Ignore headers MyEnum_t me = HELLO; pboa << me; std::cout << buf.size() << std::endl; // buf.size() = 4, but I want 1 return 0; }
Thanks in advance, Andrés
Consider making a wrapper for you enum - like this;
struct enum_wrapper { unsigned char m_value; enum_wrapper(unsigned int value) : m_value(value) { assert(value <= 255); } template<class Archive> void save(Archive &ar, unsigned int version){ ar << m_value; } void load ... }
then you can use
.... enum { a b .. } e; ar & enum_wrapper(e); ..
Robert Ramey
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
-- Andrés Senac González andres@senac.es, andres.senac@um.es +(34) 627550280
participants (2)
-
Andrés Senac
-
Robert Ramey