Boost logo

Boost :

Subject: Re: [boost] [serialization] Proposal: make 'version' trait (and others) enable_if-friendly
From: Jeffrey Lee Hellrung, Jr. (jeffrey.hellrung_at_[hidden])
Date: 2012-12-05 22:34:00


On Wed, Dec 5, 2012 at 12:42 PM, Gabriel Redner <gredner_at_[hidden]> wrote:

> 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!
>

Sounds reasonable to me.

> 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
> ===================================================================
>
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
>

- Jeff


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