forked from OSchip/llvm-project
[libcxx] [test] Fix get/put long_double_ru_RU on Glibc, FreeBSD and Windows
Note, reducing ios.width() in put_long_double instead of using variable padding, when using a variable width symbol. Some of those tests didn't actually trigger any padding in the existing form, with a longer currency symbol; reduce the width so there's no actual padding with the slightly shorter currency symbol either. The tests for the international currency symbol use the same amount of padding on all platforms, so they still exercise the padding properly. Differential Revision: https://reviews.llvm.org/D120317
This commit is contained in:
parent
47f4cd9c3d
commit
df1e43c496
|
@ -28,6 +28,7 @@
|
|||
#include <cassert>
|
||||
#include "test_iterators.h"
|
||||
|
||||
#include "locale_helpers.h"
|
||||
#include "platform_support.h" // locale name macros
|
||||
#include "test_macros.h"
|
||||
|
||||
|
@ -52,36 +53,8 @@ public:
|
|||
: Fw(refs) {}
|
||||
};
|
||||
|
||||
// GLIBC 2.27 and newer use U+202F NARROW NO-BREAK SPACE as a thousands separator.
|
||||
// This function converts the spaces in string inputs to U+202F if need
|
||||
// be. FreeBSD's locale data also uses U+202F, since 2018.
|
||||
// Windows uses U+00A0 NO-BREAK SPACE.
|
||||
static std::wstring convert_thousands_sep(std::wstring const& in) {
|
||||
#if defined(_CS_GNU_LIBC_VERSION) || defined(__FreeBSD__) || defined(_WIN32)
|
||||
#if defined(_CS_GNU_LIBC_VERSION)
|
||||
if (glibc_version_less_than("2.27"))
|
||||
return in;
|
||||
#endif
|
||||
std::wstring out;
|
||||
unsigned I = 0;
|
||||
bool seen_decimal = false;
|
||||
for (; I < in.size(); ++I) {
|
||||
if (seen_decimal || in[I] != L' ') {
|
||||
seen_decimal |= in[I] == L',';
|
||||
out.push_back(in[I]);
|
||||
continue;
|
||||
}
|
||||
assert(in[I] == L' ');
|
||||
#if defined(_WIN32)
|
||||
out.push_back(L'\u00A0');
|
||||
#else
|
||||
out.push_back(L'\u202F');
|
||||
#endif
|
||||
}
|
||||
return out;
|
||||
#else
|
||||
return in;
|
||||
#endif
|
||||
return LocaleHelpers::convert_thousands_sep_fr_FR(in);
|
||||
}
|
||||
#endif // TEST_HAS_NO_WIDE_CHARACTERS
|
||||
|
||||
|
|
|
@ -9,14 +9,6 @@
|
|||
// NetBSD does not support LC_MONETARY at the moment
|
||||
// XFAIL: netbsd
|
||||
|
||||
// Failure related to GLIBC's use of U00A0 as mon_thousands_sep
|
||||
// and U002E as mon_decimal_point.
|
||||
// TODO: U00A0 should be investigated.
|
||||
// Possibly related to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=16006
|
||||
// XFAIL: linux
|
||||
|
||||
// XFAIL: LIBCXX-WINDOWS-FIXME
|
||||
|
||||
// REQUIRES: locale.ru_RU.UTF-8
|
||||
|
||||
// <locale>
|
||||
|
@ -33,6 +25,7 @@
|
|||
#include "test_macros.h"
|
||||
#include "test_iterators.h"
|
||||
|
||||
#include "locale_helpers.h"
|
||||
#include "platform_support.h" // locale name macros
|
||||
|
||||
typedef std::money_get<char, cpp17_input_iterator<const char*> > Fn;
|
||||
|
@ -55,7 +48,11 @@ public:
|
|||
explicit my_facetw(std::size_t refs = 0)
|
||||
: Fw(refs) {}
|
||||
};
|
||||
#endif
|
||||
|
||||
static std::wstring convert_thousands_sep(std::wstring const& in) {
|
||||
return LocaleHelpers::convert_thousands_sep_ru_RU(in);
|
||||
}
|
||||
#endif // TEST_HAS_NO_WIDE_CHARACTERS
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
|
@ -71,6 +68,7 @@ int main(int, char**)
|
|||
ios.imbue(std::locale(ios.getloc(),
|
||||
new std::moneypunct_byname<wchar_t, true>(loc_name)));
|
||||
#endif
|
||||
std::string symbol(LocaleHelpers::currency_symbol_ru_RU());
|
||||
{
|
||||
const my_facet f(1);
|
||||
// char, national
|
||||
|
@ -130,7 +128,7 @@ int main(int, char**)
|
|||
assert(ex == -123456789);
|
||||
}
|
||||
{ // zero, showbase
|
||||
std::string v = "0,00 \xD1\x80\xD1\x83\xD0\xB1"".";
|
||||
std::string v = "0,00 " + symbol;
|
||||
typedef cpp17_input_iterator<const char*> I;
|
||||
long double ex;
|
||||
std::ios_base::iostate err = std::ios_base::goodbit;
|
||||
|
@ -141,7 +139,7 @@ int main(int, char**)
|
|||
assert(ex == 0);
|
||||
}
|
||||
{ // zero, showbase
|
||||
std::string v = "0,00 \xD1\x80\xD1\x83\xD0\xB1"".";
|
||||
std::string v = "0,00 " + symbol;
|
||||
std::showbase(ios);
|
||||
typedef cpp17_input_iterator<const char*> I;
|
||||
long double ex;
|
||||
|
@ -154,7 +152,7 @@ int main(int, char**)
|
|||
std::noshowbase(ios);
|
||||
}
|
||||
{ // negative one, showbase
|
||||
std::string v = "-0,01 \xD1\x80\xD1\x83\xD0\xB1"".";
|
||||
std::string v = "-0,01 " + symbol;
|
||||
typedef cpp17_input_iterator<const char*> I;
|
||||
long double ex;
|
||||
std::ios_base::iostate err = std::ios_base::goodbit;
|
||||
|
@ -165,7 +163,7 @@ int main(int, char**)
|
|||
assert(ex == -1);
|
||||
}
|
||||
{ // negative one, showbase
|
||||
std::string v = "-0,01 \xD1\x80\xD1\x83\xD0\xB1"".";
|
||||
std::string v = "-0,01 " + symbol;
|
||||
std::showbase(ios);
|
||||
typedef cpp17_input_iterator<const char*> I;
|
||||
long double ex;
|
||||
|
@ -178,7 +176,7 @@ int main(int, char**)
|
|||
std::noshowbase(ios);
|
||||
}
|
||||
{ // positive, showbase
|
||||
std::string v = "1 234 567,89 \xD1\x80\xD1\x83\xD0\xB1"".";
|
||||
std::string v = "1 234 567,89 " + symbol;
|
||||
typedef cpp17_input_iterator<const char*> I;
|
||||
long double ex;
|
||||
std::ios_base::iostate err = std::ios_base::goodbit;
|
||||
|
@ -189,7 +187,7 @@ int main(int, char**)
|
|||
assert(ex == 123456789);
|
||||
}
|
||||
{ // positive, showbase
|
||||
std::string v = "1 234 567,89 \xD1\x80\xD1\x83\xD0\xB1"".";
|
||||
std::string v = "1 234 567,89 " + symbol;
|
||||
std::showbase(ios);
|
||||
typedef cpp17_input_iterator<const char*> I;
|
||||
long double ex;
|
||||
|
@ -202,7 +200,7 @@ int main(int, char**)
|
|||
std::noshowbase(ios);
|
||||
}
|
||||
{ // negative, showbase
|
||||
std::string v = "-1 234 567,89 \xD1\x80\xD1\x83\xD0\xB1"".";
|
||||
std::string v = "-1 234 567,89 " + symbol;
|
||||
std::showbase(ios);
|
||||
typedef cpp17_input_iterator<const char*> I;
|
||||
long double ex;
|
||||
|
@ -382,7 +380,7 @@ int main(int, char**)
|
|||
std::noshowbase(ios);
|
||||
}
|
||||
{ // negative, showbase
|
||||
std::string v = "-1 234 567,89 \xD1\x80\xD1\x83\xD0\xB1"".";
|
||||
std::string v = "-1 234 567,89 " + symbol;
|
||||
std::showbase(ios);
|
||||
typedef cpp17_input_iterator<const char*> I;
|
||||
long double ex;
|
||||
|
@ -394,7 +392,7 @@ int main(int, char**)
|
|||
std::noshowbase(ios);
|
||||
}
|
||||
{ // negative, showbase
|
||||
std::string v = "-1 234 567,89 \xD1\x80\xD1\x83\xD0\xB1"".";
|
||||
std::string v = "-1 234 567,89 " + symbol;
|
||||
typedef cpp17_input_iterator<const char*> I;
|
||||
long double ex;
|
||||
std::ios_base::iostate err = std::ios_base::goodbit;
|
||||
|
@ -406,6 +404,7 @@ int main(int, char**)
|
|||
}
|
||||
}
|
||||
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
|
||||
std::wstring wsymbol(LocaleHelpers::currency_symbol_ru_RU());
|
||||
{
|
||||
const my_facetw f(1);
|
||||
// wchar_t, national
|
||||
|
@ -432,7 +431,7 @@ int main(int, char**)
|
|||
assert(ex == -1);
|
||||
}
|
||||
{ // positive
|
||||
std::wstring v = L"1 234 567,89 ";
|
||||
std::wstring v = convert_thousands_sep(L"1 234 567,89 ");
|
||||
typedef cpp17_input_iterator<const wchar_t*> I;
|
||||
long double ex;
|
||||
std::ios_base::iostate err = std::ios_base::goodbit;
|
||||
|
@ -443,7 +442,7 @@ int main(int, char**)
|
|||
assert(ex == 123456789);
|
||||
}
|
||||
{ // negative
|
||||
std::wstring v = L"-1 234 567,89 ";
|
||||
std::wstring v = convert_thousands_sep(L"-1 234 567,89 ");
|
||||
typedef cpp17_input_iterator<const wchar_t*> I;
|
||||
long double ex;
|
||||
std::ios_base::iostate err = std::ios_base::goodbit;
|
||||
|
@ -465,7 +464,7 @@ int main(int, char**)
|
|||
assert(ex == -123456789);
|
||||
}
|
||||
{ // zero, showbase
|
||||
std::wstring v = L"0,00 \x440\x443\x431"".";
|
||||
std::wstring v = L"0,00 " + wsymbol;
|
||||
typedef cpp17_input_iterator<const wchar_t*> I;
|
||||
long double ex;
|
||||
std::ios_base::iostate err = std::ios_base::goodbit;
|
||||
|
@ -476,7 +475,7 @@ int main(int, char**)
|
|||
assert(ex == 0);
|
||||
}
|
||||
{ // zero, showbase
|
||||
std::wstring v = L"0,00 \x440\x443\x431"".";
|
||||
std::wstring v = L"0,00 " + wsymbol;
|
||||
std::showbase(ios);
|
||||
typedef cpp17_input_iterator<const wchar_t*> I;
|
||||
long double ex;
|
||||
|
@ -489,7 +488,7 @@ int main(int, char**)
|
|||
std::noshowbase(ios);
|
||||
}
|
||||
{ // negative one, showbase
|
||||
std::wstring v = L"-0,01 \x440\x443\x431"".";
|
||||
std::wstring v = L"-0,01 " + wsymbol;
|
||||
typedef cpp17_input_iterator<const wchar_t*> I;
|
||||
long double ex;
|
||||
std::ios_base::iostate err = std::ios_base::goodbit;
|
||||
|
@ -500,7 +499,7 @@ int main(int, char**)
|
|||
assert(ex == -1);
|
||||
}
|
||||
{ // negative one, showbase
|
||||
std::wstring v = L"-0,01 \x440\x443\x431"".";
|
||||
std::wstring v = L"-0,01 " + wsymbol;
|
||||
std::showbase(ios);
|
||||
typedef cpp17_input_iterator<const wchar_t*> I;
|
||||
long double ex;
|
||||
|
@ -513,7 +512,7 @@ int main(int, char**)
|
|||
std::noshowbase(ios);
|
||||
}
|
||||
{ // positive, showbase
|
||||
std::wstring v = L"1 234 567,89 \x440\x443\x431"".";
|
||||
std::wstring v = convert_thousands_sep(L"1 234 567,89 ") + wsymbol;
|
||||
typedef cpp17_input_iterator<const wchar_t*> I;
|
||||
long double ex;
|
||||
std::ios_base::iostate err = std::ios_base::goodbit;
|
||||
|
@ -524,7 +523,7 @@ int main(int, char**)
|
|||
assert(ex == 123456789);
|
||||
}
|
||||
{ // positive, showbase
|
||||
std::wstring v = L"1 234 567,89 \x440\x443\x431"".";
|
||||
std::wstring v = convert_thousands_sep(L"1 234 567,89 ") + wsymbol;
|
||||
std::showbase(ios);
|
||||
typedef cpp17_input_iterator<const wchar_t*> I;
|
||||
long double ex;
|
||||
|
@ -537,7 +536,7 @@ int main(int, char**)
|
|||
std::noshowbase(ios);
|
||||
}
|
||||
{ // negative, showbase
|
||||
std::wstring v = L"-1 234 567,89 \x440\x443\x431"".";
|
||||
std::wstring v = convert_thousands_sep(L"-1 234 567,89 ") + wsymbol;
|
||||
std::showbase(ios);
|
||||
typedef cpp17_input_iterator<const wchar_t*> I;
|
||||
long double ex;
|
||||
|
@ -550,7 +549,7 @@ int main(int, char**)
|
|||
std::noshowbase(ios);
|
||||
}
|
||||
{ // negative, showbase
|
||||
std::wstring v = L"-1 234 567,89 RUB";
|
||||
std::wstring v = convert_thousands_sep(L"-1 234 567,89 RUB");
|
||||
std::showbase(ios);
|
||||
typedef cpp17_input_iterator<const wchar_t*> I;
|
||||
long double ex;
|
||||
|
@ -562,7 +561,7 @@ int main(int, char**)
|
|||
std::noshowbase(ios);
|
||||
}
|
||||
{ // negative, showbase
|
||||
std::wstring v = L"-1 234 567,89 RUB";
|
||||
std::wstring v = convert_thousands_sep(L"-1 234 567,89 RUB");
|
||||
typedef cpp17_input_iterator<const wchar_t*> I;
|
||||
long double ex;
|
||||
std::ios_base::iostate err = std::ios_base::goodbit;
|
||||
|
@ -599,7 +598,7 @@ int main(int, char**)
|
|||
assert(ex == -1);
|
||||
}
|
||||
{ // positive
|
||||
std::wstring v = L"1 234 567,89 ";
|
||||
std::wstring v = convert_thousands_sep(L"1 234 567,89 ");
|
||||
typedef cpp17_input_iterator<const wchar_t*> I;
|
||||
long double ex;
|
||||
std::ios_base::iostate err = std::ios_base::goodbit;
|
||||
|
@ -610,7 +609,7 @@ int main(int, char**)
|
|||
assert(ex == 123456789);
|
||||
}
|
||||
{ // negative
|
||||
std::wstring v = L"-1 234 567,89 ";
|
||||
std::wstring v = convert_thousands_sep(L"-1 234 567,89 ");
|
||||
typedef cpp17_input_iterator<const wchar_t*> I;
|
||||
long double ex;
|
||||
std::ios_base::iostate err = std::ios_base::goodbit;
|
||||
|
@ -680,7 +679,7 @@ int main(int, char**)
|
|||
std::noshowbase(ios);
|
||||
}
|
||||
{ // positive, showbase
|
||||
std::wstring v = L"1 234 567,89 RUB";
|
||||
std::wstring v = convert_thousands_sep(L"1 234 567,89 RUB");
|
||||
typedef cpp17_input_iterator<const wchar_t*> I;
|
||||
long double ex;
|
||||
std::ios_base::iostate err = std::ios_base::goodbit;
|
||||
|
@ -691,7 +690,7 @@ int main(int, char**)
|
|||
assert(ex == 123456789);
|
||||
}
|
||||
{ // positive, showbase
|
||||
std::wstring v = L"1 234 567,89 RUB";
|
||||
std::wstring v = convert_thousands_sep(L"1 234 567,89 RUB");
|
||||
std::showbase(ios);
|
||||
typedef cpp17_input_iterator<const wchar_t*> I;
|
||||
long double ex;
|
||||
|
@ -704,7 +703,7 @@ int main(int, char**)
|
|||
std::noshowbase(ios);
|
||||
}
|
||||
{ // negative, showbase
|
||||
std::wstring v = L"-1 234 567,89 RUB";
|
||||
std::wstring v = convert_thousands_sep(L"-1 234 567,89 RUB");
|
||||
std::showbase(ios);
|
||||
typedef cpp17_input_iterator<const wchar_t*> I;
|
||||
long double ex;
|
||||
|
@ -717,7 +716,7 @@ int main(int, char**)
|
|||
std::noshowbase(ios);
|
||||
}
|
||||
{ // negative, showbase
|
||||
std::wstring v = L"-1 234 567,89 \x440\x443\x431"".";
|
||||
std::wstring v = convert_thousands_sep(L"-1 234 567,89 ") + wsymbol;
|
||||
std::showbase(ios);
|
||||
typedef cpp17_input_iterator<const wchar_t*> I;
|
||||
long double ex;
|
||||
|
@ -729,7 +728,7 @@ int main(int, char**)
|
|||
std::noshowbase(ios);
|
||||
}
|
||||
{ // negative, showbase
|
||||
std::wstring v = L"-1 234 567,89 \x440\x443\x431"".";
|
||||
std::wstring v = convert_thousands_sep(L"-1 234 567,89 ") + wsymbol;
|
||||
typedef cpp17_input_iterator<const wchar_t*> I;
|
||||
long double ex;
|
||||
std::ios_base::iostate err = std::ios_base::goodbit;
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <cassert>
|
||||
#include "test_iterators.h"
|
||||
|
||||
#include "locale_helpers.h"
|
||||
#include "platform_support.h" // locale name macros
|
||||
#include "test_macros.h"
|
||||
|
||||
|
@ -52,38 +53,8 @@ public:
|
|||
: Fw(refs) {}
|
||||
};
|
||||
|
||||
// GLIBC 2.27 and newer use U+202F NARROW NO-BREAK SPACE as a thousands separator.
|
||||
// This function converts the spaces in string inputs to U+202F if need
|
||||
// be. FreeBSD's locale data also uses U+202F, since 2018.
|
||||
// Windows uses U+00A0 NO-BREAK SPACE.
|
||||
static std::wstring convert_thousands_sep(std::wstring const& in) {
|
||||
#if defined(_CS_GNU_LIBC_VERSION) || defined(__FreeBSD__) || defined(_WIN32)
|
||||
#if defined(_CS_GNU_LIBC_VERSION)
|
||||
if (glibc_version_less_than("2.27"))
|
||||
return in;
|
||||
#endif
|
||||
std::wstring out;
|
||||
unsigned I = 0;
|
||||
bool seen_num_start = false;
|
||||
bool seen_decimal = false;
|
||||
for (; I < in.size(); ++I) {
|
||||
seen_decimal |= in[I] == L',';
|
||||
seen_num_start |= in[I] == '-' || std::iswdigit(in[I]);
|
||||
if (seen_decimal || !seen_num_start || in[I] != L' ') {
|
||||
out.push_back(in[I]);
|
||||
continue;
|
||||
}
|
||||
assert(in[I] == L' ');
|
||||
#if defined(_WIN32)
|
||||
out.push_back(L'\u00A0');
|
||||
#else
|
||||
out.push_back(L'\u202F');
|
||||
#endif
|
||||
}
|
||||
return out;
|
||||
#else
|
||||
return in;
|
||||
#endif
|
||||
return LocaleHelpers::convert_thousands_sep_fr_FR(in);
|
||||
}
|
||||
#endif // TEST_HAS_NO_WIDE_CHARACTERS
|
||||
|
||||
|
|
|
@ -9,14 +9,6 @@
|
|||
// NetBSD does not support LC_MONETARY at the moment
|
||||
// XFAIL: netbsd
|
||||
|
||||
// Failure related to GLIBC's use of U00A0 as mon_thousands_sep
|
||||
// and U002E as mon_decimal_point.
|
||||
// TODO: U00A0 should be investigated.
|
||||
// Possibly related to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=16006
|
||||
// XFAIL: linux
|
||||
|
||||
// XFAIL: LIBCXX-WINDOWS-FIXME
|
||||
|
||||
// REQUIRES: locale.ru_RU.UTF-8
|
||||
|
||||
// <locale>
|
||||
|
@ -33,6 +25,7 @@
|
|||
#include "test_macros.h"
|
||||
#include "test_iterators.h"
|
||||
|
||||
#include "locale_helpers.h"
|
||||
#include "platform_support.h" // locale name macros
|
||||
|
||||
typedef std::money_put<char, cpp17_output_iterator<char*> > Fn;
|
||||
|
@ -55,7 +48,11 @@ public:
|
|||
explicit my_facetw(std::size_t refs = 0)
|
||||
: Fw(refs) {}
|
||||
};
|
||||
#endif
|
||||
|
||||
static std::wstring convert_thousands_sep(std::wstring const& in) {
|
||||
return LocaleHelpers::convert_thousands_sep_ru_RU(in);
|
||||
}
|
||||
#endif // TEST_HAS_NO_WIDE_CHARACTERS
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
|
@ -72,6 +69,7 @@ int main(int, char**)
|
|||
new std::moneypunct_byname<wchar_t, true>(loc_name)));
|
||||
#endif
|
||||
{
|
||||
std::string symbol(LocaleHelpers::currency_symbol_ru_RU());
|
||||
const my_facet f(1);
|
||||
// char, national
|
||||
{ // zero
|
||||
|
@ -108,7 +106,7 @@ int main(int, char**)
|
|||
char str[100];
|
||||
cpp17_output_iterator<char*> iter = f.put(cpp17_output_iterator<char*>(str), false, ios, '*', v);
|
||||
std::string ex(str, iter.base());
|
||||
assert(ex == "0,00 \xD1\x80\xD1\x83\xD0\xB1"".");
|
||||
assert(ex == "0,00 " + symbol);
|
||||
}
|
||||
{ // negative one, showbase
|
||||
long double v = -1;
|
||||
|
@ -116,7 +114,7 @@ int main(int, char**)
|
|||
char str[100];
|
||||
cpp17_output_iterator<char*> iter = f.put(cpp17_output_iterator<char*>(str), false, ios, '*', v);
|
||||
std::string ex(str, iter.base());
|
||||
assert(ex == "-0,01 \xD1\x80\xD1\x83\xD0\xB1"".");
|
||||
assert(ex == "-0,01 " + symbol);
|
||||
}
|
||||
{ // positive, showbase
|
||||
long double v = 123456789;
|
||||
|
@ -124,7 +122,7 @@ int main(int, char**)
|
|||
char str[100];
|
||||
cpp17_output_iterator<char*> iter = f.put(cpp17_output_iterator<char*>(str), false, ios, '*', v);
|
||||
std::string ex(str, iter.base());
|
||||
assert(ex == "1 234 567,89 \xD1\x80\xD1\x83\xD0\xB1"".");
|
||||
assert(ex == "1 234 567,89 " + symbol);
|
||||
}
|
||||
{ // negative, showbase
|
||||
long double v = -123456789;
|
||||
|
@ -132,39 +130,39 @@ int main(int, char**)
|
|||
char str[100];
|
||||
cpp17_output_iterator<char*> iter = f.put(cpp17_output_iterator<char*>(str), false, ios, '*', v);
|
||||
std::string ex(str, iter.base());
|
||||
assert(ex == "-1 234 567,89 \xD1\x80\xD1\x83\xD0\xB1"".");
|
||||
assert(ex == "-1 234 567,89 " + symbol);
|
||||
}
|
||||
{ // negative, showbase, left
|
||||
long double v = -123456789;
|
||||
std::showbase(ios);
|
||||
ios.width(20);
|
||||
ios.width(15);
|
||||
std::left(ios);
|
||||
char str[100];
|
||||
cpp17_output_iterator<char*> iter = f.put(cpp17_output_iterator<char*>(str), false, ios, ' ', v);
|
||||
std::string ex(str, iter.base());
|
||||
assert(ex == "-1 234 567,89 \xD1\x80\xD1\x83\xD0\xB1"".");
|
||||
assert(ex == "-1 234 567,89 " + symbol);
|
||||
assert(ios.width() == 0);
|
||||
}
|
||||
{ // negative, showbase, internal
|
||||
long double v = -123456789;
|
||||
std::showbase(ios);
|
||||
ios.width(20);
|
||||
ios.width(15);
|
||||
std::internal(ios);
|
||||
char str[100];
|
||||
cpp17_output_iterator<char*> iter = f.put(cpp17_output_iterator<char*>(str), false, ios, ' ', v);
|
||||
std::string ex(str, iter.base());
|
||||
assert(ex == "-1 234 567,89 \xD1\x80\xD1\x83\xD0\xB1"".");
|
||||
assert(ex == "-1 234 567,89 " + symbol);
|
||||
assert(ios.width() == 0);
|
||||
}
|
||||
{ // negative, showbase, right
|
||||
long double v = -123456789;
|
||||
std::showbase(ios);
|
||||
ios.width(20);
|
||||
ios.width(15);
|
||||
std::right(ios);
|
||||
char str[100];
|
||||
cpp17_output_iterator<char*> iter = f.put(cpp17_output_iterator<char*>(str), false, ios, ' ', v);
|
||||
std::string ex(str, iter.base());
|
||||
assert(ex == "-1 234 567,89 \xD1\x80\xD1\x83\xD0\xB1"".");
|
||||
assert(ex == "-1 234 567,89 " + symbol);
|
||||
assert(ios.width() == 0);
|
||||
}
|
||||
|
||||
|
@ -267,6 +265,7 @@ int main(int, char**)
|
|||
}
|
||||
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
|
||||
{
|
||||
std::wstring symbol(LocaleHelpers::currency_symbol_ru_RU());
|
||||
const my_facetw f(1);
|
||||
// wchar_t, national
|
||||
std::noshowbase(ios);
|
||||
|
@ -290,14 +289,14 @@ int main(int, char**)
|
|||
wchar_t str[100];
|
||||
cpp17_output_iterator<wchar_t*> iter = f.put(cpp17_output_iterator<wchar_t*>(str), false, ios, '*', v);
|
||||
std::wstring ex(str, iter.base());
|
||||
assert(ex == L"1 234 567,89");
|
||||
assert(ex == convert_thousands_sep(L"1 234 567,89"));
|
||||
}
|
||||
{ // negative
|
||||
long double v = -123456789;
|
||||
wchar_t str[100];
|
||||
cpp17_output_iterator<wchar_t*> iter = f.put(cpp17_output_iterator<wchar_t*>(str), false, ios, '*', v);
|
||||
std::wstring ex(str, iter.base());
|
||||
assert(ex == L"-1 234 567,89");
|
||||
assert(ex == convert_thousands_sep(L"-1 234 567,89"));
|
||||
}
|
||||
{ // zero, showbase
|
||||
long double v = 0;
|
||||
|
@ -305,7 +304,7 @@ int main(int, char**)
|
|||
wchar_t str[100];
|
||||
cpp17_output_iterator<wchar_t*> iter = f.put(cpp17_output_iterator<wchar_t*>(str), false, ios, '*', v);
|
||||
std::wstring ex(str, iter.base());
|
||||
assert(ex == L"0,00 \x440\x443\x431"".");
|
||||
assert(ex == L"0,00 " + symbol);
|
||||
}
|
||||
{ // negative one, showbase
|
||||
long double v = -1;
|
||||
|
@ -313,7 +312,7 @@ int main(int, char**)
|
|||
wchar_t str[100];
|
||||
cpp17_output_iterator<wchar_t*> iter = f.put(cpp17_output_iterator<wchar_t*>(str), false, ios, '*', v);
|
||||
std::wstring ex(str, iter.base());
|
||||
assert(ex == L"-0,01 \x440\x443\x431"".");
|
||||
assert(ex == L"-0,01 " + symbol);
|
||||
}
|
||||
{ // positive, showbase
|
||||
long double v = 123456789;
|
||||
|
@ -321,7 +320,7 @@ int main(int, char**)
|
|||
wchar_t str[100];
|
||||
cpp17_output_iterator<wchar_t*> iter = f.put(cpp17_output_iterator<wchar_t*>(str), false, ios, '*', v);
|
||||
std::wstring ex(str, iter.base());
|
||||
assert(ex == L"1 234 567,89 \x440\x443\x431"".");
|
||||
assert(ex == convert_thousands_sep(L"1 234 567,89 ") + symbol);
|
||||
}
|
||||
{ // negative, showbase
|
||||
long double v = -123456789;
|
||||
|
@ -329,39 +328,39 @@ int main(int, char**)
|
|||
wchar_t str[100];
|
||||
cpp17_output_iterator<wchar_t*> iter = f.put(cpp17_output_iterator<wchar_t*>(str), false, ios, '*', v);
|
||||
std::wstring ex(str, iter.base());
|
||||
assert(ex == L"-1 234 567,89 \x440\x443\x431"".");
|
||||
assert(ex == convert_thousands_sep(L"-1 234 567,89 ") + symbol);
|
||||
}
|
||||
{ // negative, showbase, left
|
||||
long double v = -123456789;
|
||||
std::showbase(ios);
|
||||
ios.width(20);
|
||||
ios.width(15);
|
||||
std::left(ios);
|
||||
wchar_t str[100];
|
||||
cpp17_output_iterator<wchar_t*> iter = f.put(cpp17_output_iterator<wchar_t*>(str), false, ios, ' ', v);
|
||||
std::wstring ex(str, iter.base());
|
||||
assert(ex == L"-1 234 567,89 \x440\x443\x431"". ");
|
||||
assert(ex == convert_thousands_sep(L"-1 234 567,89 ") + symbol);
|
||||
assert(ios.width() == 0);
|
||||
}
|
||||
{ // negative, showbase, internal
|
||||
long double v = -123456789;
|
||||
std::showbase(ios);
|
||||
ios.width(20);
|
||||
ios.width(15);
|
||||
std::internal(ios);
|
||||
wchar_t str[100];
|
||||
cpp17_output_iterator<wchar_t*> iter = f.put(cpp17_output_iterator<wchar_t*>(str), false, ios, ' ', v);
|
||||
std::wstring ex(str, iter.base());
|
||||
assert(ex == L"-1 234 567,89 \x440\x443\x431"".");
|
||||
assert(ex == convert_thousands_sep(L"-1 234 567,89 ") + symbol);
|
||||
assert(ios.width() == 0);
|
||||
}
|
||||
{ // negative, showbase, right
|
||||
long double v = -123456789;
|
||||
std::showbase(ios);
|
||||
ios.width(20);
|
||||
ios.width(15);
|
||||
std::right(ios);
|
||||
wchar_t str[100];
|
||||
cpp17_output_iterator<wchar_t*> iter = f.put(cpp17_output_iterator<wchar_t*>(str), false, ios, ' ', v);
|
||||
std::wstring ex(str, iter.base());
|
||||
assert(ex == L" -1 234 567,89 \x440\x443\x431"".");
|
||||
assert(ex == convert_thousands_sep(L"-1 234 567,89 ") + symbol);
|
||||
assert(ios.width() == 0);
|
||||
}
|
||||
|
||||
|
@ -387,14 +386,14 @@ int main(int, char**)
|
|||
wchar_t str[100];
|
||||
cpp17_output_iterator<wchar_t*> iter = f.put(cpp17_output_iterator<wchar_t*>(str), true, ios, '*', v);
|
||||
std::wstring ex(str, iter.base());
|
||||
assert(ex == L"1 234 567,89");
|
||||
assert(ex == convert_thousands_sep(L"1 234 567,89"));
|
||||
}
|
||||
{ // negative
|
||||
long double v = -123456789;
|
||||
wchar_t str[100];
|
||||
cpp17_output_iterator<wchar_t*> iter = f.put(cpp17_output_iterator<wchar_t*>(str), true, ios, '*', v);
|
||||
std::wstring ex(str, iter.base());
|
||||
assert(ex == L"-1 234 567,89");
|
||||
assert(ex == convert_thousands_sep(L"-1 234 567,89"));
|
||||
}
|
||||
{ // zero, showbase
|
||||
long double v = 0;
|
||||
|
@ -418,7 +417,7 @@ int main(int, char**)
|
|||
wchar_t str[100];
|
||||
cpp17_output_iterator<wchar_t*> iter = f.put(cpp17_output_iterator<wchar_t*>(str), true, ios, '*', v);
|
||||
std::wstring ex(str, iter.base());
|
||||
assert(ex == L"1 234 567,89 RUB");
|
||||
assert(ex == convert_thousands_sep(L"1 234 567,89 RUB"));
|
||||
}
|
||||
{ // negative, showbase
|
||||
long double v = -123456789;
|
||||
|
@ -426,7 +425,7 @@ int main(int, char**)
|
|||
wchar_t str[100];
|
||||
cpp17_output_iterator<wchar_t*> iter = f.put(cpp17_output_iterator<wchar_t*>(str), true, ios, '*', v);
|
||||
std::wstring ex(str, iter.base());
|
||||
assert(ex == L"-1 234 567,89 RUB");
|
||||
assert(ex == convert_thousands_sep(L"-1 234 567,89 RUB"));
|
||||
}
|
||||
{ // negative, showbase, left
|
||||
long double v = -123456789;
|
||||
|
@ -436,7 +435,7 @@ int main(int, char**)
|
|||
wchar_t str[100];
|
||||
cpp17_output_iterator<wchar_t*> iter = f.put(cpp17_output_iterator<wchar_t*>(str), true, ios, ' ', v);
|
||||
std::wstring ex(str, iter.base());
|
||||
assert(ex == L"-1 234 567,89 RUB ");
|
||||
assert(ex == convert_thousands_sep(L"-1 234 567,89 RUB "));
|
||||
assert(ios.width() == 0);
|
||||
}
|
||||
{ // negative, showbase, internal
|
||||
|
@ -447,7 +446,7 @@ int main(int, char**)
|
|||
wchar_t str[100];
|
||||
cpp17_output_iterator<wchar_t*> iter = f.put(cpp17_output_iterator<wchar_t*>(str), true, ios, ' ', v);
|
||||
std::wstring ex(str, iter.base());
|
||||
assert(ex == L"-1 234 567,89 RUB");
|
||||
assert(ex == convert_thousands_sep(L"-1 234 567,89 RUB"));
|
||||
assert(ios.width() == 0);
|
||||
}
|
||||
{ // negative, showbase, right
|
||||
|
@ -458,7 +457,7 @@ int main(int, char**)
|
|||
wchar_t str[100];
|
||||
cpp17_output_iterator<wchar_t*> iter = f.put(cpp17_output_iterator<wchar_t*>(str), true, ios, ' ', v);
|
||||
std::wstring ex(str, iter.base());
|
||||
assert(ex == L" -1 234 567,89 RUB");
|
||||
assert(ex == convert_thousands_sep(L" -1 234 567,89 RUB"));
|
||||
assert(ios.width() == 0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "locale_helpers.h"
|
||||
#include "platform_support.h" // locale name macros
|
||||
|
||||
class Fnf
|
||||
|
@ -140,19 +141,7 @@ int main(int, char**)
|
|||
|
||||
{
|
||||
Fnf f(LOCALE_ru_RU_UTF_8, 1);
|
||||
#if defined(_CS_GNU_LIBC_VERSION)
|
||||
// GLIBC <= 2.23 uses currency_symbol="<U0440><U0443><U0431>"
|
||||
// GLIBC >= 2.24 uses currency_symbol="<U20BD>"
|
||||
// See also: http://www.fileformat.info/info/unicode/char/20bd/index.htm
|
||||
if (!glibc_version_less_than("2.24"))
|
||||
assert(f.curr_symbol() == " \xE2\x82\xBD"); // \u20BD
|
||||
else
|
||||
assert(f.curr_symbol() == " \xD1\x80\xD1\x83\xD0\xB1"); // \u0440\u0443\u0431
|
||||
#elif defined(_WIN32) || defined(__FreeBSD__)
|
||||
assert(f.curr_symbol() == " \xE2\x82\xBD"); // \u20BD
|
||||
#else
|
||||
assert(f.curr_symbol() == " \xD1\x80\xD1\x83\xD0\xB1."); // \u0440\u0443\u0431.
|
||||
#endif
|
||||
assert(f.curr_symbol() == " " + static_cast<std::string>(LocaleHelpers::currency_symbol_ru_RU()));
|
||||
}
|
||||
{
|
||||
Fnt f(LOCALE_ru_RU_UTF_8, 1);
|
||||
|
@ -161,16 +150,7 @@ int main(int, char**)
|
|||
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
|
||||
{
|
||||
Fwf f(LOCALE_ru_RU_UTF_8, 1);
|
||||
#if defined(_CS_GNU_LIBC_VERSION)
|
||||
if (!glibc_version_less_than("2.24"))
|
||||
assert(f.curr_symbol() == L" \u20BD");
|
||||
else
|
||||
assert(f.curr_symbol() == L" \u0440\u0443\u0431");
|
||||
#elif defined(_WIN32) || defined(__FreeBSD__)
|
||||
assert(f.curr_symbol() == L" \u20BD");
|
||||
#else
|
||||
assert(f.curr_symbol() == L" \u0440\u0443\u0431.");
|
||||
#endif
|
||||
assert(f.curr_symbol() == L" " + static_cast<std::wstring>(LocaleHelpers::currency_symbol_ru_RU()));
|
||||
}
|
||||
|
||||
{
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef LIBCXX_TEST_SUPPORT_LOCALE_HELPERS_H
|
||||
#define LIBCXX_TEST_SUPPORT_LOCALE_HELPERS_H
|
||||
|
||||
#include <string>
|
||||
#include "platform_support.h"
|
||||
#include "test_macros.h"
|
||||
#include "make_string.h"
|
||||
|
||||
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
|
||||
|
||||
#include <cwctype>
|
||||
|
||||
#endif // TEST_HAS_NO_WIDE_CHARACTERS
|
||||
|
||||
namespace LocaleHelpers {
|
||||
|
||||
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
|
||||
|
||||
std::wstring convert_thousands_sep(std::wstring const& in, wchar_t sep) {
|
||||
std::wstring out;
|
||||
bool seen_num_start = false;
|
||||
bool seen_decimal = false;
|
||||
for (unsigned i = 0; i < in.size(); ++i) {
|
||||
seen_decimal |= in[i] == L',';
|
||||
seen_num_start |= in[i] == L'-' || std::iswdigit(in[i]);
|
||||
if (seen_decimal || !seen_num_start || in[i] != L' ') {
|
||||
out.push_back(in[i]);
|
||||
continue;
|
||||
}
|
||||
assert(in[i] == L' ');
|
||||
out.push_back(sep);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
// GLIBC 2.27 and newer use U+202F NARROW NO-BREAK SPACE as a thousands separator.
|
||||
// This function converts the spaces in string inputs to U+202F if need
|
||||
// be. FreeBSD's locale data also uses U+202F, since 2018.
|
||||
// Windows uses U+00A0 NO-BREAK SPACE.
|
||||
std::wstring convert_thousands_sep_fr_FR(std::wstring const& in) {
|
||||
#if defined(_CS_GNU_LIBC_VERSION)
|
||||
if (glibc_version_less_than("2.27"))
|
||||
return in;
|
||||
else
|
||||
return convert_thousands_sep(in, L'\u202F');
|
||||
#elif defined(__FreeBSD__)
|
||||
return convert_thousands_sep(in, L'\u202F');
|
||||
#elif defined(_WIN32)
|
||||
return convert_thousands_sep(in, L'\u00A0');
|
||||
#else
|
||||
return in;
|
||||
#endif
|
||||
}
|
||||
|
||||
// GLIBC 2.27 uses U+202F NARROW NO-BREAK SPACE as a thousands separator.
|
||||
// FreeBSD and Windows use U+00A0 NO-BREAK SPACE.
|
||||
std::wstring convert_thousands_sep_ru_RU(std::wstring const& in) {
|
||||
#if defined(TEST_HAS_GLIBC)
|
||||
return convert_thousands_sep(in, L'\u202F');
|
||||
#elif defined(__FreeBSD__) || defined(_WIN32)
|
||||
return convert_thousands_sep(in, L'\u00A0');
|
||||
#else
|
||||
return in;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // TEST_HAS_NO_WIDE_CHARACTERS
|
||||
|
||||
MultiStringType currency_symbol_ru_RU() {
|
||||
#if defined(_CS_GNU_LIBC_VERSION)
|
||||
if (glibc_version_less_than("2.24"))
|
||||
return MKSTR("\u0440\u0443\u0431");
|
||||
else
|
||||
return MKSTR("\u20BD"); // U+20BD RUBLE SIGN
|
||||
#elif defined(_WIN32) || defined(__FreeBSD__)
|
||||
return MKSTR("\u20BD"); // U+20BD RUBLE SIGN
|
||||
#else
|
||||
return MKSTR("\u0440\u0443\u0431.");
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace LocaleHelpers
|
||||
|
||||
#endif // LIBCXX_TEST_SUPPORT_LOCALE_HELPERS_H
|
Loading…
Reference in New Issue