is input_stream >> std::ws supposed to set fail() bit?

L

levent

Hi All,

Consider the following block of code:

std::istringstream in( "1" ); // no space after `1'
int i;
in >> i >> std::ws;
assert( !in::fail() )

Does the standard have any mention whether assertion fails or not?
Note that, with gcc and msvc assertion doesn't fail, but there is
compiler which it does (portland group C++) .

thanks many
slyi
 
J

James Kanze

Consider the following block of code:
std::istringstream in( "1" ); // no space after `1'
int i;
in >> i >> std::ws;
assert( !in::fail() )
Does the standard have any mention whether assertion fails or not?

I may not fail. The read of i succeeds, and manipulators never
set failbit.
Note that, with gcc and msvc assertion doesn't fail, but there is
compiler which it does (portland group C++) .

The STL port (at least the version which comes with Sun CC) has
the same bug. If you have to be portable to such an
implementation, just write your own, and use it:

std::istream&
ws( std::istream& source )
{
if ( source.good() ) {
std::ctype< char > const&
ctype = getFacet( source.getloc() ) ;
std::streambuf* sb = source.rdbuf() ;
int c = sb->sgetc() ;
while ( c != EOF
&& ctype.is( std::ctype_base::space,
static_cast< char >( c ) ) ) {
c = sb->snextc() ;
}
if ( c == EOF ) {
source.setstate( std::ios::eofbit ) ;
}
}
return source ;
}

Obviously, this is in my own namespace, so I write Gabi::ws,
rather than std::ws. And while it's not a template in my case
(I don't use anything but the char based streams), it wouldn't
be too hard to make it one.

Also, Gabi::getFacet is used, rather than std::use_facet, as a
work-around to problems in the default Sun CC library:

namespace GetFacetPrivate {

class FacetGetter ;
class FacetAddress
{
friend class FacetGetter ;
public:
template< typename Facet >
operator Facet const*() const
{
return &static_cast< Facet const& >( *myOwner ) ;
}

private: // Except for FacetGetter...
explicit FacetAddress( FacetGetter const* owner )
: myOwner( owner )
{
}

private: // Really...
FacetGetter const* myOwner ;
} ;

class FacetGetter
{
public:
explicit FacetGetter( std::locale const& locale )
: myLocale( &locale )
{
}

FacetAddress operator&() const
{
return FacetAddress( this ) ;
}

operator FacetGetter const&() const
{
return *this ;
}

template< typename Facet >
operator Facet const&() const
{
return get( *myLocale, &std::use_facet< Facet > ) ;
}

private:
std::locale const* myLocale ;

template< typename Facet >
Facet const& get( std::locale const& locale,
Facet const& (*f)( std::locale
const& ) ) const
{
return (*f)( locale ) ;
}

template< typename Facet >
Facet const& get( std::locale const& locale,
Facet const& (*f)( std::locale
const&,
Facet* ) ) const
{
return (*f)( locale, NULL ) ;
}
} ;
}

inline GetFacetPrivate::FacetGetter
getFacet(
std::locale const& locale )
{
return GetFacetPrivate::FacetGetter( locale ) ;
}

As written, it has the added advantage of not requiring you to
specify the type if it is being used to directly initialize a
reference (which is almost always the case).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,201
Messages
2,571,048
Members
47,649
Latest member
MargaretCo

Latest Threads

Top