diff --git a/src/boost/locale/icu/conversion.cpp b/src/boost/locale/icu/conversion.cpp index c9b75b70..c619dd94 100644 --- a/src/boost/locale/icu/conversion.cpp +++ b/src/boost/locale/icu/conversion.cpp @@ -81,10 +81,20 @@ namespace boost { namespace locale { namespace impl_icu { using type = TSize; }; + template + struct is_casemap_func_const; + + template + struct is_casemap_func_const : is_casemap_func_const {}; + + template + struct is_casemap_func_const : std::is_const {}; + template class raii_casemap { public: static_assert(sizeof(U8Char) == sizeof(char), "Not an UTF-8 char type"); + using string_type = std::basic_string; raii_casemap(const raii_casemap&) = delete; void operator=(const raii_casemap&) = delete; @@ -97,8 +107,24 @@ namespace boost { namespace locale { namespace impl_icu { if(!map_) throw std::runtime_error("Failed to create UCaseMap"); // LCOV_EXCL_LINE } + ~raii_casemap() { ucasemap_close(map_); } + + template + typename std::enable_if::value, string_type>::type + convert(Conv func, const U8Char* begin, const U8Char* end) + { + return do_convert(func, begin, end); + } template - std::basic_string convert(Conv func, const U8Char* begin, const U8Char* end) const + typename std::enable_if::value, string_type>::type + convert(Conv func, const U8Char* begin, const U8Char* end) const + { + return do_convert(func, begin, end); + } + + private: + template + string_type do_convert(Conv func, const U8Char* begin, const U8Char* end) const { using size_type = typename get_casemap_size_type::type; if((end - begin) >= std::numeric_limits::max() / 11) @@ -125,9 +151,8 @@ namespace boost { namespace locale { namespace impl_icu { &err); } check_and_throw_icu_error(err); - return std::basic_string(buf.data(), size); + return string_type(buf.data(), size); } - ~raii_casemap() { ucasemap_close(map_); } private: UCaseMap* map_; @@ -147,7 +172,11 @@ namespace boost { namespace locale { namespace impl_icu { switch(how) { case converter_base::upper_case: return map_.convert(ucasemap_utf8ToUpper, begin, end); case converter_base::lower_case: return map_.convert(ucasemap_utf8ToLower, begin, end); - case converter_base::title_case: return map_.convert(ucasemap_utf8ToTitle, begin, end); + case converter_base::title_case: { + // Non-const method, so need to create a separate map + raii_casemap map(locale_id_); + return map.convert(ucasemap_utf8ToTitle, begin, end); + } case converter_base::case_folding: return map_.convert(ucasemap_utf8FoldCase, begin, end); case converter_base::normalization: { icu_std_converter cvt("UTF-8");