Index: libcxx/include/support/win32/locale_win32.h =================================================================== --- libcxx/include/support/win32/locale_win32.h +++ libcxx/include/support/win32/locale_win32.h @@ -28,14 +28,72 @@ | LC_NUMERIC_MASK \ | LC_TIME_MASK ) +class __lconv_storage { +public: + __lconv_storage(const lconv *__lc_input) { + __lc = *__lc_input; + + __decimal_point = __lc_input->decimal_point; + __thousands_sep = __lc_input->thousands_sep; + __grouping = __lc_input->grouping; + __int_curr_symbol = __lc_input->int_curr_symbol; + __currency_symbol = __lc_input->currency_symbol; + __mon_decimal_point = __lc_input->mon_decimal_point; + __mon_thousands_sep = __lc_input->mon_thousands_sep; + __mon_grouping = __lc_input->mon_grouping; + __positive_sign = __lc_input->positive_sign; + __negative_sign = __lc_input->negative_sign; + + __lc.decimal_point = const_cast(__decimal_point.c_str()); + __lc.thousands_sep = const_cast(__thousands_sep.c_str()); + __lc.grouping = const_cast(__grouping.c_str()); + __lc.int_curr_symbol = const_cast(__int_curr_symbol.c_str()); + __lc.currency_symbol = const_cast(__currency_symbol.c_str()); + __lc.mon_decimal_point = const_cast(__mon_decimal_point.c_str()); + __lc.mon_thousands_sep = const_cast(__mon_thousands_sep.c_str()); + __lc.mon_grouping = const_cast(__mon_grouping.c_str()); + __lc.positive_sign = const_cast(__positive_sign.c_str()); + __lc.negative_sign = const_cast(__negative_sign.c_str()); + } + + lconv *__get() { + return &__lc; + } +private: + lconv __lc; + std::string __decimal_point; + std::string __thousands_sep; + std::string __grouping; + std::string __int_curr_symbol; + std::string __currency_symbol; + std::string __mon_decimal_point; + std::string __mon_thousands_sep; + std::string __mon_grouping; + std::string __positive_sign; + std::string __negative_sign; +}; + class locale_t { public: locale_t() - : __locale(nullptr), __locale_str(nullptr) {} + : __locale(nullptr), __locale_str(nullptr), __lc(nullptr) {} locale_t(std::nullptr_t) - : __locale(nullptr), __locale_str(nullptr) {} + : __locale(nullptr), __locale_str(nullptr), __lc(nullptr) {} locale_t(_locale_t __xlocale, const char* __xlocale_str) - : __locale(__xlocale), __locale_str(__xlocale_str) {} + : __locale(__xlocale), __locale_str(__xlocale_str), __lc(nullptr) {} + locale_t(const locale_t &__l) + : __locale(__l.__locale), __locale_str(__l.__locale_str), __lc(nullptr) {} + + ~locale_t() { + delete __lc; + } + + locale_t &operator =(const locale_t &__l) { + __locale = __l.__locale; + __locale_str = __l.__locale_str; + // __lc not copied + return *this; + } friend bool operator==(const locale_t& __left, const locale_t& __right) { return __left.__locale == __right.__locale; @@ -94,9 +152,16 @@ operator _locale_t() const { return __locale; } + + lconv *__store_lconv(const lconv *__input_lc) { + delete __lc; + __lc = new __lconv_storage(__input_lc); + return __lc->__get(); + } private: _locale_t __locale; const char* __locale_str; + __lconv_storage *__lc = nullptr; }; // Locale management functions @@ -109,7 +174,7 @@ // We can still implement raii even without uselocale though. -lconv *localeconv_l( locale_t loc ); +lconv *localeconv_l( locale_t &loc ); size_t mbrlen_l( const char *__restrict s, size_t n, mbstate_t *__restrict ps, locale_t loc); size_t mbsrtowcs_l( wchar_t *__restrict dst, const char **__restrict src, Index: libcxx/src/support/win32/locale_win32.cpp =================================================================== --- libcxx/src/support/win32/locale_win32.cpp +++ libcxx/src/support/win32/locale_win32.cpp @@ -32,11 +32,13 @@ #endif } - -lconv *localeconv_l( locale_t loc ) +lconv *localeconv_l( locale_t &loc ) { __libcpp_locale_guard __current(loc); - return localeconv(); + lconv *lc = localeconv(); + if (!lc) + return lc; + return loc.__store_lconv(lc); } size_t mbrlen_l( const char *__restrict s, size_t n, mbstate_t *__restrict ps, locale_t loc )