Programmer. (Many Interests: Philosophy & Mathematics)

Home

Boost Versioning Trick

Don’t worry if you don’t understand this post, we will go through entire boost serialization and versioning library with an example in a later post but this is for some of you who already are using it but are constrained by the nasty little assert in the BOOST_CLASS_VERSION macro that has been preventing you from going beyond version #256.

BOOST_CLASS_VERSION Macro Implementation in version.hpp.

    // specify the current version number for the class
    // version numbers limited to 8 bits !!!
    #define BOOST_CLASS_VERSION(T, N)                             \
    namespace boost {                                             \
    namespace serialization {                                     \
    template<>                                                    \
    struct version<T >                                            \
    {                                                             \
        typedef mpl::int_<N> type;                                \
        typedef mpl::integral_c_tag tag;                          \
        BOOST_STATIC_CONSTANT(int, value = version::type::value); \
        // CULPRIT ALERT !                                        \
        BOOST_MPL_ASSERT((                                        \
            boost::mpl::less<                                     \          
                boost::mpl::int_<N>,                              \         
                boost::mpl::int_<256>                             \         
                                                                  \         
        ));                                                       \         
    };                                                            \         
    }                                                             \         
    }

What is happening here ?

Apparently, whenever you specify **BOOST_CLASS_VERSION(ClassName, Version)** , all that happens is that a full specialization of the version class template is created for the class you mention in **BOOST_CLASS_VERSION** and the version is set through **BOOST_STATIC_CONSTANT** , yeah I know right, such a nifty way to avoid manually specializing for each class but that is not our problem here, our problem is that we don’t want restrictions on the number of versions we can have. The feature of restricting the user to **256 versions** is supposed to be a good practice measure taken by the creators of the library but what if you are like me and you have a mechanism of versioning which exceeds 256. All you’ve got to do is change the limit imposed in the assert statement and it is as simple as that.

    #define MAX_VERSION 10000
    namespace boost {                                            
    namespace serialization {                                     
    template<>                                                    
    struct version<T >                                            
    {                                                             
        typedef mpl::int_<N> type;                                
        typedef mpl::integral_c_tag tag;                          
        BOOST_STATIC_CONSTANT(int, value = version::type::value);                                      
        BOOST_MPL_ASSERT((                                        
            boost::mpl::less<                                               
                boost::mpl::int_<N>,                                       
                boost::mpl::int_<MAX_VERSION>                                 
                                                                         
        ));                                                              
    };                                                                   
    }                                                                    
    }

Ah ! Yeah I understand, you don’t want to specialize this ugly looking code for each class or… do you ? Just add a custom macro like the one boost does and change the assert. Simple ! isn’t it.

#define MAX_VERSION 10000

    #define TOAST_CLASS_VERSION(T, N)                             \
    namespace boost {                                             \
    namespace serialization {                                     \
    template<>                                                    \
    struct version<T >                                            \
    {                                                             \
        typedef mpl::int_<N> type;                                \
        typedef mpl::integral_c_tag tag;                          \
        BOOST_STATIC_CONSTANT(int, value = version::type::value); \
        BOOST_MPL_ASSERT((                                        \
            boost::mpl::less<                                     \          
                boost::mpl::int_<N>,                              \         
                boost::mpl::int_<MAX_VERSION>                     \         
                                                                  \         
        ));                                                       \         
    };                                                            \         
    }                                                             \         
    }

Note: You could remove the assert if you didn’t want want any hard upper limit on the version but since the version is an integral type, there is still an implicit upper limit of INT_MAX and if you exceed that there may be undefined behaviors.

There you go. Happy versioning :p