| // { dg-do run { target c++20 } } |
| |
| // Test stream state semantics for chrono operator<< |
| #include <chrono> |
| #include <format> |
| #include <iomanip> |
| #include <sstream> |
| #include <testsuite_hooks.h> |
| |
| bool |
| check_prefix(std::string_view s, size_t n, char c) |
| { |
| for (char v : s) |
| if (v != c) |
| return !n; |
| else if (!n) |
| return false; |
| else |
| --n; |
| return false; |
| } |
| |
| void |
| test_sentry_badbit() |
| { |
| using namespace std::chrono; |
| std::ostringstream os; |
| os.setstate(std::ios::badbit); |
| VERIFY( !os.good() ); |
| os << sys_time<seconds>{1'700'000'000s}; |
| VERIFY( os.bad() ); |
| VERIFY( os.str().empty() ); |
| } |
| |
| void |
| test_sentry_tied() |
| { |
| using namespace std::chrono; |
| struct testbuf : std::streambuf |
| { bool flushed = false; int sync() override { flushed = true; return 0; } }; |
| testbuf tied_buf; std::ostream tied(&tied_buf); std::ostringstream os; |
| os.tie(&tied); |
| os << sys_time<seconds>{1'700'000'000s}; |
| VERIFY( tied_buf.flushed == true ); |
| } |
| |
| void |
| test_width_fill() |
| { |
| using namespace std::chrono; |
| std::ostringstream os; |
| os << std::setw(30) << std::setfill('*') << sys_time<seconds>{1'700'000'000s}; |
| auto s = os.view(); |
| VERIFY( s.size() == 30 ); |
| VERIFY( check_prefix(s, 11, '*') ); |
| VERIFY( s.substr(11) == "2023-11-14 22:13:20" ); |
| VERIFY( os.width() == 0 ); |
| } |
| |
| void |
| test_width_left() |
| { |
| using namespace std::chrono; |
| std::ostringstream os; |
| os << std::setw(30) << std::left << std::setfill('.') << sys_time<seconds>{1'700'000'000s}; |
| auto s = os.view(); |
| VERIFY( s.size() == 30 ); |
| VERIFY( s.find("2023-11-14") == 0 ); |
| VERIFY( s.back() == '.' ); |
| VERIFY( os.width() == 0 ); |
| } |
| |
| void |
| test_width_internal() |
| { |
| using namespace std::chrono; |
| std::ostringstream os; |
| os << std::setw(30) << std::internal << std::setfill('_') << day(15); |
| auto s = os.view(); |
| VERIFY( s.size() == 30 ); |
| VERIFY( check_prefix(s, 28, '_') ); |
| VERIFY( s.substr(28) == "15" ); |
| VERIFY( os.width() == 0 ); |
| } |
| |
| void |
| test_width_reset() |
| { |
| using namespace std::chrono; |
| std::ostringstream os; |
| os << std::setw(20) << sys_time<seconds>{1'700'000'000s}; |
| VERIFY( os.width() == 0 ); |
| os << hh_mm_ss{seconds(45296)}; |
| VERIFY( os.width() == 0 ); |
| os << std::setw(15) << day(15); |
| VERIFY( os.width() == 0 ); |
| } |
| |
| void |
| test_width_zero() |
| { |
| using namespace std::chrono; |
| std::ostringstream os; |
| os << std::setw(0) << sys_time<seconds>{1'700'000'000s}; |
| auto s = os.view(); |
| VERIFY( s.find("2023-11-14") != std::string::npos ); |
| VERIFY( s.size() < 20 ); |
| VERIFY( os.width() == 0 ); |
| } |
| |
| void |
| test_multiple_chrono_types() |
| { |
| using namespace std::chrono; |
| std::ostringstream os; |
| os << std::setw(25) << std::setfill('-') << sys_time<seconds>{1'700'000'000s}; |
| VERIFY( check_prefix(os.view(), 6, '-') ); |
| VERIFY( os.width() == 0 ); |
| os << std::setw(15) << hh_mm_ss{seconds(45296)}; |
| VERIFY( check_prefix(os.view().substr(25), 7, '-') ); |
| VERIFY( os.width() == 0 ); |
| os << std::setw(10) << day(15); |
| VERIFY( check_prefix(os.view().substr(40), 8, '-') ); |
| VERIFY( os.width() == 0 ); |
| os << std::setw(10) << month(7); |
| VERIFY( check_prefix(os.view().substr(50), 7, '-') ); |
| VERIFY( os.width() == 0 ); |
| os << std::setw(10) << year(2026); |
| VERIFY( check_prefix(os.view().substr(60), 6, '-') ); |
| VERIFY( os.width() == 0 ); |
| os << std::setw(12) << Monday; |
| VERIFY( check_prefix(os.view().substr(70), 9, '-') ); |
| VERIFY( os.width() == 0 ); |
| } |
| |
| void |
| test_locale_aware() |
| { |
| using namespace std::chrono; |
| std::ostringstream os; |
| os.imbue(std::locale::classic()); |
| os << std::setw(12) << Monday; |
| auto s = os.view(); |
| VERIFY( s.size() >= 12 ); |
| VERIFY( os.width() == 0 ); |
| } |
| |
| void |
| test_wchar_t() |
| { |
| using namespace std::chrono; |
| std::wostringstream wos; |
| wos << std::chrono::sys_time<std::chrono::seconds>{1'700'000'000s}; |
| VERIFY( wos.view() == L"2023-11-14 22:13:20" ); |
| } |
| |
| void |
| test_weekday_indexed() |
| { |
| using namespace std::chrono; |
| std::ostringstream os; |
| os << Monday[1]; |
| VERIFY( os.view() == "Mon[1]" ); |
| os.str(""); |
| os << Monday[6]; // invalid index |
| VERIFY( os.view().find("Mon[") != std::string::npos ); |
| } |
| |
| int |
| main() |
| { |
| test_sentry_badbit(); |
| test_sentry_tied(); |
| test_width_fill(); |
| test_width_left(); |
| test_width_internal(); |
| test_width_reset(); |
| test_width_zero(); |
| test_multiple_chrono_types(); |
| test_locale_aware(); |
| test_wchar_t(); |
| test_weekday_indexed(); |
| } |