1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
|
// { dg-additional-options "-lstdc++exp" { target { *-*-mingw* } } }
// { dg-do run { target c++23 } }
// { dg-require-fileio "" }
#include <ostream>
#include <spanstream>
#include <string_view>
#include <iostream>
#include <iomanip>
#include <testsuite_hooks.h>
void
test_print_ostream()
{
char buf[64];
std::spanstream os(buf);
std::print(os, "File under '{}' for {}", 'O', "OUT OF FILE");
std::string_view txt(os.span());
VERIFY( txt == "File under 'O' for OUT OF FILE" );
}
void
test_println_ostream()
{
char buf[64];
std::spanstream os(buf);
std::println(os, "{} Lineman was a song I once heard", "Wichita");
std::string_view txt(os.span());
VERIFY( txt == "Wichita Lineman was a song I once heard\n" );
}
void
test_print_raw()
{
char buf[64];
std::spanstream os(buf);
std::print(os, "{}", '\xa3'); // Not a valid UTF-8 string.
std::string_view txt(os.span());
// Invalid UTF-8 should be written out unchanged if the ostream is not
// connected to a tty:
VERIFY( txt == "\xa3" );
}
void
test_print_no_padding()
{
// [ostream.formatted.print] does not say this function "determines padding",
// see https://gcc.gnu.org/pipermail/gcc-patches/2023-December/640680.html
char buf[64];
std::spanstream os(buf);
os << std::setw(60) << std::setfill('?') << std::right; // should be ignored
std::print(os, "{} Luftballons", 99);
std::string_view txt(os.span());
VERIFY( txt == "99 Luftballons" );
}
void
test_vprint_nonunicode()
{
std::ostream out(std::cout.rdbuf());
std::vprint_nonunicode(out, "{0} in \xc0 {0} out\n",
std::make_format_args("garbage"));
// { dg-output "garbage in . garbage out" }
}
struct brit_punc : std::numpunct<char>
{
std::string do_grouping() const override { return "\3\3"; }
char do_thousands_sep() const override { return ','; }
std::string do_truename() const override { return "yes mate"; }
std::string do_falsename() const override { return "nah bruv"; }
};
void
test_locale()
{
struct stream_punc : std::numpunct<char>
{
std::string do_grouping() const override { return "\2\2"; }
char do_thousands_sep() const override { return '~'; }
};
// The default C locale.
std::locale cloc = std::locale::classic();
// A custom locale using comma digit separators.
std::locale bloc(cloc, new stream_punc);
{
std::ostringstream os;
std::print(os, "{:L} {}", 12345, 6789);
VERIFY(os.str() == "12345 6789");
}
{
std::ostringstream os;
std::print(os, "{}", 42);
VERIFY(os.str() == "42");
}
{
std::ostringstream os;
os.imbue(bloc);
std::print(os, "{:L} {}", 12345, 6789);
VERIFY(os.str() == "1~23~45 6789");
}
}
void
test_errors()
{
// Failure to generate output is reported by setting badbit.
std::stringstream in(std::ios::in);
std::print(in, "{}", "nope"); // No exception here.
VERIFY(in.bad());
#ifdef __cpp_exceptions
in.clear();
in.exceptions(std::ios::badbit);
try
{
std::print(in, "{}", "nope"); // Should throw now.
VERIFY(false);
}
catch (const std::ios::failure&)
{
}
// An exception thrown when formatting the string is propagated
// without setting badbit.
std::ostringstream out;
try
{
std::vprint_nonunicode(out, "{}", std::make_format_args());
VERIFY(false);
}
catch (const std::format_error&)
{
}
VERIFY(out.good());
#endif
}
int main()
{
test_print_ostream();
test_println_ostream();
test_print_raw();
test_print_no_padding();
test_vprint_nonunicode();
test_locale();
test_errors();
}
|