
Andrew Troschinetz <ast <at> arlut.utexas.edu> writes:
On Feb 26, 2009, at 10:00 AM, Robert Ramey wrote:
The fact that the serialization of optional is implemented and tested as part of the serialization library is an anomoly. In fact, this code and test should be moved into the optional library.
Serialization and optional_io have different approaches. We refuse to read/write an uninitialized object while serialization encode whether an object is initialized or not.
But why move the get pointer up by one? Why one? Does this make sense? I can't provide a reasoning as to why it does, if it does.
Please don't guess about iostream implemenation details. All we need is a consistency with underlying type, that is, given T t = /* ...*/ ; optional<T> o(t); expressions below must exhibit a same runtime behavior: cout << t << '\n'; cout << o << '\n'; I have a sketch of new implementation: --- boost/optional/optional_io.hpp.orig 2009-03-02 17:53:09.000000000 +0900 +++ boost/optional/optional_io.hpp 2009-03-02 19:18:28.000000000 +0900 @@ -42,11 +42,18 @@ operator<<(std::basic_ostream<CharType, CharTrait>& out, optional<T> const& v) #endif { - if ( out.good() ) + if(v) + out << *v; + else { - if ( !v ) - out << "--" ; - else out << ' ' << *v ; + // Create a sentry for side effects (e.g. out.tie()->flush()) +#if defined (BOOST_NO_TEMPLATED_STREAMS) + std::ostream::sentry guard(out);; +#else + typename std::basic_ostream<CharType, CharTrait>::sentry guard(out); +#endif + if(guard) + out.setstate(std::ios_base::failbit); } return out; @@ -62,17 +69,18 @@ operator>>(std::basic_istream<CharType, CharTrait>& in, optional<T>& v) #endif { - if ( in.good() ) + if(!v) + v = T(); // TODO: what if it throws? + + try + { + if( !(in >> *v) ) + v = optional<T>(); + } + catch(std::ios_base::failure) { - int d = in.get(); - if ( d == ' ' ) - { - T x ; - in >> x; - v = x ; - } - else - v = optional<T>() ; + v = optional<T>(); + throw; } return in; Alex