[libcxx-commits] [libcxx] df1e43c - [libcxx] [test] Fix get/put long_double_ru_RU on Glibc, FreeBSD and Windows
Martin Storsjö via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Mar 3 03:31:57 PST 2022
Author: Martin Storsjö
Date: 2022-03-03T13:30:59+02:00
New Revision: df1e43c496b43e998f66c610b0e15a0951f316b3
URL: https://github.com/llvm/llvm-project/commit/df1e43c496b43e998f66c610b0e15a0951f316b3
DIFF: https://github.com/llvm/llvm-project/commit/df1e43c496b43e998f66c610b0e15a0951f316b3.diff
LOG: [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
Added:
libcxx/test/support/locale_helpers.h
Modified:
libcxx/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_fr_FR.pass.cpp
libcxx/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_ru_RU.pass.cpp
libcxx/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_fr_FR.pass.cpp
libcxx/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_ru_RU.pass.cpp
libcxx/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/curr_symbol.pass.cpp
Removed:
################################################################################
diff --git a/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_fr_FR.pass.cpp b/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_fr_FR.pass.cpp
index 16fc12feac62b..ffc57e6236d8f 100644
--- a/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_fr_FR.pass.cpp
+++ b/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_fr_FR.pass.cpp
@@ -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 @@ class my_facetw
: 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
diff --git a/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_ru_RU.pass.cpp b/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_ru_RU.pass.cpp
index f4644ab2df242..a72d0c4d210ee 100644
--- a/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_ru_RU.pass.cpp
+++ b/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_ru_RU.pass.cpp
@@ -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 @@ class my_facetw
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;
diff --git a/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_fr_FR.pass.cpp b/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_fr_FR.pass.cpp
index becb46e091590..79241674d935e 100644
--- a/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_fr_FR.pass.cpp
+++ b/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_fr_FR.pass.cpp
@@ -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 @@ class my_facetw
: 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
diff --git a/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_ru_RU.pass.cpp b/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_ru_RU.pass.cpp
index 975b9ed156486..b980df12a18a1 100644
--- a/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_ru_RU.pass.cpp
+++ b/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_ru_RU.pass.cpp
@@ -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 @@ class my_facetw
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);
}
}
diff --git a/libcxx/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/curr_symbol.pass.cpp b/libcxx/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/curr_symbol.pass.cpp
index 407a08884c3d8..620703ed64762 100644
--- a/libcxx/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/curr_symbol.pass.cpp
+++ b/libcxx/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/curr_symbol.pass.cpp
@@ -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()));
}
{
diff --git a/libcxx/test/support/locale_helpers.h b/libcxx/test/support/locale_helpers.h
new file mode 100644
index 0000000000000..9fb11b9941907
--- /dev/null
+++ b/libcxx/test/support/locale_helpers.h
@@ -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
More information about the libcxx-commits
mailing list