// Boost ios_state_unit_test.cpp test file ---------------------------------// // Copyright 2003 Daryle Walker. Use, modification, and distribution are // subject to the Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or a copy at .) // Copyright 2019 Glen Joseph Fernandes // (glenjofe@gmail.com) // See for the library's home page. // Revision History // 12 Sep 2003 Initial version (Daryle Walker) #include #include // for boost::io::ios_flags_saver, etc. #include #include // for NULL #include // for std::setiosflags, etc. #include // for std::ios_base #include // for std::cout, std::cerr, etc. #include // for std::iostream #include // for std::locale, std::numpunct #include // for std::stringstream, etc. #if defined(BOOST_GCC) || (defined(BOOST_CLANG) && defined(BOOST_GNU_STDLIB)) #include #endif // Global constants int const word_index = std::ios_base::xalloc(); // Facet with the (classic) bool names spelled backwards class backward_bool_names : public std::numpunct { typedef std::numpunct base_type; public: explicit backward_bool_names( std::size_t refs = 0 ) : base_type( refs ) {} protected: virtual ~backward_bool_names() {} virtual base_type::string_type do_truename() const { return "eurt"; } virtual base_type::string_type do_falsename() const { return "eslaf"; } }; // Unit test for format-flag saving void ios_flags_saver_unit_test ( ) { using namespace std; stringstream ss; BOOST_TEST_EQ( (ios_base::skipws | ios_base::dec), ss.flags() ); { boost::io::ios_flags_saver ifs( ss ); BOOST_TEST_EQ( (ios_base::skipws | ios_base::dec), ss.flags() ); ss << noskipws << fixed << boolalpha; BOOST_TEST_EQ( (ios_base::boolalpha | ios_base::dec | ios_base::fixed), ss.flags() ); } BOOST_TEST_EQ( (ios_base::skipws | ios_base::dec), ss.flags() ); { boost::io::ios_flags_saver ifs( ss, (ios_base::showbase | ios_base::internal) ); BOOST_TEST_EQ( (ios_base::showbase | ios_base::internal), ss.flags() ); ss << setiosflags( ios_base::unitbuf ); BOOST_TEST_EQ( (ios_base::showbase | ios_base::internal | ios_base::unitbuf), ss.flags() ); } BOOST_TEST_EQ( (ios_base::skipws | ios_base::dec), ss.flags() ); } // Unit test for precision saving void ios_precision_saver_unit_test ( ) { using namespace std; stringstream ss; BOOST_TEST_EQ( 6, ss.precision() ); { boost::io::ios_precision_saver ips( ss ); BOOST_TEST_EQ( 6, ss.precision() ); ss << setprecision( 4 ); BOOST_TEST_EQ( 4, ss.precision() ); } BOOST_TEST_EQ( 6, ss.precision() ); { boost::io::ios_precision_saver ips( ss, 8 ); BOOST_TEST_EQ( 8, ss.precision() ); ss << setprecision( 10 ); BOOST_TEST_EQ( 10, ss.precision() ); } BOOST_TEST_EQ( 6, ss.precision() ); } // Unit test for width saving void ios_width_saver_unit_test ( ) { using namespace std; stringstream ss; BOOST_TEST_EQ( 0, ss.width() ); { boost::io::ios_width_saver iws( ss ); BOOST_TEST_EQ( 0, ss.width() ); ss << setw( 4 ); BOOST_TEST_EQ( 4, ss.width() ); } BOOST_TEST_EQ( 0, ss.width() ); { boost::io::ios_width_saver iws( ss, 8 ); BOOST_TEST_EQ( 8, ss.width() ); ss << setw( 10 ); BOOST_TEST_EQ( 10, ss.width() ); } BOOST_TEST_EQ( 0, ss.width() ); } // Unit test for I/O-state saving void ios_iostate_saver_unit_test ( ) { using namespace std; stringstream ss; BOOST_TEST_EQ( ios_base::goodbit, ss.rdstate() ); BOOST_TEST( ss.good() ); { boost::io::ios_iostate_saver iis( ss ); char c; BOOST_TEST_EQ( ios_base::goodbit, ss.rdstate() ); BOOST_TEST( ss.good() ); ss >> c; BOOST_TEST_EQ( (ios_base::eofbit | ios_base::failbit), ss.rdstate() ); BOOST_TEST( ss.eof() ); BOOST_TEST( ss.fail() ); BOOST_TEST( !ss.bad() ); } BOOST_TEST_EQ( ios_base::goodbit, ss.rdstate() ); BOOST_TEST( ss.good() ); { boost::io::ios_iostate_saver iis( ss, ios_base::eofbit ); BOOST_TEST_EQ( ios_base::eofbit, ss.rdstate() ); BOOST_TEST( ss.eof() ); ss.setstate( ios_base::badbit ); BOOST_TEST_EQ( (ios_base::eofbit | ios_base::badbit), ss.rdstate() ); BOOST_TEST( ss.eof() ); BOOST_TEST( ss.fail() ); BOOST_TEST( ss.bad() ); } BOOST_TEST_EQ( ios_base::goodbit, ss.rdstate() ); BOOST_TEST( ss.good() ); } // Unit test for exception-flag saving void ios_exception_saver_unit_test ( ) { using namespace std; stringstream ss; BOOST_TEST_EQ( ios_base::goodbit, ss.exceptions() ); { boost::io::ios_exception_saver ies( ss ); BOOST_TEST_EQ( ios_base::goodbit, ss.exceptions() ); ss.exceptions( ios_base::failbit ); BOOST_TEST_EQ( ios_base::failbit, ss.exceptions() ); { boost::io::ios_iostate_saver iis( ss ); ss.exceptions( ios_base::failbit | ios_base::badbit ); char c; #if defined(BOOST_GCC) || (defined(BOOST_CLANG) && defined(BOOST_GNU_STDLIB)) BOOST_TEST_THROWS( ss >> c, std::exception ); #else BOOST_TEST_THROWS( ss >> c, std::ios_base::failure ); #endif } } BOOST_TEST_EQ( ios_base::goodbit, ss.exceptions() ); { boost::io::ios_exception_saver ies( ss, ios_base::eofbit ); BOOST_TEST_EQ( ios_base::eofbit, ss.exceptions() ); ss.exceptions( ios_base::badbit ); BOOST_TEST_EQ( ios_base::badbit, ss.exceptions() ); { boost::io::ios_iostate_saver iis( ss ); char c; BOOST_TEST_NOT( ss >> c ); } } BOOST_TEST_EQ( ios_base::goodbit, ss.exceptions() ); } // Unit test for tied-stream saving void ios_tie_saver_unit_test ( ) { using namespace std; BOOST_TEST( NULL == cout.tie() ); { boost::io::ios_tie_saver its( cout ); BOOST_TEST( NULL == cout.tie() ); cout.tie( &clog ); BOOST_TEST_EQ( &clog, cout.tie() ); } BOOST_TEST( NULL == cout.tie() ); { boost::io::ios_tie_saver its( cout, &clog ); BOOST_TEST_EQ( &clog, cout.tie() ); cout.tie( &cerr ); BOOST_TEST_EQ( &cerr, cout.tie() ); } BOOST_TEST( NULL == cout.tie() ); } // Unit test for connected-streambuf saving void ios_rdbuf_saver_unit_test ( ) { using namespace std; iostream s( NULL ); BOOST_TEST( NULL == s.rdbuf() ); { stringbuf sb; boost::io::ios_rdbuf_saver irs( s ); BOOST_TEST( NULL == s.rdbuf() ); s.rdbuf( &sb ); BOOST_TEST_EQ( &sb, s.rdbuf() ); } BOOST_TEST( NULL == s.rdbuf() ); { stringbuf sb1, sb2( "Hi there" ); boost::io::ios_rdbuf_saver irs( s, &sb1 ); BOOST_TEST_EQ( &sb1, s.rdbuf() ); s.rdbuf( &sb2 ); BOOST_TEST_EQ( &sb2, s.rdbuf() ); } BOOST_TEST( NULL == s.rdbuf() ); } // Unit test for fill-character saving void ios_fill_saver_unit_test ( ) { using namespace std; stringstream ss; BOOST_TEST_EQ( ' ', ss.fill() ); { boost::io::ios_fill_saver ifs( ss ); BOOST_TEST_EQ( ' ', ss.fill() ); ss.fill( 'x' ); BOOST_TEST_EQ( 'x', ss.fill() ); } BOOST_TEST_EQ( ' ', ss.fill() ); { boost::io::ios_fill_saver ifs( ss, '3' ); BOOST_TEST_EQ( '3', ss.fill() ); ss.fill( '+' ); BOOST_TEST_EQ( '+', ss.fill() ); } BOOST_TEST_EQ( ' ', ss.fill() ); } // Unit test for locale saving void ios_locale_saver_unit_test ( ) { using namespace std; typedef numpunct npc_type; stringstream ss; BOOST_TEST( locale() == ss.getloc() ); // locales are unprintable, so no BOOST_TEST_EQ BOOST_TEST( !has_facet(ss.getloc()) || (NULL == dynamic_cast( &use_facet(ss.getloc()) )) ); // my implementation of has_facet just checks IDs, but doesn't do dynamic // cast (therefore if a specifc facet type is missing, but its base class // is available, has_facet will mistakenly[?] match), so I have to do it // here. I wanted: "BOOST_TEST( ! has_facet< backward_bool_names >( // ss.getloc() ) )" { boost::io::ios_locale_saver ils( ss ); BOOST_TEST( locale() == ss.getloc() ); ss.imbue( locale::classic() ); BOOST_TEST( locale::classic() == ss.getloc() ); } BOOST_TEST( locale() == ss.getloc() ); BOOST_TEST( !has_facet(ss.getloc()) || (NULL == dynamic_cast( &use_facet(ss.getloc()) )) ); { boost::io::ios_locale_saver ils( ss, locale::classic() ); BOOST_TEST( locale::classic() == ss.getloc() ); BOOST_TEST( !has_facet(ss.getloc()) || (NULL == dynamic_cast( &use_facet(ss.getloc()) )) ); ss.imbue( locale(locale::classic(), new backward_bool_names) ); BOOST_TEST( locale::classic() != ss.getloc() ); BOOST_TEST( has_facet(ss.getloc()) && (NULL != dynamic_cast( &use_facet(ss.getloc()) )) ); //BOOST_TEST( has_facet(ss.getloc()) ); } BOOST_TEST( locale() == ss.getloc() ); BOOST_TEST( !has_facet(ss.getloc()) || (NULL == dynamic_cast( &use_facet(ss.getloc()) )) ); } // Unit test for user-defined integer data saving void ios_iword_saver_unit_test ( ) { using namespace std; stringstream ss; BOOST_TEST_EQ( 0, ss.iword(word_index) ); { boost::io::ios_iword_saver iis( ss, word_index ); BOOST_TEST_EQ( 0, ss.iword(word_index) ); ss.iword( word_index ) = 6; BOOST_TEST_EQ( 6, ss.iword(word_index) ); } BOOST_TEST_EQ( 0, ss.iword(word_index) ); { boost::io::ios_iword_saver iis( ss, word_index, 100 ); BOOST_TEST_EQ( 100, ss.iword(word_index) ); ss.iword( word_index ) = -2000; BOOST_TEST_EQ( -2000, ss.iword(word_index) ); } BOOST_TEST_EQ( 0, ss.iword(word_index) ); } // Unit test for user-defined pointer data saving void ios_pword_saver_unit_test ( ) { using namespace std; stringstream ss; BOOST_TEST( NULL == ss.pword(word_index) ); { boost::io::ios_pword_saver ips( ss, word_index ); BOOST_TEST( NULL == ss.pword(word_index) ); ss.pword( word_index ) = &ss; BOOST_TEST_EQ( &ss, ss.pword(word_index) ); } BOOST_TEST( NULL == ss.pword(word_index) ); { boost::io::ios_pword_saver ips( ss, word_index, ss.rdbuf() ); BOOST_TEST_EQ( ss.rdbuf(), ss.pword(word_index) ); ss.pword( word_index ) = &ss; BOOST_TEST_EQ( &ss, ss.pword(word_index) ); } BOOST_TEST( NULL == ss.pword(word_index) ); } // Unit test for all ios_base data saving void ios_base_all_saver_unit_test ( ) { using namespace std; stringstream ss; BOOST_TEST_EQ( (ios_base::skipws | ios_base::dec), ss.flags() ); BOOST_TEST_EQ( 6, ss.precision() ); BOOST_TEST_EQ( 0, ss.width() ); { boost::io::ios_base_all_saver ibas( ss ); BOOST_TEST_EQ( (ios_base::skipws | ios_base::dec), ss.flags() ); BOOST_TEST_EQ( 6, ss.precision() ); BOOST_TEST_EQ( 0, ss.width() ); ss << hex << unitbuf << setprecision( 5 ) << setw( 7 ); BOOST_TEST_EQ( (ios_base::unitbuf | ios_base::hex | ios_base::skipws), ss.flags() ); BOOST_TEST_EQ( 5, ss.precision() ); BOOST_TEST_EQ( 7, ss.width() ); } BOOST_TEST_EQ( (ios_base::skipws | ios_base::dec), ss.flags() ); BOOST_TEST_EQ( 6, ss.precision() ); BOOST_TEST_EQ( 0, ss.width() ); } // Unit test for all basic_ios data saving void ios_all_saver_unit_test ( ) { using namespace std; typedef numpunct npc_type; stringbuf sb; iostream ss( &sb ); BOOST_TEST_EQ( (ios_base::skipws | ios_base::dec), ss.flags() ); BOOST_TEST_EQ( 6, ss.precision() ); BOOST_TEST_EQ( 0, ss.width() ); BOOST_TEST_EQ( ios_base::goodbit, ss.rdstate() ); BOOST_TEST( ss.good() ); BOOST_TEST_EQ( ios_base::goodbit, ss.exceptions() ); BOOST_TEST( NULL == ss.tie() ); BOOST_TEST( &sb == ss.rdbuf() ); BOOST_TEST_EQ( ' ', ss.fill() ); BOOST_TEST( locale() == ss.getloc() ); { boost::io::ios_all_saver ias( ss ); BOOST_TEST_EQ( (ios_base::skipws | ios_base::dec), ss.flags() ); BOOST_TEST_EQ( 6, ss.precision() ); BOOST_TEST_EQ( 0, ss.width() ); BOOST_TEST_EQ( ios_base::goodbit, ss.rdstate() ); BOOST_TEST( ss.good() ); BOOST_TEST_EQ( ios_base::goodbit, ss.exceptions() ); BOOST_TEST( NULL == ss.tie() ); BOOST_TEST( &sb == ss.rdbuf() ); BOOST_TEST_EQ( ' ', ss.fill() ); BOOST_TEST( locale() == ss.getloc() ); ss << oct << showpos << noskipws; BOOST_TEST_EQ( (ios_base::showpos | ios_base::oct), ss.flags() ); ss << setprecision( 3 ); BOOST_TEST_EQ( 3, ss.precision() ); ss << setw( 9 ); BOOST_TEST_EQ( 9, ss.width() ); ss.setstate( ios_base::eofbit ); BOOST_TEST_EQ( ios_base::eofbit, ss.rdstate() ); BOOST_TEST( ss.eof() ); ss.exceptions( ios_base::failbit ); BOOST_TEST_EQ( ios_base::failbit, ss.exceptions() ); { boost::io::ios_iostate_saver iis( ss ); ss.exceptions( ios_base::failbit | ios_base::badbit ); char c; #if defined(BOOST_GCC) || (defined(BOOST_CLANG) && defined(BOOST_GNU_STDLIB)) BOOST_TEST_THROWS( ss >> c, std::exception ); #else BOOST_TEST_THROWS( ss >> c, std::ios_base::failure ); #endif } ss.tie( &clog ); BOOST_TEST_EQ( &clog, ss.tie() ); ss.rdbuf( cerr.rdbuf() ); BOOST_TEST_EQ( cerr.rdbuf(), ss.rdbuf() ); ss << setfill( 'x' ); BOOST_TEST_EQ( 'x', ss.fill() ); ss.imbue( locale(locale::classic(), new backward_bool_names) ); BOOST_TEST( locale() != ss.getloc() ); BOOST_TEST( has_facet(ss.getloc()) && (NULL != dynamic_cast( &use_facet(ss.getloc()) )) ); } BOOST_TEST_EQ( (ios_base::skipws | ios_base::dec), ss.flags() ); BOOST_TEST_EQ( 6, ss.precision() ); BOOST_TEST_EQ( 0, ss.width() ); BOOST_TEST_EQ( ios_base::goodbit, ss.rdstate() ); BOOST_TEST( ss.good() ); BOOST_TEST_EQ( ios_base::goodbit, ss.exceptions() ); BOOST_TEST( NULL == ss.tie() ); BOOST_TEST( &sb == ss.rdbuf() ); BOOST_TEST_EQ( ' ', ss.fill() ); BOOST_TEST( locale() == ss.getloc() ); } // Unit test for user-defined data saving void ios_word_saver_unit_test ( ) { using namespace std; stringstream ss; BOOST_TEST_EQ( 0, ss.iword(word_index) ); BOOST_TEST( NULL == ss.pword(word_index) ); { boost::io::ios_all_word_saver iaws( ss, word_index ); BOOST_TEST_EQ( 0, ss.iword(word_index) ); BOOST_TEST( NULL == ss.pword(word_index) ); ss.iword( word_index ) = -11; ss.pword( word_index ) = ss.rdbuf(); BOOST_TEST_EQ( -11, ss.iword(word_index) ); BOOST_TEST_EQ( ss.rdbuf(), ss.pword(word_index) ); } BOOST_TEST_EQ( 0, ss.iword(word_index) ); BOOST_TEST( NULL == ss.pword(word_index) ); } // Unit test program int main() { ios_flags_saver_unit_test(); ios_precision_saver_unit_test(); ios_width_saver_unit_test(); ios_iostate_saver_unit_test(); ios_exception_saver_unit_test(); ios_tie_saver_unit_test(); ios_rdbuf_saver_unit_test(); ios_fill_saver_unit_test(); ios_locale_saver_unit_test(); ios_iword_saver_unit_test(); ios_pword_saver_unit_test(); ios_base_all_saver_unit_test(); ios_all_saver_unit_test(); ios_word_saver_unit_test(); return boost::report_errors(); }