Boost logo

Boost :

From: Preston A. Elder (prez_at_[hidden])
Date: 2005-01-30 03:24:16


On Sun, 30 Jan 2005 10:01:06 +0200, Yuval Ronen wrote:

> BTW, I've thought of the following (rare) scenario:
You put your finger on it, 'rare'.

Besides, whats to stop them doing 'ss.unsetf(skipws)' in their operator>>.
If memory serves the white space skipping isn't done until something is
actually going to be pulled off the rdbuf anyway (I could be wrong, of
course). If this is the case, they would have:

std::istream operator>>(std::istream &is, my_class &c)
{
  flags = is.flags();
  is.flags(flags &= ~skipws);
  is >> c.field1 >> c.field2 >> c.field3;
  is.flags(flags);
  return is;
}

Of course, if I'm wrong about the whitespace being skipped only at the
point where something is pulled off the buffer, then this won't work, and
we're back to the other suggestion I had.

My point is though, if you're going to use operator<< and operator>> with
istream/ostream in a manner that is not default, then you should
accomodate for the method you're breaking the defaults yourself in your
operator<< and operator>> - as opposed to forcing everyone ELSE who uses
operator<< and operator>> to ensure they get things in the default manner
(which often the client programmer can't do if they didn't write the
original code).

> Unfortunately, it's not that easy. calling lexical_cast<T, noskipws>
> according to your second proposal, will make it not ignore leading
> whitespace, but it will still ignore trailing whitespace. Ignoring/not
> ignoring trailing whitespace requires some additional code other than
> setting ios_base flags.
>
> I'm not saying it's not possible, just that it's not that easy :-(

not so.

Right now, trailing white space is skipped only because we actually have
this code:

T result;
ss >> result >> std::ws;
if (!ss.eof())
    throw bad_lexical_cast;

We should just take out the '>> std::ws' as well. Which should then not
skip trailing white space on noskipws, and if memory serves, will do so if
skipws is on. Even if it doesn't, its a simple matter of:

T result;
ss >> result;
if (ss.flags() & skipws)
    ss >> std::ws;
if (!ss.eof())
    throw bad_lexical_cast;

This handles what we want beautifully. If skipws is on, then white space
at the beginning and end are skipped, AND white space between values
(remember the original string "4 5"). If skipws is off, then no white
space is skipped anywhere, and if you have leading or trailing white
space, you'd better handle it, or the eof() check will fail.

Don't fall into the trap of over-engineering the problem :)

-- 
PreZ :)
Founder. The Neuromancy Society (http://www.neuromancy.net)

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