Boost logo

Boost :

From: Neal Becker (ndbecker2_at_[hidden])
Date: 2005-08-26 16:32:51


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


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