summaryrefslogtreecommitdiff
path: root/system/lib/libcxx/locale.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'system/lib/libcxx/locale.cpp')
-rw-r--r--system/lib/libcxx/locale.cpp1006
1 files changed, 625 insertions, 381 deletions
diff --git a/system/lib/libcxx/locale.cpp b/system/lib/libcxx/locale.cpp
index 87c47636..d9bc6f9a 100644
--- a/system/lib/libcxx/locale.cpp
+++ b/system/lib/libcxx/locale.cpp
@@ -7,6 +7,12 @@
//
//===----------------------------------------------------------------------===//
+// On Solaris, we need to define something to make the C99 parts of localeconv
+// visible.
+#ifdef __sun__
+#define _LCONV_C99
+#endif
+
#include "string"
#include "locale"
#include "codecvt"
@@ -19,39 +25,28 @@
#include "cstring"
#include "cwctype"
#include "__sso_allocator"
-#if _WIN32
-#include <locale.h>
+#ifdef _WIN32
+#include <support/win32/locale_win32.h>
#else // _WIN32
#include <langinfo.h>
#endif // _!WIN32
#include <stdlib.h>
-#ifdef _LIBCPP_STABLE_APPLE_ABI
-namespace {
- decltype(MB_CUR_MAX_L(_VSTD::declval<locale_t>()))
- inline _LIBCPP_INLINE_VISIBILITY
- mb_cur_max_l(locale_t loc)
- {
- return MB_CUR_MAX_L(loc);
- }
-}
-#endif
+// On Linux, wint_t and wchar_t have different signed-ness, and this causes
+// lots of noise in the build log, but no bugs that I know of.
+#pragma clang diagnostic ignored "-Wsign-conversion"
_LIBCPP_BEGIN_NAMESPACE_STD
-#ifndef _LIBCPP_STABLE_APPLE_ABI
+#ifdef __cloc_defined
locale_t __cloc() {
// In theory this could create a race condition. In practice
// the race condition is non-fatal since it will just create
// a little resource leak. Better approach would be appreciated.
-#ifdef __APPLE__
- return 0;
-#else
static locale_t result = newlocale(LC_ALL_MASK, "C", 0);
return result;
-#endif
}
-#endif // _LIBCPP_STABLE_APPLE_ABI
+#endif // __cloc_defined
namespace {
@@ -90,14 +85,44 @@ make(A0 a0, A1 a1, A2 a2)
return *(T*)&buf;
}
+template <typename T, size_t N>
+inline
+_LIBCPP_CONSTEXPR
+size_t
+countof(const T (&)[N])
+{
+ return N;
+}
+
+template <typename T>
+inline
+_LIBCPP_CONSTEXPR
+size_t
+countof(const T * const begin, const T * const end)
+{
+ return static_cast<size_t>(end - begin);
+}
+
}
+const locale::category locale::none;
+const locale::category locale::collate;
+const locale::category locale::ctype;
+const locale::category locale::monetary;
+const locale::category locale::numeric;
+const locale::category locale::time;
+const locale::category locale::messages;
+const locale::category locale::all;
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpadded"
+
class _LIBCPP_HIDDEN locale::__imp
: public facet
{
enum {N = 28};
- string name_;
vector<facet*, __sso_allocator<facet*, N> > facets_;
+ string name_;
public:
explicit __imp(size_t refs = 0);
explicit __imp(const string& name, size_t refs = 0);
@@ -108,7 +133,8 @@ public:
~__imp();
const string& name() const {return name_;}
- bool has_facet(long id) const {return id < facets_.size() && facets_[id];}
+ bool has_facet(long id) const
+ {return static_cast<size_t>(id) < facets_.size() && facets_[static_cast<size_t>(id)];}
const locale::facet* use_facet(long id) const;
static const locale& make_classic();
@@ -119,46 +145,48 @@ private:
template <class F> void install_from(const __imp& other);
};
+#pragma clang diagnostic pop
+
locale::__imp::__imp(size_t refs)
: facet(refs),
- name_("C"),
- facets_(N)
+ facets_(N),
+ name_("C")
{
facets_.clear();
- install(&make<_VSTD::collate<char> >(1));
- install(&make<_VSTD::collate<wchar_t> >(1));
- install(&make<_VSTD::ctype<char> >((ctype_base::mask*)0, false, 1));
- install(&make<_VSTD::ctype<wchar_t> >(1));
- install(&make<codecvt<char, char, mbstate_t> >(1));
- install(&make<codecvt<wchar_t, char, mbstate_t> >(1));
- install(&make<codecvt<char16_t, char, mbstate_t> >(1));
- install(&make<codecvt<char32_t, char, mbstate_t> >(1));
- install(&make<numpunct<char> >(1));
- install(&make<numpunct<wchar_t> >(1));
- install(&make<num_get<char> >(1));
- install(&make<num_get<wchar_t> >(1));
- install(&make<num_put<char> >(1));
- install(&make<num_put<wchar_t> >(1));
- install(&make<moneypunct<char, false> >(1));
- install(&make<moneypunct<char, true> >(1));
- install(&make<moneypunct<wchar_t, false> >(1));
- install(&make<moneypunct<wchar_t, true> >(1));
- install(&make<money_get<char> >(1));
- install(&make<money_get<wchar_t> >(1));
- install(&make<money_put<char> >(1));
- install(&make<money_put<wchar_t> >(1));
- install(&make<time_get<char> >(1));
- install(&make<time_get<wchar_t> >(1));
- install(&make<time_put<char> >(1));
- install(&make<time_put<wchar_t> >(1));
- install(&make<_VSTD::messages<char> >(1));
- install(&make<_VSTD::messages<wchar_t> >(1));
+ install(&make<_VSTD::collate<char> >(1u));
+ install(&make<_VSTD::collate<wchar_t> >(1u));
+ install(&make<_VSTD::ctype<char> >((ctype_base::mask*)0, false, 1u));
+ install(&make<_VSTD::ctype<wchar_t> >(1u));
+ install(&make<codecvt<char, char, mbstate_t> >(1u));
+ install(&make<codecvt<wchar_t, char, mbstate_t> >(1u));
+ install(&make<codecvt<char16_t, char, mbstate_t> >(1u));
+ install(&make<codecvt<char32_t, char, mbstate_t> >(1u));
+ install(&make<numpunct<char> >(1u));
+ install(&make<numpunct<wchar_t> >(1u));
+ install(&make<num_get<char> >(1u));
+ install(&make<num_get<wchar_t> >(1u));
+ install(&make<num_put<char> >(1u));
+ install(&make<num_put<wchar_t> >(1u));
+ install(&make<moneypunct<char, false> >(1u));
+ install(&make<moneypunct<char, true> >(1u));
+ install(&make<moneypunct<wchar_t, false> >(1u));
+ install(&make<moneypunct<wchar_t, true> >(1u));
+ install(&make<money_get<char> >(1u));
+ install(&make<money_get<wchar_t> >(1u));
+ install(&make<money_put<char> >(1u));
+ install(&make<money_put<wchar_t> >(1u));
+ install(&make<time_get<char> >(1u));
+ install(&make<time_get<wchar_t> >(1u));
+ install(&make<time_put<char> >(1u));
+ install(&make<time_put<wchar_t> >(1u));
+ install(&make<_VSTD::messages<char> >(1u));
+ install(&make<_VSTD::messages<wchar_t> >(1u));
}
locale::__imp::__imp(const string& name, size_t refs)
: facet(refs),
- name_(name),
- facets_(N)
+ facets_(N),
+ name_(name)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
try
@@ -200,9 +228,14 @@ locale::__imp::__imp(const string& name, size_t refs)
#endif // _LIBCPP_NO_EXCEPTIONS
}
+// NOTE avoid the `base class should be explicitly initialized in the
+// copy constructor` warning emitted by GCC
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wextra"
+
locale::__imp::__imp(const __imp& other)
- : name_(other.name_),
- facets_(max<size_t>(N, other.facets_.size()))
+ : facets_(max<size_t>(N, other.facets_.size())),
+ name_(other.name_)
{
facets_ = other.facets_;
for (unsigned i = 0; i < facets_.size(); ++i)
@@ -210,9 +243,11 @@ locale::__imp::__imp(const __imp& other)
facets_[i]->__add_shared();
}
+#pragma GCC diagnostic pop
+
locale::__imp::__imp(const __imp& other, const string& name, locale::category c)
- : name_("*"),
- facets_(N)
+ : facets_(N),
+ name_("*")
{
facets_ = other.facets_;
for (unsigned i = 0; i < facets_.size(); ++i)
@@ -282,8 +317,8 @@ locale::__imp::install_from(const locale::__imp& one)
}
locale::__imp::__imp(const __imp& other, const __imp& one, locale::category c)
- : name_("*"),
- facets_(N)
+ : facets_(N),
+ name_("*")
{
facets_ = other.facets_;
for (unsigned i = 0; i < facets_.size(); ++i)
@@ -352,8 +387,8 @@ locale::__imp::__imp(const __imp& other, const __imp& one, locale::category c)
}
locale::__imp::__imp(const __imp& other, facet* f, long id)
- : name_("*"),
- facets_(max<size_t>(N, other.facets_.size()+1))
+ : facets_(max<size_t>(N, other.facets_.size()+1)),
+ name_("*")
{
f->__add_shared();
unique_ptr<facet, release> hold(f);
@@ -376,11 +411,11 @@ locale::__imp::install(facet* f, long id)
{
f->__add_shared();
unique_ptr<facet, release> hold(f);
- if (id >= facets_.size())
- facets_.resize(id+1);
- if (facets_[id])
- facets_[id]->__release_shared();
- facets_[id] = hold.release();
+ if (static_cast<size_t>(id) >= facets_.size())
+ facets_.resize(static_cast<size_t>(id+1));
+ if (facets_[static_cast<size_t>(id)])
+ facets_[static_cast<size_t>(id)]->__release_shared();
+ facets_[static_cast<size_t>(id)] = hold.release();
}
const locale::facet*
@@ -390,7 +425,7 @@ locale::__imp::use_facet(long id) const
if (!has_facet(id))
throw bad_cast();
#endif // _LIBCPP_NO_EXCEPTIONS
- return facets_[id];
+ return facets_[static_cast<size_t>(id)];
}
// locale
@@ -401,7 +436,7 @@ locale::__imp::make_classic()
// only one thread can get in here and it only gets in once
static aligned_storage<sizeof(locale)>::type buf;
locale* c = (locale*)&buf;
- c->__locale_ = &make<__imp>(1);
+ c->__locale_ = &make<__imp>(1u);
return *c;
}
@@ -417,7 +452,6 @@ locale::__imp::make_global()
{
// only one thread can get in here and it only gets in once
static aligned_storage<sizeof(locale)>::type buf;
- locale* g = (locale*)&buf;
::new (&buf) locale(locale::classic());
return *(locale*)&buf;
}
@@ -695,6 +729,19 @@ collate_byname<wchar_t>::do_transform(const char_type* lo, const char_type* hi)
// template <> class ctype<wchar_t>;
+const ctype_base::mask ctype_base::space;
+const ctype_base::mask ctype_base::print;
+const ctype_base::mask ctype_base::cntrl;
+const ctype_base::mask ctype_base::upper;
+const ctype_base::mask ctype_base::lower;
+const ctype_base::mask ctype_base::alpha;
+const ctype_base::mask ctype_base::digit;
+const ctype_base::mask ctype_base::punct;
+const ctype_base::mask ctype_base::xdigit;
+const ctype_base::mask ctype_base::blank;
+const ctype_base::mask ctype_base::alnum;
+const ctype_base::mask ctype_base::graph;
+
locale::id ctype<wchar_t>::id;
ctype<wchar_t>::~ctype()
@@ -737,10 +784,12 @@ ctype<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high)
wchar_t
ctype<wchar_t>::do_toupper(char_type c) const
{
-#if !(defined(_LIBCPP_STABLE_APPLE_ABI) || defined(__FreeBSD__))
+#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
+ return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c;
+#elif defined(__GLIBC__) || defined(EMSCRIPTEN)
return isascii(c) ? ctype<char>::__classic_upper_table()[c] : c;
#else
- return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c;
+ return (isascii(c) && iswlower_l(c, __cloc())) ? c-L'a'+L'A' : c;
#endif
}
@@ -748,11 +797,13 @@ const wchar_t*
ctype<wchar_t>::do_toupper(char_type* low, const char_type* high) const
{
for (; low != high; ++low)
-#if !(defined(_LIBCPP_STABLE_APPLE_ABI) || defined(__FreeBSD__))
+#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
+ *low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low;
+#elif defined(__GLIBC__) || defined(EMSCRIPTEN)
*low = isascii(*low) ? ctype<char>::__classic_upper_table()[*low]
: *low;
#else
- *low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low;
+ *low = (isascii(*low) && islower_l(*low, __cloc())) ? (*low-L'a'+L'A') : *low;
#endif
return low;
}
@@ -760,10 +811,12 @@ ctype<wchar_t>::do_toupper(char_type* low, const char_type* high) const
wchar_t
ctype<wchar_t>::do_tolower(char_type c) const
{
-#ifndef _LIBCPP_STABLE_APPLE_ABI
+#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
+ return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c;
+#elif defined(__GLIBC__) || defined(EMSCRIPTEN)
return isascii(c) ? ctype<char>::__classic_lower_table()[c] : c;
#else
- return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c;
+ return (isascii(c) && isupper_l(c, __cloc())) ? c-L'A'+'a' : c;
#endif
}
@@ -771,11 +824,13 @@ const wchar_t*
ctype<wchar_t>::do_tolower(char_type* low, const char_type* high) const
{
for (; low != high; ++low)
-#ifndef _LIBCPP_STABLE_APPLE_ABI
+#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
+ *low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low;
+#elif defined(__GLIBC__) || defined(EMSCRIPTEN)
*low = isascii(*low) ? ctype<char>::__classic_lower_table()[*low]
: *low;
#else
- *low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low;
+ *low = (isascii(*low) && isupper_l(*low, __cloc())) ? *low-L'A'+L'a' : *low;
#endif
return low;
}
@@ -807,7 +862,7 @@ ctype<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfau
{
for (; low != high; ++low, ++dest)
if (isascii(*low))
- *dest = *low;
+ *dest = static_cast<char>(*low);
else
*dest = dfault;
return low;
@@ -835,10 +890,14 @@ ctype<char>::~ctype()
char
ctype<char>::do_toupper(char_type c) const
{
-#ifndef _LIBCPP_STABLE_APPLE_ABI
- return isascii(c) ? __classic_upper_table()[c] : c;
+#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
+ return isascii(c) ?
+ static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(c)]) : c;
+#elif defined(__GLIBC__) || defined(EMSCRIPTEN)
+ return isascii(c) ?
+ static_cast<char>(__classic_upper_table()[static_cast<size_t>(c)]) : c;
#else
- return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c;
+ return (isascii(c) && islower_l(c, __cloc())) ? c-'a'+'A' : c;
#endif
}
@@ -846,10 +905,14 @@ const char*
ctype<char>::do_toupper(char_type* low, const char_type* high) const
{
for (; low != high; ++low)
-#ifndef _LIBCPP_STABLE_APPLE_ABI
- *low = isascii(*low) ? __classic_upper_table()[*low] : *low;
+#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
+ *low = isascii(*low) ?
+ static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(*low)]) : *low;
+#elif defined(__GLIBC__) || defined(EMSCRIPTEN)
+ *low = isascii(*low) ?
+ static_cast<char>(__classic_upper_table()[static_cast<size_t>(*low)]) : *low;
#else
- *low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low;
+ *low = (isascii(*low) && islower_l(*low, __cloc())) ? *low-'a'+'A' : *low;
#endif
return low;
}
@@ -857,10 +920,14 @@ ctype<char>::do_toupper(char_type* low, const char_type* high) const
char
ctype<char>::do_tolower(char_type c) const
{
-#ifndef _LIBCPP_STABLE_APPLE_ABI
- return isascii(c) ? __classic_lower_table()[c] : c;
+#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
+ return isascii(c) ?
+ static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(c)]) : c;
+#elif defined(__GLIBC__) || defined(EMSCRIPTEN)
+ return isascii(c) ?
+ static_cast<char>(__classic_lower_table()[static_cast<size_t>(c)]) : c;
#else
- return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c;
+ return (isascii(c) && isupper_l(c, __cloc())) ? c-'A'+'a' : c;
#endif
}
@@ -868,10 +935,12 @@ const char*
ctype<char>::do_tolower(char_type* low, const char_type* high) const
{
for (; low != high; ++low)
-#ifndef _LIBCPP_STABLE_APPLE_ABI
- *low = isascii(*low) ? __classic_lower_table()[*low] : *low;
+#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
+ *low = isascii(*low) ? static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(*low)]) : *low;
+#elif defined(__GLIBC__) || defined(EMSCRIPTEN)
+ *low = isascii(*low) ? static_cast<char>(__classic_lower_table()[static_cast<size_t>(*low)]) : *low;
#else
- *low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low;
+ *low = (isascii(*low) && isupper_l(*low, __cloc())) ? *low-'A'+'a' : *low;
#endif
return low;
}
@@ -909,10 +978,11 @@ ctype<char>::do_narrow(const char_type* low, const char_type* high, char dfault,
return low;
}
-// XXX Emscripten define local table
+#ifdef EMSCRIPTEN
extern "C" const unsigned short ** __ctype_b_loc();
extern "C" const int ** __ctype_tolower_loc();
extern "C" const int ** __ctype_toupper_loc();
+#endif
const ctype<char>::mask*
ctype<char>::classic_table() _NOEXCEPT
@@ -921,44 +991,50 @@ ctype<char>::classic_table() _NOEXCEPT
return _DefaultRuneLocale.__runetype;
#elif defined(__GLIBC__)
return __cloc()->__ctype_b;
+#elif __sun__
+ return __ctype_mask;
+#elif defined(_WIN32)
+ return _ctype+1; // internal ctype mask table defined in msvcrt.dll
// This is assumed to be safe, which is a nonsense assumption because we're
// going to end up dereferencing it later...
#elif defined(EMSCRIPTEN)
return *__ctype_b_loc();
#else
+ // Platform not supported: abort so the person doing the port knows what to
+ // fix
+# warning ctype<char>::classic_table() is not implemented
+ abort();
return NULL;
#endif
}
-#ifndef _LIBCPP_STABLE_APPLE_ABI
+#if defined(__GLIBC__)
const int*
ctype<char>::__classic_lower_table() _NOEXCEPT
{
-#if defined(__APPLE__) || defined(__FreeBSD__)
- return _DefaultRuneLocale.__maplower;
-#elif defined(__GLIBC__)
return __cloc()->__ctype_tolower;
-#elif defined(EMSCRIPTEN)
- return *__ctype_tolower_loc();
-#else
- return NULL;
-#endif
}
const int*
ctype<char>::__classic_upper_table() _NOEXCEPT
{
-#if defined(__APPLE__) || defined(__FreeBSD__)
- return _DefaultRuneLocale.__mapupper;
-#elif defined(__GLIBC__)
return __cloc()->__ctype_toupper;
-#elif defined(EMSCRIPTEN)
+}
+#endif // __GLIBC__
+
+#if defined(EMSCRIPTEN)
+const int*
+ctype<char>::__classic_lower_table() _NOEXCEPT
+{
+ return *__ctype_tolower_loc();
+}
+
+const int*
+ctype<char>::__classic_upper_table() _NOEXCEPT
+{
return *__ctype_toupper_loc();
-#else
- return NULL;
-#endif
}
-#endif // _LIBCPP_STABLE_APPLE_ABI
+#endif // EMSCRIPTEN
// template <> class ctype_byname<char>
@@ -992,28 +1068,28 @@ ctype_byname<char>::~ctype_byname()
char
ctype_byname<char>::do_toupper(char_type c) const
{
- return toupper_l(c, __l);
+ return static_cast<char>(toupper_l(c, __l));
}
const char*
ctype_byname<char>::do_toupper(char_type* low, const char_type* high) const
{
for (; low != high; ++low)
- *low = toupper_l(*low, __l);
+ *low = static_cast<char>(toupper_l(*low, __l));
return low;
}
char
ctype_byname<char>::do_tolower(char_type c) const
{
- return tolower_l(c, __l);
+ return static_cast<char>(tolower_l(c, __l));
}
const char*
ctype_byname<char>::do_tolower(char_type* low, const char_type* high) const
{
for (; low != high; ++low)
- *low = tolower_l(*low, __l);
+ *low = static_cast<char>(tolower_l(*low, __l));
return low;
}
@@ -1052,18 +1128,19 @@ ctype_byname<wchar_t>::do_is(mask m, char_type c) const
#ifdef _LIBCPP_WCTYPE_IS_MASK
return static_cast<bool>(iswctype_l(c, m, __l));
#else
- // FIXME: This is broken for things that test more than one flag.
- if (m & space && !iswspace_l(c, __l)) return false;
- if (m & print && !iswprint_l(c, __l)) return false;
- if (m & cntrl && !iswcntrl_l(c, __l)) return false;
- if (m & upper && !iswupper_l(c, __l)) return false;
- if (m & lower && !iswlower_l(c, __l)) return false;
- if (m & alpha && !iswalpha_l(c, __l)) return false;
- if (m & digit && !iswdigit_l(c, __l)) return false;
- if (m & punct && !iswpunct_l(c, __l)) return false;
- if (m & xdigit && !iswxdigit_l(c, __l)) return false;
- if (m & blank && !iswblank_l(c, __l)) return false;
- return true;
+ bool result = false;
+ wint_t ch = static_cast<wint_t>(c);
+ if (m & space) result |= (iswspace_l(ch, __l) != 0);
+ if (m & print) result |= (iswprint_l(ch, __l) != 0);
+ if (m & cntrl) result |= (iswcntrl_l(ch, __l) != 0);
+ if (m & upper) result |= (iswupper_l(ch, __l) != 0);
+ if (m & lower) result |= (iswlower_l(ch, __l) != 0);
+ if (m & alpha) result |= (iswalpha_l(ch, __l) != 0);
+ if (m & digit) result |= (iswdigit_l(ch, __l) != 0);
+ if (m & punct) result |= (iswpunct_l(ch, __l) != 0);
+ if (m & xdigit) result |= (iswxdigit_l(ch, __l) != 0);
+ if (m & blank) result |= (iswblank_l(ch, __l) != 0);
+ return result;
#endif
}
@@ -1077,23 +1154,24 @@ ctype_byname<wchar_t>::do_is(const char_type* low, const char_type* high, mask*
else
{
*vec = 0;
- if (iswspace_l(*low, __l))
+ wint_t ch = static_cast<wint_t>(*low);
+ if (iswspace_l(ch, __l))
*vec |= space;
- if (iswprint_l(*low, __l))
+ if (iswprint_l(ch, __l))
*vec |= print;
- if (iswcntrl_l(*low, __l))
+ if (iswcntrl_l(ch, __l))
*vec |= cntrl;
- if (iswupper_l(*low, __l))
+ if (iswupper_l(ch, __l))
*vec |= upper;
- if (iswlower_l(*low, __l))
+ if (iswlower_l(ch, __l))
*vec |= lower;
- if (iswalpha_l(*low, __l))
+ if (iswalpha_l(ch, __l))
*vec |= alpha;
- if (iswdigit_l(*low, __l))
+ if (iswdigit_l(ch, __l))
*vec |= digit;
- if (iswpunct_l(*low, __l))
+ if (iswpunct_l(ch, __l))
*vec |= punct;
- if (iswxdigit_l(*low, __l))
+ if (iswxdigit_l(ch, __l))
*vec |= xdigit;
}
}
@@ -1109,17 +1187,17 @@ ctype_byname<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type*
if (iswctype_l(*low, m, __l))
break;
#else
- if (m & space && !iswspace_l(*low, __l)) continue;
- if (m & print && !iswprint_l(*low, __l)) continue;
- if (m & cntrl && !iswcntrl_l(*low, __l)) continue;
- if (m & upper && !iswupper_l(*low, __l)) continue;
- if (m & lower && !iswlower_l(*low, __l)) continue;
- if (m & alpha && !iswalpha_l(*low, __l)) continue;
- if (m & digit && !iswdigit_l(*low, __l)) continue;
- if (m & punct && !iswpunct_l(*low, __l)) continue;
- if (m & xdigit && !iswxdigit_l(*low, __l)) continue;
- if (m & blank && !iswblank_l(*low, __l)) continue;
- break;
+ wint_t ch = static_cast<wint_t>(*low);
+ if (m & space && iswspace_l(ch, __l)) break;
+ if (m & print && iswprint_l(ch, __l)) break;
+ if (m & cntrl && iswcntrl_l(ch, __l)) break;
+ if (m & upper && iswupper_l(ch, __l)) break;
+ if (m & lower && iswlower_l(ch, __l)) break;
+ if (m & alpha && iswalpha_l(ch, __l)) break;
+ if (m & digit && iswdigit_l(ch, __l)) break;
+ if (m & punct && iswpunct_l(ch, __l)) break;
+ if (m & xdigit && iswxdigit_l(ch, __l)) break;
+ if (m & blank && iswblank_l(ch, __l)) break;
#endif
}
return low;
@@ -1134,16 +1212,17 @@ ctype_byname<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type
if (!iswctype_l(*low, m, __l))
break;
#else
- if (m & space && iswspace_l(*low, __l)) continue;
- if (m & print && iswprint_l(*low, __l)) continue;
- if (m & cntrl && iswcntrl_l(*low, __l)) continue;
- if (m & upper && iswupper_l(*low, __l)) continue;
- if (m & lower && iswlower_l(*low, __l)) continue;
- if (m & alpha && iswalpha_l(*low, __l)) continue;
- if (m & digit && iswdigit_l(*low, __l)) continue;
- if (m & punct && iswpunct_l(*low, __l)) continue;
- if (m & xdigit && iswxdigit_l(*low, __l)) continue;
- if (m & blank && iswblank_l(*low, __l)) continue;
+ wint_t ch = static_cast<wint_t>(*low);
+ if (m & space && iswspace_l(ch, __l)) continue;
+ if (m & print && iswprint_l(ch, __l)) continue;
+ if (m & cntrl && iswcntrl_l(ch, __l)) continue;
+ if (m & upper && iswupper_l(ch, __l)) continue;
+ if (m & lower && iswlower_l(ch, __l)) continue;
+ if (m & alpha && iswalpha_l(ch, __l)) continue;
+ if (m & digit && iswdigit_l(ch, __l)) continue;
+ if (m & punct && iswpunct_l(ch, __l)) continue;
+ if (m & xdigit && iswxdigit_l(ch, __l)) continue;
+ if (m & blank && iswblank_l(ch, __l)) continue;
break;
#endif
}
@@ -1181,7 +1260,7 @@ ctype_byname<wchar_t>::do_tolower(char_type* low, const char_type* high) const
wchar_t
ctype_byname<wchar_t>::do_widen(char c) const
{
-#ifdef _LIBCPP_STABLE_APPLE_ABI
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
return btowc_l(c, __l);
#else
return __btowc_l(c, __l);
@@ -1192,7 +1271,7 @@ const char*
ctype_byname<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const
{
for (; low != high; ++low, ++dest)
-#ifdef _LIBCPP_STABLE_APPLE_ABI
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
*dest = btowc_l(*low, __l);
#else
*dest = __btowc_l(*low, __l);
@@ -1203,12 +1282,12 @@ ctype_byname<wchar_t>::do_widen(const char* low, const char* high, char_type* de
char
ctype_byname<wchar_t>::do_narrow(char_type c, char dfault) const
{
-#ifdef _LIBCPP_STABLE_APPLE_ABI
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
int r = wctob_l(c, __l);
#else
int r = __wctob_l(c, __l);
#endif
- return r != WEOF ? static_cast<char>(r) : dfault;
+ return r != static_cast<int>(WEOF) ? static_cast<char>(r) : dfault;
}
const wchar_t*
@@ -1216,12 +1295,12 @@ ctype_byname<wchar_t>::do_narrow(const char_type* low, const char_type* high, ch
{
for (; low != high; ++low, ++dest)
{
-#ifdef _LIBCPP_STABLE_APPLE_ABI
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
int r = wctob_l(*low, __l);
#else
int r = __wctob_l(*low, __l);
#endif
- *dest = r != WEOF ? static_cast<char>(r) : dfault;
+ *dest = r != static_cast<int>(WEOF) ? static_cast<char>(r) : dfault;
}
return low;
}
@@ -1278,7 +1357,7 @@ int
codecvt<char, char, mbstate_t>::do_length(state_type&,
const extern_type* frm, const extern_type* end, size_t mx) const
{
- return static_cast<int>(min<size_t>(mx, end-frm));
+ return static_cast<int>(min<size_t>(mx, static_cast<size_t>(end-frm)));
}
int
@@ -1330,8 +1409,9 @@ codecvt<wchar_t, char, mbstate_t>::do_out(state_type& st,
{
// save state in case needed to reover to_nxt on error
mbstate_t save_state = st;
-#ifdef _LIBCPP_STABLE_APPLE_ABI
- size_t n = wcsnrtombs_l(to, &frm_nxt, fend-frm, to_end-to, &st, __l);
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+ size_t n = wcsnrtombs_l(to, &frm_nxt, static_cast<size_t>(fend-frm),
+ static_cast<size_t>(to_end-to), &st, __l);
#else
size_t n = __wcsnrtombs_l(to, &frm_nxt, fend-frm, to_end-to, &st, __l);
#endif
@@ -1340,7 +1420,7 @@ codecvt<wchar_t, char, mbstate_t>::do_out(state_type& st,
// need to recover to_nxt
for (to_nxt = to; frm != frm_nxt; ++frm)
{
-#ifdef _LIBCPP_STABLE_APPLE_ABI
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
n = wcrtomb_l(to_nxt, *frm, &save_state, __l);
#else
n = __wcrtomb_l(to_nxt, *frm, &save_state, __l);
@@ -1361,14 +1441,14 @@ codecvt<wchar_t, char, mbstate_t>::do_out(state_type& st,
{
// Try to write the terminating null
extern_type tmp[MB_LEN_MAX];
-#ifdef _LIBCPP_STABLE_APPLE_ABI
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
n = wcrtomb_l(tmp, intern_type(), &st, __l);
#else
n = __wcrtomb_l(tmp, intern_type(), &st, __l);
#endif
if (n == size_t(-1)) // on error
return error;
- if (n > to_end-to_nxt) // is there room?
+ if (n > static_cast<size_t>(to_end-to_nxt)) // is there room?
return partial;
for (extern_type* p = tmp; n; --n) // write it
*to_nxt++ = *p++;
@@ -1398,8 +1478,9 @@ codecvt<wchar_t, char, mbstate_t>::do_in(state_type& st,
{
// save state in case needed to reover to_nxt on error
mbstate_t save_state = st;
-#ifdef _LIBCPP_STABLE_APPLE_ABI
- size_t n = mbsnrtowcs_l(to, &frm_nxt, fend-frm, to_end-to, &st, __l);
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+ size_t n = mbsnrtowcs_l(to, &frm_nxt, static_cast<size_t>(fend-frm),
+ static_cast<size_t>(to_end-to), &st, __l);
#else
size_t n = __mbsnrtowcs_l(to, &frm_nxt, fend-frm, to_end-to, &st, __l);
#endif
@@ -1408,8 +1489,9 @@ codecvt<wchar_t, char, mbstate_t>::do_in(state_type& st,
// need to recover to_nxt
for (to_nxt = to; frm != frm_nxt; ++to_nxt)
{
-#ifdef _LIBCPP_STABLE_APPLE_ABI
- n = mbrtowc_l(to_nxt, frm, fend-frm, &save_state, __l);
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+ n = mbrtowc_l(to_nxt, frm, static_cast<size_t>(fend-frm),
+ &save_state, __l);
#else
n = __mbrtowc_l(to_nxt, frm, fend-frm, &save_state, __l);
#endif
@@ -1418,10 +1500,10 @@ codecvt<wchar_t, char, mbstate_t>::do_in(state_type& st,
case 0:
++frm;
break;
- case static_cast<size_t>(-1): // XXX EMSCRIPTEN
+ case size_t(-1):
frm_nxt = frm;
return error;
- case static_cast<size_t>(-2): // XXX EMSCRIPTEN
+ case size_t(-2):
frm_nxt = frm;
return partial;
default:
@@ -1440,7 +1522,7 @@ codecvt<wchar_t, char, mbstate_t>::do_in(state_type& st,
if (fend != frm_end) // set up next null terminated sequence
{
// Try to write the terminating null
-#ifdef _LIBCPP_STABLE_APPLE_ABI
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
n = mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l);
#else
n = __mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l);
@@ -1464,7 +1546,7 @@ codecvt<wchar_t, char, mbstate_t>::do_unshift(state_type& st,
{
to_nxt = to;
extern_type tmp[MB_LEN_MAX];
-#ifdef _LIBCPP_STABLE_APPLE_ABI
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
size_t n = wcrtomb_l(tmp, intern_type(), &st, __l);
#else
size_t n = __wcrtomb_l(tmp, intern_type(), &st, __l);
@@ -1472,7 +1554,7 @@ codecvt<wchar_t, char, mbstate_t>::do_unshift(state_type& st,
if (n == size_t(-1) || n == 0) // on error
return error;
--n;
- if (n > to_end-to_nxt) // is there room?
+ if (n > static_cast<size_t>(to_end-to_nxt)) // is there room?
return partial;
for (extern_type* p = tmp; n; --n) // write it
*to_nxt++ = *p++;
@@ -1482,14 +1564,14 @@ codecvt<wchar_t, char, mbstate_t>::do_unshift(state_type& st,
int
codecvt<wchar_t, char, mbstate_t>::do_encoding() const _NOEXCEPT
{
-#ifdef _LIBCPP_STABLE_APPLE_ABI
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
if (mbtowc_l((wchar_t*) 0, (const char*) 0, MB_LEN_MAX, __l) == 0)
#else
if (__mbtowc_l((wchar_t*) 0, (const char*) 0, MB_LEN_MAX, __l) == 0)
#endif
{
// stateless encoding
-#ifdef _LIBCPP_STABLE_APPLE_ABI
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
if (__l == 0 || MB_CUR_MAX_L(__l) == 1) // there are no known constant length encodings
#else
if (__l == 0 || __mb_cur_max_l(__l) == 1) // there are no known constant length encodings
@@ -1513,8 +1595,8 @@ codecvt<wchar_t, char, mbstate_t>::do_length(state_type& st,
int nbytes = 0;
for (size_t nwchar_t = 0; nwchar_t < mx && frm != frm_end; ++nwchar_t)
{
-#ifdef _LIBCPP_STABLE_APPLE_ABI
- size_t n = mbrlen_l(frm, frm_end-frm, &st, __l);
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+ size_t n = mbrlen_l(frm, static_cast<size_t>(frm_end-frm), &st, __l);
#else
size_t n = __mbrlen_l(frm, frm_end-frm, &st, __l);
#endif
@@ -1524,8 +1606,8 @@ codecvt<wchar_t, char, mbstate_t>::do_length(state_type& st,
++nbytes;
++frm;
break;
- case static_cast<size_t>(-1): // XXX EMSCRIPTEN
- case static_cast<size_t>(-2): // XXX EMSCRIPTEN
+ case size_t(-1):
+ case size_t(-2):
return nbytes;
default:
nbytes += n;
@@ -1539,10 +1621,10 @@ codecvt<wchar_t, char, mbstate_t>::do_length(state_type& st,
int
codecvt<wchar_t, char, mbstate_t>::do_max_length() const _NOEXCEPT
{
-#ifdef _LIBCPP_STABLE_APPLE_ABI
- return __l == 0 ? 1 : MB_CUR_MAX_L(__l);
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+ return __l == 0 ? 1 : static_cast<int>( MB_CUR_MAX_L(__l));
#else
- return __l == 0 ? 1 : __mb_cur_max_l(__l);
+ return __l == 0 ? 1 : static_cast<int>(__mb_cur_max_l(__l));
#endif
}
@@ -1997,9 +2079,6 @@ utf8_to_utf16_length(const uint8_t* frm, const uint8_t* frm_end,
break;
uint8_t c2 = frm_nxt[1];
uint8_t c3 = frm_nxt[2];
- uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
- | ((c2 & 0x3F) << 6)
- | (c3 & 0x3F));
switch (c1)
{
case 0xE0:
@@ -2017,7 +2096,7 @@ utf8_to_utf16_length(const uint8_t* frm, const uint8_t* frm_end,
}
if ((c3 & 0xC0) != 0x80)
break;
- if ((((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F)) > Maxcode)
+ if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
break;
frm_nxt += 3;
}
@@ -2259,7 +2338,7 @@ utf8_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
{
if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))
break;
- if ((((c1 & 0x1F) << 6) | (frm_nxt[1] & 0x3F)) > Maxcode)
+ if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode)
break;
frm_nxt += 2;
}
@@ -2286,7 +2365,7 @@ utf8_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
}
if ((c3 & 0xC0) != 0x80)
break;
- if ((((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F)) > Maxcode)
+ if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
break;
frm_nxt += 3;
}
@@ -2314,12 +2393,8 @@ utf8_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
}
if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
break;
- uint32_t t = static_cast<uint32_t>(((c1 & 0x07) << 18)
- | ((c2 & 0x3F) << 12)
- | ((c3 & 0x3F) << 6)
- | (c4 & 0x3F));
- if ((((c1 & 0x07) << 18) | ((c2 & 0x3F) << 12) |
- ((c3 & 0x3F) << 6) | (c4 & 0x3F)) > Maxcode)
+ if ((((c1 & 0x07u) << 18) | ((c2 & 0x3Fu) << 12) |
+ ((c3 & 0x3Fu) << 6) | (c4 & 0x3Fu)) > Maxcode)
break;
frm_nxt += 4;
}
@@ -2488,7 +2563,7 @@ utf8_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
{
if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))
break;
- if ((((c1 & 0x1F) << 6) | (frm_nxt[1] & 0x3F)) > Maxcode)
+ if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode)
break;
frm_nxt += 2;
}
@@ -2515,7 +2590,7 @@ utf8_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
}
if ((c3 & 0xC0) != 0x80)
break;
- if ((((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F)) > Maxcode)
+ if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
break;
frm_nxt += 3;
}
@@ -2587,7 +2662,7 @@ utf16be_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_
}
for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
{
- uint16_t c1 = frm_nxt[0] << 8 | frm_nxt[1];
+ uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
if ((c1 & 0xFC00) == 0xDC00)
return codecvt_base::error;
if ((c1 & 0xFC00) != 0xD800)
@@ -2601,7 +2676,7 @@ utf16be_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_
{
if (frm_end-frm_nxt < 4)
return codecvt_base::partial;
- uint16_t c2 = frm_nxt[2] << 8 | frm_nxt[3];
+ uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]);
if ((c2 & 0xFC00) != 0xDC00)
return codecvt_base::error;
uint32_t t = static_cast<uint32_t>(
@@ -2624,7 +2699,6 @@ utf16be_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
codecvt_mode mode = codecvt_mode(0))
{
const uint8_t* frm_nxt = frm;
- frm_nxt = frm;
if (mode & consume_header)
{
if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
@@ -2632,7 +2706,7 @@ utf16be_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
}
for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)
{
- uint16_t c1 = frm_nxt[0] << 8 | frm_nxt[1];
+ uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
if ((c1 & 0xFC00) == 0xDC00)
break;
if ((c1 & 0xFC00) != 0xD800)
@@ -2645,7 +2719,7 @@ utf16be_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
{
if (frm_end-frm_nxt < 4)
break;
- uint16_t c2 = frm_nxt[2] << 8 | frm_nxt[3];
+ uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]);
if ((c2 & 0xFC00) != 0xDC00)
break;
uint32_t t = static_cast<uint32_t>(
@@ -2720,7 +2794,7 @@ utf16le_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_
}
for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
{
- uint16_t c1 = frm_nxt[1] << 8 | frm_nxt[0];
+ uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
if ((c1 & 0xFC00) == 0xDC00)
return codecvt_base::error;
if ((c1 & 0xFC00) != 0xD800)
@@ -2734,7 +2808,7 @@ utf16le_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_
{
if (frm_end-frm_nxt < 4)
return codecvt_base::partial;
- uint16_t c2 = frm_nxt[3] << 8 | frm_nxt[2];
+ uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]);
if ((c2 & 0xFC00) != 0xDC00)
return codecvt_base::error;
uint32_t t = static_cast<uint32_t>(
@@ -2757,7 +2831,6 @@ utf16le_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
codecvt_mode mode = codecvt_mode(0))
{
const uint8_t* frm_nxt = frm;
- frm_nxt = frm;
if (mode & consume_header)
{
if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
@@ -2765,7 +2838,7 @@ utf16le_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
}
for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)
{
- uint16_t c1 = frm_nxt[1] << 8 | frm_nxt[0];
+ uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
if ((c1 & 0xFC00) == 0xDC00)
break;
if ((c1 & 0xFC00) != 0xD800)
@@ -2778,7 +2851,7 @@ utf16le_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
{
if (frm_end-frm_nxt < 4)
break;
- uint16_t c2 = frm_nxt[3] << 8 | frm_nxt[2];
+ uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]);
if ((c2 & 0xFC00) != 0xDC00)
break;
uint32_t t = static_cast<uint32_t>(
@@ -2836,7 +2909,7 @@ utf16be_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_
}
for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
{
- uint16_t c1 = frm_nxt[0] << 8 | frm_nxt[1];
+ uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
return codecvt_base::error;
*to_nxt = c1;
@@ -2852,7 +2925,6 @@ utf16be_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
codecvt_mode mode = codecvt_mode(0))
{
const uint8_t* frm_nxt = frm;
- frm_nxt = frm;
if (mode & consume_header)
{
if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
@@ -2860,7 +2932,7 @@ utf16be_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
}
for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)
{
- uint16_t c1 = frm_nxt[0] << 8 | frm_nxt[1];
+ uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
break;
frm_nxt += 2;
@@ -2911,7 +2983,7 @@ utf16le_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_
}
for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
{
- uint16_t c1 = frm_nxt[1] << 8 | frm_nxt[0];
+ uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
return codecvt_base::error;
*to_nxt = c1;
@@ -2935,7 +3007,7 @@ utf16le_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
}
for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)
{
- uint16_t c1 = frm_nxt[1] << 8 | frm_nxt[0];
+ uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
break;
frm_nxt += 2;
@@ -4088,11 +4160,11 @@ numpunct_byname<char>::__init(const char* nm)
{
__locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
#ifndef _LIBCPP_NO_EXCEPTIONS
- if (loc == 0)
+ if (loc == nullptr)
throw runtime_error("numpunct_byname<char>::numpunct_byname"
" failed to construct for " + string(nm));
#endif // _LIBCPP_NO_EXCEPTIONS
-#ifdef _LIBCPP_STABLE_APPLE_ABI
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
lconv* lc = localeconv_l(loc.get());
#else
lconv* lc = __localeconv_l(loc.get());
@@ -4131,11 +4203,11 @@ numpunct_byname<wchar_t>::__init(const char* nm)
{
__locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
#ifndef _LIBCPP_NO_EXCEPTIONS
- if (loc == 0)
+ if (loc == nullptr)
throw runtime_error("numpunct_byname<char>::numpunct_byname"
" failed to construct for " + string(nm));
#endif // _LIBCPP_NO_EXCEPTIONS
-#ifdef _LIBCPP_STABLE_APPLE_ABI
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
lconv* lc = localeconv_l(loc.get());
#else
lconv* lc = __localeconv_l(loc.get());
@@ -4179,7 +4251,7 @@ __check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end,
{
if (0 < *__ig && *__ig < numeric_limits<char>::max())
{
- if (*__ig != *__r)
+ if (static_cast<unsigned>(*__ig) != *__r)
{
__err = ios_base::failbit;
return;
@@ -4190,7 +4262,7 @@ __check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end,
}
if (0 < *__ig && *__ig < numeric_limits<char>::max())
{
- if (*__ig < __g_end[-1] || __g_end[-1] == 0)
+ if (static_cast<unsigned>(*__ig) < __g_end[-1] || __g_end[-1] == 0)
__err = ios_base::failbit;
}
}
@@ -4563,11 +4635,14 @@ __time_get::~__time_get()
freelocale(__loc_);
}
+#pragma clang diagnostic ignored "-Wmissing-field-initializers"
+#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
+
template <>
string
__time_get_storage<char>::__analyze(char fmt, const ctype<char>& ct)
{
- tm t;
+ tm t = {0};
t.tm_sec = 59;
t.tm_min = 55;
t.tm_hour = 23;
@@ -4581,7 +4656,7 @@ __time_get_storage<char>::__analyze(char fmt, const ctype<char>& ct)
char f[3] = {0};
f[0] = '%';
f[1] = fmt;
- size_t n = strftime_l(buf, 100, f, &t, __loc_);
+ size_t n = strftime_l(buf, countof(buf), f, &t, __loc_);
char* bb = buf;
char* be = buf + n;
string result;
@@ -4596,7 +4671,7 @@ __time_get_storage<char>::__analyze(char fmt, const ctype<char>& ct)
}
char* w = bb;
ios_base::iostate err = ios_base::goodbit;
- int i = __scan_keyword(w, be, this->__weeks_, this->__weeks_+14,
+ ptrdiff_t i = __scan_keyword(w, be, this->__weeks_, this->__weeks_+14,
ct, err, false)
- this->__weeks_;
if (i < 14)
@@ -4707,11 +4782,13 @@ __time_get_storage<char>::__analyze(char fmt, const ctype<char>& ct)
return result;
}
+#pragma clang diagnostic ignored "-Wmissing-braces"
+
template <>
wstring
__time_get_storage<wchar_t>::__analyze(char fmt, const ctype<wchar_t>& ct)
{
- tm t;
+ tm t = {0};
t.tm_sec = 59;
t.tm_min = 55;
t.tm_hour = 23;
@@ -4725,19 +4802,19 @@ __time_get_storage<wchar_t>::__analyze(char fmt, const ctype<wchar_t>& ct)
char f[3] = {0};
f[0] = '%';
f[1] = fmt;
- size_t be = strftime_l(buf, 100, f, &t, __loc_);
+ strftime_l(buf, countof(buf), f, &t, __loc_);
wchar_t wbuf[100];
wchar_t* wbb = wbuf;
mbstate_t mb = {0};
const char* bb = buf;
-#ifdef _LIBCPP_STABLE_APPLE_ABI
- size_t i = mbsrtowcs_l( wbb, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+ size_t j = mbsrtowcs_l( wbb, &bb, countof(wbuf), &mb, __loc_);
#else
- size_t i = __mbsrtowcs_l( wbb, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
+ size_t j = __mbsrtowcs_l( wbb, &bb, countof(wbuf), &mb, __loc_);
#endif
- if (i == -1)
+ if (j == size_t(-1))
__throw_runtime_error("locale not supported");
- wchar_t* wbe = wbb + i;
+ wchar_t* wbe = wbb + j;
wstring result;
while (wbb != wbe)
{
@@ -4750,7 +4827,7 @@ __time_get_storage<wchar_t>::__analyze(char fmt, const ctype<wchar_t>& ct)
}
wchar_t* w = wbb;
ios_base::iostate err = ios_base::goodbit;
- int i = __scan_keyword(w, wbe, this->__weeks_, this->__weeks_+14,
+ ptrdiff_t i = __scan_keyword(w, wbe, this->__weeks_, this->__weeks_+14,
ct, err, false)
- this->__weeks_;
if (i < 14)
@@ -4865,32 +4942,32 @@ template <>
void
__time_get_storage<char>::init(const ctype<char>& ct)
{
- tm t;
+ tm t = {0};
char buf[100];
// __weeks_
for (int i = 0; i < 7; ++i)
{
t.tm_wday = i;
- strftime_l(buf, 100, "%A", &t, __loc_);
+ strftime_l(buf, countof(buf), "%A", &t, __loc_);
__weeks_[i] = buf;
- strftime_l(buf, 100, "%a", &t, __loc_);
+ strftime_l(buf, countof(buf), "%a", &t, __loc_);
__weeks_[i+7] = buf;
}
// __months_
for (int i = 0; i < 12; ++i)
{
t.tm_mon = i;
- strftime_l(buf, 100, "%B", &t, __loc_);
+ strftime_l(buf, countof(buf), "%B", &t, __loc_);
__months_[i] = buf;
- strftime_l(buf, 100, "%b", &t, __loc_);
+ strftime_l(buf, countof(buf), "%b", &t, __loc_);
__months_[i+12] = buf;
}
// __am_pm_
t.tm_hour = 1;
- strftime_l(buf, 100, "%p", &t, __loc_);
+ strftime_l(buf, countof(buf), "%p", &t, __loc_);
__am_pm_[0] = buf;
t.tm_hour = 13;
- strftime_l(buf, 100, "%p", &t, __loc_);
+ strftime_l(buf, countof(buf), "%p", &t, __loc_);
__am_pm_[1] = buf;
__c_ = __analyze('c', ct);
__r_ = __analyze('r', ct);
@@ -4904,7 +4981,6 @@ __time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct)
{
tm t = {0};
char buf[100];
- size_t be;
wchar_t wbuf[100];
wchar_t* wbe;
mbstate_t mb = {0};
@@ -4912,27 +4988,27 @@ __time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct)
for (int i = 0; i < 7; ++i)
{
t.tm_wday = i;
- be = strftime_l(buf, 100, "%A", &t, __loc_);
+ strftime_l(buf, countof(buf), "%A", &t, __loc_);
mb = mbstate_t();
const char* bb = buf;
-#ifdef _LIBCPP_STABLE_APPLE_ABI
- size_t j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+ size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
#else
- size_t j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
+ size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
#endif
- if (j == -1)
+ if (j == size_t(-1))
__throw_runtime_error("locale not supported");
wbe = wbuf + j;
__weeks_[i].assign(wbuf, wbe);
- be = strftime_l(buf, 100, "%a", &t, __loc_);
+ strftime_l(buf, countof(buf), "%a", &t, __loc_);
mb = mbstate_t();
bb = buf;
-#ifdef _LIBCPP_STABLE_APPLE_ABI
- j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+ j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
#else
- j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
+ j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
#endif
- if (j == -1)
+ if (j == size_t(-1))
__throw_runtime_error("locale not supported");
wbe = wbuf + j;
__weeks_[i+7].assign(wbuf, wbe);
@@ -4941,55 +5017,55 @@ __time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct)
for (int i = 0; i < 12; ++i)
{
t.tm_mon = i;
- be = strftime_l(buf, 100, "%B", &t, __loc_);
+ strftime_l(buf, countof(buf), "%B", &t, __loc_);
mb = mbstate_t();
const char* bb = buf;
-#ifdef _LIBCPP_STABLE_APPLE_ABI
- size_t j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+ size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
#else
- size_t j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
+ size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
#endif
- if (j == -1)
+ if (j == size_t(-1))
__throw_runtime_error("locale not supported");
wbe = wbuf + j;
__months_[i].assign(wbuf, wbe);
- be = strftime_l(buf, 100, "%b", &t, __loc_);
+ strftime_l(buf, countof(buf), "%b", &t, __loc_);
mb = mbstate_t();
bb = buf;
-#ifdef _LIBCPP_STABLE_APPLE_ABI
- j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+ j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
#else
- j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
+ j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
#endif
- if (j == -1)
+ if (j == size_t(-1))
__throw_runtime_error("locale not supported");
wbe = wbuf + j;
__months_[i+12].assign(wbuf, wbe);
}
// __am_pm_
t.tm_hour = 1;
- be = strftime_l(buf, 100, "%p", &t, __loc_);
+ strftime_l(buf, countof(buf), "%p", &t, __loc_);
mb = mbstate_t();
const char* bb = buf;
-#ifdef _LIBCPP_STABLE_APPLE_ABI
- size_t j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+ size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
#else
- size_t j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
+ size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
#endif
- if (j == -1)
+ if (j == size_t(-1))
__throw_runtime_error("locale not supported");
wbe = wbuf + j;
__am_pm_[0].assign(wbuf, wbe);
t.tm_hour = 13;
- be = strftime_l(buf, 100, "%p", &t, __loc_);
+ strftime_l(buf, countof(buf), "%p", &t, __loc_);
mb = mbstate_t();
bb = buf;
-#ifdef _LIBCPP_STABLE_APPLE_ABI
- j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+ j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
#else
- j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
+ j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
#endif
- if (j == -1)
+ if (j == size_t(-1))
__throw_runtime_error("locale not supported");
wbe = wbuf + j;
__am_pm_[1].assign(wbuf, wbe);
@@ -5250,7 +5326,7 @@ __time_put::__do_put(char* __nb, char*& __ne, const tm* __tm,
char fmt[] = {'%', __fmt, __mod, 0};
if (__mod != 0)
swap(fmt[1], fmt[2]);
- size_t n = strftime_l(__nb, __ne-__nb, fmt, __tm, __loc_);
+ size_t n = strftime_l(__nb, countof(__nb, __ne), fmt, __tm, __loc_);
__ne = __nb + n;
}
@@ -5263,128 +5339,212 @@ __time_put::__do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm,
__do_put(__nar, __ne, __tm, __fmt, __mod);
mbstate_t mb = {0};
const char* __nb = __nar;
-#ifdef _LIBCPP_STABLE_APPLE_ABI
- size_t j = mbsrtowcs_l(__wb, &__nb, 100, &mb, __loc_);
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+ size_t j = mbsrtowcs_l(__wb, &__nb, countof(__wb, __we), &mb, __loc_);
#else
- size_t j = __mbsrtowcs_l(__wb, &__nb, 100, &mb, __loc_);
+ size_t j = __mbsrtowcs_l(__wb, &__nb, countof(__wb, __we), &mb, __loc_);
#endif
- if (j == -1)
+ if (j == size_t(-1))
__throw_runtime_error("locale not supported");
__we = __wb + j;
}
// moneypunct_byname
+template <class charT>
static
void
-__init_pat(money_base::pattern& pat, char cs_precedes, char sep_by_space, char sign_posn)
+__init_pat(money_base::pattern& pat, basic_string<charT>& __curr_symbol_,
+ bool intl, char cs_precedes, char sep_by_space, char sign_posn,
+ charT space_char)
{
const char sign = static_cast<char>(money_base::sign);
const char space = static_cast<char>(money_base::space);
const char none = static_cast<char>(money_base::none);
const char symbol = static_cast<char>(money_base::symbol);
const char value = static_cast<char>(money_base::value);
+ const bool symbol_contains_sep = intl && __curr_symbol_.size() == 4;
+
+ // Comments on case branches reflect 'C11 7.11.2.1 The localeconv
+ // function'. "Space between sign and symbol or value" means that
+ // if the sign is adjacent to the symbol, there's a space between
+ // them, and otherwise there's a space between the sign and value.
+ //
+ // C11's localeconv specifies that the fourth character of an
+ // international curr_symbol is used to separate the sign and
+ // value when sep_by_space says to do so. C++ can't represent
+ // that, so we just use a space. When sep_by_space says to
+ // separate the symbol and value-or-sign with a space, we rearrange the
+ // curr_symbol to put its spacing character on the correct side of
+ // the symbol.
+ //
+ // We also need to avoid adding an extra space between the sign
+ // and value when the currency symbol is suppressed (by not
+ // setting showbase). We match glibc's strfmon by interpreting
+ // sep_by_space==1 as "omit the space when the currency symbol is
+ // absent".
+ //
+ // Users who want to get this right should use ICU instead.
+
switch (cs_precedes)
{
- case 0:
+ case 0: // value before curr_symbol
+ if (symbol_contains_sep) {
+ // Move the separator to before the symbol, to place it
+ // between the value and symbol.
+ rotate(__curr_symbol_.begin(), __curr_symbol_.begin() + 3,
+ __curr_symbol_.end());
+ }
switch (sign_posn)
{
- case 0:
+ case 0: // Parentheses surround the quantity and currency symbol.
pat.field[0] = sign;
pat.field[1] = value;
+ pat.field[2] = none; // Any space appears in the symbol.
pat.field[3] = symbol;
switch (sep_by_space)
{
- case 0:
- pat.field[2] = none;
+ case 0: // No space separates the currency symbol and value.
+ // This case may have changed between C99 and C11;
+ // assume the currency symbol matches the intention.
+ case 2: // Space between sign and currency or value.
+ // The "sign" is two parentheses, so no space here either.
return;
- case 1:
- case 2:
- pat.field[2] = space;
+ case 1: // Space between currency-and-sign or currency and value.
+ if (!symbol_contains_sep) {
+ // We insert the space into the symbol instead of
+ // setting pat.field[2]=space so that when
+ // showbase is not set, the space goes away too.
+ __curr_symbol_.insert(0, 1, space_char);
+ }
return;
default:
break;
}
break;
- case 1:
+ case 1: // The sign string precedes the quantity and currency symbol.
pat.field[0] = sign;
pat.field[3] = symbol;
switch (sep_by_space)
{
- case 0:
+ case 0: // No space separates the currency symbol and value.
pat.field[1] = value;
pat.field[2] = none;
return;
- case 1:
+ case 1: // Space between currency-and-sign or currency and value.
pat.field[1] = value;
- pat.field[2] = space;
+ pat.field[2] = none;
+ if (!symbol_contains_sep) {
+ // We insert the space into the symbol instead of
+ // setting pat.field[2]=space so that when
+ // showbase is not set, the space goes away too.
+ __curr_symbol_.insert(0, 1, space_char);
+ }
return;
- case 2:
+ case 2: // Space between sign and currency or value.
pat.field[1] = space;
pat.field[2] = value;
+ if (symbol_contains_sep) {
+ // Remove the separator from the symbol, since it
+ // has already appeared after the sign.
+ __curr_symbol_.erase(__curr_symbol_.begin());
+ }
return;
default:
break;
}
break;
- case 2:
+ case 2: // The sign string succeeds the quantity and currency symbol.
pat.field[0] = value;
pat.field[3] = sign;
switch (sep_by_space)
{
- case 0:
+ case 0: // No space separates the currency symbol and value.
pat.field[1] = none;
pat.field[2] = symbol;
return;
- case 1:
- pat.field[1] = space;
+ case 1: // Space between currency-and-sign or currency and value.
+ if (!symbol_contains_sep) {
+ // We insert the space into the symbol instead of
+ // setting pat.field[1]=space so that when
+ // showbase is not set, the space goes away too.
+ __curr_symbol_.insert(0, 1, space_char);
+ }
+ pat.field[1] = none;
pat.field[2] = symbol;
return;
- case 2:
+ case 2: // Space between sign and currency or value.
pat.field[1] = symbol;
pat.field[2] = space;
+ if (symbol_contains_sep) {
+ // Remove the separator from the symbol, since it
+ // should not be removed if showbase is absent.
+ __curr_symbol_.erase(__curr_symbol_.begin());
+ }
return;
default:
break;
}
break;
- case 3:
+ case 3: // The sign string immediately precedes the currency symbol.
pat.field[0] = value;
pat.field[3] = symbol;
switch (sep_by_space)
{
- case 0:
+ case 0: // No space separates the currency symbol and value.
pat.field[1] = none;
pat.field[2] = sign;
return;
- case 1:
+ case 1: // Space between currency-and-sign or currency and value.
pat.field[1] = space;
pat.field[2] = sign;
+ if (symbol_contains_sep) {
+ // Remove the separator from the symbol, since it
+ // has already appeared before the sign.
+ __curr_symbol_.erase(__curr_symbol_.begin());
+ }
return;
- case 2:
+ case 2: // Space between sign and currency or value.
pat.field[1] = sign;
- pat.field[2] = space;
+ pat.field[2] = none;
+ if (!symbol_contains_sep) {
+ // We insert the space into the symbol instead of
+ // setting pat.field[2]=space so that when
+ // showbase is not set, the space goes away too.
+ __curr_symbol_.insert(0, 1, space_char);
+ }
return;
default:
break;
}
break;
- case 4:
+ case 4: // The sign string immediately succeeds the currency symbol.
pat.field[0] = value;
pat.field[3] = sign;
switch (sep_by_space)
{
- case 0:
+ case 0: // No space separates the currency symbol and value.
pat.field[1] = none;
pat.field[2] = symbol;
return;
- case 1:
- pat.field[1] = space;
+ case 1: // Space between currency-and-sign or currency and value.
+ pat.field[1] = none;
pat.field[2] = symbol;
+ if (!symbol_contains_sep) {
+ // We insert the space into the symbol instead of
+ // setting pat.field[1]=space so that when
+ // showbase is not set, the space goes away too.
+ __curr_symbol_.insert(0, 1, space_char);
+ }
return;
- case 2:
+ case 2: // Space between sign and currency or value.
pat.field[1] = symbol;
pat.field[2] = space;
+ if (symbol_contains_sep) {
+ // Remove the separator from the symbol, since it
+ // should not disappear when showbase is absent.
+ __curr_symbol_.erase(__curr_symbol_.begin());
+ }
return;
default:
break;
@@ -5394,105 +5554,157 @@ __init_pat(money_base::pattern& pat, char cs_precedes, char sep_by_space, char s
break;
}
break;
- case 1:
+ case 1: // curr_symbol before value
switch (sign_posn)
{
- case 0:
+ case 0: // Parentheses surround the quantity and currency symbol.
pat.field[0] = sign;
pat.field[1] = symbol;
+ pat.field[2] = none; // Any space appears in the symbol.
pat.field[3] = value;
switch (sep_by_space)
{
- case 0:
- pat.field[2] = none;
+ case 0: // No space separates the currency symbol and value.
+ // This case may have changed between C99 and C11;
+ // assume the currency symbol matches the intention.
+ case 2: // Space between sign and currency or value.
+ // The "sign" is two parentheses, so no space here either.
return;
- case 1:
- case 2:
- pat.field[2] = space;
+ case 1: // Space between currency-and-sign or currency and value.
+ if (!symbol_contains_sep) {
+ // We insert the space into the symbol instead of
+ // setting pat.field[2]=space so that when
+ // showbase is not set, the space goes away too.
+ __curr_symbol_.insert(0, 1, space_char);
+ }
return;
default:
break;
}
break;
- case 1:
+ case 1: // The sign string precedes the quantity and currency symbol.
pat.field[0] = sign;
pat.field[3] = value;
switch (sep_by_space)
{
- case 0:
+ case 0: // No space separates the currency symbol and value.
pat.field[1] = symbol;
pat.field[2] = none;
return;
- case 1:
+ case 1: // Space between currency-and-sign or currency and value.
pat.field[1] = symbol;
- pat.field[2] = space;
+ pat.field[2] = none;
+ if (!symbol_contains_sep) {
+ // We insert the space into the symbol instead of
+ // setting pat.field[2]=space so that when
+ // showbase is not set, the space goes away too.
+ __curr_symbol_.push_back(space_char);
+ }
return;
- case 2:
+ case 2: // Space between sign and currency or value.
pat.field[1] = space;
pat.field[2] = symbol;
+ if (symbol_contains_sep) {
+ // Remove the separator from the symbol, since it
+ // has already appeared after the sign.
+ __curr_symbol_.pop_back();
+ }
return;
default:
break;
}
break;
- case 2:
+ case 2: // The sign string succeeds the quantity and currency symbol.
pat.field[0] = symbol;
pat.field[3] = sign;
switch (sep_by_space)
{
- case 0:
+ case 0: // No space separates the currency symbol and value.
pat.field[1] = none;
pat.field[2] = value;
return;
- case 1:
- pat.field[1] = space;
+ case 1: // Space between currency-and-sign or currency and value.
+ pat.field[1] = none;
pat.field[2] = value;
+ if (!symbol_contains_sep) {
+ // We insert the space into the symbol instead of
+ // setting pat.field[1]=space so that when
+ // showbase is not set, the space goes away too.
+ __curr_symbol_.push_back(space_char);
+ }
return;
- case 2:
+ case 2: // Space between sign and currency or value.
pat.field[1] = value;
pat.field[2] = space;
+ if (symbol_contains_sep) {
+ // Remove the separator from the symbol, since it
+ // will appear before the sign.
+ __curr_symbol_.pop_back();
+ }
return;
default:
break;
}
break;
- case 3:
+ case 3: // The sign string immediately precedes the currency symbol.
pat.field[0] = sign;
pat.field[3] = value;
switch (sep_by_space)
{
- case 0:
+ case 0: // No space separates the currency symbol and value.
pat.field[1] = symbol;
pat.field[2] = none;
return;
- case 1:
+ case 1: // Space between currency-and-sign or currency and value.
pat.field[1] = symbol;
- pat.field[2] = space;
+ pat.field[2] = none;
+ if (!symbol_contains_sep) {
+ // We insert the space into the symbol instead of
+ // setting pat.field[2]=space so that when
+ // showbase is not set, the space goes away too.
+ __curr_symbol_.push_back(space_char);
+ }
return;
- case 2:
+ case 2: // Space between sign and currency or value.
pat.field[1] = space;
pat.field[2] = symbol;
+ if (symbol_contains_sep) {
+ // Remove the separator from the symbol, since it
+ // has already appeared after the sign.
+ __curr_symbol_.pop_back();
+ }
return;
default:
break;
}
break;
- case 4:
+ case 4: // The sign string immediately succeeds the currency symbol.
pat.field[0] = symbol;
pat.field[3] = value;
switch (sep_by_space)
{
- case 0:
+ case 0: // No space separates the currency symbol and value.
pat.field[1] = sign;
pat.field[2] = none;
return;
- case 1:
+ case 1: // Space between currency-and-sign or currency and value.
pat.field[1] = sign;
pat.field[2] = space;
+ if (symbol_contains_sep) {
+ // Remove the separator from the symbol, since it
+ // should not disappear when showbase is absent.
+ __curr_symbol_.pop_back();
+ }
return;
- case 2:
- pat.field[1] = space;
+ case 2: // Space between sign and currency or value.
+ pat.field[1] = none;
pat.field[2] = sign;
+ if (!symbol_contains_sep) {
+ // We insert the space into the symbol instead of
+ // setting pat.field[1]=space so that when
+ // showbase is not set, the space goes away too.
+ __curr_symbol_.push_back(space_char);
+ }
return;
default:
break;
@@ -5518,11 +5730,11 @@ moneypunct_byname<char, false>::init(const char* nm)
typedef moneypunct<char, false> base;
__locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
#ifndef _LIBCPP_NO_EXCEPTIONS
- if (loc == 0)
+ if (loc == nullptr)
throw runtime_error("moneypunct_byname"
" failed to construct for " + string(nm));
#endif // _LIBCPP_NO_EXCEPTIONS
-#ifdef _LIBCPP_STABLE_APPLE_ABI
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
lconv* lc = localeconv_l(loc.get());
#else
lconv* lc = __localeconv_l(loc.get());
@@ -5549,8 +5761,14 @@ moneypunct_byname<char, false>::init(const char* nm)
__negative_sign_ = "()";
else
__negative_sign_ = lc->negative_sign;
- __init_pat(__pos_format_, lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn);
- __init_pat(__neg_format_, lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn);
+ // Assume the positive and negative formats will want spaces in
+ // the same places in curr_symbol since there's no way to
+ // represent anything else.
+ string_type __dummy_curr_symbol = __curr_symbol_;
+ __init_pat(__pos_format_, __dummy_curr_symbol, false,
+ lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' ');
+ __init_pat(__neg_format_, __curr_symbol_, false,
+ lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' ');
}
template<>
@@ -5560,11 +5778,11 @@ moneypunct_byname<char, true>::init(const char* nm)
typedef moneypunct<char, true> base;
__locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
#ifndef _LIBCPP_NO_EXCEPTIONS
- if (loc == 0)
+ if (loc == nullptr)
throw runtime_error("moneypunct_byname"
" failed to construct for " + string(nm));
#endif // _LIBCPP_NO_EXCEPTIONS
-#ifdef _LIBCPP_STABLE_APPLE_ABI
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
lconv* lc = localeconv_l(loc.get());
#else
lconv* lc = __localeconv_l(loc.get());
@@ -5583,7 +5801,7 @@ moneypunct_byname<char, true>::init(const char* nm)
__frac_digits_ = lc->int_frac_digits;
else
__frac_digits_ = base::do_frac_digits();
-#if _WIN32
+#ifdef _WIN32
if (lc->p_sign_posn == 0)
#else // _WIN32
if (lc->int_p_sign_posn == 0)
@@ -5591,7 +5809,7 @@ moneypunct_byname<char, true>::init(const char* nm)
__positive_sign_ = "()";
else
__positive_sign_ = lc->positive_sign;
-#if _WIN32
+#ifdef _WIN32
if(lc->n_sign_posn == 0)
#else // _WIN32
if (lc->int_n_sign_posn == 0)
@@ -5599,12 +5817,22 @@ moneypunct_byname<char, true>::init(const char* nm)
__negative_sign_ = "()";
else
__negative_sign_ = lc->negative_sign;
-#if _WIN32
- __init_pat(__pos_format_, lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn);
- __init_pat(__neg_format_, lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn);
+ // Assume the positive and negative formats will want spaces in
+ // the same places in curr_symbol since there's no way to
+ // represent anything else.
+ string_type __dummy_curr_symbol = __curr_symbol_;
+#ifdef _WIN32
+ __init_pat(__pos_format_, __dummy_curr_symbol, true,
+ lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' ');
+ __init_pat(__neg_format_, __curr_symbol_, true,
+ lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' ');
#else
- __init_pat(__pos_format_, lc->int_p_cs_precedes, lc->int_p_sep_by_space, lc->int_p_sign_posn);
- __init_pat(__neg_format_, lc->int_n_cs_precedes, lc->int_n_sep_by_space, lc->int_n_sign_posn);
+ __init_pat(__pos_format_, __dummy_curr_symbol, true,
+ lc->int_p_cs_precedes, lc->int_p_sep_by_space,
+ lc->int_p_sign_posn, ' ');
+ __init_pat(__neg_format_, __curr_symbol_, true,
+ lc->int_n_cs_precedes, lc->int_n_sep_by_space,
+ lc->int_n_sign_posn, ' ');
#endif // _WIN32
}
@@ -5615,11 +5843,11 @@ moneypunct_byname<wchar_t, false>::init(const char* nm)
typedef moneypunct<wchar_t, false> base;
__locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
#ifndef _LIBCPP_NO_EXCEPTIONS
- if (loc == 0)
+ if (loc == nullptr)
throw runtime_error("moneypunct_byname"
" failed to construct for " + string(nm));
#endif // _LIBCPP_NO_EXCEPTIONS
-#ifdef _LIBCPP_STABLE_APPLE_ABI
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
lconv* lc = localeconv_l(loc.get());
#else
lconv* lc = __localeconv_l(loc.get());
@@ -5636,12 +5864,12 @@ moneypunct_byname<wchar_t, false>::init(const char* nm)
wchar_t wbuf[100];
mbstate_t mb = {0};
const char* bb = lc->currency_symbol;
-#ifdef _LIBCPP_STABLE_APPLE_ABI
- size_t j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+ size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
#else
- size_t j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
+ size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
#endif
- if (j == -1)
+ if (j == size_t(-1))
__throw_runtime_error("locale not supported");
wchar_t* wbe = wbuf + j;
__curr_symbol_.assign(wbuf, wbe);
@@ -5655,12 +5883,12 @@ moneypunct_byname<wchar_t, false>::init(const char* nm)
{
mb = mbstate_t();
bb = lc->positive_sign;
-#ifdef _LIBCPP_STABLE_APPLE_ABI
- j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+ j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
#else
- j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
+ j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
#endif
- if (j == -1)
+ if (j == size_t(-1))
__throw_runtime_error("locale not supported");
wbe = wbuf + j;
__positive_sign_.assign(wbuf, wbe);
@@ -5671,18 +5899,24 @@ moneypunct_byname<wchar_t, false>::init(const char* nm)
{
mb = mbstate_t();
bb = lc->negative_sign;
-#ifdef _LIBCPP_STABLE_APPLE_ABI
- j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+ j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
#else
- j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
+ j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
#endif
- if (j == -1)
+ if (j == size_t(-1))
__throw_runtime_error("locale not supported");
wbe = wbuf + j;
__negative_sign_.assign(wbuf, wbe);
}
- __init_pat(__pos_format_, lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn);
- __init_pat(__neg_format_, lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn);
+ // Assume the positive and negative formats will want spaces in
+ // the same places in curr_symbol since there's no way to
+ // represent anything else.
+ string_type __dummy_curr_symbol = __curr_symbol_;
+ __init_pat(__pos_format_, __dummy_curr_symbol, false,
+ lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' ');
+ __init_pat(__neg_format_, __curr_symbol_, false,
+ lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' ');
}
template<>
@@ -5692,11 +5926,11 @@ moneypunct_byname<wchar_t, true>::init(const char* nm)
typedef moneypunct<wchar_t, true> base;
__locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
#ifndef _LIBCPP_NO_EXCEPTIONS
- if (loc == 0)
+ if (loc == nullptr)
throw runtime_error("moneypunct_byname"
" failed to construct for " + string(nm));
#endif // _LIBCPP_NO_EXCEPTIONS
-#ifdef _LIBCPP_STABLE_APPLE_ABI
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
lconv* lc = localeconv_l(loc.get());
#else
lconv* lc = __localeconv_l(loc.get());
@@ -5713,12 +5947,12 @@ moneypunct_byname<wchar_t, true>::init(const char* nm)
wchar_t wbuf[100];
mbstate_t mb = {0};
const char* bb = lc->int_curr_symbol;
-#ifdef _LIBCPP_STABLE_APPLE_ABI
- size_t j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+ size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
#else
- size_t j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
+ size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
#endif
- if (j == -1)
+ if (j == size_t(-1))
__throw_runtime_error("locale not supported");
wchar_t* wbe = wbuf + j;
__curr_symbol_.assign(wbuf, wbe);
@@ -5726,7 +5960,7 @@ moneypunct_byname<wchar_t, true>::init(const char* nm)
__frac_digits_ = lc->int_frac_digits;
else
__frac_digits_ = base::do_frac_digits();
-#if _WIN32
+#ifdef _WIN32
if (lc->p_sign_posn == 0)
#else // _WIN32
if (lc->int_p_sign_posn == 0)
@@ -5736,17 +5970,17 @@ moneypunct_byname<wchar_t, true>::init(const char* nm)
{
mb = mbstate_t();
bb = lc->positive_sign;
-#ifdef _LIBCPP_STABLE_APPLE_ABI
- j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+ j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
#else
- j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
+ j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
#endif
- if (j == -1)
+ if (j == size_t(-1))
__throw_runtime_error("locale not supported");
wbe = wbuf + j;
__positive_sign_.assign(wbuf, wbe);
}
-#if _WIN32
+#ifdef _WIN32
if (lc->n_sign_posn == 0)
#else // _WIN32
if (lc->int_n_sign_posn == 0)
@@ -5756,22 +5990,32 @@ moneypunct_byname<wchar_t, true>::init(const char* nm)
{
mb = mbstate_t();
bb = lc->negative_sign;
-#ifdef _LIBCPP_STABLE_APPLE_ABI
- j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+ j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
#else
- j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
+ j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
#endif
- if (j == -1)
+ if (j == size_t(-1))
__throw_runtime_error("locale not supported");
wbe = wbuf + j;
__negative_sign_.assign(wbuf, wbe);
}
-#if _WIN32
- __init_pat(__pos_format_, lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn);
- __init_pat(__neg_format_, lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn);
+ // Assume the positive and negative formats will want spaces in
+ // the same places in curr_symbol since there's no way to
+ // represent anything else.
+ string_type __dummy_curr_symbol = __curr_symbol_;
+#ifdef _WIN32
+ __init_pat(__pos_format_, __dummy_curr_symbol, true,
+ lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' ');
+ __init_pat(__neg_format_, __curr_symbol_, true,
+ lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' ');
#else // _WIN32
- __init_pat(__pos_format_, lc->int_p_cs_precedes, lc->int_p_sep_by_space, lc->int_p_sign_posn);
- __init_pat(__neg_format_, lc->int_n_cs_precedes, lc->int_n_sep_by_space, lc->int_n_sign_posn);
+ __init_pat(__pos_format_, __dummy_curr_symbol, true,
+ lc->int_p_cs_precedes, lc->int_p_sep_by_space,
+ lc->int_p_sign_posn, L' ');
+ __init_pat(__neg_format_, __curr_symbol_, true,
+ lc->int_n_cs_precedes, lc->int_n_sep_by_space,
+ lc->int_n_sign_posn, L' ');
#endif // _WIN32
}
@@ -5790,14 +6034,14 @@ template class collate<wchar_t>;
template class num_get<char>;
template class num_get<wchar_t>;
-template class __num_get<char>;
-template class __num_get<wchar_t>;
+template struct __num_get<char>;
+template struct __num_get<wchar_t>;
template class num_put<char>;
template class num_put<wchar_t>;
-template class __num_put<char>;
-template class __num_put<wchar_t>;
+template struct __num_put<char>;
+template struct __num_put<wchar_t>;
template class time_get<char>;
template class time_get<wchar_t>;