|
Boost Users : |
Subject: Re: [Boost-users] boost serialization stream error question
From: Robert Ramey (ramey_at_[hidden])
Date: 2010-01-31 12:31:24
Gabe Sibley wrote:
> Dear All,
>
> I'm using boost serialization and have come across issues with "steam
> error" when I try to deseriailze from an xml or text archive.
> Binary archives are fine, but I can't use binary because my users
> need xml archives.
>
> The problem is caused by double values less than DBL_MIN.
> Apparently, streaming such values in causes the input stream fail_bit
> to be set, which causes the serialization lib to throw an exception.
>
> One work around is to make sure all double values are clamped and
> finite when the archive is created. I can live with this, esp.
> since I have algorithms that will from time to time produce
> non-finite results.
>
> So far what I've done is just replace BOOST_SERIALIZATION_NVP macro
> with the following MAKE_NVP macro that calls "FixReal":
>
>
> #define BOOST_SERIALIZATION_NVP(name) \
> boost::serialization::make_nvp(BOOST_PP_STRINGIZE(name), name )
>
>
>
> // Use this macro instead of BOOST_SERIALIZATION_NVP because it fixes
> doubles that are not streamable.
> // That is, it fixes double values that cause streaming errors.
> #define MAKE_NVP(name) \
> boost::serialization::make_nvp(BOOST_PP_STRINGIZE(name),
> FixReal(name) ) // note the call to FixReal
>
> // does nothing -- just pass all non-double types through
> template<class T> inline T& FixReal( T& t ) { return t; }
>
> /// Routine to make sure doubles are streamable -- Nan, Inf, etc.
> cause stream errors, so we prevent them.
> inline double& FixReal( double& d )
> {
> if( d < DBL_MIN ) {
> d = DBL_MIN;
> }
> if( d > DBL_MAX ) {
> d = DBL_MAX;
> }
> if( std::isnan(d) ) {
> d = 0;
> }
> if( std::isinf(d) ){
> d = DBL_MAX;
> }
> return d;
> }
>
> /// We also need to fix double arrays. The ugly syntax is because
> // we have to pass and return a reference to an array.
> inline double (&FixReal( double (&d)[2] ))[2]
> {
> for( size_t ii = 0; ii < 2; ii++ ){
> FixReal(d[ii]);
> }
> return d;
> }
>
>
> Ok, here's my question: How can I get the "FixReal" functionality
> above without having to write a specialized function for every
> possible double signature?
>
> For instance, I don't want to have to write
>
> inline double (&FixReal( double (&d)[3] ))[3]
> inline double (&FixReal( double (&d)[4] ))[4]
> ...
> etc.
>
> or any of the other POD double signatures possible.
>
> I just want the serialization library to fix the errant double values
> when I create the archive.
>
> I guess I could modify the "void save(const double t)" function in
> basic_text_oprimitive.hpp to check all doubles, but that seems like a
> bad plan.
>
> Any suggestions?
>
>
> thanks for your help,
> Gabe
>
>
>
>
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net