57-locale.patch 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. diff --git a/src/locale.cpp b/src/locale.cpp
  2. index 317b4de..071edb9 100644
  3. --- a/src/locale.cpp
  4. +++ b/src/locale.cpp
  5. @@ -37,8 +37,8 @@
  6. # include <langinfo.h>
  7. #endif
  8. -#include "include/atomic_support.h"
  9. #include "include/sso_allocator.h"
  10. +#include <mutex>
  11. // On Linux, wint_t and wchar_t have different signed-ness, and this causes
  12. // lots of noise in the build log, but no bugs that I know of.
  13. @@ -691,8 +691,17 @@ locale::facet::__on_zero_shared() noexcept
  14. constinit int32_t locale::id::__next_id = 0;
  15. long locale::id::__get() {
  16. - call_once(__flag_, [&] { __id_ = __libcpp_atomic_add(&__next_id, 1); });
  17. - return __id_ - 1;
  18. + int32_t result = __id_.load(std::memory_order_acquire);
  19. + if (result == 0) {
  20. + static std::mutex m;
  21. + std::lock_guard<std::mutex> guard(m);
  22. + result = __id_.load(std::memory_order_acquire);
  23. + if (result == 0) {
  24. + result = ++__next_id;
  25. + __id_.store(result, std::memory_order_release);
  26. + }
  27. + }
  28. + return result - 1;
  29. }
  30. // template <> class collate_byname<char>
  31. @@ -1066,6 +1075,11 @@ extern "C" const int ** __ctype_tolower_loc();
  32. extern "C" const int ** __ctype_toupper_loc();
  33. #endif
  34. +#if defined(__ANDROID__)
  35. +// See src/support/android/android_locale.cpp
  36. +extern "C" const unsigned short* const _ctype_android;
  37. +#endif
  38. +
  39. #ifdef _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE
  40. const ctype<char>::mask*
  41. ctype<char>::classic_table() noexcept
  42. @@ -1163,6 +1177,8 @@ ctype<char>::classic_table() noexcept
  43. #elif defined(_NEWLIB_VERSION)
  44. // Newlib has a 257-entry table in ctype_.c, where (char)0 starts at [1].
  45. return _ctype_ + 1;
  46. +#elif defined(__ANDROID__)
  47. + return _ctype_android;
  48. #elif defined(_AIX)
  49. return (const unsigned int *)__lc_ctype_ptr->obj->mask;
  50. #elif defined(__MVS__)
  51. @@ -4188,14 +4204,25 @@ __codecvt_utf16<char32_t, true>::do_out(state_type&,
  52. const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
  53. extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
  54. {
  55. +#if defined(_LIBCPP_SHORT_WCHAR)
  56. + const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
  57. + const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
  58. + const uint16_t* _frm_nxt = _frm;
  59. +#else
  60. const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
  61. const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
  62. const uint32_t* _frm_nxt = _frm;
  63. +#endif
  64. uint8_t* _to = reinterpret_cast<uint8_t*>(to);
  65. uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
  66. uint8_t* _to_nxt = _to;
  67. +#if defined(_LIBCPP_SHORT_WCHAR)
  68. + result r = ucs2_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
  69. + __maxcode_, __mode_);
  70. +#else
  71. result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
  72. __maxcode_, __mode_);
  73. +#endif
  74. frm_nxt = frm + (_frm_nxt - _frm);
  75. to_nxt = to + (_to_nxt - _to);
  76. return r;
  77. @@ -4266,7 +4293,7 @@ __codecvt_utf8_utf16<wchar_t>::do_out(state_type&,
  78. const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
  79. extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
  80. {
  81. -#if defined(_LIBCPP_SHORT_WCHAR)
  82. +#ifdef _WIN32
  83. const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
  84. const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
  85. const uint16_t* _frm_nxt = _frm;
  86. @@ -4293,7 +4320,7 @@ __codecvt_utf8_utf16<wchar_t>::do_in(state_type&,
  87. const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
  88. const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
  89. const uint8_t* _frm_nxt = _frm;
  90. -#if defined(_LIBCPP_SHORT_WCHAR)
  91. +#ifdef _WIN32
  92. uint16_t* _to = reinterpret_cast<uint16_t*>(to);
  93. uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
  94. uint16_t* _to_nxt = _to;
  95. @@ -4452,9 +4479,15 @@ __codecvt_utf8_utf16<char32_t>::do_in(state_type&,
  96. const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
  97. const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
  98. const uint8_t* _frm_nxt = _frm;
  99. +#if defined(_LIBCPP_SHORT_WCHAR)
  100. + uint16_t* _to = reinterpret_cast<uint16_t*>(to);
  101. + uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
  102. + uint16_t* _to_nxt = _to;
  103. +#else
  104. uint32_t* _to = reinterpret_cast<uint32_t*>(to);
  105. uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
  106. uint32_t* _to_nxt = _to;
  107. +#endif
  108. result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
  109. __maxcode_, __mode_);
  110. frm_nxt = frm + (_frm_nxt - _frm);
  111. @@ -5922,7 +5955,7 @@ __init_pat(money_base::pattern& pat, basic_string<charT>& __curr_symbol_,
  112. // We insert the space into the symbol instead of
  113. // setting pat.field[2]=space so that when
  114. // showbase is not set, the space goes away too.
  115. - __curr_symbol_.insert(0, 1, space_char);
  116. + __curr_symbol_.insert((size_t)0, 1, space_char);
  117. }
  118. return;
  119. default:
  120. @@ -5945,7 +5978,7 @@ __init_pat(money_base::pattern& pat, basic_string<charT>& __curr_symbol_,
  121. // We insert the space into the symbol instead of
  122. // setting pat.field[2]=space so that when
  123. // showbase is not set, the space goes away too.
  124. - __curr_symbol_.insert(0, 1, space_char);
  125. + __curr_symbol_.insert((size_t)0, 1, space_char);
  126. }
  127. return;
  128. case 2: // Space between sign and currency or value.
  129. @@ -5975,7 +6008,7 @@ __init_pat(money_base::pattern& pat, basic_string<charT>& __curr_symbol_,
  130. // We insert the space into the symbol instead of
  131. // setting pat.field[1]=space so that when
  132. // showbase is not set, the space goes away too.
  133. - __curr_symbol_.insert(0, 1, space_char);
  134. + __curr_symbol_.insert((size_t)0, 1, space_char);
  135. }
  136. pat.field[1] = none;
  137. pat.field[2] = symbol;
  138. @@ -6018,7 +6051,7 @@ __init_pat(money_base::pattern& pat, basic_string<charT>& __curr_symbol_,
  139. // We insert the space into the symbol instead of
  140. // setting pat.field[2]=space so that when
  141. // showbase is not set, the space goes away too.
  142. - __curr_symbol_.insert(0, 1, space_char);
  143. + __curr_symbol_.insert((size_t)0, 1, space_char);
  144. }
  145. return;
  146. default:
  147. @@ -6041,7 +6074,7 @@ __init_pat(money_base::pattern& pat, basic_string<charT>& __curr_symbol_,
  148. // We insert the space into the symbol instead of
  149. // setting pat.field[1]=space so that when
  150. // showbase is not set, the space goes away too.
  151. - __curr_symbol_.insert(0, 1, space_char);
  152. + __curr_symbol_.insert((size_t)0, 1, space_char);
  153. }
  154. return;
  155. case 2: // Space between sign and currency or value.
  156. @@ -6082,7 +6115,7 @@ __init_pat(money_base::pattern& pat, basic_string<charT>& __curr_symbol_,
  157. // We insert the space into the symbol instead of
  158. // setting pat.field[2]=space so that when
  159. // showbase is not set, the space goes away too.
  160. - __curr_symbol_.insert(0, 1, space_char);
  161. + __curr_symbol_.insert((size_t)0, 1, space_char);
  162. }
  163. return;
  164. default: