Boost logo

Boost :

Subject: [boost] [serialization] Proposal: make 'version' trait (and others) enable_if-friendly
From: Gabriel Redner (gredner_at_[hidden])
Date: 2012-12-05 15:42:37


I have recently run up against a limitation of the serialization
library in terms of specializing the 'version' trait. Fortunately, I
believe the issue has a simple workaround which I don't believe will
break existing code.

In general, one can change the version of a serialized class by
specializing the 'version' template class:
==============================
template <typename T>
struct version
{
    BOOST_STATIC_CONSTANT(unsigned int, value = 0);
};
...
template <>
struct version<MyType>
{
    BOOST_STATIC_CONSTANT(unsigned int, value = 1);
};
==============================

However, this approach does not work if 'MyType' is of the form (see [1]):
==============================
template <typename T>
struct Foo
{
  struct MyType
  {
    int data1;
  };
};

template <typename T>
struct version<Foo<T>::MyType> // ERROR
{
    BOOST_STATIC_CONSTANT(unsigned int, value = 1);
};
==============================
It's not possible for the compiler to deduce the enclosing type, so
this doesn't work.

However, if MyType can be identified by a metafunction, then I can use
enable_if to select the specialization of 'version' that I want.
However, this requires support from 'version' itself:
==============================
template <typename T, typename Enable = void> // NOTE new template parameter
struct version
{
    BOOST_STATIC_CONSTANT(unsigned int, value = 0);
};
...
template <typaneme T>
struct version<MyType, typename boost::enable_if<is_mytype<T> >::type>
{
    BOOST_STATIC_CONSTANT(unsigned int, value = 1);
};
==============================

So, my proposal is simply to add this extra template parameter to
'version'. I do not believe other uses of 'version' will be affected,
but it would not surprise me if I've overlooked something. Presumably
the same modification could be made to implementation_level etc.

A patch (for 'version' only) against trunk is enclosed below.
Comments are welcome!

Thanks,
-Gabe

[1] http://boost.2283326.n4.nabble.com/serialization-versioning-for-class-nested-within-template-class-td4639380.html

===================================================================
--- version.hpp (revision 81723)
+++ version.hpp (working copy)
@@ -32,7 +32,7 @@

 // default version number is 0. Override with higher version
 // when class definition changes.
-template<class T>
+template<class T, class Enable=void>
 struct version
 {
     template<class U>
@@ -53,8 +53,8 @@
 };

 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
-template<class T>
-const int version<T>::value;
+template<class T, class Enable>
+const int version<T, Enable>::value;
 #endif

 } // namespace serialization
===================================================================


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk