blob: d46ffab549130e774b38fa3f69ed8bced4a9ef6b [file] [log] [blame]
/*
Copyright 2003 Daryle Walker
Copyright 2019 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#include <boost/io/ios_state.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/config.hpp>
#include <iomanip>
#include <ios>
#include <iostream>
#include <istream>
#include <locale>
#if defined(BOOST_GCC) || (defined(BOOST_CLANG) && defined(BOOST_GNU_STDLIB))
#include <stdexcept>
#endif
#include <sstream>
#include <cstddef>
class backward_bool_names
: public std::numpunct<char> {
typedef std::numpunct<char> base_type;
public:
explicit backward_bool_names(std::size_t refs = 0)
: base_type(refs) { }
protected:
~backward_bool_names() { }
base_type::string_type do_truename() const {
return "eurt";
}
base_type::string_type do_falsename() const {
return "eslaf";
}
};
void
ios_flags_saver_unit_test()
{
std::stringstream ss;
BOOST_TEST_EQ(std::ios_base::skipws | std::ios_base::dec, ss.flags());
{
boost::io::ios_flags_saver ifs(ss);
BOOST_TEST_EQ(std::ios_base::skipws | std::ios_base::dec, ss.flags());
ss << std::noskipws << std::fixed << std::boolalpha;
BOOST_TEST_EQ(std::ios_base::boolalpha |
std::ios_base::dec |
std::ios_base::fixed, ss.flags());
}
BOOST_TEST_EQ(std::ios_base::skipws | std::ios_base::dec, ss.flags());
{
boost::io::ios_flags_saver ifs(ss,
std::ios_base::showbase | std::ios_base::internal);
BOOST_TEST_EQ(std::ios_base::showbase |
std::ios_base::internal, ss.flags());
ss << std::setiosflags(std::ios_base::unitbuf);
BOOST_TEST_EQ(std::ios_base::showbase |
std::ios_base::internal |
std::ios_base::unitbuf, ss.flags());
}
BOOST_TEST_EQ(std::ios_base::skipws | std::ios_base::dec, ss.flags());
}
void
ios_precision_saver_unit_test()
{
std::stringstream ss;
BOOST_TEST_EQ(6, ss.precision());
{
boost::io::ios_precision_saver ips(ss);
BOOST_TEST_EQ(6, ss.precision());
ss << std::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 << std::setprecision(10);
BOOST_TEST_EQ(10, ss.precision());
}
BOOST_TEST_EQ(6, ss.precision());
}
void
ios_width_saver_unit_test()
{
std::stringstream ss;
BOOST_TEST_EQ(0, ss.width());
{
boost::io::ios_width_saver iws(ss);
BOOST_TEST_EQ(0, ss.width());
ss << std::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 << std::setw(10);
BOOST_TEST_EQ(10, ss.width());
}
BOOST_TEST_EQ(0, ss.width());
}
void
ios_iostate_saver_unit_test()
{
std::stringstream ss;
BOOST_TEST_EQ(std::ios_base::goodbit, ss.rdstate());
BOOST_TEST(ss.good());
{
boost::io::ios_iostate_saver iis(ss);
char c;
BOOST_TEST_EQ(std::ios_base::goodbit, ss.rdstate());
BOOST_TEST(ss.good());
ss >> c;
BOOST_TEST_EQ(std::ios_base::eofbit | std::ios_base::failbit,
ss.rdstate());
BOOST_TEST(ss.eof());
BOOST_TEST(ss.fail());
BOOST_TEST(!ss.bad());
}
BOOST_TEST_EQ(std::ios_base::goodbit, ss.rdstate());
BOOST_TEST(ss.good());
{
boost::io::ios_iostate_saver iis(ss, std::ios_base::eofbit);
BOOST_TEST_EQ(std::ios_base::eofbit, ss.rdstate());
BOOST_TEST(ss.eof());
ss.setstate(std::ios_base::badbit);
BOOST_TEST_EQ(std::ios_base::eofbit | std::ios_base::badbit,
ss.rdstate());
BOOST_TEST(ss.eof());
BOOST_TEST(ss.fail());
BOOST_TEST(ss.bad());
}
BOOST_TEST_EQ(std::ios_base::goodbit, ss.rdstate());
BOOST_TEST(ss.good());
}
void
ios_exception_saver_unit_test()
{
std::stringstream ss;
BOOST_TEST_EQ(std::ios_base::goodbit, ss.exceptions());
{
boost::io::ios_exception_saver ies(ss);
BOOST_TEST_EQ(std::ios_base::goodbit, ss.exceptions());
ss.exceptions(std::ios_base::failbit);
BOOST_TEST_EQ(std::ios_base::failbit, ss.exceptions());
{
boost::io::ios_iostate_saver iis(ss);
ss.exceptions(std::ios_base::failbit | std::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(std::ios_base::goodbit, ss.exceptions());
{
boost::io::ios_exception_saver ies(ss, std::ios_base::eofbit);
BOOST_TEST_EQ(std::ios_base::eofbit, ss.exceptions());
ss.exceptions(std::ios_base::badbit);
BOOST_TEST_EQ(std::ios_base::badbit, ss.exceptions());
{
boost::io::ios_iostate_saver iis(ss);
char c;
BOOST_TEST_NOT(ss >> c);
}
}
BOOST_TEST_EQ(std::ios_base::goodbit, ss.exceptions());
}
void
ios_tie_saver_unit_test()
{
BOOST_TEST(NULL == std::cout.tie());
{
boost::io::ios_tie_saver its(std::cout);
BOOST_TEST(NULL == std::cout.tie());
std::cout.tie(&std::clog);
BOOST_TEST_EQ(&std::clog, std::cout.tie());
}
BOOST_TEST(NULL == std::cout.tie());
{
boost::io::ios_tie_saver its(std::cout, &std::clog);
BOOST_TEST_EQ(&std::clog, std::cout.tie());
std::cout.tie(&std::cerr);
BOOST_TEST_EQ(&std::cerr, std::cout.tie());
}
BOOST_TEST(NULL == std::cout.tie());
}
void
ios_rdbuf_saver_unit_test()
{
std::iostream s(NULL);
BOOST_TEST(NULL == s.rdbuf());
{
std::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());
{
std::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());
}
void
ios_fill_saver_unit_test()
{
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());
}
void
ios_locale_saver_unit_test()
{
typedef std::numpunct<char> npc_type;
std::stringstream ss;
BOOST_TEST(std::locale() == ss.getloc());
BOOST_TEST(!std::has_facet<npc_type>(ss.getloc()) ||
!dynamic_cast<const backward_bool_names*>(&
std::use_facet<npc_type>(ss.getloc())));
{
boost::io::ios_locale_saver ils(ss);
BOOST_TEST(std::locale() == ss.getloc());
ss.imbue(std::locale::classic());
BOOST_TEST(std::locale::classic() == ss.getloc());
}
BOOST_TEST(std::locale() == ss.getloc());
BOOST_TEST(!std::has_facet<npc_type>(ss.getloc()) ||
!dynamic_cast<const backward_bool_names*>(&
std::use_facet<npc_type>(ss.getloc())));
{
boost::io::ios_locale_saver ils(ss, std::locale::classic());
BOOST_TEST(std::locale::classic() == ss.getloc());
BOOST_TEST(!std::has_facet<npc_type>(ss.getloc()) ||
!dynamic_cast<const backward_bool_names*>(&
std::use_facet<npc_type>(ss.getloc())));
ss.imbue(std::locale(std::locale::classic(), new backward_bool_names));
BOOST_TEST(std::locale::classic() != ss.getloc());
BOOST_TEST(std::has_facet<npc_type>(ss.getloc()) &&
dynamic_cast<const backward_bool_names*>(&
std::use_facet<npc_type>(ss.getloc())));
}
BOOST_TEST(std::locale() == ss.getloc());
BOOST_TEST(!std::has_facet<npc_type>(ss.getloc()) ||
!dynamic_cast<const backward_bool_names*>(&
std::use_facet<npc_type>(ss.getloc())));
}
void
ios_iword_saver_unit_test(int index)
{
std::stringstream ss;
BOOST_TEST_EQ(0, ss.iword(index));
{
boost::io::ios_iword_saver iis(ss, index);
BOOST_TEST_EQ(0, ss.iword(index));
ss.iword(index) = 6;
BOOST_TEST_EQ(6, ss.iword(index));
}
BOOST_TEST_EQ(0, ss.iword(index));
{
boost::io::ios_iword_saver iis(ss, index, 100);
BOOST_TEST_EQ(100, ss.iword(index));
ss.iword(index) = -2000;
BOOST_TEST_EQ(-2000, ss.iword(index));
}
BOOST_TEST_EQ(0, ss.iword(index));
}
void
ios_pword_saver_unit_test(int index)
{
std::stringstream ss;
BOOST_TEST(NULL == ss.pword(index));
{
boost::io::ios_pword_saver ips(ss, index);
BOOST_TEST(NULL == ss.pword(index));
ss.pword(index) = &ss;
BOOST_TEST_EQ(&ss, ss.pword(index));
}
BOOST_TEST(NULL == ss.pword(index));
{
boost::io::ios_pword_saver ips(ss, index, ss.rdbuf());
BOOST_TEST_EQ(ss.rdbuf(), ss.pword(index));
ss.pword(index) = &ss;
BOOST_TEST_EQ(&ss, ss.pword(index));
}
BOOST_TEST(NULL == ss.pword(index));
}
void
ios_base_all_saver_unit_test()
{
std::stringstream ss;
BOOST_TEST_EQ(std::ios_base::skipws | std::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(std::ios_base::skipws | std::ios_base::dec, ss.flags());
BOOST_TEST_EQ(6, ss.precision());
BOOST_TEST_EQ(0, ss.width());
ss << std::hex << std::unitbuf << std::setprecision(5) << std::setw(7);
BOOST_TEST_EQ(std::ios_base::unitbuf |
std::ios_base::hex |
std::ios_base::skipws, ss.flags());
BOOST_TEST_EQ(5, ss.precision());
BOOST_TEST_EQ(7, ss.width());
}
BOOST_TEST_EQ(std::ios_base::skipws | std::ios_base::dec, ss.flags());
BOOST_TEST_EQ(6, ss.precision());
BOOST_TEST_EQ(0, ss.width());
}
void
ios_all_saver_unit_test()
{
typedef std::numpunct<char> npc_type;
std::stringbuf sb;
std::iostream ss(&sb);
BOOST_TEST_EQ(std::ios_base::skipws | std::ios_base::dec, ss.flags());
BOOST_TEST_EQ(6, ss.precision());
BOOST_TEST_EQ(0, ss.width());
BOOST_TEST_EQ(std::ios_base::goodbit, ss.rdstate());
BOOST_TEST(ss.good());
BOOST_TEST_EQ(std::ios_base::goodbit, ss.exceptions());
BOOST_TEST(NULL == ss.tie());
BOOST_TEST(&sb == ss.rdbuf());
BOOST_TEST_EQ(' ', ss.fill());
BOOST_TEST(std::locale() == ss.getloc());
{
boost::io::ios_all_saver ias(ss);
BOOST_TEST_EQ(std::ios_base::skipws | std::ios_base::dec, ss.flags());
BOOST_TEST_EQ(6, ss.precision());
BOOST_TEST_EQ(0, ss.width());
BOOST_TEST_EQ(std::ios_base::goodbit, ss.rdstate());
BOOST_TEST(ss.good());
BOOST_TEST_EQ(std::ios_base::goodbit, ss.exceptions());
BOOST_TEST(NULL == ss.tie());
BOOST_TEST(&sb == ss.rdbuf());
BOOST_TEST_EQ(' ', ss.fill());
BOOST_TEST(std::locale() == ss.getloc());
ss << std::oct << std::showpos << std::noskipws;
BOOST_TEST_EQ(std::ios_base::showpos | std::ios_base::oct, ss.flags());
ss << std::setprecision(3);
BOOST_TEST_EQ(3, ss.precision());
ss << std::setw(9);
BOOST_TEST_EQ(9, ss.width());
ss.setstate(std::ios_base::eofbit);
BOOST_TEST_EQ(std::ios_base::eofbit, ss.rdstate());
BOOST_TEST(ss.eof());
ss.exceptions(std::ios_base::failbit);
BOOST_TEST_EQ(std::ios_base::failbit, ss.exceptions());
{
boost::io::ios_iostate_saver iis(ss);
ss.exceptions(std::ios_base::failbit | std::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(&std::clog);
BOOST_TEST_EQ(&std::clog, ss.tie());
ss.rdbuf(std::cerr.rdbuf());
BOOST_TEST_EQ(std::cerr.rdbuf(), ss.rdbuf());
ss << std::setfill('x');
BOOST_TEST_EQ('x', ss.fill());
ss.imbue(std::locale(std::locale::classic(), new backward_bool_names));
BOOST_TEST(std::locale() != ss.getloc());
BOOST_TEST(std::has_facet<npc_type>(ss.getloc()) &&
dynamic_cast<const backward_bool_names*>(&
std::use_facet<npc_type>(ss.getloc())));
}
BOOST_TEST_EQ(std::ios_base::skipws | std::ios_base::dec, ss.flags());
BOOST_TEST_EQ(6, ss.precision());
BOOST_TEST_EQ(0, ss.width());
BOOST_TEST_EQ(std::ios_base::goodbit, ss.rdstate());
BOOST_TEST(ss.good());
BOOST_TEST_EQ(std::ios_base::goodbit, ss.exceptions());
BOOST_TEST(NULL == ss.tie());
BOOST_TEST(&sb == ss.rdbuf());
BOOST_TEST_EQ(' ', ss.fill());
BOOST_TEST(std::locale() == ss.getloc());
}
void
ios_word_saver_unit_test(int index)
{
std::stringstream ss;
BOOST_TEST_EQ(0, ss.iword(index));
BOOST_TEST(NULL == ss.pword(index));
{
boost::io::ios_all_word_saver iaws(ss, index);
BOOST_TEST_EQ(0, ss.iword(index));
BOOST_TEST(NULL == ss.pword(index));
ss.iword(index) = -11;
ss.pword(index) = ss.rdbuf();
BOOST_TEST_EQ(-11, ss.iword(index));
BOOST_TEST_EQ(ss.rdbuf(), ss.pword(index));
}
BOOST_TEST_EQ(0, ss.iword(index));
BOOST_TEST(NULL == ss.pword(index));
}
int main()
{
int index = std::ios_base::xalloc();
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(index);
ios_pword_saver_unit_test(index);
ios_base_all_saver_unit_test();
ios_all_saver_unit_test();
ios_word_saver_unit_test(index);
return boost::report_errors();
}