
Robert Ramey wrote:
Neal Becker wrote:
Robert Ramey wrote:
A couple of questions/observations:
a) ...
template<typename Archive, typename T> inline void save (Archive &ar, const std::complex<T>& z, const unsigned int) { ar << real (z); ar << imag (z); }
I presume that real imag return either primitives(float or double) or references to these. So that tracking would not be an issue.
template<typename Archive, typename T> inline void load (Archive &ar, std::complex<T>& z, const unsigned int) { T i, r; ar >> r; ar >> i; z = std::complex<T> (r, i); }
Hmm, loading to a temporary and then moving to a final destination could create an issue with tracking. There are a couple of possibilities:
* if real/imag return references, then reformulate the above to: ar >> real(z); ar >> imag(z); since this is now symetric with the save one could avoid the split entirely and simplify it even more.
* use reset_object_address
You and I both wish real() and imag() returned a ref!!! But they don't.
So I have: template<typename Archive, typename T> inline void load (Archive &ar, std::complex<T>& z, const unsigned int) { T i, r; ar >> boost::serialization::make_nvp ("real", r); ar >> boost::serialization::make_nvp ("imag", i); z = std::complex<T> (r, i); }
Now how can I use reset_object_address, now that the the addresses of the real and imag pieces of the constructed object are no longer accessable?
Looking at this more carefully, and realizine that real and imag return values rather than references, I think I gave the wrong answer.
inline void load (Archive &ar, std::complex<T>& z, const unsigned int) { T i, r; ar >> boost::serialization::make_nvp ("real", r); ar >> boost::serialization::make_nvp ("imag", i); z = std::complex<T> (r, i); }
I think the above will work just fine. The address being tracked is that of z so I expect that this will work exactly as one would expect. The saving would be exactly as you had it before.
The only remaining question is what serialization traits - if any - should be assigned to std::complex<T>. Tracked/non-tracked. implementation level - primitive, object, with class-id, etc. My guess would be
non-tracked primitive
Thanks. I believe I have this OK now, but it was _much_ harder than it should have been, because the only documentation is wrong. I tried to follow the example here: http://boost.org/libs/serialization/doc/traits.html#templates But it looks like the correct implementation is this: namespace boost { namespace serialization { template<class T> struct implementation_level<std::complex<T> > { // typedef mpl::int_<object_serializable> type; typedef mpl::integral_c_tag tag; typedef mpl::int_<primitive_type> type; BOOST_STATIC_CONSTANT( int, value = implementation_level::type::value ); }; // // nvp objects are generally created on the stack and are never tracked template<class T> struct tracking_level<std::complex<T> > { typedef mpl::integral_c_tag tag; typedef mpl::int_<track_never> type; BOOST_STATIC_CONSTANT( int, value = tracking_level::type::value ); BOOST_STATIC_ASSERT(( mpl::greater< /* that is a prmitive */ implementation_level< T >, mpl::int_<primitive_type> >::value )); }; } } This is what I found in level.hpp and tracking.hpp