mirror of
https://github.com/gcc-mirror/gcc.git
synced 2026-05-06 14:59:39 +02:00
As pointed out by Daniel Krügler we do not need to use reserved name in tests. libstdc++-v3/ChangeLog: * testsuite/23_containers/vector/bool/format.cc: Replaced _CharT with CharT. * testsuite/std/format/debug.cc: Likewise. * testsuite/std/format/ranges/adaptors.cc: Likewise. * testsuite/std/format/ranges/formatter.cc: Likewise. * testsuite/std/format/ranges/map.cc: Likewise. * testsuite/std/format/ranges/sequence.cc: Likewise. * testsuite/std/format/ranges/string.cc: Likewise. * testsuite/std/format/tuple.cc: Likewise. * testsuite/std/time/format/empty_spec.cc: Likewise. * testsuite/std/time/format/pr120114.cc: Likewise. * testsuite/std/time/format/pr120481.cc: Likewise. * testsuite/std/time/format/precision.cc: Likewise.
844 lines
21 KiB
C++
844 lines
21 KiB
C++
// { dg-options "-fexec-charset=UTF-8 -fwide-exec-charset=UTF-32LE -DUNICODE_ENC" { target le } }
|
|
// { dg-options "-fexec-charset=UTF-8 -fwide-exec-charset=UTF-32BE -DUNICODE_ENC" { target be } }
|
|
// { dg-do run { target c++23 } }
|
|
// { dg-require-effective-target 4byte_wchar_t }
|
|
// { dg-add-options no_pch }
|
|
// { dg-timeout-factor 2 }
|
|
|
|
#include <format>
|
|
#include <testsuite_hooks.h>
|
|
|
|
std::string
|
|
fdebug(char t)
|
|
{ return std::format("{:?}", t); }
|
|
|
|
std::wstring
|
|
fdebug(wchar_t t)
|
|
{ return std::format(L"{:?}", t); }
|
|
|
|
std::string
|
|
fdebug(std::string_view t)
|
|
{ return std::format("{:?}", t); }
|
|
|
|
std::wstring
|
|
fdebug(std::wstring_view t)
|
|
{ return std::format(L"{:?}", t); }
|
|
|
|
|
|
#define WIDEN_(C, S) ::std::__format::_Widen<C>(S, L##S)
|
|
#define WIDEN(S) WIDEN_(CharT, S)
|
|
|
|
template<typename CharT>
|
|
void
|
|
test_basic_escapes()
|
|
{
|
|
std::basic_string<CharT> res;
|
|
|
|
const auto tab = WIDEN("\t");
|
|
res = fdebug(tab);
|
|
VERIFY( res == WIDEN(R"("\t")") );
|
|
res = fdebug(tab[0]);
|
|
VERIFY( res == WIDEN(R"('\t')") );
|
|
|
|
const auto nline = WIDEN("\n");
|
|
res = fdebug(nline);
|
|
VERIFY( res == WIDEN(R"("\n")") );
|
|
res = fdebug(nline[0]);
|
|
VERIFY( res == WIDEN(R"('\n')") );
|
|
|
|
const auto carret = WIDEN("\r");
|
|
res = fdebug(carret);
|
|
VERIFY( res == WIDEN(R"("\r")") );
|
|
res = fdebug(carret[0]);
|
|
VERIFY( res == WIDEN(R"('\r')") );
|
|
|
|
const auto bslash = WIDEN("\\");
|
|
res = fdebug(bslash);
|
|
VERIFY( res == WIDEN(R"("\\")") );
|
|
res = fdebug(bslash[0]);
|
|
VERIFY( res == WIDEN(R"('\\')") );
|
|
|
|
const auto quote = WIDEN("\"");
|
|
res = fdebug(quote);
|
|
VERIFY( res == WIDEN(R"("\"")") );
|
|
res = fdebug(quote[0]);
|
|
VERIFY( res == WIDEN(R"('"')") );
|
|
|
|
const auto apos = WIDEN("\'");
|
|
res = fdebug(apos);
|
|
VERIFY( res == WIDEN(R"("'")") );
|
|
res = fdebug(apos[0]);
|
|
VERIFY( res == WIDEN(R"('\'')") );
|
|
}
|
|
|
|
template<typename CharT>
|
|
void
|
|
test_ascii_escapes()
|
|
{
|
|
std::basic_string<CharT> res;
|
|
|
|
const auto in = WIDEN("\x10 abcde\x7f\t0123");
|
|
res = fdebug(in);
|
|
VERIFY( res == WIDEN(R"("\u{10} abcde\u{7f}\t0123")") );
|
|
res = fdebug(in[0]);
|
|
VERIFY( res == WIDEN(R"('\u{10}')") );
|
|
res = fdebug(in[1]);
|
|
VERIFY( res == WIDEN(R"(' ')") );
|
|
res = fdebug(in[2]);
|
|
VERIFY( res == WIDEN(R"('a')") );
|
|
}
|
|
|
|
template<typename CharT>
|
|
void
|
|
test_extended_ascii()
|
|
{
|
|
std::basic_string<CharT> res;
|
|
|
|
const auto in = WIDEN("Åëÿ");
|
|
res = fdebug(in);
|
|
VERIFY( res == WIDEN(R"("Åëÿ")") );
|
|
|
|
static constexpr bool __test_characters
|
|
#if UNICODE_ENC
|
|
= sizeof(CharT) >= 2;
|
|
#else // ISO8859-1
|
|
= true;
|
|
#endif // UNICODE_ENC
|
|
|
|
if constexpr (__test_characters)
|
|
{
|
|
res = fdebug(in[0]);
|
|
VERIFY( res == WIDEN(R"('Å')") );
|
|
res = fdebug(in[1]);
|
|
VERIFY( res == WIDEN(R"('ë')") );
|
|
res = fdebug(in[2]);
|
|
VERIFY( res == WIDEN(R"('ÿ')") );
|
|
}
|
|
}
|
|
|
|
template<typename CharT>
|
|
void
|
|
test_unicode_escapes()
|
|
{
|
|
#if UNICODE_ENC
|
|
std::basic_string<CharT> res;
|
|
|
|
const auto in = WIDEN(
|
|
"\u008a" // Cc, Control, Line Tabulation Set,
|
|
"\u00ad" // Cf, Format, Soft Hyphen
|
|
"\u1d3d" // Lm, Modifier letter, Modifier Letter Capital Ou
|
|
"\u00a0" // Zs, Space Separator, No-Break Space (NBSP)
|
|
"\u2029" // Zp, Paragraph Separator, Paragraph Separator
|
|
"\U0001f984" // So, Other Symbol, Unicorn Face
|
|
);
|
|
const auto out = WIDEN("\""
|
|
R"(\u{8a})"
|
|
R"(\u{ad})"
|
|
"\u1d3d"
|
|
R"(\u{a0})"
|
|
R"(\u{2029})"
|
|
"\U0001f984"
|
|
"\"");
|
|
|
|
res = fdebug(in);
|
|
VERIFY( res == out );
|
|
|
|
if constexpr (sizeof(CharT) >= 2)
|
|
{
|
|
res = fdebug(in[0]);
|
|
VERIFY( res == WIDEN(R"('\u{8a}')") );
|
|
res = fdebug(in[1]);
|
|
VERIFY( res == WIDEN(R"('\u{ad}')") );
|
|
res = fdebug(in[2]);
|
|
VERIFY( res == WIDEN("'\u1d3d'") );
|
|
res = fdebug(in[3]);
|
|
VERIFY( res == WIDEN(R"('\u{a0}')") );
|
|
res = fdebug(in[4]);
|
|
VERIFY( res == WIDEN(R"('\u{2029}')") );
|
|
}
|
|
|
|
if constexpr (sizeof(CharT) >= 4)
|
|
{
|
|
res = fdebug(in[5]);
|
|
VERIFY( res == WIDEN("'\U0001f984'") );
|
|
}
|
|
#endif // UNICODE_ENC
|
|
}
|
|
|
|
template<typename CharT>
|
|
void
|
|
test_grapheme_extend()
|
|
{
|
|
#if UNICODE_ENC
|
|
std::basic_string<CharT> res;
|
|
|
|
const auto vin = WIDEN("o\u0302\u0323");
|
|
res = fdebug(vin);
|
|
VERIFY( res == WIDEN("\"o\u0302\u0323\"") );
|
|
|
|
std::basic_string_view<CharT> in = WIDEN("\t\u0302\u0323");
|
|
res = fdebug(in);
|
|
VERIFY( res == WIDEN(R"("\t\u{302}\u{323}")") );
|
|
|
|
res = fdebug(in.substr(1));
|
|
VERIFY( res == WIDEN(R"("\u{302}\u{323}")") );
|
|
|
|
if constexpr (sizeof(CharT) >= 2)
|
|
{
|
|
res = fdebug(in[1]);
|
|
VERIFY( res == WIDEN(R"('\u{302}')") );
|
|
}
|
|
#endif // UNICODE_ENC
|
|
}
|
|
|
|
template<typename CharT>
|
|
void
|
|
test_replacement_char()
|
|
{
|
|
#if UNICODE_ENC
|
|
std::basic_string<CharT> repl = WIDEN("\uFFFD");
|
|
std::basic_string<CharT> res = fdebug(repl);
|
|
VERIFY( res == WIDEN("\"\uFFFD\"") );
|
|
|
|
repl = WIDEN("\uFFFD\uFFFD");
|
|
res = fdebug(repl);
|
|
VERIFY( res == WIDEN("\"\uFFFD\uFFFD\"") );
|
|
#endif // UNICODE_ENC
|
|
}
|
|
|
|
void
|
|
test_ill_formed_utf8_seq()
|
|
{
|
|
#if UNICODE_ENC
|
|
std::string_view seq = "\xf0\x9f\xa6\x84"; // \U0001F984
|
|
std::string res;
|
|
|
|
res = fdebug(seq);
|
|
VERIFY( res == "\"\U0001F984\"" );
|
|
|
|
res = fdebug(seq.substr(1));
|
|
VERIFY( res == R"("\x{9f}\x{a6}\x{84}")" );
|
|
|
|
res = fdebug(seq.substr(2));
|
|
VERIFY( res == R"("\x{a6}\x{84}")" );
|
|
|
|
res = fdebug(seq[0]);
|
|
VERIFY( res == R"('\x{f0}')" );
|
|
res = fdebug(seq.substr(0, 1));
|
|
VERIFY( res == R"("\x{f0}")" );
|
|
|
|
res = fdebug(seq[1]);
|
|
VERIFY( res == R"('\x{9f}')" );
|
|
res = fdebug(seq.substr(1, 1));
|
|
VERIFY( res == R"("\x{9f}")" );
|
|
|
|
res = fdebug(seq[2]);
|
|
VERIFY( res == R"('\x{a6}')" );
|
|
res = fdebug(seq.substr(2, 1));
|
|
VERIFY( res == R"("\x{a6}")" );
|
|
|
|
res = fdebug(seq[3]);
|
|
VERIFY( res == R"('\x{84}')" );
|
|
res = fdebug(seq.substr(3, 1));
|
|
VERIFY( res == R"("\x{84}")" );
|
|
#endif // UNICODE_ENC
|
|
}
|
|
|
|
void
|
|
test_ill_formed_utf32()
|
|
{
|
|
#if UNICODE_ENC
|
|
std::wstring res;
|
|
|
|
wchar_t ic1 = static_cast<wchar_t>(0xff'ffff);
|
|
res = fdebug(ic1);
|
|
VERIFY( res == LR"('\x{ffffff}')" );
|
|
|
|
std::wstring is1(1, ic1);
|
|
res = fdebug(is1);
|
|
VERIFY( res == LR"("\x{ffffff}")" );
|
|
|
|
wchar_t ic2 = static_cast<wchar_t>(0xffff'ffff);
|
|
res = fdebug(ic2);
|
|
VERIFY( res == LR"('\x{ffffffff}')" );
|
|
|
|
std::wstring is2(1, ic2);
|
|
res = fdebug(is2);
|
|
VERIFY( res == LR"("\x{ffffffff}")" );
|
|
#endif // UNICODE_ENC
|
|
}
|
|
|
|
template<typename CharT>
|
|
void
|
|
test_fill()
|
|
{
|
|
std::basic_string<CharT> res;
|
|
|
|
std::basic_string_view<CharT> in = WIDEN("a\t\x10\u00ad");
|
|
res = std::format(WIDEN("{:10?}"), in.substr(0, 1));
|
|
VERIFY( res == WIDEN(R"("a" )") );
|
|
|
|
res = std::format(WIDEN("{:->10?}"), in.substr(1, 1));
|
|
VERIFY( res == WIDEN(R"(------"\t")") );
|
|
|
|
res = std::format(WIDEN("{:+<10?}"), in.substr(2, 1));
|
|
VERIFY( res == WIDEN(R"("\u{10}"++)") );
|
|
|
|
|
|
res = std::format(WIDEN("{:10?}"), in[0]);
|
|
VERIFY( res == WIDEN(R"('a' )") );
|
|
|
|
res = std::format(WIDEN("{:->10?}"), in[1]);
|
|
VERIFY( res == WIDEN(R"(------'\t')") );
|
|
|
|
res = std::format(WIDEN("{:+<10?}"), in[2]);
|
|
VERIFY( res == WIDEN(R"('\u{10}'++)") );
|
|
|
|
#if UNICODE_ENC
|
|
res = std::format(WIDEN("{:=^10?}"), in.substr(3));
|
|
VERIFY( res == WIDEN(R"(="\u{ad}"=)") );
|
|
|
|
// width is 2
|
|
std::basic_string_view<CharT> in2 = WIDEN("\u1100");
|
|
res = std::format(WIDEN("{:*^10?}"), in2);
|
|
VERIFY( res == WIDEN("***\"\u1100\"***") );
|
|
|
|
if constexpr (sizeof(CharT) >= 2)
|
|
{
|
|
res = std::format(WIDEN("{:=^10?}"), in[3]);
|
|
VERIFY( res == WIDEN(R"(='\u{ad}'=)") );
|
|
|
|
res = std::format(WIDEN("{:*^10?}"), in2[0]);
|
|
VERIFY( res == WIDEN("***'\u1100'***") );
|
|
}
|
|
#endif // UNICODE_ENC
|
|
}
|
|
|
|
template<typename CharT>
|
|
void
|
|
test_prec()
|
|
{
|
|
std::basic_string<CharT> res;
|
|
// with ? escpaed presentation is copied to ouput, same as source
|
|
|
|
std::basic_string_view<CharT> in = WIDEN("a\t\x10\u00ad");
|
|
res = std::format(WIDEN("{:.2?}"), in.substr(0, 1));
|
|
VERIFY( res == WIDEN(R"("a)") );
|
|
|
|
res = std::format(WIDEN("{:.4?}"), in.substr(1, 1));
|
|
VERIFY( res == WIDEN(R"("\t")") );
|
|
|
|
res = std::format(WIDEN("{:.5?}"), in.substr(2, 1));
|
|
VERIFY( res == WIDEN(R"("\u{1)") );
|
|
|
|
#if UNICODE_ENC
|
|
res = std::format(WIDEN("{:.10?}"), in.substr(3));
|
|
VERIFY( res == WIDEN(R"("\u{ad}")") );
|
|
|
|
std::basic_string_view<CharT> in2 = WIDEN("\u1100");
|
|
res = std::format(WIDEN("{:.3?}"), in2);
|
|
VERIFY( res == WIDEN("\"\u1100") );
|
|
#endif // UNICODE_ENC
|
|
}
|
|
|
|
bool strip_quote(std::string_view& v)
|
|
{
|
|
if (!v.starts_with('"'))
|
|
return false;
|
|
v.remove_prefix(1);
|
|
return true;
|
|
}
|
|
|
|
bool strip_quotes(std::string_view& v)
|
|
{
|
|
if (!v.starts_with('"') || !v.ends_with('"'))
|
|
return false;
|
|
v.remove_prefix(1);
|
|
v.remove_suffix(1);
|
|
return true;
|
|
}
|
|
|
|
bool strip_prefix(std::string_view& v, size_t n, char c)
|
|
{
|
|
size_t pos = v.find_first_not_of(c);
|
|
if (pos == std::string_view::npos)
|
|
pos = v.size();
|
|
if (pos != n)
|
|
return false;
|
|
v.remove_prefix(n);
|
|
return true;
|
|
}
|
|
|
|
void test_padding()
|
|
{
|
|
std::string res;
|
|
std::string_view resv;
|
|
|
|
// width and size are 26
|
|
std::string in = "abcdefghijklmnopqrstuvwxyz";
|
|
in += in; // width and size are 52
|
|
in += in; // width and size are 104
|
|
in += in; // width and size are 208
|
|
in += in; // width and size are 416
|
|
std::string_view inv = in;
|
|
|
|
resv = res = std::format("{}", in);
|
|
VERIFY( resv == inv );
|
|
|
|
resv = res = std::format("{:.500}", in);
|
|
VERIFY( resv == inv );
|
|
|
|
resv = res = std::format("{:.400}", in);
|
|
VERIFY( resv == inv.substr(0, 400) );
|
|
|
|
resv = res = std::format("{:.200}", in);
|
|
VERIFY( resv == inv.substr(0, 200) );
|
|
|
|
resv = res = std::format("{:.10}", in);
|
|
VERIFY( resv == inv.substr(0, 10) );
|
|
|
|
resv = res = std::format("{:.0}", in);
|
|
VERIFY( resv == "" );
|
|
|
|
resv = res = std::format("{:*>20}", in);
|
|
VERIFY( resv == inv );
|
|
|
|
resv = res = std::format("{:*>20.500}", in);
|
|
VERIFY( resv == inv );
|
|
|
|
resv = res = std::format("{:*>20.400}", in);
|
|
VERIFY( resv == inv.substr(0, 400) );
|
|
|
|
resv = res = std::format("{:*>20.200}", in);
|
|
VERIFY( resv == inv.substr(0, 200) );
|
|
|
|
resv = res = std::format("{:*>20.10}", in);
|
|
VERIFY( strip_prefix(resv, 10, '*') );
|
|
VERIFY( resv == inv.substr(0, 10) );
|
|
|
|
resv = res = std::format("{:*>20.0}", in);
|
|
VERIFY( strip_prefix(resv, 20, '*') );
|
|
VERIFY( resv == "" );
|
|
|
|
resv = res = std::format("{:*>450}", in);
|
|
VERIFY( strip_prefix(resv, 34, '*') );
|
|
VERIFY( resv == inv );
|
|
|
|
resv = res = std::format("{:*>450.500}", in);
|
|
VERIFY( strip_prefix(resv, 34, '*') );
|
|
VERIFY( resv == inv );
|
|
|
|
resv = res = std::format("{:*>450.420}", in);
|
|
VERIFY( strip_prefix(resv, 34, '*') );
|
|
VERIFY( resv == inv );
|
|
|
|
resv = res = std::format("{:*>450.400}", in);
|
|
VERIFY( strip_prefix(resv, 50, '*') );
|
|
VERIFY( resv == inv.substr(0, 400) );
|
|
|
|
resv = res = std::format("{:*>450.200}", in);
|
|
VERIFY( strip_prefix(resv, 250, '*') );
|
|
VERIFY( resv == inv.substr(0, 200) );
|
|
|
|
resv = res = std::format("{:*>450.10}", in);
|
|
VERIFY( strip_prefix(resv, 440, '*') );
|
|
VERIFY( resv == inv.substr(0, 10) );
|
|
|
|
resv = res = std::format("{:*>450.0}", in);
|
|
VERIFY( strip_prefix(resv, 450, '*') );
|
|
VERIFY( resv == "" );
|
|
|
|
resv = res = std::format("{:?}", in);
|
|
VERIFY( strip_quotes(resv) );
|
|
VERIFY( resv == inv );
|
|
|
|
resv = res = std::format("{:.500?}", in);
|
|
VERIFY( strip_quotes(resv) );
|
|
VERIFY( resv == inv );
|
|
|
|
resv = res = std::format("{:.400?}", in);
|
|
VERIFY( strip_quote(resv) );
|
|
VERIFY( resv == inv.substr(0, 399) );
|
|
|
|
resv = res = std::format("{:.200?}", in);
|
|
VERIFY( strip_quote(resv) );
|
|
VERIFY( resv == inv.substr(0, 199) );
|
|
|
|
resv = res = std::format("{:.10?}", in);
|
|
VERIFY( strip_quote(resv) );
|
|
VERIFY( resv == inv.substr(0, 9) );
|
|
|
|
resv = res = std::format("{:.1?}", in);
|
|
VERIFY( strip_quote(resv) );
|
|
VERIFY( resv == "" );
|
|
|
|
resv = res = std::format("{:.0?}", in);
|
|
VERIFY( resv == "" );
|
|
|
|
resv = res = std::format("{:*>20?}", in);
|
|
VERIFY( strip_quotes(resv) );
|
|
VERIFY( resv == inv );
|
|
|
|
resv = res = std::format("{:*>20.500?}", in);
|
|
VERIFY( strip_quotes(resv) );
|
|
VERIFY( resv == inv );
|
|
|
|
resv = res = std::format("{:*>20.400?}", in);
|
|
VERIFY( strip_quote(resv) );
|
|
VERIFY( resv == inv.substr(0, 399) );
|
|
|
|
resv = res = std::format("{:*>20.200?}", in);
|
|
VERIFY( strip_quote(resv) );
|
|
VERIFY( resv == inv.substr(0, 199) );
|
|
|
|
resv = res = std::format("{:*>20.10?}", in);
|
|
VERIFY( strip_prefix(resv, 10, '*') );
|
|
VERIFY( strip_quote(resv) );
|
|
VERIFY( resv == inv.substr(0, 9) );
|
|
|
|
resv = res = std::format("{:*>20.1?}", in);
|
|
VERIFY( strip_prefix(resv, 19, '*') );
|
|
VERIFY( strip_quote(resv) );
|
|
VERIFY( resv == "" );
|
|
|
|
resv = res = std::format("{:*>20.0?}", in);
|
|
VERIFY( strip_prefix(resv, 20, '*') );
|
|
VERIFY( resv == "" );
|
|
|
|
resv = res = std::format("{:*>450?}", in);
|
|
VERIFY( strip_prefix(resv, 32, '*') );
|
|
VERIFY( strip_quotes(resv) );
|
|
VERIFY( resv == inv );
|
|
|
|
resv = res = std::format("{:*>450.500?}", in);
|
|
VERIFY( strip_prefix(resv, 32, '*') );
|
|
VERIFY( strip_quotes(resv) );
|
|
VERIFY( resv == inv );
|
|
|
|
resv = res = std::format("{:*>450.420?}", in);
|
|
VERIFY( strip_prefix(resv, 32, '*') );
|
|
VERIFY( strip_quotes(resv) );
|
|
VERIFY( resv == inv );
|
|
|
|
resv = res = std::format("{:*>450.400?}", in);
|
|
VERIFY( strip_prefix(resv, 50, '*') );
|
|
VERIFY( strip_quote(resv) );
|
|
VERIFY( resv == inv.substr(0, 399) );
|
|
|
|
resv = res = std::format("{:*>450.200?}", in);
|
|
VERIFY( strip_prefix(resv, 250, '*') );
|
|
VERIFY( strip_quote(resv) );
|
|
VERIFY( resv == inv.substr(0, 199) );
|
|
|
|
resv = res = std::format("{:*>450.10?}", in);
|
|
VERIFY( strip_prefix(resv, 440, '*') );
|
|
VERIFY( strip_quote(resv) );
|
|
VERIFY( resv == inv.substr(0, 9) );
|
|
|
|
resv = res = std::format("{:*>450.1?}", in);
|
|
VERIFY( strip_prefix(resv, 449, '*') );
|
|
VERIFY( strip_quote(resv) );
|
|
VERIFY( resv == "" );
|
|
|
|
resv = res = std::format("{:*>450.0?}", in);
|
|
VERIFY( strip_prefix(resv, 450, '*') );
|
|
VERIFY( resv == "" );
|
|
|
|
#if UNICODE_ENC
|
|
// width is 3, size is 15
|
|
in = "o\u0302\u0323i\u0302\u0323u\u0302\u0323";
|
|
in += in; // width is 6, size is 30
|
|
in += in; // width is 12, size is 60
|
|
in += in; // width is 24, size is 120
|
|
in += in; // width is 48, size is 240
|
|
in += in; // width is 96, size is 480
|
|
in += in; // width is 192, size is 960
|
|
inv = in;
|
|
|
|
resv = res = std::format("{:}", in);
|
|
VERIFY( resv == inv );
|
|
|
|
resv = res = std::format("{:.200}", in);
|
|
VERIFY( resv == inv );
|
|
|
|
resv = res = std::format("{:.96}", in);
|
|
VERIFY( resv == inv.substr(0, 480) );
|
|
|
|
resv = res = std::format("{:.12}", in);
|
|
VERIFY( resv == inv.substr(0, 60) );
|
|
|
|
resv = res = std::format("{:.3}", in);
|
|
VERIFY( resv == inv.substr(0, 15) );
|
|
|
|
resv = res = std::format("{:.0}", in);
|
|
VERIFY( resv == "" );
|
|
|
|
resv = res = std::format("{:*>10}", in);
|
|
VERIFY( resv == inv );
|
|
|
|
resv = res = std::format("{:*>10.200}", in);
|
|
VERIFY( resv == inv );
|
|
|
|
resv = res = std::format("{:*>10.96}", in);
|
|
VERIFY( resv == inv.substr(0, 480) );
|
|
|
|
resv = res = std::format("{:*>10.12}", in);
|
|
VERIFY( resv == inv.substr(0, 60) );
|
|
|
|
resv = res = std::format("{:*>10.3}", in);
|
|
VERIFY( strip_prefix(resv, 7, '*') );
|
|
VERIFY( resv == inv.substr(0, 15) );
|
|
|
|
resv = res = std::format("{:*>10.0}", in);
|
|
VERIFY( strip_prefix(resv, 10, '*') );
|
|
VERIFY( resv == "" );
|
|
|
|
resv = res = std::format("{:*>240s}", in);
|
|
VERIFY( strip_prefix(resv, 48, '*') );
|
|
VERIFY( resv == inv );
|
|
|
|
resv = res = std::format("{:*>300.200s}", in);
|
|
VERIFY( strip_prefix(resv, 108, '*') );
|
|
VERIFY( resv == inv );
|
|
|
|
resv = res = std::format("{:*>240.200s}", in);
|
|
VERIFY( strip_prefix(resv, 48, '*') );
|
|
VERIFY( resv == inv );
|
|
|
|
resv = res = std::format("{:*>240.96s}", in);
|
|
VERIFY( strip_prefix(resv, 144, '*') );
|
|
VERIFY( resv == inv.substr(0, 480) );
|
|
|
|
resv = res = std::format("{:*>240.12}", in);
|
|
VERIFY( strip_prefix(resv, 228, '*') );
|
|
VERIFY( resv == inv.substr(0, 60) );
|
|
|
|
resv = res = std::format("{:*>240.3s}", in);
|
|
VERIFY( strip_prefix(resv, 237, '*') );
|
|
VERIFY( resv == inv.substr(0, 15) );
|
|
|
|
resv = res = std::format("{:*>240.0s}", in);
|
|
VERIFY( strip_prefix(resv, 240, '*') );
|
|
VERIFY( resv == "" );
|
|
|
|
resv = res = std::format("{:?}", in);
|
|
VERIFY( strip_quotes(resv) );
|
|
VERIFY( resv == inv );
|
|
|
|
resv = res = std::format("{:.200?}", in);
|
|
VERIFY( strip_quotes(resv) );
|
|
VERIFY( resv == inv );
|
|
|
|
resv = res = std::format("{:.97?}", in);
|
|
VERIFY( strip_quote(resv) );
|
|
VERIFY( resv == inv.substr(0, 480) );
|
|
|
|
resv = res = std::format("{:.13?}", in);
|
|
VERIFY( strip_quote(resv) );
|
|
VERIFY( resv == inv.substr(0, 60) );
|
|
|
|
resv = res = std::format("{:.4?}", in);
|
|
VERIFY( strip_quote(resv) );
|
|
VERIFY( resv == inv.substr(0, 15) );
|
|
|
|
resv = res = std::format("{:.1?}", in);
|
|
VERIFY( strip_quote(resv) );
|
|
VERIFY( resv == "" );
|
|
|
|
resv = res = std::format("{:.0?}", in);
|
|
VERIFY( resv == "" );
|
|
|
|
resv = res = std::format("{:*>10?}", in);
|
|
VERIFY( strip_quotes(resv) );
|
|
VERIFY( resv == inv );
|
|
|
|
resv = res = std::format("{:*>10.200?}", in);
|
|
VERIFY( strip_quotes(resv) );
|
|
VERIFY( resv == inv );
|
|
|
|
resv = res = std::format("{:*>10.97?}", in);
|
|
VERIFY( strip_quote(resv) );
|
|
VERIFY( resv == inv.substr(0, 480) );
|
|
|
|
resv = res = std::format("{:*>10.13?}", in);
|
|
VERIFY( strip_quote(resv) );
|
|
VERIFY( resv == inv.substr(0, 60) );
|
|
|
|
resv = res = std::format("{:*>10.4?}", in);
|
|
VERIFY( strip_prefix(resv, 6, '*') );
|
|
VERIFY( strip_quote(resv) );
|
|
VERIFY( resv == inv.substr(0, 15) );
|
|
|
|
resv = res = std::format("{:*>10.1?}", in);
|
|
VERIFY( strip_prefix(resv, 9, '*') );
|
|
VERIFY( strip_quote(resv) );
|
|
VERIFY( resv == "" );
|
|
|
|
resv = res = std::format("{:*>10.0?}", in);
|
|
VERIFY( strip_prefix(resv, 10, '*') );
|
|
VERIFY( resv == "" );
|
|
|
|
resv = res = std::format("{:*>240?}", in);
|
|
VERIFY( strip_prefix(resv, 46, '*') );
|
|
VERIFY( strip_quotes(resv) );
|
|
VERIFY( resv == inv );
|
|
|
|
resv = res = std::format("{:*>300.200?}", in);
|
|
VERIFY( strip_prefix(resv, 106, '*') );
|
|
VERIFY( strip_quotes(resv) );
|
|
VERIFY( resv == inv );
|
|
|
|
resv = res = std::format("{:*>240.200?}", in);
|
|
VERIFY( strip_prefix(resv, 46, '*') );
|
|
VERIFY( strip_quotes(resv) );
|
|
VERIFY( resv == inv );
|
|
|
|
resv = res = std::format("{:*>240.97?}", in);
|
|
VERIFY( strip_prefix(resv, 143, '*') );
|
|
VERIFY( strip_quote(resv) );
|
|
VERIFY( resv == inv.substr(0, 480) );
|
|
|
|
resv = res = std::format("{:*>240.13?}", in);
|
|
VERIFY( strip_prefix(resv, 227, '*') );
|
|
VERIFY( strip_quote(resv) );
|
|
VERIFY( resv == inv.substr(0, 60) );
|
|
|
|
resv = res = std::format("{:*>240.4?}", in);
|
|
VERIFY( strip_prefix(resv, 236, '*') );
|
|
VERIFY( strip_quote(resv) );
|
|
VERIFY( resv == inv.substr(0, 15) );
|
|
|
|
resv = res = std::format("{:*>240.1?}", in);
|
|
VERIFY( strip_prefix(resv, 239, '*') );
|
|
VERIFY( strip_quote(resv) );
|
|
VERIFY( resv == "" );
|
|
|
|
resv = res = std::format("{:*>240.0?}", in);
|
|
VERIFY( strip_prefix(resv, 240, '*') );
|
|
VERIFY( resv == "" );
|
|
#endif // UNICODE_ENC
|
|
}
|
|
|
|
void test_char_as_wchar()
|
|
{
|
|
std::wstring res;
|
|
|
|
res = std::format(L"{:?}", 'a');
|
|
VERIFY( res == LR"('a')" );
|
|
|
|
res = std::format(L"{:?}", '\t');
|
|
VERIFY( res == LR"('\t')" );
|
|
|
|
res = std::format(L"{:+<10?}", '\x10');
|
|
VERIFY( res == LR"('\u{10}'++)" );
|
|
}
|
|
|
|
template<typename T>
|
|
struct DebugWrapper
|
|
{
|
|
T val;
|
|
};
|
|
|
|
template<typename T, typename CharT>
|
|
struct std::formatter<DebugWrapper<T>, CharT>
|
|
{
|
|
constexpr std::basic_format_parse_context<CharT>::iterator
|
|
parse(std::basic_format_parse_context<CharT>& pc)
|
|
{
|
|
auto out = under.parse(pc);
|
|
under.set_debug_format();
|
|
return out;
|
|
}
|
|
|
|
template<typename Out>
|
|
Out format(DebugWrapper<T> const& t,
|
|
std::basic_format_context<Out, CharT>& fc) const
|
|
{ return under.format(t.val, fc); }
|
|
|
|
private:
|
|
std::formatter<T, CharT> under;
|
|
};
|
|
|
|
template<typename CharT, typename StrT>
|
|
void
|
|
test_formatter_str()
|
|
{
|
|
CharT buf[]{ 'a', 'b', 'c', 0 };
|
|
DebugWrapper<StrT> in{ buf };
|
|
std::basic_string<CharT> res = std::format(WIDEN("{:?}"), in );
|
|
VERIFY( res == WIDEN(R"("abc")") );
|
|
}
|
|
|
|
template<typename CharT>
|
|
void
|
|
test_formatter_arr()
|
|
{
|
|
std::basic_string<CharT> res;
|
|
|
|
DebugWrapper<CharT[3]> in3{ 'a', 'b', 'c' };
|
|
res = std::format(WIDEN("{:?}"), in3 );
|
|
VERIFY( res == WIDEN(R"("abc")") );
|
|
|
|
// We print all characters, including null-terminator
|
|
DebugWrapper<CharT[4]> in4{ 'a', 'b', 'c', 0 };
|
|
res = std::format(WIDEN("{:?}"), in4 );
|
|
VERIFY( res == WIDEN(R"("abc\u{0}")") );
|
|
}
|
|
|
|
template<typename CharT, typename SrcT>
|
|
void
|
|
test_formatter_char()
|
|
{
|
|
DebugWrapper<SrcT> in{ 'a' };
|
|
std::basic_string<CharT> res = std::format(WIDEN("{:?}"), in);
|
|
VERIFY( res == WIDEN(R"('a')") );
|
|
}
|
|
|
|
template<typename CharT>
|
|
void
|
|
test_formatters()
|
|
{
|
|
test_formatter_char<CharT, CharT>();
|
|
test_formatter_str<CharT, CharT*>();
|
|
test_formatter_str<CharT, const CharT*>();
|
|
test_formatter_str<CharT, std::basic_string<CharT>>();
|
|
test_formatter_str<CharT, std::basic_string_view<CharT>>();
|
|
test_formatter_arr<CharT>();
|
|
}
|
|
|
|
void
|
|
test_formatters_c()
|
|
{
|
|
test_formatters<char>();
|
|
test_formatters<wchar_t>();
|
|
test_formatter_char<wchar_t, char>();
|
|
}
|
|
|
|
int main()
|
|
{
|
|
test_basic_escapes<char>();
|
|
test_basic_escapes<wchar_t>();
|
|
test_ascii_escapes<char>();
|
|
test_ascii_escapes<wchar_t>();
|
|
test_extended_ascii<char>();
|
|
test_extended_ascii<wchar_t>();
|
|
|
|
test_unicode_escapes<char>();
|
|
test_unicode_escapes<wchar_t>();
|
|
test_grapheme_extend<char>();
|
|
test_grapheme_extend<wchar_t>();
|
|
test_replacement_char<char>();
|
|
test_replacement_char<wchar_t>();
|
|
test_ill_formed_utf8_seq();
|
|
test_ill_formed_utf32();
|
|
|
|
test_fill<char>();
|
|
test_fill<wchar_t>();
|
|
test_prec<char>();
|
|
test_prec<wchar_t>();
|
|
|
|
test_padding();
|
|
|
|
test_formatters_c();
|
|
}
|