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@lists.boost.org
> http://lists.boost.org/mailman/listinfo.cgi/boost-users