diff --git a/src/locale.cpp b/src/locale.cpp index 7fdd5be..1b937dc 100644 --- a/src/locale.cpp +++ b/src/locale.cpp @@ -38,8 +38,8 @@ # include #endif -#include "include/atomic_support.h" #include "include/sso_allocator.h" +#include // 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. @@ -593,8 +593,17 @@ void locale::facet::__on_zero_shared() noexcept { delete this; } constinit int32_t locale::id::__next_id = 0; long locale::id::__get() { - call_once(__flag_, [&] { __id_ = __libcpp_atomic_add(&__next_id, 1); }); - return __id_ - 1; + int32_t result = __id_.load(std::memory_order_acquire); + if (result == 0) { + static std::mutex m; + std::lock_guard guard(m); + result = __id_.load(std::memory_order_acquire); + if (result == 0) { + result = ++__next_id; + __id_.store(result, std::memory_order_release); + } + } + return result - 1; } // template <> class collate_byname @@ -895,6 +904,11 @@ extern "C" const int** __ctype_tolower_loc(); extern "C" const int** __ctype_toupper_loc(); #endif +#if defined(__ANDROID__) +// See src/support/android/android_locale.cpp +extern "C" const unsigned short* const _ctype_android; +#endif + #ifdef _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE const ctype::mask* ctype::classic_table() noexcept { // clang-format off @@ -990,6 +1004,8 @@ const ctype::mask* ctype::classic_table() noexcept { # elif defined(_NEWLIB_VERSION) // Newlib has a 257-entry table in ctype_.c, where (char)0 starts at [1]. return _ctype_ + 1; +# elif defined(__ANDROID__) + return _ctype_android; # elif defined(_AIX) return (const unsigned int*)__lc_ctype_ptr->obj->mask; # elif defined(__MVS__) @@ -3644,15 +3660,25 @@ __codecvt_utf16::result __codecvt_utf16::do_out( extern_type* to, extern_type* to_end, extern_type*& to_nxt) const { +#if defined(_LIBCPP_SHORT_WCHAR) + const uint16_t* _frm = reinterpret_cast(frm); + const uint16_t* _frm_end = reinterpret_cast(frm_end); + const uint16_t* _frm_nxt = _frm; +#else const uint32_t* _frm = reinterpret_cast(frm); const uint32_t* _frm_end = reinterpret_cast(frm_end); const uint32_t* _frm_nxt = _frm; - uint8_t* _to = reinterpret_cast(to); - uint8_t* _to_end = reinterpret_cast(to_end); - uint8_t* _to_nxt = _to; - result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_); - frm_nxt = frm + (_frm_nxt - _frm); - to_nxt = to + (_to_nxt - _to); +#endif + uint8_t* _to = reinterpret_cast(to); + uint8_t* _to_end = reinterpret_cast(to_end); + uint8_t* _to_nxt = _to; +#if defined(_LIBCPP_SHORT_WCHAR) + result r = ucs2_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_); +#else + result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_); +#endif + frm_nxt = frm + (_frm_nxt - _frm); + to_nxt = to + (_to_nxt - _to); return r; } @@ -3712,7 +3738,7 @@ __codecvt_utf8_utf16::result __codecvt_utf8_utf16::do_out( extern_type* to, extern_type* to_end, extern_type*& to_nxt) const { -# if defined(_LIBCPP_SHORT_WCHAR) +# ifdef _WIN32 const uint16_t* _frm = reinterpret_cast(frm); const uint16_t* _frm_end = reinterpret_cast(frm_end); const uint16_t* _frm_nxt = _frm; @@ -3741,7 +3767,7 @@ __codecvt_utf8_utf16::result __codecvt_utf8_utf16::do_in( const uint8_t* _frm = reinterpret_cast(frm); const uint8_t* _frm_end = reinterpret_cast(frm_end); const uint8_t* _frm_nxt = _frm; -# if defined(_LIBCPP_SHORT_WCHAR) +# ifdef _WIN32 uint16_t* _to = reinterpret_cast(to); uint16_t* _to_end = reinterpret_cast(to_end); uint16_t* _to_nxt = _to; @@ -3880,12 +3906,18 @@ __codecvt_utf8_utf16::result __codecvt_utf8_utf16::do_in( const uint8_t* _frm = reinterpret_cast(frm); const uint8_t* _frm_end = reinterpret_cast(frm_end); const uint8_t* _frm_nxt = _frm; - uint32_t* _to = reinterpret_cast(to); - uint32_t* _to_end = reinterpret_cast(to_end); - uint32_t* _to_nxt = _to; - result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_); - frm_nxt = frm + (_frm_nxt - _frm); - to_nxt = to + (_to_nxt - _to); +#if defined(_LIBCPP_SHORT_WCHAR) + uint16_t* _to = reinterpret_cast(to); + uint16_t* _to_end = reinterpret_cast(to_end); + uint16_t* _to_nxt = _to; +#else + uint32_t* _to = reinterpret_cast(to); + uint32_t* _to_end = reinterpret_cast(to_end); + uint32_t* _to_nxt = _to; +#endif + result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, __maxcode_, __mode_); + frm_nxt = frm + (_frm_nxt - _frm); + to_nxt = to + (_to_nxt - _to); return r; } @@ -5123,7 +5155,7 @@ static void __init_pat( // 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); + __curr_symbol_.insert((size_t)0, 1, space_char); } return; default: @@ -5145,7 +5177,7 @@ static void __init_pat( // 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); + __curr_symbol_.insert((size_t)0, 1, space_char); } return; case 2: // Space between sign and currency or value. @@ -5174,7 +5206,7 @@ static void __init_pat( // 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); + __curr_symbol_.insert((size_t)0, 1, space_char); } pat.field[1] = none; pat.field[2] = symbol; @@ -5216,7 +5248,7 @@ static void __init_pat( // 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); + __curr_symbol_.insert((size_t)0, 1, space_char); } return; default: @@ -5238,7 +5270,7 @@ static void __init_pat( // 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); + __curr_symbol_.insert((size_t)0, 1, space_char); } return; case 2: // Space between sign and currency or value. @@ -5277,7 +5309,7 @@ static void __init_pat( // 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); + __curr_symbol_.insert((size_t)0, 1, space_char); } return; default: