Boost logo

Boost :

Subject: Re: [boost] [serialization] Custom archive and arrays
From: Seth (bugs_at_[hidden])
Date: 2016-01-22 18:43:00


On 22-01-16 20:50, Robert Ramey wrote:
> On 1/22/16 9:55 AM, Bjorn Reese wrote:
>> On 01/22/2016 05:54 PM, Robert Ramey wrote:
>
>> My concern is more that Boost.Serialization imposes a serialization
>> sequence that is invalid for certain encoding formats. This means that
>> we have to by-pass Boost.Serialization for the serialization of arrays.
>
> Hmmm - try thinking of the serialization library in a slightly
> different way. Think of it as a framework for implementation of
> serialization for other types. Then consider the specific types
> included in the library as "examples" of how to use the library.
> Think of overloading as "customization points".

In that vein, how do you like a "decorating" wrapper that allows you to
override default behaviour:

#include <iostream>
#include <boost/serialization/tracking.hpp>
#include <boost/serialization/wrapper.hpp>

namespace mylib {
    template <typename T> using custom_wrapper_traits =
boost::serialization::wrapper_traits<T,
            boost::serialization::level_type::not_serializable,
            boost::serialization::track_never,
            0,
            boost::serialization::extended_type_info_impl<void> // T
>;

    // primary template transparent relay to underlying type
    template <typename T> struct custom_serialize_wrapper :
custom_wrapper_traits<custom_serialize_wrapper<T> > {
        T &_ref;
        custom_serialize_wrapper(T& ref) : _ref(ref) {}
        template <typename Ar> void serialize(Ar &ar, unsigned) { ar
&_ref; }
    };

    // specialization array references
    template <typename T, size_t N> struct
custom_serialize_wrapper<T[N]> :
custom_wrapper_traits<custom_serialize_wrapper<T[N]> > {
        T(&_ref)[N];
        custom_serialize_wrapper(T (&ref)[N]) : _ref(ref) {}
        template <typename Ar> void serialize(Ar &ar, unsigned) {
            for (auto &el : _ref) ar &el;
        }
    };

    template <typename T> custom_serialize_wrapper<T> make_custom(T
&ref) { return { ref }; }
}

#include <boost/serialization/serialization.hpp>
#include <boost/archive/text_oarchive.hpp>

struct X {
    int m;
    template <typename Ar> void serialize(Ar &ar, unsigned) { ar &m; }
};

int main() {
    auto const flags = boost::archive::archive_flags::no_header;

    X arr[10] = { X{42}, X{43}, X{44}, X{45}, X{46}, X{47}, X{48},
X{49}, X{50}, X{51}, };

    {
        // BAD: prefixes length:
        boost::archive::text_oarchive oa(std::cout, flags);
        oa & arr;
    }

    {
        // this is the behaviour wanted:
        boost::archive::text_oarchive oa(std::cout, flags);
        oa & arr[0] & arr[1] & arr[2] & arr[3] & arr[4] & arr[5] &
arr[6] & arr[7] & arr[8] & arr[9];
    }

    {
        // same behaviour with custom_wrapper:
        boost::archive::text_oarchive oa(std::cout, flags);
        oa & mylib::make_custom(arr); // wrapped
    }
}

See it Live On Coliru <http://coliru.stacked-crooked.com/a/5f2cc73ed973c5c8>

Output

    10 0 0 42 43 44 45 46 47 48 49 50 51

    0 0 42 43 44 45 46 47 48 49 50 51

    0 0 42 43 44 45 46 47 48 49 50 51

Seth


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