diff options
author | Alexander Smirnov <alex@ydb.tech> | 2024-10-28 20:34:11 +0000 |
---|---|---|
committer | Alexander Smirnov <alex@ydb.tech> | 2024-10-28 20:34:11 +0000 |
commit | ef9875b11a33dbd25e92bc6b4cf692c18c9ba0ce (patch) | |
tree | 1f2fd4e4d9e585da35937b42fbda5f854af04728 /contrib/restricted | |
parent | 37ae9cc90160b53eb0e22021c47b3996a01cd656 (diff) | |
parent | e3c8507a3d1cb090278f211232ddfde3bedc54d4 (diff) | |
download | ydb-ef9875b11a33dbd25e92bc6b4cf692c18c9ba0ce.tar.gz |
Merge branch 'rightlib' into mergelibs-241028-2033
Diffstat (limited to 'contrib/restricted')
68 files changed, 1043 insertions, 600 deletions
diff --git a/contrib/restricted/abseil-cpp-tstring/y_absl/base/config.h b/contrib/restricted/abseil-cpp-tstring/y_absl/base/config.h index 527b6181a2..287b06dd4c 100644 --- a/contrib/restricted/abseil-cpp-tstring/y_absl/base/config.h +++ b/contrib/restricted/abseil-cpp-tstring/y_absl/base/config.h @@ -917,12 +917,6 @@ static_assert(Y_ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || #define Y_ABSL_INTERNAL_HAVE_SSSE3 1 #endif -#ifdef __NVCC__ -#undef Y_ABSL_INTERNAL_HAVE_SSE -#undef Y_ABSL_INTERNAL_HAVE_SSE2 -#undef Y_ABSL_INTERNAL_HAVE_SSSE3 -#endif - // Y_ABSL_INTERNAL_HAVE_ARM_NEON is used for compile-time detection of NEON (ARM // SIMD). // @@ -936,6 +930,13 @@ static_assert(Y_ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || #define Y_ABSL_INTERNAL_HAVE_ARM_NEON 1 #endif +#ifdef __NVCC__ +#undef Y_ABSL_INTERNAL_HAVE_SSE +#undef Y_ABSL_INTERNAL_HAVE_SSE2 +#undef Y_ABSL_INTERNAL_HAVE_SSSE3 +#undef Y_ABSL_INTERNAL_HAVE_ARM_NEON +#endif + // Y_ABSL_HAVE_CONSTANT_EVALUATED is used for compile-time detection of // constant evaluation support through `y_absl::is_constant_evaluated`. #ifdef Y_ABSL_HAVE_CONSTANT_EVALUATED diff --git a/contrib/restricted/boost/locale/.yandex_meta/devtools.copyrights.report b/contrib/restricted/boost/locale/.yandex_meta/devtools.copyrights.report index afe16926c1..b8639e0153 100644 --- a/contrib/restricted/boost/locale/.yandex_meta/devtools.copyrights.report +++ b/contrib/restricted/boost/locale/.yandex_meta/devtools.copyrights.report @@ -56,12 +56,12 @@ BELONGS ya.make include/boost/locale/date_time_facet.hpp [2:2] include/boost/locale/encoding.hpp [2:2] include/boost/locale/encoding_errors.hpp [2:2] - include/boost/locale/encoding_utf.hpp [2:2] + include/boost/locale/encoding_utf.hpp [2:3] include/boost/locale/format.hpp [2:3] include/boost/locale/formatting.hpp [2:3] include/boost/locale/generator.hpp [2:2] include/boost/locale/gnu_gettext.hpp [2:2] - include/boost/locale/info.hpp [2:2] + include/boost/locale/info.hpp [2:3] include/boost/locale/localization_backend.hpp [2:2] include/boost/locale/message.hpp [2:3] include/boost/locale/time_zone.hpp [2:2] @@ -78,7 +78,7 @@ BELONGS ya.make src/boost/locale/icu/codecvt.cpp [2:3] src/boost/locale/icu/codecvt.hpp [2:2] src/boost/locale/icu/collator.cpp [2:2] - src/boost/locale/icu/conversion.cpp [2:2] + src/boost/locale/icu/conversion.cpp [2:3] src/boost/locale/icu/date_time.cpp [2:3] src/boost/locale/icu/formatter.cpp [2:3] src/boost/locale/icu/formatter.hpp [2:2] @@ -98,13 +98,13 @@ BELONGS ya.make src/boost/locale/posix/numeric.cpp [2:2] src/boost/locale/posix/posix_backend.cpp [2:3] src/boost/locale/posix/posix_backend.hpp [2:2] - src/boost/locale/shared/date_time.cpp [2:2] + src/boost/locale/shared/date_time.cpp [2:3] src/boost/locale/shared/format.cpp [2:2] src/boost/locale/shared/formatting.cpp [2:2] src/boost/locale/shared/generator.cpp [2:2] src/boost/locale/shared/iconv_codecvt.cpp [2:3] src/boost/locale/shared/iconv_codecvt.hpp [2:2] - src/boost/locale/shared/ids.cpp [2:2] + src/boost/locale/shared/ids.cpp [2:3] src/boost/locale/shared/ios_prop.hpp [2:3] src/boost/locale/shared/localization_backend.cpp [2:2] src/boost/locale/shared/mo_hash.hpp [2:2] @@ -124,7 +124,7 @@ BELONGS ya.make src/boost/locale/util/gregorian.cpp [2:2] src/boost/locale/util/gregorian.hpp [2:2] src/boost/locale/util/iconv.hpp [2:2] - src/boost/locale/util/info.cpp [2:2] + src/boost/locale/util/info.cpp [2:3] src/boost/locale/util/locale_data.cpp [2:3] src/boost/locale/util/numeric.hpp [2:2] src/boost/locale/util/timezone.hpp [2:2] @@ -150,6 +150,19 @@ BELONGS ya.make Files with this license: src/boost/locale/icu/uconv.hpp [2:3] +KEEP COPYRIGHT_SERVICE_LABEL 187d73eada66cef6d5d08ed727437603 +BELONGS ya.make + License text: + // Copyright (c) 2024 Alexander Grund + Scancode info: + Original SPDX id: COPYRIGHT_SERVICE_LABEL + Score : 100.00 + Match type : COPYRIGHT + Files with this license: + include/boost/locale/detail/allocator_traits.hpp [2:2] + src/boost/locale/shared/ids.cpp [2:3] + src/boost/locale/shared/std_collate_adapter.hpp [2:2] + KEEP COPYRIGHT_SERVICE_LABEL 5f6f0ebf2d6180caac56d446585150fe BELONGS ya.make License text: @@ -163,6 +176,18 @@ BELONGS ya.make include/boost/locale/generic_codecvt.hpp [2:3] include/boost/locale/utf8_codecvt.hpp [2:2] +KEEP COPYRIGHT_SERVICE_LABEL 70211eab6462dd6308fa5b813ba0f2c0 +BELONGS ya.make + License text: + // Copyright (c) 2009-2011 Artyom Beilis (Tonkikh) + // Copyright (c) 2022-2024 Alexander Grund + Scancode info: + Original SPDX id: COPYRIGHT_SERVICE_LABEL + Score : 100.00 + Match type : COPYRIGHT + Files with this license: + include/boost/locale/encoding_utf.hpp [2:3] + KEEP COPYRIGHT_SERVICE_LABEL 8d04644911f5fff0cef0ea7eeadf74ee BELONGS ya.make License text: @@ -182,14 +207,15 @@ BELONGS ya.make KEEP COPYRIGHT_SERVICE_LABEL a999dc6b43b371fa616fd4c0c30cf6f3 BELONGS ya.make License text: - // Copyright (c) 2009-2011 Artyom Beilis (Tonkikh) // Copyright (c) 2023 Alexander Grund Scancode info: Original SPDX id: COPYRIGHT_SERVICE_LABEL Score : 100.00 Match type : COPYRIGHT Files with this license: + include/boost/locale/detail/any_string.hpp [2:2] include/boost/locale/util/locale_data.hpp [2:3] + src/boost/locale/shared/message.hpp [2:2] src/boost/locale/util/make_std_unique.hpp [2:2] KEEP COPYRIGHT_SERVICE_LABEL c75aae6c76ff96e098e51412b5d4691b @@ -206,18 +232,22 @@ BELONGS ya.make include/boost/locale/detail/facet_id.hpp [2:2] include/boost/locale/detail/is_supported_char.hpp [2:2] include/boost/locale/formatting.hpp [2:3] + include/boost/locale/info.hpp [2:3] include/boost/locale/util.hpp [2:3] include/boost/locale/util/string.hpp [2:2] src/boost/locale/encoding/codepage.cpp [2:3] src/boost/locale/icu/codecvt.cpp [2:3] + src/boost/locale/icu/conversion.cpp [2:3] src/boost/locale/icu/icu_backend.cpp [2:3] src/boost/locale/posix/codecvt.cpp [2:3] src/boost/locale/posix/posix_backend.cpp [2:3] + src/boost/locale/shared/date_time.cpp [2:3] src/boost/locale/shared/iconv_codecvt.cpp [2:3] src/boost/locale/std/std_backend.cpp [2:3] src/boost/locale/util/codecvt_converter.cpp [2:3] src/boost/locale/util/encoding.cpp [2:3] src/boost/locale/util/encoding.hpp [2:3] + src/boost/locale/util/info.cpp [2:3] src/boost/locale/util/locale_data.cpp [2:3] src/boost/locale/win32/win_backend.cpp [2:3] diff --git a/contrib/restricted/boost/locale/.yandex_meta/devtools.licenses.report b/contrib/restricted/boost/locale/.yandex_meta/devtools.licenses.report index 65abee9ce0..7173da1354 100644 --- a/contrib/restricted/boost/locale/.yandex_meta/devtools.licenses.report +++ b/contrib/restricted/boost/locale/.yandex_meta/devtools.licenses.report @@ -86,14 +86,15 @@ BELONGS ya.make include/boost/locale/config.hpp [5:5] include/boost/locale/conversion.hpp [5:5] include/boost/locale/date_time_facet.hpp [5:5] + include/boost/locale/detail/allocator_traits.hpp [5:5] include/boost/locale/detail/encoding.hpp [5:5] include/boost/locale/detail/is_supported_char.hpp [5:5] include/boost/locale/encoding.hpp [5:5] include/boost/locale/encoding_errors.hpp [5:5] - include/boost/locale/encoding_utf.hpp [5:5] + include/boost/locale/encoding_utf.hpp [6:6] include/boost/locale/formatting.hpp [6:6] include/boost/locale/generic_codecvt.hpp [6:6] - include/boost/locale/info.hpp [5:5] + include/boost/locale/info.hpp [6:6] include/boost/locale/message.hpp [6:6] include/boost/locale/time_zone.hpp [5:5] include/boost/locale/utf8_codecvt.hpp [5:5] @@ -113,11 +114,13 @@ BELONGS ya.make src/boost/locale/posix/converter.cpp [5:5] src/boost/locale/posix/numeric.cpp [5:5] src/boost/locale/posix/posix_backend.hpp [5:5] - src/boost/locale/shared/date_time.cpp [5:5] + src/boost/locale/shared/date_time.cpp [6:6] src/boost/locale/shared/formatting.cpp [5:5] src/boost/locale/shared/iconv_codecvt.hpp [5:5] - src/boost/locale/shared/ids.cpp [5:5] + src/boost/locale/shared/ids.cpp [6:6] src/boost/locale/shared/ios_prop.hpp [6:6] + src/boost/locale/shared/message.hpp [5:5] + src/boost/locale/shared/std_collate_adapter.hpp [5:5] src/boost/locale/std/codecvt.cpp [5:5] src/boost/locale/std/collate.cpp [5:5] src/boost/locale/std/converter.cpp [5:5] @@ -130,7 +133,7 @@ BELONGS ya.make src/boost/locale/util/foreach_char.hpp [5:5] src/boost/locale/util/gregorian.hpp [5:5] src/boost/locale/util/iconv.hpp [5:5] - src/boost/locale/util/info.cpp [5:5] + src/boost/locale/util/info.cpp [6:6] src/boost/locale/util/locale_data.cpp [6:6] src/boost/locale/util/make_std_unique.hpp [5:5] src/boost/locale/win32/all_generator.hpp [5:5] @@ -158,14 +161,15 @@ BELONGS ya.make include/boost/locale/config.hpp [4:4] include/boost/locale/conversion.hpp [4:4] include/boost/locale/date_time_facet.hpp [4:4] + include/boost/locale/detail/allocator_traits.hpp [4:4] include/boost/locale/detail/encoding.hpp [4:4] include/boost/locale/detail/is_supported_char.hpp [4:4] include/boost/locale/encoding.hpp [4:4] include/boost/locale/encoding_errors.hpp [4:4] - include/boost/locale/encoding_utf.hpp [4:4] + include/boost/locale/encoding_utf.hpp [5:5] include/boost/locale/formatting.hpp [5:5] include/boost/locale/generic_codecvt.hpp [5:5] - include/boost/locale/info.hpp [4:4] + include/boost/locale/info.hpp [5:5] include/boost/locale/message.hpp [5:5] include/boost/locale/time_zone.hpp [4:4] include/boost/locale/utf8_codecvt.hpp [4:4] @@ -185,11 +189,13 @@ BELONGS ya.make src/boost/locale/posix/converter.cpp [4:4] src/boost/locale/posix/numeric.cpp [4:4] src/boost/locale/posix/posix_backend.hpp [4:4] - src/boost/locale/shared/date_time.cpp [4:4] + src/boost/locale/shared/date_time.cpp [5:5] src/boost/locale/shared/formatting.cpp [4:4] src/boost/locale/shared/iconv_codecvt.hpp [4:4] - src/boost/locale/shared/ids.cpp [4:4] + src/boost/locale/shared/ids.cpp [5:5] src/boost/locale/shared/ios_prop.hpp [5:5] + src/boost/locale/shared/message.hpp [4:4] + src/boost/locale/shared/std_collate_adapter.hpp [4:4] src/boost/locale/std/codecvt.cpp [4:4] src/boost/locale/std/collate.cpp [4:4] src/boost/locale/std/converter.cpp [4:4] @@ -202,7 +208,7 @@ BELONGS ya.make src/boost/locale/util/foreach_char.hpp [4:4] src/boost/locale/util/gregorian.hpp [4:4] src/boost/locale/util/iconv.hpp [4:4] - src/boost/locale/util/info.cpp [4:4] + src/boost/locale/util/info.cpp [5:5] src/boost/locale/util/locale_data.cpp [5:5] src/boost/locale/util/make_std_unique.hpp [4:4] src/boost/locale/win32/all_generator.hpp [4:4] @@ -227,6 +233,7 @@ BELONGS ya.make include/boost/locale/boundary/boundary_point.hpp [4:5] include/boost/locale/boundary/types.hpp [4:5] include/boost/locale/date_time.hpp [4:5] + include/boost/locale/detail/any_string.hpp [4:5] include/boost/locale/detail/facet_id.hpp [4:5] include/boost/locale/format.hpp [5:6] include/boost/locale/generator.hpp [4:5] @@ -240,7 +247,7 @@ BELONGS ya.make src/boost/locale/encoding/wconv_converter.hpp [4:5] src/boost/locale/icu/codecvt.cpp [5:6] src/boost/locale/icu/collator.cpp [4:5] - src/boost/locale/icu/conversion.cpp [4:5] + src/boost/locale/icu/conversion.cpp [5:6] src/boost/locale/icu/date_time.cpp [5:6] src/boost/locale/icu/formatter.cpp [5:6] src/boost/locale/icu/formatters_cache.cpp [5:6] diff --git a/contrib/restricted/boost/locale/.yandex_meta/licenses.list.txt b/contrib/restricted/boost/locale/.yandex_meta/licenses.list.txt index f1ce436b42..2769441dcd 100644 --- a/contrib/restricted/boost/locale/.yandex_meta/licenses.list.txt +++ b/contrib/restricted/boost/locale/.yandex_meta/licenses.list.txt @@ -77,7 +77,7 @@ DEALINGS IN THE SOFTWARE. ====================COPYRIGHT==================== // Copyright (c) 2009-2011 Artyom Beilis (Tonkikh) -// Copyright (c) 2023 Alexander Grund +// Copyright (c) 2022-2024 Alexander Grund ====================COPYRIGHT==================== @@ -95,4 +95,12 @@ DEALINGS IN THE SOFTWARE. ====================COPYRIGHT==================== +// Copyright (c) 2023 Alexander Grund + + +====================COPYRIGHT==================== // Copyright (c) 2023-2023 Alexander Grund + + +====================COPYRIGHT==================== +// Copyright (c) 2024 Alexander Grund diff --git a/contrib/restricted/boost/locale/README.md b/contrib/restricted/boost/locale/README.md index 2cc876784e..ea18e02d99 100644 --- a/contrib/restricted/boost/locale/README.md +++ b/contrib/restricted/boost/locale/README.md @@ -42,10 +42,10 @@ Distributed under the [Boost Software License, Version 1.0](https://www.boost.or ### Build Status -Branch | GH Actions | Appveyor | codecov.io | Deps | Docs | Tests | -:-------------: | ---------- | -------- | ---------- | ---- | ---- | ----- | -[`master`](https://github.com/boostorg/locale/tree/master) | [![CI](https://github.com/boostorg/locale/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/boostorg/locale/actions/workflows/ci.yml) | [![Build status](https://ci.appveyor.com/api/projects/status/github/boostorg/locale?branch=master&svg=true)](https://ci.appveyor.com/project/Flamefire/locale/branch/master) | [![codecov](https://codecov.io/gh/boostorg/locale/branch/master/graph/badge.svg)](https://codecov.io/gh/boostorg/locale/branch/master) | [![Deps](https://img.shields.io/badge/deps-master-brightgreen.svg)](https://pdimov.github.io/boostdep-report/master/locale.html) | [![Documentation](https://img.shields.io/badge/docs-master-brightgreen.svg)](https://www.boost.org/doc/libs/master/libs/locale/doc/html/index.html) | [![Enter the Matrix](https://img.shields.io/badge/matrix-master-brightgreen.svg)](http://www.boost.org/development/tests/master/developer/locale.html) -[`develop`](https://github.com/boostorg/locale/tree/develop) | [![CI](https://github.com/boostorg/locale/actions/workflows/ci.yml/badge.svg?branch=develop)](https://github.com/boostorg/locale/actions/workflows/ci.yml) | [![Build status](https://ci.appveyor.com/api/projects/status/github/boostorg/locale?branch=develop&svg=true)](https://ci.appveyor.com/project/Flamefire/locale/branch/develop) | [![codecov](https://codecov.io/gh/boostorg/locale/branch/develop/graph/badge.svg)](https://codecov.io/gh/boostorg/locale/branch/develop) | [![Deps](https://img.shields.io/badge/deps-develop-brightgreen.svg)](https://pdimov.github.io/boostdep-report/develop/locale.html) | [![Documentation](https://img.shields.io/badge/docs-develop-brightgreen.svg)](https://www.boost.org/doc/libs/develop/libs/locale/doc/html/index.html) | [![Enter the Matrix](https://img.shields.io/badge/matrix-develop-brightgreen.svg)](http://www.boost.org/development/tests/develop/developer/locale.html) +Branch | GH Actions | Appveyor | Drone | codecov.io | Deps | Docs | Tests | +:-------------: | ---------- | -------- | ----- | ---------- | ---- | ---- | ----- | +[`master`](https://github.com/boostorg/locale/tree/master) | [![CI](https://github.com/boostorg/locale/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/boostorg/locale/actions/workflows/ci.yml) | [![Build status](https://ci.appveyor.com/api/projects/status/github/boostorg/locale?branch=master&svg=true)](https://ci.appveyor.com/project/Flamefire/locale/branch/master) | [![Build Status](https://drone.cpp.al/api/badges/boostorg/locale/status.svg?ref=refs/heads/master)](https://drone.cpp.al/boostorg/locale) | [![codecov](https://codecov.io/gh/boostorg/locale/branch/master/graph/badge.svg)](https://codecov.io/gh/boostorg/locale/branch/master) | [![Deps](https://img.shields.io/badge/deps-master-brightgreen.svg)](https://pdimov.github.io/boostdep-report/master/locale.html) | [![Documentation](https://img.shields.io/badge/docs-master-brightgreen.svg)](https://www.boost.org/doc/libs/master/libs/locale/doc/html/index.html) | [![Enter the Matrix](https://img.shields.io/badge/matrix-master-brightgreen.svg)](http://www.boost.org/development/tests/master/developer/locale.html) +[`develop`](https://github.com/boostorg/locale/tree/develop) | [![CI](https://github.com/boostorg/locale/actions/workflows/ci.yml/badge.svg?branch=develop)](https://github.com/boostorg/locale/actions/workflows/ci.yml) | [![Build status](https://ci.appveyor.com/api/projects/status/github/boostorg/locale?branch=develop&svg=true)](https://ci.appveyor.com/project/Flamefire/locale/branch/develop) | [![Build Status](https://drone.cpp.al/api/badges/boostorg/locale/status.svg?ref=refs/heads/develop)](https://drone.cpp.al/boostorg/locale) | [![codecov](https://codecov.io/gh/boostorg/locale/branch/develop/graph/badge.svg)](https://codecov.io/gh/boostorg/locale/branch/develop) | [![Deps](https://img.shields.io/badge/deps-develop-brightgreen.svg)](https://pdimov.github.io/boostdep-report/develop/locale.html) | [![Documentation](https://img.shields.io/badge/docs-develop-brightgreen.svg)](https://www.boost.org/doc/libs/develop/libs/locale/doc/html/index.html) | [![Enter the Matrix](https://img.shields.io/badge/matrix-develop-brightgreen.svg)](http://www.boost.org/development/tests/develop/developer/locale.html) ### Directories diff --git a/contrib/restricted/boost/locale/include/boost/locale/boundary/boundary_point.hpp b/contrib/restricted/boost/locale/include/boost/locale/boundary/boundary_point.hpp index 494352a081..370dd5f816 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/boundary/boundary_point.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/boundary/boundary_point.hpp @@ -100,6 +100,9 @@ namespace boost { namespace locale { namespace boundary { typedef boundary_point<std::string::const_iterator> sboundary_point; ///< convenience typedef typedef boundary_point<std::wstring::const_iterator> wsboundary_point; ///< convenience typedef +#ifndef BOOST_LOCALE_NO_CXX20_STRING8 + typedef boundary_point<std::u8string::const_iterator> u8sboundary_point; ///< convenience typedef +#endif #ifdef BOOST_LOCALE_ENABLE_CHAR16_T typedef boundary_point<std::u16string::const_iterator> u16sboundary_point; ///< convenience typedef #endif @@ -109,6 +112,9 @@ namespace boost { namespace locale { namespace boundary { typedef boundary_point<const char*> cboundary_point; ///< convenience typedef typedef boundary_point<const wchar_t*> wcboundary_point; ///< convenience typedef +#ifdef __cpp_char8_t + typedef boundary_point<const char8_t*> u8cboundary_point; ///< convenience typedef +#endif #ifdef BOOST_LOCALE_ENABLE_CHAR16_T typedef boundary_point<const char16_t*> u16cboundary_point; ///< convenience typedef #endif diff --git a/contrib/restricted/boost/locale/include/boost/locale/boundary/index.hpp b/contrib/restricted/boost/locale/include/boost/locale/boundary/index.hpp index fb4319b1bf..92b7613fd3 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/boundary/index.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/boundary/index.hpp @@ -868,6 +868,9 @@ namespace boost { namespace locale { namespace boundary { typedef segment_index<std::string::const_iterator> ssegment_index; ///< convenience typedef typedef segment_index<std::wstring::const_iterator> wssegment_index; ///< convenience typedef +#ifndef BOOST_LOCALE_NO_CXX20_STRING8 + typedef segment_index<std::u8string::const_iterator> u8ssegment_index; ///< convenience typedef +#endif #ifdef BOOST_LOCALE_ENABLE_CHAR16_T typedef segment_index<std::u16string::const_iterator> u16ssegment_index; ///< convenience typedef #endif @@ -877,6 +880,9 @@ namespace boost { namespace locale { namespace boundary { typedef segment_index<const char*> csegment_index; ///< convenience typedef typedef segment_index<const wchar_t*> wcsegment_index; ///< convenience typedef +#ifdef __cpp_char8_t + typedef segment_index<const char8_t*> u8csegment_index; ///< convenience typedef +#endif #ifdef BOOST_LOCALE_ENABLE_CHAR16_T typedef segment_index<const char16_t*> u16csegment_index; ///< convenience typedef #endif @@ -886,6 +892,9 @@ namespace boost { namespace locale { namespace boundary { typedef boundary_point_index<std::string::const_iterator> sboundary_point_index; ///< convenience typedef typedef boundary_point_index<std::wstring::const_iterator> wsboundary_point_index; ///< convenience typedef +#ifndef BOOST_LOCALE_NO_CXX20_STRING8 + typedef boundary_point_index<std::u8string::const_iterator> u8sboundary_point_index; ///< convenience typedef +#endif #ifdef BOOST_LOCALE_ENABLE_CHAR16_T typedef boundary_point_index<std::u16string::const_iterator> u16sboundary_point_index; ///< convenience typedef #endif @@ -895,6 +904,9 @@ namespace boost { namespace locale { namespace boundary { typedef boundary_point_index<const char*> cboundary_point_index; ///< convenience typedef typedef boundary_point_index<const wchar_t*> wcboundary_point_index; ///< convenience typedef +#ifdef __cpp_char8_t + typedef boundary_point_index<const char8_t*> u8cboundary_point_index; ///< convenience typedef +#endif #ifdef BOOST_LOCALE_ENABLE_CHAR16_T typedef boundary_point_index<const char16_t*> u16cboundary_point_index; ///< convenience typedef #endif diff --git a/contrib/restricted/boost/locale/include/boost/locale/boundary/segment.hpp b/contrib/restricted/boost/locale/include/boost/locale/boundary/segment.hpp index 9e38188e3f..24e129dcf1 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/boundary/segment.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/boundary/segment.hpp @@ -340,6 +340,9 @@ namespace boost { namespace locale { namespace boundary { typedef segment<std::string::const_iterator> ssegment; ///< convenience typedef typedef segment<std::wstring::const_iterator> wssegment; ///< convenience typedef +#ifndef BOOST_LOCALE_NO_CXX20_STRING8 + typedef segment<std::u8string::const_iterator> u8ssegment; ///< convenience typedef +#endif #ifdef BOOST_LOCALE_ENABLE_CHAR16_T typedef segment<std::u16string::const_iterator> u16ssegment; ///< convenience typedef #endif @@ -349,6 +352,9 @@ namespace boost { namespace locale { namespace boundary { typedef segment<const char*> csegment; ///< convenience typedef typedef segment<const wchar_t*> wcsegment; ///< convenience typedef +#ifdef __cpp_char8_t + typedef segment<const char8_t*> u8csegment; ///< convenience typedef +#endif #ifdef BOOST_LOCALE_ENABLE_CHAR16_T typedef segment<const char16_t*> u16csegment; ///< convenience typedef #endif diff --git a/contrib/restricted/boost/locale/include/boost/locale/collator.hpp b/contrib/restricted/boost/locale/include/boost/locale/collator.hpp index b45f15475f..693d33a6be 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/collator.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/collator.hpp @@ -8,6 +8,7 @@ #define BOOST_LOCALE_COLLATOR_HPP_INCLUDED #include <boost/locale/config.hpp> +#include <boost/locale/detail/facet_id.hpp> #include <locale> #ifdef BOOST_MSVC @@ -43,17 +44,16 @@ namespace boost { namespace locale { /// \brief Collation facet. /// - /// It reimplements standard C++ std::collate, - /// allowing usage of std::locale for direct string comparison + /// It reimplements standard C++ std::collate with support for collation levels template<typename CharType> - class collator : public std::collate<CharType> { + class BOOST_SYMBOL_VISIBLE collator : public std::locale::facet, public detail::facet_id<collator<CharType>> { public: /// Type of the underlying character typedef CharType char_type; /// Type of string used with this facet typedef std::basic_string<CharType> string_type; - /// Compare two strings in rage [b1,e1), [b2,e2) according using a collation level \a level. Calls do_compare + /// Compare two strings in range [b1,e1), [b2,e2) according to collation level \a level. Calls do_compare /// /// Returns -1 if the first of the two strings sorts before the seconds, returns 1 if sorts after and 0 if /// they considered equal. @@ -66,6 +66,13 @@ namespace boost { namespace locale { return do_compare(level, b1, e1, b2, e2); } + /// Default compare function as-in std::collate that does not take collation level into account. + /// Uses identical level + int compare(const char_type* b1, const char_type* e1, const char_type* b2, const char_type* e2) const + { + return compare(collate_level::identical, b1, e1, b2, e2); + } + /// Create a binary string that can be compared to other in order to get collation order. The string is created /// for text in range [b,e). It is useful for collation of multiple strings for text. /// @@ -80,6 +87,13 @@ namespace boost { namespace locale { return do_transform(level, b, e); } + /// Default transform function as-in std::collate that does not take collation level into account. + /// Uses identical level + string_type transform(const char_type* b, const char_type* e) const + { + return transform(collate_level::identical, b, e); + } + /// Calculate a hash of a text in range [b,e). The value can be used for collation sensitive string comparison. /// /// If compare(level,b1,e1,b2,e2) == 0 then hash(level,b1,e1) == hash(level,b2,e2) @@ -87,6 +101,10 @@ namespace boost { namespace locale { /// Calls do_hash long hash(collate_level level, const char_type* b, const char_type* e) const { return do_hash(level, b, e); } + /// Default hash function as-in std::collate that does not take collation level into account. + /// Uses identical level + long hash(const char_type* b, const char_type* e) const { return hash(collate_level::identical, b, e); } + /// Compare two strings \a l and \a r using collation level \a level /// /// Returns -1 if the first of the two strings sorts before the seconds, returns 1 if sorts after and 0 if @@ -107,7 +125,7 @@ namespace boost { namespace locale { /// Create a binary string from string \a s, that can be compared to other, useful for collation of multiple /// strings. /// - /// The transformation follows these rules: + /// The transformation follows this rule: /// \code /// compare(level,s1,s2) == sign( transform(level,s1).compare(transform(level,s2)) ); /// \endcode @@ -118,29 +136,7 @@ namespace boost { namespace locale { protected: /// constructor of the collator object - collator(size_t refs = 0) : std::collate<CharType>(refs) {} - - /// This function is used to override default collation function that does not take in account collation level. - /// Uses primary level - int - do_compare(const char_type* b1, const char_type* e1, const char_type* b2, const char_type* e2) const override - { - return do_compare(collate_level::identical, b1, e1, b2, e2); - } - - /// This function is used to override default collation function that does not take in account collation level. - /// Uses primary level - string_type do_transform(const char_type* b, const char_type* e) const override - { - return do_transform(collate_level::identical, b, e); - } - - /// This function is used to override default collation function that does not take in account collation level. - /// Uses primary level - long do_hash(const char_type* b, const char_type* e) const override - { - return do_hash(collate_level::identical, b, e); - } + collator(size_t refs = 0) : std::locale::facet(refs) {} /// Actual function that performs comparison between the strings. For details see compare member function. Can /// be overridden. @@ -157,7 +153,7 @@ namespace boost { namespace locale { }; /// \brief This class can be used in STL algorithms and containers for comparison of strings - /// with a level other than primary + /// with a level other than identical /// /// For example: /// @@ -169,21 +165,22 @@ namespace boost { namespace locale { template<typename CharType, collate_level default_level = collate_level::identical> struct comparator { public: - /// Create a comparator class for locale \a l and with collation leval \a level + /// Create a comparator class for locale \a l and with collation level \a level /// /// \throws std::bad_cast: \a l does not have \ref collator facet installed comparator(const std::locale& l = std::locale(), collate_level level = default_level) : - locale_(l), level_(level) + locale_(l), collator_(std::use_facet<collator<CharType>>(locale_)), level_(level) {} /// Compare two strings -- equivalent to return left < right according to collation rules bool operator()(const std::basic_string<CharType>& left, const std::basic_string<CharType>& right) const { - return std::use_facet<collator<CharType>>(locale_).compare(level_, left, right) < 0; + return collator_.compare(level_, left, right) < 0; } private: std::locale locale_; + const collator<CharType>& collator_; collate_level level_; }; diff --git a/contrib/restricted/boost/locale/include/boost/locale/config.hpp b/contrib/restricted/boost/locale/include/boost/locale/config.hpp index 9c8e6c2f2f..1c69c92dc4 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/config.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/config.hpp @@ -8,6 +8,12 @@ #define BOOST_LOCALE_CONFIG_HPP_INCLUDED #include <boost/config.hpp> +#include <boost/config/workaround.hpp> +#ifdef __has_include +# if __has_include(<version>) +# include <version> +# endif +#endif #if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_LOCALE_DYN_LINK) # ifdef BOOST_LOCALE_SOURCE @@ -82,6 +88,12 @@ #if !defined(BOOST_LOCALE_NO_SANITIZE) # define BOOST_LOCALE_NO_SANITIZE(what) #endif + +#if !defined(__cpp_lib_char8_t) || BOOST_WORKAROUND(BOOST_CLANG_VERSION, < 150000) +// No std::basic_string<char8_t> or bug in Clang: https://github.com/llvm/llvm-project/issues/55560 +# define BOOST_LOCALE_NO_CXX20_STRING8 +#endif + /// \endcond #endif // boost/locale/config.hpp diff --git a/contrib/restricted/boost/locale/include/boost/locale/date_time.hpp b/contrib/restricted/boost/locale/include/boost/locale/date_time.hpp index 46b171bc35..7666cfa109 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/date_time.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/date_time.hpp @@ -11,6 +11,7 @@ #include <boost/locale/formatting.hpp> #include <boost/locale/hold_ptr.hpp> #include <boost/locale/time_zone.hpp> +#include <array> #include <locale> #include <stdexcept> #include <vector> @@ -388,14 +389,14 @@ namespace boost { namespace locale { } // namespace period - /// \brief this class that represents a set of periods, + /// \brief This class represents a set of periods. /// /// It is generally created by operations on periods: /// 1995*year + 3*month + 1*day. Note: operations are not commutative. class date_time_period_set { public: /// Default constructor - empty set - date_time_period_set() {} + date_time_period_set() = default; /// Create a set of single period with value 1 date_time_period_set(period::period_type f) { basic_[0] = date_time_period(f); } @@ -406,25 +407,21 @@ namespace boost { namespace locale { /// Append date_time_period \a f to the set void add(date_time_period f) { - size_t n = size(); - if(n < 4) + const size_t n = size(); + if(n < basic_.size()) basic_[n] = f; else periods_.push_back(f); } - /// Get number if items in list + /// Get number of items in list size_t size() const { - if(basic_[0].type == period::period_type()) - return 0; - if(basic_[1].type == period::period_type()) - return 1; - if(basic_[2].type == period::period_type()) - return 2; - if(basic_[3].type == period::period_type()) - return 3; - return 4 + periods_.size(); + for(size_t i = 0; i < basic_.size(); ++i) { + if(basic_[i].type == period::period_type()) + return i; + } + return basic_.size() + periods_.size(); } /// Get item at position \a n the set, n should be in range [0,size) @@ -432,14 +429,14 @@ namespace boost { namespace locale { { if(n >= size()) throw std::out_of_range("Invalid index to date_time_period"); - if(n < 4) + if(n < basic_.size()) return basic_[n]; else - return periods_[n - 4]; + return periods_[n - basic_.size()]; } private: - date_time_period basic_[4]; + std::array<date_time_period, 4> basic_; std::vector<date_time_period> periods_; }; @@ -707,6 +704,11 @@ namespace boost { namespace locale { hold_ptr<abstract_calendar> impl_; }; + inline void swap(date_time& left, date_time& right) noexcept + { + left.swap(right); + } + /// Writes date_time \a t to output stream \a out. /// /// This function uses locale, calendar and time zone of the target stream \a in. @@ -721,16 +723,15 @@ namespace boost { namespace locale { template<typename CharType> std::basic_ostream<CharType>& operator<<(std::basic_ostream<CharType>& out, const date_time& t) { - double time_point = t.time(); - uint64_t display_flags = ios_info::get(out).display_flags(); - if(display_flags == flags::date || display_flags == flags::time || display_flags == flags::datetime - || display_flags == flags::strftime) - { + const double time_point = t.time(); + ios_info& info = ios_info::get(out); + const uint64_t display_flags = info.display_flags(); + if(as::detail::is_datetime_display_flags(display_flags)) { out << time_point; } else { - ios_info::get(out).display_flags(flags::datetime); + info.display_flags(flags::datetime); out << time_point; - ios_info::get(out).display_flags(display_flags); + info.display_flags(display_flags); } return out; } @@ -742,10 +743,8 @@ namespace boost { namespace locale { std::basic_istream<CharType>& operator>>(std::basic_istream<CharType>& in, date_time& t) { double v; - uint64_t display_flags = ios_info::get(in).display_flags(); - if(display_flags == flags::date || display_flags == flags::time || display_flags == flags::datetime - || display_flags == flags::strftime) - { + const uint64_t display_flags = ios_info::get(in).display_flags(); + if(as::detail::is_datetime_display_flags(display_flags)) { in >> v; } else { ios_info::get(in).display_flags(flags::datetime); diff --git a/contrib/restricted/boost/locale/include/boost/locale/detail/allocator_traits.hpp b/contrib/restricted/boost/locale/include/boost/locale/detail/allocator_traits.hpp new file mode 100644 index 0000000000..8ea225f39b --- /dev/null +++ b/contrib/restricted/boost/locale/include/boost/locale/detail/allocator_traits.hpp @@ -0,0 +1,30 @@ +// +// Copyright (c) 2024 Alexander Grund +// +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_LOCALE_DETAIL_ALLOCATOR_TRAITS_HPP_INCLUDED +#define BOOST_LOCALE_DETAIL_ALLOCATOR_TRAITS_HPP_INCLUDED + +#include <boost/locale/config.hpp> +#include <memory> +#include <type_traits> + +/// \cond INTERNAL +namespace boost { namespace locale { namespace conv { namespace detail { + template<class Alloc, typename T> + using rebind_alloc = typename std::allocator_traits<Alloc>::template rebind_alloc<T>; + + template<class Alloc, typename T, typename Result = void> + using enable_if_allocator_for = + typename std::enable_if<std::is_same<typename Alloc::value_type, T>::value, Result>::type; + template<class Alloc, typename T, class Alloc2, typename T2, typename Result = void> + using enable_if_allocator_for2 = typename std::enable_if<std::is_same<typename Alloc::value_type, T>::value + && std::is_same<typename Alloc2::value_type, T2>::value, + Result>::type; +}}}} // namespace boost::locale::conv::detail + +/// \endcond + +#endif diff --git a/contrib/restricted/boost/locale/include/boost/locale/detail/any_string.hpp b/contrib/restricted/boost/locale/include/boost/locale/detail/any_string.hpp new file mode 100644 index 0000000000..c0cc7ffb3e --- /dev/null +++ b/contrib/restricted/boost/locale/include/boost/locale/detail/any_string.hpp @@ -0,0 +1,71 @@ +// +// Copyright (c) 2023 Alexander Grund +// +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_LOCALE_DETAIL_ANY_STRING_HPP_INCLUDED +#define BOOST_LOCALE_DETAIL_ANY_STRING_HPP_INCLUDED + +#include <boost/locale/config.hpp> +#include <boost/assert.hpp> +#include <boost/utility/string_view.hpp> +#include <memory> +#include <stdexcept> +#include <string> + +/// \cond INTERNAL +namespace boost { namespace locale { namespace detail { + /// Type-erased std::basic_string + class any_string { + struct BOOST_SYMBOL_VISIBLE base { + virtual ~base() = default; + virtual base* clone() const = 0; + + protected: + base() = default; + base(const base&) = default; + base(base&&) = delete; + base& operator=(const base&) = default; + base& operator=(base&&) = delete; + }; + template<typename Char> + struct BOOST_SYMBOL_VISIBLE impl : base { + explicit impl(const boost::basic_string_view<Char> value) : s(value) {} + impl* clone() const override { return new impl(*this); } + std::basic_string<Char> s; + }; + + std::unique_ptr<const base> s_; + + public: + any_string() = default; + any_string(const any_string& other) : s_(other.s_ ? other.s_->clone() : nullptr) {} + any_string(any_string&&) = default; + any_string& operator=(any_string other) // Covers the copy and move assignment + { + s_.swap(other.s_); + return *this; + } + + template<typename Char> + void set(const boost::basic_string_view<Char> s) + { + BOOST_ASSERT(!s.empty()); + s_.reset(new impl<Char>(s)); + } + + template<typename Char> + std::basic_string<Char> get() const + { + if(!s_) + throw std::bad_cast(); + return dynamic_cast<const impl<Char>&>(*s_).s; + } + }; + +}}} // namespace boost::locale::detail + +/// \endcond + +#endif diff --git a/contrib/restricted/boost/locale/include/boost/locale/detail/facet_id.hpp b/contrib/restricted/boost/locale/include/boost/locale/detail/facet_id.hpp index 7405149905..14ab458395 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/detail/facet_id.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/detail/facet_id.hpp @@ -12,7 +12,7 @@ /// \cond INTERNAL namespace boost { namespace locale { namespace detail { -#if defined(__clang__) +#if BOOST_CLANG_VERSION >= 40900 # pragma clang diagnostic push # pragma clang diagnostic ignored "-Wundefined-var-template" #endif @@ -25,7 +25,7 @@ namespace boost { namespace locale { namespace detail { struct BOOST_LOCALE_DECL facet_id { static std::locale::id id; }; -#if defined(__clang__) +#if BOOST_CLANG_VERSION >= 40900 # pragma clang diagnostic pop #endif }}} // namespace boost::locale::detail diff --git a/contrib/restricted/boost/locale/include/boost/locale/detail/is_supported_char.hpp b/contrib/restricted/boost/locale/include/boost/locale/detail/is_supported_char.hpp index d9fb092e5a..5c29e36d5e 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/detail/is_supported_char.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/detail/is_supported_char.hpp @@ -20,6 +20,10 @@ namespace boost { namespace locale { namespace detail { struct is_supported_char<char> : std::true_type {}; template<> struct is_supported_char<wchar_t> : std::true_type {}; +#ifdef __cpp_char8_t + template<> + struct is_supported_char<char8_t> : std::true_type {}; +#endif #ifdef BOOST_LOCALE_ENABLE_CHAR16_T template<> diff --git a/contrib/restricted/boost/locale/include/boost/locale/encoding_utf.hpp b/contrib/restricted/boost/locale/include/boost/locale/encoding_utf.hpp index c19e67d3b8..592b0f3683 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/encoding_utf.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/encoding_utf.hpp @@ -1,5 +1,6 @@ // // Copyright (c) 2009-2011 Artyom Beilis (Tonkikh) +// Copyright (c) 2022-2024 Alexander Grund // // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt @@ -7,10 +8,13 @@ #ifndef BOOST_LOCALE_ENCODING_UTF_HPP_INCLUDED #define BOOST_LOCALE_ENCODING_UTF_HPP_INCLUDED +#include <boost/locale/detail/allocator_traits.hpp> #include <boost/locale/encoding_errors.hpp> #include <boost/locale/utf.hpp> #include <boost/locale/util/string.hpp> #include <iterator> +#include <memory> +#include <type_traits> #ifdef BOOST_MSVC # pragma warning(push) @@ -25,12 +29,13 @@ namespace boost { namespace locale { namespace conv { /// Convert a Unicode text in range [begin,end) to other Unicode encoding /// /// \throws conversion_error: Conversion failed (e.g. \a how is \c stop and any character cannot be decoded) - template<typename CharOut, typename CharIn> - std::basic_string<CharOut> utf_to_utf(const CharIn* begin, const CharIn* end, method_type how = default_method) + template<typename CharOut, typename CharIn, class Alloc = std::allocator<CharOut>> + std::basic_string<CharOut, std::char_traits<CharOut>, Alloc> + utf_to_utf(const CharIn* begin, const CharIn* end, method_type how = default_method, const Alloc& alloc = Alloc()) { - std::basic_string<CharOut> result; + std::basic_string<CharOut, std::char_traits<CharOut>, Alloc> result(alloc); result.reserve(end - begin); - std::back_insert_iterator<std::basic_string<CharOut>> inserter(result); + auto inserter = std::back_inserter(result); while(begin != end) { const utf::code_point c = utf::utf_traits<CharIn>::decode(begin, end); if(c == utf::illegal || c == utf::incomplete) { @@ -42,22 +47,97 @@ namespace boost { namespace locale { namespace conv { return result; } - /// Convert a Unicode NULL terminated string \a str other Unicode encoding + /// Convert a Unicode string \a str to other Unicode encoding. + /// Invalid characters are skipped. + template<typename CharOut, typename CharIn, class Alloc> + std::basic_string<CharOut, std::char_traits<CharOut>, Alloc> + utf_to_utf(const CharIn* begin, const CharIn* end, const Alloc& alloc) + { + return utf_to_utf<CharOut>(begin, end, skip, alloc); + } + + /// Convert a Unicode NULL terminated string \a str to other Unicode encoding + /// + /// \throws conversion_error: Conversion failed (e.g. \a how is \c stop and any character cannot be decoded) + template<typename CharOut, typename CharIn, class Alloc = std::allocator<CharOut>> + std::basic_string<CharOut, std::char_traits<CharOut>, Alloc> + utf_to_utf(const CharIn* str, method_type how = default_method, const Alloc& alloc = Alloc()) + { + return utf_to_utf<CharOut>(str, util::str_end(str), how, alloc); + } + + /// Convert a Unicode string \a str to other Unicode encoding. + /// Invalid characters are skipped. + template<typename CharOut, typename CharIn, class Alloc> +#ifndef BOOST_LOCALE_DOXYGEN + detail::enable_if_allocator_for<Alloc, + CharOut, +#endif + std::basic_string<CharOut, std::char_traits<CharOut>, Alloc> +#ifndef BOOST_LOCALE_DOXYGEN + > +#endif + utf_to_utf(const CharIn* str, const Alloc& alloc) + { + return utf_to_utf<CharOut>(str, skip, alloc); + } + + /// Convert a Unicode string \a str to other Unicode encoding /// /// \throws conversion_error: Conversion failed (e.g. \a how is \c stop and any character cannot be decoded) - template<typename CharOut, typename CharIn> - std::basic_string<CharOut> utf_to_utf(const CharIn* str, method_type how = default_method) + template<typename CharOut, typename CharIn, class Alloc> +#ifndef BOOST_LOCALE_DOXYGEN + detail::enable_if_allocator_for< + Alloc, + CharIn, +#endif + std::basic_string<CharOut, std::char_traits<CharOut>, detail::rebind_alloc<Alloc, CharOut>> +#ifndef BOOST_LOCALE_DOXYGEN + > +#endif + utf_to_utf(const std::basic_string<CharIn, std::char_traits<CharIn>, Alloc>& str, method_type how = default_method) { - return utf_to_utf<CharOut, CharIn>(str, util::str_end(str), how); + return utf_to_utf<CharOut>(str.c_str(), + str.c_str() + str.size(), + how, + detail::rebind_alloc<Alloc, CharOut>(str.get_allocator())); } - /// Convert a Unicode string \a str other Unicode encoding + /// Convert a Unicode string \a str to other Unicode encoding /// /// \throws conversion_error: Conversion failed (e.g. \a how is \c stop and any character cannot be decoded) - template<typename CharOut, typename CharIn> - std::basic_string<CharOut> utf_to_utf(const std::basic_string<CharIn>& str, method_type how = default_method) + template<typename CharOut, typename CharIn, class AllocOut, class AllocIn> +#ifndef BOOST_LOCALE_DOXYGEN + detail::enable_if_allocator_for<AllocIn, + CharIn, +#endif + std::basic_string<CharOut, std::char_traits<CharOut>, AllocOut> +#ifndef BOOST_LOCALE_DOXYGEN + > +#endif + utf_to_utf(const std::basic_string<CharIn, std::char_traits<CharIn>, AllocIn>& str, + method_type how = default_method, + const AllocOut& alloc = AllocOut()) + { + return utf_to_utf<CharOut>(str.c_str(), str.c_str() + str.size(), how, alloc); + } + + /// Convert a Unicode string \a str to other Unicode encoding. + /// Invalid characters are skipped. + template<typename CharOut, typename CharIn, class AllocOut, class AllocIn> +#ifndef BOOST_LOCALE_DOXYGEN + detail::enable_if_allocator_for2<AllocIn, + CharIn, + AllocOut, + CharOut, +#endif + std::basic_string<CharOut, std::char_traits<CharOut>, AllocOut> +#ifndef BOOST_LOCALE_DOXYGEN + > +#endif + utf_to_utf(const std::basic_string<CharIn, std::char_traits<CharIn>, AllocIn>& str, const AllocOut& alloc) { - return utf_to_utf<CharOut, CharIn>(str.c_str(), str.c_str() + str.size(), how); + return utf_to_utf<CharOut>(str, skip, alloc); } /// @} diff --git a/contrib/restricted/boost/locale/include/boost/locale/format.hpp b/contrib/restricted/boost/locale/include/boost/locale/format.hpp index 266b65c735..6adb844031 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/format.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/format.hpp @@ -295,6 +295,7 @@ namespace boost { namespace locale { for(size_t pos = 0; format[pos];) { if(format[pos] != obrk) { if(format[pos] == cbrk && format[pos + 1] == cbrk) { + // Escaped closing brace out << cbrk; pos += 2; } else { @@ -305,7 +306,9 @@ namespace boost { namespace locale { } pos++; if(format[pos] == obrk) { + // Escaped opening brace out << obrk; + pos++; continue; } @@ -415,6 +418,10 @@ namespace boost { namespace locale { typedef basic_format<char> format; /// Definition of wchar_t based format typedef basic_format<wchar_t> wformat; +#ifndef BOOST_LOCALE_NO_CXX20_STRING8 + /// Definition of char8_t based format + typedef basic_format<char8_t> u8format; +#endif #ifdef BOOST_LOCALE_ENABLE_CHAR16_T /// Definition of char16_t based format diff --git a/contrib/restricted/boost/locale/include/boost/locale/formatting.hpp b/contrib/restricted/boost/locale/include/boost/locale/formatting.hpp index 936ce7e12d..e3c8619e48 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/formatting.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/formatting.hpp @@ -8,15 +8,13 @@ #ifndef BOOST_LOCALE_FORMATTING_HPP_INCLUDED #define BOOST_LOCALE_FORMATTING_HPP_INCLUDED +#include <boost/locale/detail/any_string.hpp> #include <boost/locale/time_zone.hpp> -#include <boost/assert.hpp> -#include <boost/utility/string_view.hpp> #include <cstdint> #include <cstring> #include <istream> #include <ostream> #include <string> -#include <typeinfo> #ifdef BOOST_MSVC # pragma warning(push) @@ -130,13 +128,13 @@ namespace boost { namespace locale { template<typename CharType> void date_time_pattern(const std::basic_string<CharType>& str) { - date_time_pattern_set().set<CharType>(str); + datetime_.set<CharType>(str); } /// Get date/time pattern (strftime like) template<typename CharType> std::basic_string<CharType> date_time_pattern() const { - return date_time_pattern_set().get<CharType>(); + return datetime_.get<CharType>(); } /// \cond INTERNAL @@ -144,51 +142,10 @@ namespace boost { namespace locale { /// \endcond private: - class string_set; - - const string_set& date_time_pattern_set() const; - string_set& date_time_pattern_set(); - - class BOOST_LOCALE_DECL string_set { - public: - string_set(); - ~string_set(); - string_set(const string_set& other); - string_set& operator=(string_set other); - void swap(string_set& other); - - template<typename Char> - void set(const boost::basic_string_view<Char> s) - { - BOOST_ASSERT(!s.empty()); - delete[] ptr; - ptr = nullptr; - type = &typeid(Char); - size = sizeof(Char) * s.size(); - ptr = size ? new char[size] : nullptr; - memcpy(ptr, s.data(), size); - } - - template<typename Char> - std::basic_string<Char> get() const - { - if(type == nullptr || *type != typeid(Char)) - throw std::bad_cast(); - std::basic_string<Char> result(size / sizeof(Char), Char(0)); - memcpy(&result.front(), ptr, size); - return result; - } - - private: - const std::type_info* type; - size_t size; - char* ptr; - }; - uint64_t flags_; int domain_id_; std::string time_zone_; - string_set datetime_; + detail::any_string datetime_; }; /// \brief This namespace includes all manipulators that can be used on IO streams @@ -363,6 +320,12 @@ namespace boost { namespace locale { /// \cond INTERNAL namespace detail { + inline bool is_datetime_display_flags(const uint64_t display_flags) + { + return (display_flags == flags::date || display_flags == flags::time || display_flags == flags::datetime + || display_flags == flags::strftime); + } + template<typename CharType> struct add_ftime { std::basic_string<CharType> ftime; diff --git a/contrib/restricted/boost/locale/include/boost/locale/generator.hpp b/contrib/restricted/boost/locale/include/boost/locale/generator.hpp index f9ae9c777d..675aa604b6 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/generator.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/generator.hpp @@ -35,11 +35,14 @@ namespace locale { nochar = 0, ///< Unspecified character category for character independent facets char_f = 1 << 0, ///< 8-bit character facets wchar_f = 1 << 1, ///< wide character facets +#ifdef __cpp_char8_t + char8_f = 1 << 2, ///< C++20 char8_t facets +#endif #ifdef BOOST_LOCALE_ENABLE_CHAR16_T - char16_f = 1 << 2, ///< C++11 char16_t facets + char16_f = 1 << 3, ///< C++11 char16_t facets #endif #ifdef BOOST_LOCALE_ENABLE_CHAR32_T - char32_f = 1 << 3, ///< C++11 char32_t facets + char32_f = 1 << 4, ///< C++11 char32_t facets #endif }; typedef BOOST_DEPRECATED("Use char_facet_t") char_facet_t character_facet_type; @@ -52,6 +55,8 @@ namespace locale { char_facet_t::char32_f; #elif defined BOOST_LOCALE_ENABLE_CHAR16_T char_facet_t::char16_f; +#elif defined __cpp_char8_t + char_facet_t::char8_f; #else char_facet_t::wchar_f; #endif diff --git a/contrib/restricted/boost/locale/include/boost/locale/generic_codecvt.hpp b/contrib/restricted/boost/locale/include/boost/locale/generic_codecvt.hpp index 449b1de728..824cc48699 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/generic_codecvt.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/generic_codecvt.hpp @@ -150,7 +150,7 @@ namespace boost { namespace locale { template<typename CharType, typename CodecvtImpl, int CharSize = sizeof(CharType)> class generic_codecvt; - /// \brief UTF-16 to/from UTF-8 codecvt facet to use with char16_t or wchar_t on Windows + /// \brief UTF-16 to/from narrow char codecvt facet to use with char16_t or wchar_t on Windows /// /// Note in order to fit the requirements of usability by std::wfstream it uses mbstate_t /// to handle intermediate states in handling of variable length UTF-16 sequences @@ -344,7 +344,7 @@ namespace boost { namespace locale { } }; - /// \brief UTF-32 to/from UTF-8 codecvt facet to use with char32_t or wchar_t on POSIX platforms + /// \brief UTF-32 to/from narrow char codecvt facet to use with char32_t or wchar_t on POSIX platforms /// /// Its member functions implement standard virtual functions of basic codecvt. /// mbstate_t is not used for UTF-32 handling due to fixed length encoding @@ -456,11 +456,11 @@ namespace boost { namespace locale { } }; - template<typename CharType, typename CodecvtImpl> - class generic_codecvt<CharType, CodecvtImpl, 1> : public std::codecvt<CharType, char, std::mbstate_t>, - public generic_codecvt_base { + template<typename CodecvtImpl> + class generic_codecvt<char, CodecvtImpl, 1> : public std::codecvt<char, char, std::mbstate_t>, + public generic_codecvt_base { public: - typedef CharType uchar; + typedef char uchar; const CodecvtImpl& implementation() const { return *static_cast<const CodecvtImpl*>(this); } diff --git a/contrib/restricted/boost/locale/include/boost/locale/hold_ptr.hpp b/contrib/restricted/boost/locale/include/boost/locale/hold_ptr.hpp index c421b29013..ee4abf743b 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/hold_ptr.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/hold_ptr.hpp @@ -54,15 +54,10 @@ namespace boost { namespace locale { /// Get a mutable pointer to the object T* operator->() { return ptr_; } - /// Transfer an ownership on the pointer to user - T* release() - { - T* tmp = ptr_; - ptr_ = nullptr; - return tmp; - } + /// Transfer ownership of the pointer to user + T* release() { return exchange(ptr_, nullptr); } - /// Set new value to pointer, previous object is destroyed, ownership on new object is transferred + /// Set new value to pointer, previous object is destroyed, ownership of new object is transferred void reset(T* p = nullptr) { if(ptr_) @@ -71,12 +66,7 @@ namespace boost { namespace locale { } /// Swap two pointers - void swap(hold_ptr& other) noexcept - { - T* tmp = other.ptr_; - other.ptr_ = ptr_; - ptr_ = tmp; - } + void swap(hold_ptr& other) noexcept { ptr_ = exchange(other.ptr_, ptr_); } private: T* ptr_; diff --git a/contrib/restricted/boost/locale/include/boost/locale/info.hpp b/contrib/restricted/boost/locale/include/boost/locale/info.hpp index 37b5358d5f..bb7d1728d0 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/info.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/info.hpp @@ -1,5 +1,6 @@ // // Copyright (c) 2009-2011 Artyom Beilis (Tonkikh) +// Copyright (c) 2022-2023 Alexander Grund // // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt @@ -25,7 +26,7 @@ namespace boost { namespace locale { class BOOST_SYMBOL_VISIBLE info : public std::locale::facet, public detail::facet_id<info> { public: /// String information about the locale - enum string_propery { + enum string_property { language_property, ///< ISO 639 language id country_property, ///< ISO 3166 country id variant_property, ///< Variant for locale @@ -57,7 +58,7 @@ namespace boost { namespace locale { protected: /// Get string property by its id \a v - virtual std::string get_string_property(string_propery v) const = 0; + virtual std::string get_string_property(string_property v) const = 0; /// Get integer property by its id \a v virtual int get_integer_property(integer_property v) const = 0; }; diff --git a/contrib/restricted/boost/locale/include/boost/locale/message.hpp b/contrib/restricted/boost/locale/include/boost/locale/message.hpp index b0a512c18a..88a4aefbf1 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/message.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/message.hpp @@ -341,6 +341,10 @@ namespace boost { namespace locale { typedef basic_message<char> message; /// Convenience typedef for wchar_t typedef basic_message<wchar_t> wmessage; +#ifndef BOOST_LOCALE_NO_CXX20_STRING8 + /// Convenience typedef for char8_t + typedef basic_message<char8_t> u8message; +#endif #ifdef BOOST_LOCALE_ENABLE_CHAR16_T /// Convenience typedef for char16_t typedef basic_message<char16_t> u16message; diff --git a/contrib/restricted/boost/locale/include/boost/locale/utf8_codecvt.hpp b/contrib/restricted/boost/locale/include/boost/locale/utf8_codecvt.hpp index 797d907346..1ccd598f2b 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/utf8_codecvt.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/utf8_codecvt.hpp @@ -15,7 +15,7 @@ namespace boost { namespace locale { - /// \brief Geneneric utf8 codecvt facet, it allows to convert UTF-8 strings to UTF-16 and UTF-32 using wchar_t, + /// \brief Generic utf8 codecvt facet, it allows to convert UTF-8 strings to UTF-16 and UTF-32 using wchar_t, /// char32_t and char16_t template<typename CharType> class utf8_codecvt : public generic_codecvt<CharType, utf8_codecvt<CharType>> { diff --git a/contrib/restricted/boost/locale/include/boost/locale/util.hpp b/contrib/restricted/boost/locale/include/boost/locale/util.hpp index 5eaf450556..0d486013ab 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/util.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/util.hpp @@ -71,7 +71,7 @@ namespace boost { namespace locale { /// or an invalid UTF-8 sequence is found static constexpr utf::code_point illegal = utf::illegal; - /// This value is returned in following cases: The of incomplete input sequence was found or + /// This value is returned in following cases: An incomplete input sequence was found or /// insufficient output buffer was provided so complete output could not be written. static constexpr utf::code_point incomplete = utf::incomplete; @@ -114,7 +114,7 @@ namespace boost { namespace locale { virtual utf::code_point to_unicode(const char*& begin, const char* end) { if(begin == end) - return incomplete; + return incomplete; // LCOV_EXCL_LINE unsigned char cp = *begin; if(cp <= 0x7F) { begin++; @@ -136,7 +136,7 @@ namespace boost { namespace locale { virtual utf::len_or_error from_unicode(utf::code_point u, char* begin, const char* end) { if(begin == end) - return incomplete; + return incomplete; // LCOV_EXCL_LINE if(u >= 0x80) return illegal; *begin = static_cast<char>(u); diff --git a/contrib/restricted/boost/locale/include/boost/locale/util/string.hpp b/contrib/restricted/boost/locale/include/boost/locale/util/string.hpp index 9ab9521c55..ba066bd461 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/util/string.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/util/string.hpp @@ -38,7 +38,7 @@ namespace boost { namespace locale { namespace util { /// Cast an unsigned char to a (possibly signed) char avoiding implementation defined behavior constexpr char to_char(unsigned char c) { - return static_cast<char>((c - std::numeric_limits<char>::min()) + std::numeric_limits<char>::min()); + return static_cast<char>((c - (std::numeric_limits<char>::min)()) + (std::numeric_limits<char>::min)()); } }}} // namespace boost::locale::util diff --git a/contrib/restricted/boost/locale/src/boost/locale/encoding/codepage.cpp b/contrib/restricted/boost/locale/src/boost/locale/encoding/codepage.cpp index 34b01395bc..0ac9659ab5 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/encoding/codepage.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/encoding/codepage.cpp @@ -224,6 +224,10 @@ namespace boost { namespace locale { namespace conv { BOOST_LOCALE_INSTANTIATE(char); BOOST_LOCALE_INSTANTIATE_NO_CHAR(wchar_t); +#ifndef BOOST_LOCALE_NO_CXX20_STRING8 + BOOST_LOCALE_INSTANTIATE_NO_CHAR(char8_t); +#endif + #ifdef BOOST_LOCALE_ENABLE_CHAR16_T BOOST_LOCALE_INSTANTIATE_NO_CHAR(char16_t); #endif diff --git a/contrib/restricted/boost/locale/src/boost/locale/encoding/iconv_converter.hpp b/contrib/restricted/boost/locale/src/boost/locale/encoding/iconv_converter.hpp index 38a8f485ea..2877dbca5e 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/encoding/iconv_converter.hpp +++ b/contrib/restricted/boost/locale/src/boost/locale/encoding/iconv_converter.hpp @@ -10,6 +10,7 @@ #include <boost/locale/encoding.hpp> #include "boost/locale/util/encoding.hpp" #include "boost/locale/util/iconv.hpp" +#include <boost/assert.hpp> #include <cerrno> #include <string> @@ -47,6 +48,7 @@ namespace boost { namespace locale { namespace conv { namespace impl { if(in_left == 0) is_unshifting = true; + const auto old_in_left = in_left; const size_t res = (!is_unshifting) ? conv(&begin, &in_left, &out_ptr, &out_left) : conv(nullptr, nullptr, &out_ptr, &out_left); @@ -60,6 +62,7 @@ namespace boost { namespace locale { namespace conv { namespace impl { if(res == (size_t)(-1)) { const int err = errno; + BOOST_ASSERT_MSG(err == EILSEQ || err == EINVAL || err == E2BIG, "Invalid error code from IConv"); if(err == EILSEQ || err == EINVAL) { if(how_ == stop) throw conversion_error(); @@ -70,9 +73,11 @@ namespace boost { namespace locale { namespace conv { namespace impl { break; } else break; - } else if(err == E2BIG) - continue; - else // Invalid error code, shouldn't ever happen or iconv has a bug + } else if(err == E2BIG) { + if(in_left != old_in_left || out_ptr != out_start) // Check to avoid infinite loop + continue; + throw std::runtime_error("No progress, IConv is faulty!"); // LCOV_EXCL_LINE + } else // Invalid error code, shouldn't ever happen or iconv has a bug throw conversion_error(); // LCOV_EXCL_LINE } if(is_unshifting) diff --git a/contrib/restricted/boost/locale/src/boost/locale/encoding/wconv_converter.hpp b/contrib/restricted/boost/locale/src/boost/locale/encoding/wconv_converter.hpp index 1a0325565e..32cd78e21a 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/encoding/wconv_converter.hpp +++ b/contrib/restricted/boost/locale/src/boost/locale/encoding/wconv_converter.hpp @@ -175,12 +175,15 @@ namespace boost { namespace locale { namespace conv { namespace impl { return false; return true; } - std::string convert(const char* begin, const char* end) override + + template<typename Char> + std::basic_string<Char> convert(const char* begin, const char* end) { + static_assert(sizeof(Char) == sizeof(char), "Not a narrow char type"); if(to_code_page_ == CP_UTF8 && from_code_page_ == CP_UTF8) - return utf_to_utf<char>(begin, end, how_); + return utf_to_utf<Char>(begin, end, how_); - std::string res; + std::basic_string<Char> res; std::vector<wchar_t> tmp; // buffer for mb2w std::wstring tmps; // buffer for utf_to_utf @@ -202,16 +205,18 @@ namespace boost { namespace locale { namespace conv { namespace impl { } if(to_code_page_ == CP_UTF8) - return utf_to_utf<char>(wbegin, wend, how_); + return utf_to_utf<Char>(wbegin, wend, how_); std::vector<char> ctmp; wide_to_multibyte(to_code_page_, wbegin, wend, how_ == skip, ctmp); if(ctmp.empty()) return res; - res.assign(ctmp.data(), ctmp.size()); + res.assign(reinterpret_cast<const Char*>(ctmp.data()), ctmp.size()); return res; } + std::string convert(const char* begin, const char* end) override { return convert<char>(begin, end); } + private: method_type how_; int to_code_page_; @@ -224,21 +229,27 @@ namespace boost { namespace locale { namespace conv { namespace impl { template<typename CharType, int size = sizeof(CharType)> class wconv_from_utf; - template<> - class wconv_to_utf<char, 1> final : public detail::utf_encoder<char> { + template<typename CharType> + class wconv_to_utf<CharType, 1> final : public detail::utf_encoder<CharType> { public: bool open(const std::string& cs, method_type how) { return cvt.open("UTF-8", cs, how); } - std::string convert(const char* begin, const char* end) override { return cvt.convert(begin, end); } + std::basic_string<CharType> convert(const char* begin, const char* end) override + { + return cvt.convert<CharType>(begin, end); + } private: wconv_between cvt; }; - template<> - class wconv_from_utf<char, 1> final : public detail::utf_decoder<char> { + template<typename CharType> + class wconv_from_utf<CharType, 1> final : public detail::utf_decoder<CharType> { public: bool open(const std::string& cs, method_type how) { return cvt.open(cs, "UTF-8", how); } - std::string convert(const char* begin, const char* end) override { return cvt.convert(begin, end); } + std::string convert(const CharType* begin, const CharType* end) override + { + return cvt.convert(reinterpret_cast<const char*>(begin), reinterpret_cast<const char*>(end)); + } private: wconv_between cvt; diff --git a/contrib/restricted/boost/locale/src/boost/locale/icu/all_generator.hpp b/contrib/restricted/boost/locale/src/boost/locale/icu/all_generator.hpp index 9c429a4b37..b2f8c34a33 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/icu/all_generator.hpp +++ b/contrib/restricted/boost/locale/src/boost/locale/icu/all_generator.hpp @@ -10,7 +10,7 @@ #include <boost/locale/generator.hpp> namespace boost { namespace locale { namespace impl_icu { - struct cdata; + class cdata; std::locale create_convert(const std::locale&, const cdata&, char_facet_t); std::locale create_collate(const std::locale&, const cdata&, char_facet_t); std::locale create_formatting(const std::locale&, const cdata&, char_facet_t); diff --git a/contrib/restricted/boost/locale/src/boost/locale/icu/boundary.cpp b/contrib/restricted/boost/locale/src/boost/locale/icu/boundary.cpp index a26dfc98cf..4adada4f42 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/icu/boundary.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/icu/boundary.cpp @@ -137,7 +137,9 @@ namespace boost { namespace locale { #if BOOST_LOCALE_ICU_VERSION >= 5502 UErrorCode err = U_ZERO_ERROR; BOOST_LOCALE_START_CONST_CONDITION - if(sizeof(CharType) == 2 || (sizeof(CharType) == 1 && util::normalize_encoding(encoding) == "utf8")) { + if(sizeof(CharType) == 2 || util::is_char8_t<CharType>::value + || (sizeof(CharType) == 1 && util::normalize_encoding(encoding) == "utf8")) + { UText ut_stack = UTEXT_INITIALIZER; std::unique_ptr<UText> ut; if(sizeof(CharType) == 1) @@ -176,7 +178,7 @@ namespace boost { namespace locale { template<typename CharType> class boundary_indexing_impl : public boundary_indexing<CharType> { public: - boundary_indexing_impl(const cdata& data) : locale_(data.locale), encoding_(data.encoding) {} + boundary_indexing_impl(const cdata& data) : locale_(data.locale()), encoding_(data.encoding()) {} index_type map(boundary_type t, const CharType* begin, const CharType* end) const { return do_map<CharType>(t, begin, end, locale_, encoding_); @@ -197,6 +199,9 @@ namespace boost { namespace locale { case char_facet_t::nochar: break; case char_facet_t::char_f: return std::locale(in, new boundary_indexing_impl<char>(cd)); case char_facet_t::wchar_f: return std::locale(in, new boundary_indexing_impl<wchar_t>(cd)); +#ifdef __cpp_char8_t + case char_facet_t::char8_f: return std::locale(in, new boundary_indexing_impl<char8_t>(cd)); +#endif #ifdef BOOST_LOCALE_ENABLE_CHAR16_T case char_facet_t::char16_f: return std::locale(in, new boundary_indexing_impl<char16_t>(cd)); #endif diff --git a/contrib/restricted/boost/locale/src/boost/locale/icu/cdata.hpp b/contrib/restricted/boost/locale/src/boost/locale/icu/cdata.hpp index 851a265b5a..37ce36888e 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/icu/cdata.hpp +++ b/contrib/restricted/boost/locale/src/boost/locale/icu/cdata.hpp @@ -8,14 +8,25 @@ #define BOOST_LOCALE_ICU_CDATA_HPP #include <boost/locale/config.hpp> +#include <boost/locale/util/locale_data.hpp> #include <string> #include <unicode/locid.h> namespace boost { namespace locale { namespace impl_icu { - struct cdata { - icu::Locale locale; - std::string encoding; - bool utf8; + class cdata : util::locale_data { + icu::Locale locale_; + + public: + cdata() = default; + void set(const std::string& id) + { + parse(id); + locale_ = icu::Locale::createCanonical(id.c_str()); + } + const util::locale_data& data() { return *this; } + const icu::Locale& locale() const { return locale_; } + using locale_data::encoding; + using locale_data::is_utf8; }; }}} // namespace boost::locale::impl_icu diff --git a/contrib/restricted/boost/locale/src/boost/locale/icu/codecvt.cpp b/contrib/restricted/boost/locale/src/boost/locale/icu/codecvt.cpp index 9e7de6db21..cdf958ab58 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/icu/codecvt.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/icu/codecvt.cpp @@ -95,13 +95,7 @@ namespace boost { namespace locale { namespace impl_icu { try { return util::create_simple_codecvt(in, encoding, type); } catch(const boost::locale::conv::invalid_charset_error&) { - std::unique_ptr<util::base_converter> cvt; - try { - cvt = create_uconv_converter(encoding); - } catch(const std::exception& /*e*/) { - cvt.reset(new util::base_converter()); - } - return util::create_codecvt(in, std::move(cvt), type); + return util::create_codecvt(in, create_uconv_converter(encoding), type); } } diff --git a/contrib/restricted/boost/locale/src/boost/locale/icu/collator.cpp b/contrib/restricted/boost/locale/src/boost/locale/icu/collator.cpp index 8a20950cb7..72ade74fbb 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/icu/collator.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/icu/collator.cpp @@ -11,8 +11,10 @@ #include "boost/locale/icu/icu_util.hpp" #include "boost/locale/icu/uconv.hpp" #include "boost/locale/shared/mo_hash.hpp" +#include "boost/locale/shared/std_collate_adapter.hpp" #include <boost/thread.hpp> #include <limits> +#include <memory> #include <unicode/coll.h> #include <vector> #if BOOST_LOCALE_ICU_VERSION >= 402 @@ -51,7 +53,7 @@ namespace boost { namespace locale { namespace impl_icu { { icu::StringPiece left(b1, e1 - b1); icu::StringPiece right(b2, e2 - b2); - return get_collator(level)->compareUTF8(left, right, status); + return get_collator(level).compareUTF8(left, right, status); } #endif @@ -64,7 +66,7 @@ namespace boost { namespace locale { namespace impl_icu { { icu::UnicodeString left = cvt_.icu(b1, e1); icu::UnicodeString right = cvt_.icu(b2, e2); - return get_collator(level)->compare(left, right, status); + return get_collator(level).compare(left, right, status); } int do_real_compare(collate_level level, @@ -101,11 +103,11 @@ namespace boost { namespace locale { namespace impl_icu { icu::UnicodeString str = cvt_.icu(b, e); std::vector<uint8_t> tmp; tmp.resize(str.length() + 1u); - icu::Collator* collate = get_collator(level); - const int len = collate->getSortKey(str, tmp.data(), tmp.size()); + icu::Collator& collate = get_collator(level); + const int len = collate.getSortKey(str, tmp.data(), tmp.size()); if(len > int(tmp.size())) { tmp.resize(len); - collate->getSortKey(str, tmp.data(), tmp.size()); + collate.getSortKey(str, tmp.data(), tmp.size()); } else tmp.resize(len); return tmp; @@ -124,9 +126,9 @@ namespace boost { namespace locale { namespace impl_icu { return gnu_gettext::pj_winberger_hash_function(reinterpret_cast<char*>(tmp.data())); } - collate_impl(const cdata& d) : cvt_(d.encoding), locale_(d.locale), is_utf8_(d.utf8) {} + collate_impl(const cdata& d) : cvt_(d.encoding()), locale_(d.locale()), is_utf8_(d.is_utf8()) {} - icu::Collator* get_collator(collate_level level) const + icu::Collator& get_collator(collate_level level) const { const int lvl_idx = level_to_int(level); constexpr icu::Collator::ECollationStrength levels[level_count] = {icu::Collator::PRIMARY, @@ -136,18 +138,17 @@ namespace boost { namespace locale { namespace impl_icu { icu::Collator::IDENTICAL}; icu::Collator* col = collates_[lvl_idx].get(); - if(col) - return col; - - UErrorCode status = U_ZERO_ERROR; - - collates_[lvl_idx].reset(icu::Collator::createInstance(locale_, status)); - - if(U_FAILURE(status)) - throw std::runtime_error(std::string("Creation of collate failed:") + u_errorName(status)); - - collates_[lvl_idx]->setStrength(levels[lvl_idx]); - return collates_[lvl_idx].get(); + if(!col) { + UErrorCode status = U_ZERO_ERROR; + std::unique_ptr<icu::Collator> tmp_col(icu::Collator::createInstance(locale_, status)); + if(U_FAILURE(status)) + throw std::runtime_error(std::string("Creation of collate failed:") + u_errorName(status)); + + tmp_col->setStrength(levels[lvl_idx]); + col = tmp_col.release(); + collates_[lvl_idx].reset(col); + } + return *col; } private: @@ -173,18 +174,21 @@ namespace boost { namespace locale { namespace impl_icu { return do_ustring_compare(level, b1, e1, b2, e2, status); } #endif - std::locale create_collate(const std::locale& in, const cdata& cd, char_facet_t type) { switch(type) { case char_facet_t::nochar: break; - case char_facet_t::char_f: return std::locale(in, new collate_impl<char>(cd)); - case char_facet_t::wchar_f: return std::locale(in, new collate_impl<wchar_t>(cd)); + case char_facet_t::char_f: return impl::create_collators<char, collate_impl>(in, cd); + case char_facet_t::wchar_f: return impl::create_collators<wchar_t, collate_impl>(in, cd); +#ifdef __cpp_char8_t + case char_facet_t::char8_f: + return std::locale(in, new collate_impl<char8_t>(cd)); // std-facet not available (yet) +#endif #ifdef BOOST_LOCALE_ENABLE_CHAR16_T - case char_facet_t::char16_f: return std::locale(in, new collate_impl<char16_t>(cd)); + case char_facet_t::char16_f: return impl::create_collators<char16_t, collate_impl>(in, cd); #endif #ifdef BOOST_LOCALE_ENABLE_CHAR32_T - case char_facet_t::char32_f: return std::locale(in, new collate_impl<char32_t>(cd)); + case char_facet_t::char32_f: return impl::create_collators<char32_t, collate_impl>(in, cd); #endif } return in; diff --git a/contrib/restricted/boost/locale/src/boost/locale/icu/conversion.cpp b/contrib/restricted/boost/locale/src/boost/locale/icu/conversion.cpp index 9f45db5cc1..c619dd94a1 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/icu/conversion.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/icu/conversion.cpp @@ -1,5 +1,6 @@ // // Copyright (c) 2009-2011 Artyom Beilis (Tonkikh) +// Copyright (c) 2022-2023 Alexander Grund // // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt @@ -46,7 +47,7 @@ namespace boost { namespace locale { namespace impl_icu { public: typedef std::basic_string<CharType> string_type; - converter_impl(const cdata& d) : locale_(d.locale), encoding_(d.encoding) {} + converter_impl(const cdata& d) : locale_(d.locale()), encoding_(d.encoding()) {} string_type convert(converter_base::conversion_type how, const CharType* begin, @@ -55,12 +56,13 @@ namespace boost { namespace locale { namespace impl_icu { { icu_std_converter<CharType> cvt(encoding_); icu::UnicodeString str = cvt.icu(begin, end); + using conversion_type = converter_base::conversion_type; switch(how) { - case converter_base::normalization: normalize_string(str, flags); break; - case converter_base::upper_case: str.toUpper(locale_); break; - case converter_base::lower_case: str.toLower(locale_); break; - case converter_base::title_case: str.toTitle(nullptr, locale_); break; - case converter_base::case_folding: str.foldCase(); break; + case conversion_type::normalization: normalize_string(str, flags); break; + case conversion_type::upper_case: str.toUpper(locale_); break; + case conversion_type::lower_case: str.toLower(locale_); break; + case conversion_type::title_case: str.toTitle(nullptr, locale_); break; + case conversion_type::case_folding: str.foldCase(); break; } return cvt.std(str); } @@ -79,8 +81,21 @@ namespace boost { namespace locale { namespace impl_icu { using type = TSize; }; + template<typename Func> + struct is_casemap_func_const; + + template<typename Func> + struct is_casemap_func_const<Func*> : is_casemap_func_const<Func> {}; + + template<typename TRes, typename TCaseMap, typename... TArgs> + struct is_casemap_func_const<TRes(TCaseMap*, TArgs...)> : std::is_const<TCaseMap> {}; + + template<typename U8Char> class raii_casemap { public: + static_assert(sizeof(U8Char) == sizeof(char), "Not an UTF-8 char type"); + using string_type = std::basic_string<U8Char>; + raii_casemap(const raii_casemap&) = delete; void operator=(const raii_casemap&) = delete; @@ -90,73 +105,92 @@ namespace boost { namespace locale { namespace impl_icu { map_ = ucasemap_open(locale_id.c_str(), 0, &err); check_and_throw_icu_error(err); if(!map_) - throw std::runtime_error("Failed to create UCaseMap"); + throw std::runtime_error("Failed to create UCaseMap"); // LCOV_EXCL_LINE + } + ~raii_casemap() { ucasemap_close(map_); } + + template<typename Conv> + typename std::enable_if<!is_casemap_func_const<Conv>::value, string_type>::type + convert(Conv func, const U8Char* begin, const U8Char* end) + { + return do_convert(func, begin, end); + } + template<typename Conv> + typename std::enable_if<is_casemap_func_const<Conv>::value, string_type>::type + convert(Conv func, const U8Char* begin, const U8Char* end) const + { + return do_convert(func, begin, end); } + + private: template<typename Conv> - std::string convert(Conv func, const char* begin, const char* end) const + string_type do_convert(Conv func, const U8Char* begin, const U8Char* end) const { using size_type = typename get_casemap_size_type<Conv>::type; if((end - begin) >= std::numeric_limits<std::ptrdiff_t>::max() / 11) - throw std::range_error("String to long to be converted by ICU"); + throw std::range_error("String to long to be converted by ICU"); // LCOV_EXCL_LINE const auto max_converted_size = (end - begin) * 11 / 10 + 1; if(max_converted_size >= std::numeric_limits<size_type>::max()) - throw std::range_error("String to long to be converted by ICU"); - std::vector<char> buf(max_converted_size); + throw std::range_error("String to long to be converted by ICU"); // LCOV_EXCL_LINE + std::vector<U8Char> buf(max_converted_size); UErrorCode err = U_ZERO_ERROR; auto size = func(map_, - buf.data(), + reinterpret_cast<char*>(buf.data()), static_cast<size_type>(buf.size()), - begin, + reinterpret_cast<const char*>(begin), static_cast<size_type>(end - begin), &err); if(err == U_BUFFER_OVERFLOW_ERROR) { err = U_ZERO_ERROR; buf.resize(size + 1); size = func(map_, - buf.data(), + reinterpret_cast<char*>(buf.data()), static_cast<size_type>(buf.size()), - begin, + reinterpret_cast<const char*>(begin), static_cast<size_type>(end - begin), &err); } check_and_throw_icu_error(err); - return std::string(buf.data(), size); + return string_type(buf.data(), size); } - ~raii_casemap() { ucasemap_close(map_); } private: UCaseMap* map_; }; - class utf8_converter_impl : public converter<char> { + template<typename U8Char> + class utf8_converter_impl : public converter<U8Char> { public: - utf8_converter_impl(const cdata& d) : locale_id_(d.locale.getName()), map_(locale_id_) {} + static_assert(sizeof(U8Char) == sizeof(char), "Not an UTF-8 char type"); + utf8_converter_impl(const cdata& d) : locale_id_(d.locale().getName()), map_(locale_id_) {} - std::string - convert(converter_base::conversion_type how, const char* begin, const char* end, int flags = 0) const override + std::basic_string<U8Char> convert(converter_base::conversion_type how, + const U8Char* begin, + const U8Char* end, + int flags = 0) const override { 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: { // Non-const method, so need to create a separate map - raii_casemap map(locale_id_); + raii_casemap<U8Char> 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<char> cvt("UTF-8"); + icu_std_converter<U8Char> cvt("UTF-8"); icu::UnicodeString str = cvt.icu(begin, end); normalize_string(str, flags); return cvt.std(str); } } - return std::string(begin, end - begin); + return std::basic_string<U8Char>(begin, end - begin); // LCOV_EXCL_LINE } private: std::string locale_id_; - raii_casemap map_; + raii_casemap<U8Char> map_; }; // converter_impl #endif // BOOST_LOCALE_WITH_CASEMAP @@ -167,11 +201,21 @@ namespace boost { namespace locale { namespace impl_icu { case char_facet_t::nochar: break; case char_facet_t::char_f: #ifdef BOOST_LOCALE_WITH_CASEMAP - if(cd.utf8) - return std::locale(in, new utf8_converter_impl(cd)); + if(cd.is_utf8()) + return std::locale(in, new utf8_converter_impl<char>(cd)); #endif return std::locale(in, new converter_impl<char>(cd)); case char_facet_t::wchar_f: return std::locale(in, new converter_impl<wchar_t>(cd)); +#ifndef BOOST_LOCALE_NO_CXX20_STRING8 + case char_facet_t::char8_f: +# if defined(BOOST_LOCALE_WITH_CASEMAP) + return std::locale(in, new utf8_converter_impl<char8_t>(cd)); +# else + return std::locale(in, new converter_impl<char8_t>(cd)); +# endif +#elif defined(__cpp_char8_t) + case char_facet_t::char8_f: break; +#endif #ifdef BOOST_LOCALE_ENABLE_CHAR16_T case char_facet_t::char16_f: return std::locale(in, new converter_impl<char16_t>(cd)); #endif diff --git a/contrib/restricted/boost/locale/src/boost/locale/icu/date_time.cpp b/contrib/restricted/boost/locale/src/boost/locale/icu/date_time.cpp index c488390ad9..14e21d9f15 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/icu/date_time.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/icu/date_time.cpp @@ -62,13 +62,16 @@ namespace boost { namespace locale { namespace impl_icu { calendar_impl(const cdata& dat) { UErrorCode err = U_ZERO_ERROR; - calendar_.reset(icu::Calendar::createInstance(dat.locale, err)); + calendar_.reset(icu::Calendar::createInstance(dat.locale(), err)); + // Use accuracy of seconds, see #221 + const double rounded_time = std::floor(calendar_->getTime(err) / U_MILLIS_PER_SECOND) * U_MILLIS_PER_SECOND; + calendar_->setTime(rounded_time, err); check_and_throw_dt(err); #if BOOST_LOCALE_ICU_VERSION < 402 // workaround old/invalid data, it should be 4 in general calendar_->setMinimalDaysInFirstWeek(4); #endif - encoding_ = dat.encoding; + encoding_ = dat.encoding(); } calendar_impl(const calendar_impl& other) { @@ -110,13 +113,6 @@ namespace boost { namespace locale { namespace impl_icu { return v; } - void set_time(const posix_time& p) override - { - double utime = p.seconds * 1000.0 + p.nanoseconds / 1000000.0; - UErrorCode code = U_ZERO_ERROR; - calendar_->setTime(utime, code); - check_and_throw_dt(code); - } void normalize() override { // Can't call complete() explicitly (protected) @@ -125,6 +121,17 @@ namespace boost { namespace locale { namespace impl_icu { calendar_->get(UCAL_YEAR, code); check_and_throw_dt(code); } + + void set_time(const posix_time& p) override + { + // Ignore `p.nanoseconds / 1e6` for simplicity of users as there is no + // easy way to set the sub-seconds via `date_time`. + // Matches behavior of other backends that only have seconds resolution + const double utime = p.seconds * 1e3; + UErrorCode code = U_ZERO_ERROR; + calendar_->setTime(utime, code); + check_and_throw_dt(code); + } posix_time get_time() const override { const double timeMs = get_time_ms(); @@ -146,6 +153,7 @@ namespace boost { namespace locale { namespace impl_icu { check_and_throw_dt(code); return result; } + void set_option(calendar_option_type opt, int /*v*/) override { switch(opt) { diff --git a/contrib/restricted/boost/locale/src/boost/locale/icu/formatter.cpp b/contrib/restricted/boost/locale/src/boost/locale/icu/formatter.cpp index 89763d39ba..12cb73632e 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/icu/formatter.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/icu/formatter.cpp @@ -448,7 +448,7 @@ namespace boost { namespace locale { namespace impl_icu { } #define BOOST_LOCALE_INSTANTIATE(CHAR) template class formatter<CHAR>; - BOOST_LOCALE_FOREACH_CHAR(BOOST_LOCALE_INSTANTIATE) + BOOST_LOCALE_FOREACH_CHAR_STRING(BOOST_LOCALE_INSTANTIATE) }}} // namespace boost::locale::impl_icu diff --git a/contrib/restricted/boost/locale/src/boost/locale/icu/icu_backend.cpp b/contrib/restricted/boost/locale/src/boost/locale/icu/icu_backend.cpp index e5d5eb78ec..ecb78ae45c 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/icu/icu_backend.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/icu/icu_backend.cpp @@ -9,9 +9,9 @@ #include <boost/locale/gnu_gettext.hpp> #include <boost/locale/localization_backend.hpp> #include <boost/locale/util.hpp> -#include <boost/locale/util/locale_data.hpp> #include "boost/locale/icu/all_generator.hpp" #include "boost/locale/icu/cdata.hpp" +#include "boost/locale/shared/message.hpp" #include "boost/locale/util/make_std_unique.hpp" #include <unicode/ucnv.h> @@ -52,21 +52,13 @@ namespace boost { namespace locale { namespace impl_icu { if(!invalid_) return; invalid_ = false; - real_id_ = locale_id_; - if(real_id_.empty()) { - bool utf8 = !use_ansi_encoding_; - real_id_ = util::get_system_locale(utf8); - } - util::locale_data d; - d.parse(real_id_); + if(locale_id_.empty()) + real_id_ = util::get_system_locale(/*utf8*/ !use_ansi_encoding_); + else + real_id_ = locale_id_; - data_.locale = icu::Locale::createCanonical(real_id_.c_str()); - data_.encoding = d.encoding(); - data_.utf8 = d.is_utf8(); - language_ = d.language(); - country_ = d.country(); - variant_ = d.variant(); + data_.set(real_id_); } std::locale install(const std::locale& base, category_t category, char_facet_t type) override @@ -78,32 +70,9 @@ namespace boost { namespace locale { namespace impl_icu { case category_t::collation: return create_collate(base, data_, type); case category_t::formatting: return create_formatting(base, data_, type); case category_t::parsing: return create_parsing(base, data_, type); - case category_t::codepage: return create_codecvt(base, data_.encoding, type); - case category_t::message: { - gnu_gettext::messages_info minf; - minf.language = language_; - minf.country = country_; - minf.variant = variant_; - minf.encoding = data_.encoding; - minf.domains = gnu_gettext::messages_info::domains_type(domains_.begin(), domains_.end()); - minf.paths = paths_; - switch(type) { - case char_facet_t::nochar: break; - case char_facet_t::char_f: - return std::locale(base, gnu_gettext::create_messages_facet<char>(minf)); - case char_facet_t::wchar_f: - return std::locale(base, gnu_gettext::create_messages_facet<wchar_t>(minf)); -#ifdef BOOST_LOCALE_ENABLE_CHAR16_T - case char_facet_t::char16_f: - return std::locale(base, gnu_gettext::create_messages_facet<char16_t>(minf)); -#endif -#ifdef BOOST_LOCALE_ENABLE_CHAR32_T - case char_facet_t::char32_f: - return std::locale(base, gnu_gettext::create_messages_facet<char32_t>(minf)); -#endif - } - return base; - } + case category_t::codepage: return create_codecvt(base, data_.encoding(), type); + case category_t::message: + return detail::install_message_facet(base, type, data_.data(), domains_, paths_); case category_t::boundary: return create_boundary(base, data_, type); case category_t::calendar: return create_calendar(base, data_); case category_t::information: return util::create_info(base, real_id_); @@ -115,12 +84,8 @@ namespace boost { namespace locale { namespace impl_icu { std::vector<std::string> paths_; std::vector<std::string> domains_; std::string locale_id_; - - cdata data_; - std::string language_; - std::string country_; - std::string variant_; std::string real_id_; + cdata data_; bool invalid_; bool use_ansi_encoding_; }; diff --git a/contrib/restricted/boost/locale/src/boost/locale/icu/numeric.cpp b/contrib/restricted/boost/locale/src/boost/locale/icu/numeric.cpp index 963af7ba5b..d81f55f7ba 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/icu/numeric.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/icu/numeric.cpp @@ -71,7 +71,8 @@ namespace boost { namespace locale { namespace impl_icu { typedef std::basic_string<CharType> string_type; typedef formatter<CharType> formatter_type; - num_format(const cdata& d, size_t refs = 0) : std::num_put<CharType>(refs), loc_(d.locale), enc_(d.encoding) {} + num_format(const cdata& d, size_t refs = 0) : std::num_put<CharType>(refs), loc_(d.locale()), enc_(d.encoding()) + {} protected: iter_type do_put(iter_type out, std::ios_base& ios, CharType fill, long val) const override @@ -148,7 +149,8 @@ namespace boost { namespace locale { namespace impl_icu { template<typename CharType> class num_parse : public std::num_get<CharType> { public: - num_parse(const cdata& d, size_t refs = 0) : std::num_get<CharType>(refs), loc_(d.locale), enc_(d.encoding) {} + num_parse(const cdata& d, size_t refs = 0) : std::num_get<CharType>(refs), loc_(d.locale()), enc_(d.encoding()) + {} protected: typedef typename std::num_get<CharType>::iter_type iter_type; @@ -307,7 +309,7 @@ namespace boost { namespace locale { namespace impl_icu { { std::locale tmp = std::locale(in, new num_format<CharType>(cd)); if(!std::has_facet<formatters_cache>(in)) - tmp = std::locale(tmp, new formatters_cache(cd.locale)); + tmp = std::locale(tmp, new formatters_cache(cd.locale())); return tmp; } @@ -316,7 +318,7 @@ namespace boost { namespace locale { namespace impl_icu { { std::locale tmp = std::locale(in, new num_parse<CharType>(cd)); if(!std::has_facet<formatters_cache>(in)) - tmp = std::locale(tmp, new formatters_cache(cd.locale)); + tmp = std::locale(tmp, new formatters_cache(cd.locale())); return tmp; } @@ -326,6 +328,9 @@ namespace boost { namespace locale { namespace impl_icu { case char_facet_t::nochar: break; case char_facet_t::char_f: return install_formatting_facets<char>(in, cd); case char_facet_t::wchar_f: return install_formatting_facets<wchar_t>(in, cd); +#ifdef __cpp_char8_t + case char_facet_t::char8_f: break; // std-facet not available (yet) +#endif #ifdef BOOST_LOCALE_ENABLE_CHAR16_T case char_facet_t::char16_f: return install_formatting_facets<char16_t>(in, cd); #endif @@ -342,6 +347,9 @@ namespace boost { namespace locale { namespace impl_icu { case char_facet_t::nochar: break; case char_facet_t::char_f: return install_parsing_facets<char>(in, cd); case char_facet_t::wchar_f: return install_parsing_facets<wchar_t>(in, cd); +#ifdef __cpp_char8_t + case char_facet_t::char8_f: break; // std-facet not available (yet) +#endif #ifdef BOOST_LOCALE_ENABLE_CHAR16_T case char_facet_t::char16_f: return install_parsing_facets<char16_t>(in, cd); #endif diff --git a/contrib/restricted/boost/locale/src/boost/locale/icu/uconv.hpp b/contrib/restricted/boost/locale/src/boost/locale/icu/uconv.hpp index 7f3c88b5d2..6563afb627 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/icu/uconv.hpp +++ b/contrib/restricted/boost/locale/src/boost/locale/icu/uconv.hpp @@ -86,9 +86,11 @@ namespace boost { namespace locale { namespace impl_icu { int max_char_size() const { return ucnv_getMaxCharSize(cvt_); } - std::string go(const UChar* buf, int length, int max_size) const + template<typename U8Char = char> + std::basic_string<U8Char> go(const UChar* buf, int length, int max_size) const { - std::string res; + static_assert(sizeof(U8Char) == sizeof(char), "Not an UTF-8 char type"); + std::basic_string<U8Char> res; res.resize(UCNV_GET_MAX_BYTES_FOR_STRING(length, max_size)); char* ptr = reinterpret_cast<char*>(&res[0]); UErrorCode err = U_ZERO_ERROR; @@ -141,7 +143,7 @@ namespace boost { namespace locale { namespace impl_icu { string_type std(const icu::UnicodeString& str) const { - return cvt_.go(str.getBuffer(), str.length(), max_len_); + return cvt_.go<CharType>(str.getBuffer(), str.length(), max_len_); } icu_std_converter(const std::string& charset, cpcvt_type cvt_type = cpcvt_type::skip) : @@ -156,7 +158,9 @@ namespace boost { namespace locale { namespace impl_icu { size_t from_char = 0) const { size_t code_points = str.countChar32(from_u, n); - return cvt_.cut(code_points, begin + from_char, end); + return cvt_.cut(code_points, + reinterpret_cast<const char*>(begin) + from_char, + reinterpret_cast<const char*>(end)); } private: diff --git a/contrib/restricted/boost/locale/src/boost/locale/posix/collate.cpp b/contrib/restricted/boost/locale/src/boost/locale/posix/collate.cpp index e5c46ac248..c9fb0251ff 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/posix/collate.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/posix/collate.cpp @@ -83,6 +83,9 @@ namespace boost { namespace locale { namespace impl_posix { case char_facet_t::nochar: break; case char_facet_t::char_f: return std::locale(in, new collator<char>(std::move(lc))); case char_facet_t::wchar_f: return std::locale(in, new collator<wchar_t>(std::move(lc))); +#ifdef __cpp_char8_t + case char_facet_t::char8_f: break; // std-facet not available (yet) +#endif #ifdef BOOST_LOCALE_ENABLE_CHAR16_T case char_facet_t::char16_f: return std::locale(in, new collator<char16_t>(std::move(lc))); #endif diff --git a/contrib/restricted/boost/locale/src/boost/locale/posix/converter.cpp b/contrib/restricted/boost/locale/src/boost/locale/posix/converter.cpp index f769c7259e..b787a562c5 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/posix/converter.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/posix/converter.cpp @@ -74,37 +74,41 @@ namespace boost { namespace locale { namespace impl_posix { std::shared_ptr<locale_t> lc_; }; - class utf8_converter : public converter<char> { + template<typename U8Char> + class utf8_converter : public converter<U8Char> { public: - utf8_converter(std::shared_ptr<locale_t> lc, size_t refs = 0) : converter<char>(refs), lc_(std::move(lc)) {} - std::string convert(converter_base::conversion_type how, - const char* begin, - const char* end, - int /*flags*/ = 0) const override + static_assert(sizeof(U8Char) == sizeof(char), "Not an UTF-8 char type"); + + utf8_converter(std::shared_ptr<locale_t> lc, size_t refs = 0) : converter<U8Char>(refs), lc_(std::move(lc)) {} + std::basic_string<U8Char> convert(converter_base::conversion_type how, + const U8Char* begin, + const U8Char* end, + int /*flags*/ = 0) const override { + using conversion_type = converter_base::conversion_type; switch(how) { - case upper_case: { + case conversion_type::upper_case: { const std::wstring tmp = conv::utf_to_utf<wchar_t>(begin, end); std::wstring wres; wres.reserve(tmp.size()); for(const wchar_t c : tmp) wres += towupper_l(c, *lc_); - return conv::utf_to_utf<char>(wres); + return conv::utf_to_utf<U8Char>(wres); } - case lower_case: - case case_folding: { + case conversion_type::lower_case: + case conversion_type::case_folding: { const std::wstring tmp = conv::utf_to_utf<wchar_t>(begin, end); std::wstring wres; wres.reserve(tmp.size()); for(const wchar_t c : tmp) wres += towlower_l(c, *lc_); - return conv::utf_to_utf<char>(wres); + return conv::utf_to_utf<U8Char>(wres); } - case normalization: - case title_case: break; + case conversion_type::normalization: + case conversion_type::title_case: break; } - return std::string(begin, end - begin); + return std::basic_string<U8Char>(begin, end - begin); } private: @@ -117,10 +121,15 @@ namespace boost { namespace locale { namespace impl_posix { case char_facet_t::nochar: break; case char_facet_t::char_f: { if(util::normalize_encoding(nl_langinfo_l(CODESET, *lc)) == "utf8") - return std::locale(in, new utf8_converter(std::move(lc))); + return std::locale(in, new utf8_converter<char>(std::move(lc))); return std::locale(in, new std_converter<char>(std::move(lc))); } case char_facet_t::wchar_f: return std::locale(in, new std_converter<wchar_t>(std::move(lc))); +#ifndef BOOST_LOCALE_NO_CXX20_STRING8 + case char_facet_t::char8_f: return std::locale(in, new utf8_converter<char8_t>(std::move(lc))); +#elif defined(__cpp_char8_t) + case char_facet_t::char8_f: break; +#endif #ifdef BOOST_LOCALE_ENABLE_CHAR16_T case char_facet_t::char16_f: return std::locale(in, new std_converter<char16_t>(std::move(lc))); #endif diff --git a/contrib/restricted/boost/locale/src/boost/locale/posix/numeric.cpp b/contrib/restricted/boost/locale/src/boost/locale/posix/numeric.cpp index 031ce81463..a3ee2c4055 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/posix/numeric.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/posix/numeric.cpp @@ -405,6 +405,9 @@ namespace boost { namespace locale { namespace impl_posix { case char_facet_t::nochar: break; case char_facet_t::char_f: return create_formatting_impl<char>(in, std::move(lc)); case char_facet_t::wchar_f: return create_formatting_impl<wchar_t>(in, std::move(lc)); +#ifdef __cpp_char8_t + case char_facet_t::char8_f: break; // std-facet not available (yet) +#endif #ifdef BOOST_LOCALE_ENABLE_CHAR16_T case char_facet_t::char16_f: return create_formatting_impl<char16_t>(in, lc); #endif @@ -421,6 +424,9 @@ namespace boost { namespace locale { namespace impl_posix { case char_facet_t::nochar: break; case char_facet_t::char_f: return create_parsing_impl<char>(in, std::move(lc)); case char_facet_t::wchar_f: return create_parsing_impl<wchar_t>(in, std::move(lc)); +#ifdef __cpp_char8_t + case char_facet_t::char8_f: break; // std-facet not available (yet) +#endif #ifdef BOOST_LOCALE_ENABLE_CHAR16_T case char_facet_t::char16_f: return create_parsing_impl<char16_t>(in, lc); #endif diff --git a/contrib/restricted/boost/locale/src/boost/locale/posix/posix_backend.cpp b/contrib/restricted/boost/locale/src/boost/locale/posix/posix_backend.cpp index 14d864bbf9..020d0c77e0 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/posix/posix_backend.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/posix/posix_backend.cpp @@ -20,6 +20,7 @@ #endif #include "boost/locale/posix/all_generator.hpp" +#include "boost/locale/shared/message.hpp" #include "boost/locale/util/gregorian.hpp" #include "boost/locale/util/make_std_unique.hpp" @@ -62,12 +63,11 @@ namespace boost { namespace locale { namespace impl_posix { { if(!invalid_) return; - invalid_ = false; - lc_.reset(); - real_id_ = locale_id_; - if(real_id_.empty()) - real_id_ = util::get_system_locale(); + real_id_ = locale_id_.empty() ? util::get_system_locale() : locale_id_; + data_.parse(real_id_); + + lc_.reset(); locale_t tmp = newlocale(LC_ALL_MASK, real_id_.c_str(), nullptr); if(!tmp) tmp = newlocale(LC_ALL_MASK, "C", nullptr); @@ -82,6 +82,7 @@ namespace boost { namespace locale { namespace impl_posix { throw; } lc_ = std::shared_ptr<locale_t>(tmp_p, free_locale_by_ptr); + invalid_ = false; } std::locale install(const std::locale& base, category_t category, char_facet_t type) override @@ -94,40 +95,8 @@ namespace boost { namespace locale { namespace impl_posix { case category_t::formatting: return create_formatting(base, lc_, type); case category_t::parsing: return create_parsing(base, lc_, type); case category_t::codepage: return create_codecvt(base, nl_langinfo_l(CODESET, *lc_), type); - case category_t::calendar: { - util::locale_data inf; - inf.parse(real_id_); - return util::install_gregorian_calendar(base, inf.country()); - } - case category_t::message: { - gnu_gettext::messages_info minf; - util::locale_data inf; - inf.parse(real_id_); - minf.language = inf.language(); - minf.country = inf.country(); - minf.variant = inf.variant(); - minf.encoding = inf.encoding(); - std::copy(domains_.begin(), - domains_.end(), - std::back_inserter<gnu_gettext::messages_info::domains_type>(minf.domains)); - minf.paths = paths_; - switch(type) { - case char_facet_t::nochar: break; - case char_facet_t::char_f: - return std::locale(base, gnu_gettext::create_messages_facet<char>(minf)); - case char_facet_t::wchar_f: - return std::locale(base, gnu_gettext::create_messages_facet<wchar_t>(minf)); -#ifdef BOOST_LOCALE_ENABLE_CHAR16_T - case char_facet_t::char16_f: - return std::locale(base, gnu_gettext::create_messages_facet<char16_t>(minf)); -#endif -#ifdef BOOST_LOCALE_ENABLE_CHAR32_T - case char_facet_t::char32_f: - return std::locale(base, gnu_gettext::create_messages_facet<char32_t>(minf)); -#endif - } - return base; - } + case category_t::calendar: return util::install_gregorian_calendar(base, data_.country()); + case category_t::message: return detail::install_message_facet(base, type, data_, domains_, paths_); case category_t::information: return util::create_info(base, real_id_); case category_t::boundary: break; // Not implemented } @@ -139,6 +108,7 @@ namespace boost { namespace locale { namespace impl_posix { std::vector<std::string> domains_; std::string locale_id_; std::string real_id_; + util::locale_data data_; bool invalid_; std::shared_ptr<locale_t> lc_; diff --git a/contrib/restricted/boost/locale/src/boost/locale/shared/date_time.cpp b/contrib/restricted/boost/locale/src/boost/locale/shared/date_time.cpp index 60f96feb7b..c418406d18 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/shared/date_time.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/shared/date_time.cpp @@ -1,9 +1,14 @@ // // Copyright (c) 2009-2011 Artyom Beilis (Tonkikh) +// Copyright (c) 2022-2023 Alexander Grund // // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt +#ifndef NOMINMAX +# define NOMINMAX +#endif + #include <boost/locale/date_time.hpp> #include <boost/locale/formatting.hpp> #include <boost/core/exchange.hpp> @@ -299,22 +304,23 @@ namespace boost { namespace locale { void date_time::time(double v) { + constexpr int64_t ns_in_s = static_cast<int64_t>(1000) * 1000 * 1000; + double seconds; const double fract_seconds = std::modf(v, &seconds); // v = seconds + fract_seconds posix_time ptime; ptime.seconds = static_cast<int64_t>(seconds); - int64_t nano = static_cast<int64_t>(fract_seconds * 1e9); + int64_t nano = static_cast<int64_t>(fract_seconds * ns_in_s); - constexpr int64_t ns_in_s = static_cast<int64_t>(1000) * 1000 * 1000; - if(seconds < 0 && nano != 0) { - assert(nano < 0); // Same sign - seconds -= 1; - nano = ns_in_s + nano; - } - if(nano < 0) - nano = 0; - else if(nano >= ns_in_s) - nano = ns_in_s - 1; + if(nano < 0) { + // Add 1s from seconds to nano to make nano positive + ptime.seconds -= 1; + nano = std::max(int64_t(0), nano + ns_in_s); // std::max to handle rounding issues + } else if(nano >= ns_in_s) // Unlikely rounding issue, when fract_seconds is close to 1. + nano = ns_in_s - 1; // LCOV_EXCL_LINE + + BOOST_ASSERT(nano < ns_in_s); + static_assert(ns_in_s <= std::numeric_limits<uint32_t>::max(), "Insecure cast"); ptime.nanoseconds = static_cast<uint32_t>(nano); impl_->set_time(ptime); } @@ -418,3 +424,5 @@ namespace boost { namespace locale { } // namespace time_zone }} // namespace boost::locale + +// boostinspect:nominmax diff --git a/contrib/restricted/boost/locale/src/boost/locale/shared/formatting.cpp b/contrib/restricted/boost/locale/src/boost/locale/shared/formatting.cpp index 489d1fd5a0..457ba782e9 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/shared/formatting.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/shared/formatting.cpp @@ -7,43 +7,8 @@ #include <boost/locale/date_time.hpp> #include <boost/locale/formatting.hpp> #include "boost/locale/shared/ios_prop.hpp" -#include <algorithm> -#include <typeinfo> namespace boost { namespace locale { - - ios_info::string_set::string_set() : type(nullptr), size(0), ptr(nullptr) {} - ios_info::string_set::~string_set() - { - delete[] ptr; - } - ios_info::string_set::string_set(const string_set& other) - { - if(other.ptr != nullptr) { - ptr = new char[other.size]; - size = other.size; - type = other.type; - memcpy(ptr, other.ptr, size); - } else { - ptr = nullptr; - size = 0; - type = nullptr; - } - } - - void ios_info::string_set::swap(string_set& other) - { - std::swap(type, other.type); - std::swap(size, other.size); - std::swap(ptr, other.ptr); - } - - ios_info::string_set& ios_info::string_set::operator=(string_set other) - { - swap(other); - return *this; - } - ios_info::ios_info() : flags_(0), domain_id_(0), time_zone_(time_zone::global()) {} ios_info::~ios_info() = default; @@ -105,16 +70,6 @@ namespace boost { namespace locale { return time_zone_; } - const ios_info::string_set& ios_info::date_time_pattern_set() const - { - return datetime_; - } - - ios_info::string_set& ios_info::date_time_pattern_set() - { - return datetime_; - } - ios_info& ios_info::get(std::ios_base& ios) { return impl::ios_prop<ios_info>::get(ios); diff --git a/contrib/restricted/boost/locale/src/boost/locale/shared/iconv_codecvt.cpp b/contrib/restricted/boost/locale/src/boost/locale/shared/iconv_codecvt.cpp index d34cb738be..2ed618a0ae 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/shared/iconv_codecvt.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/shared/iconv_codecvt.cpp @@ -42,7 +42,7 @@ namespace boost { namespace locale { insize = 1; outsize = sizeof(obuf); call_iconv(d, nullptr, nullptr, nullptr, nullptr); - size_t res = call_iconv(d, ibuf, &insize, reinterpret_cast<char*>(obuf), &outsize); + const size_t res = call_iconv(d, ibuf, &insize, reinterpret_cast<char*>(obuf), &outsize); // Now if this single byte starts a sequence we add incomplete // to know to ask that we need two bytes, otherwise it may only be illegal @@ -118,15 +118,14 @@ namespace boost { namespace locale { const utf::code_point inbuf[2] = {cp, 0}; size_t insize = sizeof(inbuf); char outseq[3] = {0}; - size_t outsize = 3; + size_t outsize = sizeof(outseq); call_iconv(from_utf_, reinterpret_cast<const char*>(inbuf), &insize, outseq, &outsize); - if(insize != 0 || outsize > 1) + if(insize != 0 || outsize == sizeof(outseq)) return illegal; - const size_t len = 2 - outsize; - const size_t reminder = end - begin; - if(reminder < len) + const size_t len = sizeof(outseq) - outsize - 1; // Skip trailing NULL + if(static_cast<std::ptrdiff_t>(len) > end - begin) return incomplete; for(unsigned i = 0; i < len; i++) *begin++ = outseq[i]; diff --git a/contrib/restricted/boost/locale/src/boost/locale/shared/ids.cpp b/contrib/restricted/boost/locale/src/boost/locale/shared/ids.cpp index 95a64ff19a..819de7f993 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/shared/ids.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/shared/ids.cpp @@ -1,5 +1,6 @@ // // Copyright (c) 2009-2011 Artyom Beilis (Tonkikh) +// Copyright (c) 2024 Alexander Grund // // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt @@ -24,6 +25,7 @@ namespace boost { namespace locale { BOOST_LOCALE_DEFINE_ID(calendar_facet); #define BOOST_LOCALE_INSTANTIATE(CHARTYPE) \ + BOOST_LOCALE_DEFINE_ID(collator<CHARTYPE>); \ BOOST_LOCALE_DEFINE_ID(converter<CHARTYPE>); \ BOOST_LOCALE_DEFINE_ID(message_format<CHARTYPE>); \ BOOST_LOCALE_DEFINE_ID(boundary::boundary_indexing<CHARTYPE>); @@ -48,6 +50,7 @@ namespace boost { namespace locale { void init_by(const std::locale& l) { init_facet<boundary::boundary_indexing<Char>>(l); + init_facet<collator<Char>>(l); init_facet<converter<Char>>(l); init_facet<message_format<Char>>(l); } diff --git a/contrib/restricted/boost/locale/src/boost/locale/shared/message.cpp b/contrib/restricted/boost/locale/src/boost/locale/shared/message.cpp index 75dd905b09..da8b4b934f 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/shared/message.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/shared/message.cpp @@ -20,6 +20,7 @@ #include <boost/locale/encoding.hpp> #include <boost/locale/message.hpp> +#include "boost/locale/shared/message.hpp" #include "boost/locale/shared/mo_hash.hpp" #include "boost/locale/shared/mo_lambda.hpp" #include "boost/locale/util/encoding.hpp" @@ -242,14 +243,26 @@ namespace boost { namespace locale { namespace gnu_gettext { template<> struct mo_file_use_traits<char> { static constexpr bool in_use = true; - typedef char CharType; - using string_view_type = basic_string_view<CharType>; + using string_view_type = basic_string_view<char>; static string_view_type use(const mo_file& mo, const char* context, const char* key) { return mo.find(context, key); } }; +#ifdef __cpp_char8_t + template<> + struct mo_file_use_traits<char8_t> { + static constexpr bool in_use = true; + using string_view_type = basic_string_view<char8_t>; + static string_view_type use(const mo_file& mo, const char8_t* context, const char8_t* key) + { + string_view res = mo.find(reinterpret_cast<const char*>(context), reinterpret_cast<const char*>(key)); + return {reinterpret_cast<const char8_t*>(res.data()), res.size()}; + } + }; +#endif + template<typename CharType> class converter : conv::utf_encoder<CharType> { using encoder = conv::utf_encoder<CharType>; @@ -467,7 +480,7 @@ namespace boost { namespace locale { namespace gnu_gettext { domain_data_type& data, const messages_info::callback_type& callback) { - locale_encoding_ = locale_encoding; + locale_encoding_ = util::is_char8_t<CharType>::value ? "UTF-8" : locale_encoding; key_encoding_ = key_encoding; key_conversion_required_ = @@ -585,6 +598,40 @@ namespace boost { namespace locale { namespace gnu_gettext { #define BOOST_LOCALE_INSTANTIATE(CHARTYPE) \ template BOOST_LOCALE_DECL message_format<CHARTYPE>* create_messages_facet(const messages_info& info); - BOOST_LOCALE_FOREACH_CHAR(BOOST_LOCALE_INSTANTIATE) + BOOST_LOCALE_FOREACH_CHAR_STRING(BOOST_LOCALE_INSTANTIATE) }}} // namespace boost::locale::gnu_gettext + +namespace boost { namespace locale { namespace detail { + std::locale install_message_facet(const std::locale& in, + const char_facet_t type, + const util::locale_data& data, + const std::vector<std::string>& domains, + const std::vector<std::string>& paths) + { + gnu_gettext::messages_info minf; + minf.language = data.language(); + minf.country = data.country(); + minf.variant = data.variant(); + minf.encoding = data.encoding(); + minf.domains = gnu_gettext::messages_info::domains_type(domains.begin(), domains.end()); + minf.paths = paths; + switch(type) { + case char_facet_t::nochar: break; + case char_facet_t::char_f: return std::locale(in, gnu_gettext::create_messages_facet<char>(minf)); + case char_facet_t::wchar_f: return std::locale(in, gnu_gettext::create_messages_facet<wchar_t>(minf)); +#ifndef BOOST_LOCALE_NO_CXX20_STRING8 + case char_facet_t::char8_f: return std::locale(in, gnu_gettext::create_messages_facet<char8_t>(minf)); +#elif defined(__cpp_char8_t) + case char_facet_t::char8_f: break; +#endif +#ifdef BOOST_LOCALE_ENABLE_CHAR16_T + case char_facet_t::char16_f: return std::locale(in, gnu_gettext::create_messages_facet<char16_t>(minf)); +#endif +#ifdef BOOST_LOCALE_ENABLE_CHAR32_T + case char_facet_t::char32_f: return std::locale(in, gnu_gettext::create_messages_facet<char32_t>(minf)); +#endif + } + return in; + } +}}} // namespace boost::locale::detail diff --git a/contrib/restricted/boost/locale/src/boost/locale/shared/message.hpp b/contrib/restricted/boost/locale/src/boost/locale/shared/message.hpp new file mode 100644 index 0000000000..a68cefcab6 --- /dev/null +++ b/contrib/restricted/boost/locale/src/boost/locale/shared/message.hpp @@ -0,0 +1,24 @@ +// +// Copyright (c) 2023 Alexander Grund +// +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_LOCALE_SHARED_MESSAGE_HPP +#define BOOST_LOCALE_SHARED_MESSAGE_HPP + +#include <boost/locale/generator.hpp> +#include <boost/locale/util/locale_data.hpp> +#include <locale> +#include <string> +#include <vector> + +namespace boost { namespace locale { namespace detail { + std::locale install_message_facet(const std::locale& in, + char_facet_t type, + const util::locale_data& data, + const std::vector<std::string>& domains, + const std::vector<std::string>& paths); +}}} // namespace boost::locale::detail + +#endif diff --git a/contrib/restricted/boost/locale/src/boost/locale/shared/mo_lambda.cpp b/contrib/restricted/boost/locale/src/boost/locale/shared/mo_lambda.cpp index a6d2eb6a44..7b37ca91e8 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/shared/mo_lambda.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/shared/mo_lambda.cpp @@ -22,7 +22,7 @@ namespace boost { namespace locale { namespace gnu_gettext { namespace lambda { namespace { // anon template<class TExp, typename... Ts> - expr_ptr make_expr(Ts... ts) + expr_ptr make_expr(Ts&&... ts) { return expr_ptr(new TExp(std::forward<Ts>(ts)...)); } diff --git a/contrib/restricted/boost/locale/src/boost/locale/shared/std_collate_adapter.hpp b/contrib/restricted/boost/locale/src/boost/locale/shared/std_collate_adapter.hpp new file mode 100644 index 0000000000..ee4ff43b8c --- /dev/null +++ b/contrib/restricted/boost/locale/src/boost/locale/shared/std_collate_adapter.hpp @@ -0,0 +1,58 @@ +// +// Copyright (c) 2024 Alexander Grund +// +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_LOCALE_STD_COLLATE_ADAPTER_HPP +#define BOOST_LOCALE_STD_COLLATE_ADAPTER_HPP + +#include <boost/locale/collator.hpp> +#include <locale> +#include <utility> + +namespace boost { namespace locale { namespace impl { + + template<typename CharT, class Base> + class BOOST_SYMBOL_VISIBLE std_collate_adapter : public std::collate<CharT> { + public: + using typename std::collate<CharT>::string_type; + + template<typename... TArgs> + explicit std_collate_adapter(TArgs&&... args) : base_(std::forward<TArgs>(args)...) + {} + + protected: + int do_compare(const CharT* beg1, const CharT* end1, const CharT* beg2, const CharT* end2) const override + { + return base_.compare(collate_level::identical, beg1, end1, beg2, end2); + } + + string_type do_transform(const CharT* beg, const CharT* end) const override + { + return base_.transform(collate_level::identical, beg, end); + } + long do_hash(const CharT* beg, const CharT* end) const override + { + return base_.hash(collate_level::identical, beg, end); + } + Base base_; + }; + + template<typename CharType, class CollatorImpl, typename... TArgs> + static std::locale create_collators(const std::locale& in, TArgs&&... args) + { + static_assert(std::is_base_of<collator<CharType>, CollatorImpl>::value, "Must be a collator implementation"); + std::locale res(in, new CollatorImpl(args...)); + return std::locale(res, new std_collate_adapter<CharType, CollatorImpl>(args...)); + } + + template<typename CharType, template<typename> class CollatorImpl, typename... TArgs> + static std::locale create_collators(const std::locale& in, TArgs&&... args) + { + return create_collators<CharType, CollatorImpl<CharType>>(in, args...); + } + +}}} // namespace boost::locale::impl + +#endif diff --git a/contrib/restricted/boost/locale/src/boost/locale/std/codecvt.cpp b/contrib/restricted/boost/locale/src/boost/locale/std/codecvt.cpp index 95a5171fe3..22af5d7639 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/std/codecvt.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/std/codecvt.cpp @@ -32,6 +32,9 @@ namespace boost { namespace locale { namespace impl_std { case char_facet_t::nochar: break; case char_facet_t::char_f: return codecvt_bychar<char>(in, locale_name); case char_facet_t::wchar_f: return codecvt_bychar<wchar_t>(in, locale_name); +#ifdef __cpp_char8_t + case char_facet_t::char8_f: break; // std-facet not available (yet) +#endif #if defined(BOOST_LOCALE_ENABLE_CHAR16_T) case char_facet_t::char16_f: return codecvt_bychar<char16_t>(in, locale_name); #endif diff --git a/contrib/restricted/boost/locale/src/boost/locale/std/collate.cpp b/contrib/restricted/boost/locale/src/boost/locale/std/collate.cpp index ee249bfa5f..48d80bcc97 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/std/collate.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/std/collate.cpp @@ -90,10 +90,12 @@ namespace boost { namespace locale { namespace impl_std { case char_facet_t::wchar_f: return std::locale(in, new std::collate_byname<wchar_t>(locale_name)); +#ifdef __cpp_char8_t + case char_facet_t::char8_f: break; // std-facet not available (yet) +#endif #ifdef BOOST_LOCALE_ENABLE_CHAR16_T case char_facet_t::char16_f: return std::locale(in, new std::collate_byname<char16_t>(locale_name)); #endif - #ifdef BOOST_LOCALE_ENABLE_CHAR32_T case char_facet_t::char32_f: return std::locale(in, new std::collate_byname<char32_t>(locale_name)); #endif diff --git a/contrib/restricted/boost/locale/src/boost/locale/std/converter.cpp b/contrib/restricted/boost/locale/src/boost/locale/std/converter.cpp index 477c76f657..ce08606b06 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/std/converter.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/std/converter.cpp @@ -54,35 +54,39 @@ namespace boost { namespace locale { namespace impl_std { std::locale base_; }; - class utf8_converter : public converter<char> { + template<typename U8Char> + class utf8_converter : public converter<U8Char> { public: + typedef std::basic_string<U8Char> string_type; typedef std::ctype<wchar_t> wctype_type; + utf8_converter(const std::string& locale_name) : base_(std::locale::classic(), new std::ctype_byname<wchar_t>(locale_name)) {} - std::string convert(converter_base::conversion_type how, - const char* begin, - const char* end, + string_type convert(converter_base::conversion_type how, + const U8Char* begin, + const U8Char* end, int /*flags*/ = 0) const override { + using conversion_type = converter_base::conversion_type; switch(how) { - case upper_case: - case lower_case: - case case_folding: { + case conversion_type::upper_case: + case conversion_type::lower_case: + case conversion_type::case_folding: { std::wstring tmp = conv::utf_to_utf<wchar_t>(begin, end); const wctype_type& ct = std::use_facet<wctype_type>(base_); wchar_t* lbegin = &tmp.front(); const size_t len = tmp.size(); - if(how == upper_case) + if(how == conversion_type::upper_case) ct.toupper(lbegin, lbegin + len); else ct.tolower(lbegin, lbegin + len); - return conv::utf_to_utf<char>(lbegin, lbegin + len); + return conv::utf_to_utf<U8Char>(lbegin, lbegin + len); } - case title_case: - case normalization: break; + case conversion_type::title_case: + case conversion_type::normalization: break; } - return std::string(begin, end - begin); + return string_type(begin, end - begin); } private: @@ -96,10 +100,15 @@ namespace boost { namespace locale { namespace impl_std { case char_facet_t::nochar: break; case char_facet_t::char_f: if(utf != utf8_support::none) - return std::locale(in, new utf8_converter(locale_name)); + return std::locale(in, new utf8_converter<char>(locale_name)); else return std::locale(in, new std_converter<char>(locale_name)); case char_facet_t::wchar_f: return std::locale(in, new std_converter<wchar_t>(locale_name)); +#ifndef BOOST_LOCALE_NO_CXX20_STRING8 + case char_facet_t::char8_f: return std::locale(in, new utf8_converter<char8_t>(locale_name)); +#elif defined(__cpp_char8_t) + case char_facet_t::char8_f: break; +#endif #ifdef BOOST_LOCALE_ENABLE_CHAR16_T case char_facet_t::char16_f: return std::locale(in, new std_converter<char16_t>(locale_name)); #endif diff --git a/contrib/restricted/boost/locale/src/boost/locale/std/numeric.cpp b/contrib/restricted/boost/locale/src/boost/locale/std/numeric.cpp index d8c7d5aff8..fe3dc09515 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/std/numeric.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/std/numeric.cpp @@ -274,6 +274,9 @@ namespace boost { namespace locale { namespace impl_std { } else return create_basic_formatting<char>(in, locale_name); case char_facet_t::wchar_f: return create_basic_formatting<wchar_t>(in, locale_name); +#ifdef __cpp_char8_t + case char_facet_t::char8_f: break; // std-facet not available (yet) +#endif #ifdef BOOST_LOCALE_ENABLE_CHAR16_T case char_facet_t::char16_f: return create_basic_formatting<char16_t>(in, locale_name); #endif @@ -300,6 +303,9 @@ namespace boost { namespace locale { namespace impl_std { } else return create_basic_parsing<char>(in, locale_name); case char_facet_t::wchar_f: return create_basic_parsing<wchar_t>(in, locale_name); +#ifdef __cpp_char8_t + case char_facet_t::char8_f: break; // std-facet not available (yet) +#endif #ifdef BOOST_LOCALE_ENABLE_CHAR16_T case char_facet_t::char16_f: return create_basic_parsing<char16_t>(in, locale_name); #endif diff --git a/contrib/restricted/boost/locale/src/boost/locale/std/std_backend.cpp b/contrib/restricted/boost/locale/src/boost/locale/std/std_backend.cpp index 7b70e8a9f8..4a134c2584 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/std/std_backend.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/std/std_backend.cpp @@ -23,6 +23,7 @@ # include "boost/locale/win32/lcid.hpp" # include <windows.h> #endif +#include "boost/locale/shared/message.hpp" #include "boost/locale/std/all_generator.hpp" #include "boost/locale/util/encoding.hpp" #include "boost/locale/util/gregorian.hpp" @@ -177,33 +178,7 @@ namespace boost { namespace locale { namespace impl_std { case category_t::parsing: return create_parsing(base, name_, type, utf_mode_); case category_t::codepage: return create_codecvt(base, name_, type, utf_mode_); case category_t::calendar: return util::install_gregorian_calendar(base, data_.country()); - case category_t::message: { - gnu_gettext::messages_info minf; - minf.language = data_.language(); - minf.country = data_.country(); - minf.variant = data_.variant(); - minf.encoding = data_.encoding(); - std::copy(domains_.begin(), - domains_.end(), - std::back_inserter<gnu_gettext::messages_info::domains_type>(minf.domains)); - minf.paths = paths_; - switch(type) { - case char_facet_t::nochar: break; - case char_facet_t::char_f: - return std::locale(base, gnu_gettext::create_messages_facet<char>(minf)); - case char_facet_t::wchar_f: - return std::locale(base, gnu_gettext::create_messages_facet<wchar_t>(minf)); -#ifdef BOOST_LOCALE_ENABLE_CHAR16_T - case char_facet_t::char16_f: - return std::locale(base, gnu_gettext::create_messages_facet<char16_t>(minf)); -#endif -#ifdef BOOST_LOCALE_ENABLE_CHAR32_T - case char_facet_t::char32_f: - return std::locale(base, gnu_gettext::create_messages_facet<char32_t>(minf)); -#endif - } - return base; - } + case category_t::message: return detail::install_message_facet(base, type, data_, domains_, paths_); case category_t::information: return util::create_info(base, in_use_id_); case category_t::boundary: break; // Not implemented } diff --git a/contrib/restricted/boost/locale/src/boost/locale/util/codecvt_converter.cpp b/contrib/restricted/boost/locale/src/boost/locale/util/codecvt_converter.cpp index 7ad9846d23..b1cf9df9a9 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/util/codecvt_converter.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/util/codecvt_converter.cpp @@ -275,6 +275,9 @@ namespace boost { namespace locale { namespace util { case char_facet_t::nochar: break; case char_facet_t::char_f: return do_create_codecvt<char>(in, std::move(cvt)); case char_facet_t::wchar_f: return do_create_codecvt<wchar_t>(in, std::move(cvt)); +#ifdef __cpp_char8_t + case char_facet_t::char8_f: break; // No std facet +#endif #ifdef BOOST_LOCALE_ENABLE_CHAR16_T case char_facet_t::char16_f: return do_create_codecvt<char16_t>(in, std::move(cvt)); #endif @@ -293,6 +296,9 @@ namespace boost { namespace locale { namespace util { case char_facet_t::nochar: break; case char_facet_t::char_f: return std::locale(in, new utf8_codecvt<char>()); case char_facet_t::wchar_f: return std::locale(in, new utf8_codecvt<wchar_t>()); +#ifdef __cpp_char8_t + case char_facet_t::char8_f: break; // No std facet +#endif #ifdef BOOST_LOCALE_ENABLE_CHAR16_T case char_facet_t::char16_f: return std::locale(in, new utf8_codecvt<char16_t>()); #endif @@ -312,6 +318,9 @@ namespace boost { namespace locale { namespace util { case char_facet_t::nochar: break; case char_facet_t::char_f: return std::locale(in, new simple_codecvt<char>(encoding)); case char_facet_t::wchar_f: return std::locale(in, new simple_codecvt<wchar_t>(encoding)); +#ifdef __cpp_char8_t + case char_facet_t::char8_f: break; // No std facet +#endif #ifdef BOOST_LOCALE_ENABLE_CHAR16_T case char_facet_t::char16_f: return std::locale(in, new simple_codecvt<char16_t>(encoding)); #endif diff --git a/contrib/restricted/boost/locale/src/boost/locale/util/encoding.hpp b/contrib/restricted/boost/locale/src/boost/locale/util/encoding.hpp index 7f2f6a8cd8..0f4c3b56e5 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/util/encoding.hpp +++ b/contrib/restricted/boost/locale/src/boost/locale/util/encoding.hpp @@ -12,6 +12,7 @@ #include <boost/utility/string_view.hpp> #include <cstdint> #include <string> +#include <type_traits> #include <vector> namespace boost { namespace locale { namespace util { @@ -38,6 +39,14 @@ namespace boost { namespace locale { namespace util { BOOST_UNREACHABLE_RETURN("Unknown UTF"); } +#ifdef __cpp_char8_t + template<typename T> + struct is_char8_t : std::is_same<T, char8_t> {}; +#else + template<typename T> + struct is_char8_t : std::false_type {}; +#endif + /// Make encoding lowercase and remove all non-alphanumeric characters BOOST_LOCALE_DECL std::string normalize_encoding(string_view encoding); /// True if the normalized encodings are equal diff --git a/contrib/restricted/boost/locale/src/boost/locale/util/foreach_char.hpp b/contrib/restricted/boost/locale/src/boost/locale/util/foreach_char.hpp index df5857b9d9..37328e1216 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/util/foreach_char.hpp +++ b/contrib/restricted/boost/locale/src/boost/locale/util/foreach_char.hpp @@ -9,6 +9,16 @@ #include <boost/locale/config.hpp> +#ifndef BOOST_LOCALE_NO_CXX20_STRING8 +# define BOOST_LOCALE_FOREACH_CHAR_I_CHAR8_T(F) F(char8_t) +# define BOOST_LOCALE_FOREACH_CHAR_I2_CHAR8_T(F) F(char8_t) +#elif defined(__cpp_char8_t) +# define BOOST_LOCALE_FOREACH_CHAR_I_CHAR8_T(F) F(char8_t) +# define BOOST_LOCALE_FOREACH_CHAR_I2_CHAR8_T(F) +#else +# define BOOST_LOCALE_FOREACH_CHAR_I_CHAR8_T(F) +# define BOOST_LOCALE_FOREACH_CHAR_I2_CHAR8_T(F) +#endif #ifdef BOOST_LOCALE_ENABLE_CHAR16_T # define BOOST_LOCALE_FOREACH_CHAR_I_CHAR16_T(F) F(char16_t) #else @@ -23,6 +33,15 @@ #define BOOST_LOCALE_FOREACH_CHAR(F) \ F(char) \ F(wchar_t) \ + BOOST_LOCALE_FOREACH_CHAR_I_CHAR8_T(F) \ + BOOST_LOCALE_FOREACH_CHAR_I_CHAR16_T(F) \ + BOOST_LOCALE_FOREACH_CHAR_I_CHAR32_T(F) + +// Same but only where std::basic_string<C> is available +#define BOOST_LOCALE_FOREACH_CHAR_STRING(F) \ + F(char) \ + F(wchar_t) \ + BOOST_LOCALE_FOREACH_CHAR_I2_CHAR8_T(F) \ BOOST_LOCALE_FOREACH_CHAR_I_CHAR16_T(F) \ BOOST_LOCALE_FOREACH_CHAR_I_CHAR32_T(F) diff --git a/contrib/restricted/boost/locale/src/boost/locale/util/info.cpp b/contrib/restricted/boost/locale/src/boost/locale/util/info.cpp index 65f8167a59..2dcbbee178 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/util/info.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/util/info.cpp @@ -1,5 +1,6 @@ // // Copyright (c) 2009-2011 Artyom Beilis (Tonkikh) +// Copyright (c) 2022-2023 Alexander Grund // // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt @@ -19,7 +20,7 @@ namespace boost { namespace locale { namespace util { class simple_info : public info { public: simple_info(const std::string& name, size_t refs = 0) : info(refs), name_(name) { d.parse(name); } - std::string get_string_property(string_propery v) const override + std::string get_string_property(string_property v) const override { switch(v) { case language_property: return d.language(); @@ -28,7 +29,7 @@ namespace boost { namespace locale { namespace util { case encoding_property: return d.encoding(); case name_property: return name_; } - return ""; + return ""; // LCOV_EXCL_LINE } int get_integer_property(integer_property v) const override @@ -36,7 +37,7 @@ namespace boost { namespace locale { namespace util { switch(v) { case utf8_property: return d.is_utf8(); } - return 0; + return 0; // LCOV_EXCL_LINE } private: diff --git a/contrib/restricted/boost/locale/src/boost/locale/win32/all_generator.hpp b/contrib/restricted/boost/locale/src/boost/locale/win32/all_generator.hpp index ad1984b712..3cf7da94fb 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/win32/all_generator.hpp +++ b/contrib/restricted/boost/locale/src/boost/locale/win32/all_generator.hpp @@ -12,7 +12,7 @@ namespace boost { namespace locale { namespace impl_win { - class winlocale; + struct winlocale; std::locale create_convert(const std::locale& in, const winlocale& lc, char_facet_t type); @@ -22,8 +22,6 @@ namespace boost { namespace locale { namespace impl_win { std::locale create_parsing(const std::locale& in, const winlocale& lc, char_facet_t type); - std::locale create_codecvt(const std::locale& in, char_facet_t type); - }}} // namespace boost::locale::impl_win #endif diff --git a/contrib/restricted/boost/locale/src/boost/locale/win32/api.hpp b/contrib/restricted/boost/locale/src/boost/locale/win32/api.hpp index aeda7ae602..33791ef968 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/win32/api.hpp +++ b/contrib/restricted/boost/locale/src/boost/locale/win32/api.hpp @@ -27,6 +27,7 @@ #include <boost/locale/collator.hpp> #include <boost/locale/conversion.hpp> +#include <boost/assert.hpp> namespace boost { namespace locale { namespace impl_win { @@ -45,18 +46,16 @@ namespace boost { namespace locale { namespace impl_win { case collate_level::quaternary: case collate_level::identical: return 0; } - return 0; + return 0; // LCOV_EXCL_LINE } - class winlocale { - public: - winlocale() : lcid(0) {} + struct winlocale { + explicit winlocale(unsigned locale_id = 0) : lcid(locale_id) {} + explicit winlocale(const std::string& name) { lcid = locale_to_lcid(name); } - winlocale(const std::string& name) { lcid = locale_to_lcid(name); } + bool is_c() const { return lcid == 0; } unsigned lcid; - - bool is_c() const { return lcid == 0; } }; //////////////////////////////////////////////////////////////////////// @@ -87,7 +86,7 @@ namespace boost { namespace locale { namespace impl_win { || GetLocaleInfoW(lcid, LOCALE_SDECIMAL, de, de_size) == 0 || GetLocaleInfoW(lcid, LOCALE_SGROUPING, gr, gr_size) == 0) { - return res; + return res; // LCOV_EXCL_LINE } res.decimal_point = de; res.thousands_sep = th; @@ -118,7 +117,7 @@ namespace boost { namespace locale { namespace impl_win { throw std::length_error("String to long for int type"); int len = LCMapStringW(l.lcid, flags, begin, static_cast<int>(end - begin), 0, 0); if(len == 0) - return res; + return res; // LCOV_EXCL_LINE if(len == std::numeric_limits<int>::max()) throw std::length_error("String to long for int type"); std::vector<wchar_t> buf(len + 1); @@ -149,6 +148,7 @@ namespace boost { namespace locale { namespace impl_win { static_cast<int>(le - lb), rb, static_cast<int>(re - rb)); + BOOST_ASSERT_MSG(result != 0, "CompareStringW failed"); return result - 2; // Subtract 2 to get the meaning of <0, ==0, and >0 } @@ -195,8 +195,7 @@ namespace boost { namespace locale { namespace impl_win { inline std::wstring wcsfold(const wchar_t* begin, const wchar_t* end) { - winlocale l; - l.lcid = 0x0409; // en-US + const winlocale l(0x0409); // en-US return win_map_string_l(LCMAP_LOWERCASE, begin, end, l); } @@ -214,9 +213,9 @@ namespace boost { namespace locale { namespace impl_win { if(end - begin > std::numeric_limits<int>::max()) throw std::length_error("String to long for int type"); - int len = FoldStringW(flags, begin, static_cast<int>(end - begin), 0, 0); + int len = FoldStringW(flags, begin, static_cast<int>(end - begin), nullptr, 0); if(len == 0) - return std::wstring(); + return std::wstring(); // LCOV_EXCL_LINE if(len == std::numeric_limits<int>::max()) throw std::length_error("String to long for int type"); std::vector<wchar_t> v(len + 1); @@ -226,9 +225,7 @@ namespace boost { namespace locale { namespace impl_win { inline std::wstring wcsxfrm_l(collate_level level, const wchar_t* begin, const wchar_t* end, const winlocale& l) { - int flag = LCMAP_SORTKEY | collation_level_to_flag(level); - - return win_map_string_l(flag, begin, end, l); + return win_map_string_l(LCMAP_SORTKEY | collation_level_to_flag(level), begin, end, l); } inline std::wstring towupper_l(const wchar_t* begin, const wchar_t* end, const winlocale& l) diff --git a/contrib/restricted/boost/locale/src/boost/locale/win32/collate.cpp b/contrib/restricted/boost/locale/src/boost/locale/win32/collate.cpp index 465676e437..16fe38d1f8 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/win32/collate.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/win32/collate.cpp @@ -7,33 +7,71 @@ #include <boost/locale/encoding.hpp> #include <boost/locale/generator.hpp> #include "boost/locale/shared/mo_hash.hpp" +#include "boost/locale/shared/std_collate_adapter.hpp" #include "boost/locale/win32/api.hpp" #include <ios> #include <locale> #include <string> +#include <type_traits> namespace boost { namespace locale { namespace impl_win { + template<typename CharT, typename Result> + using enable_if_sizeof_wchar_t = typename std::enable_if<sizeof(CharT) == sizeof(wchar_t), Result>::type; + template<typename CharT, typename Result> + using disable_if_sizeof_wchar_t = typename std::enable_if<sizeof(CharT) != sizeof(wchar_t), Result>::type; - class utf8_collator : public collator<char> { - public: - utf8_collator(winlocale lc, size_t refs = 0) : collator<char>(refs), lc_(lc) {} - int - do_compare(collate_level level, const char* lb, const char* le, const char* rb, const char* re) const override + namespace { + template<typename CharT> + enable_if_sizeof_wchar_t<CharT, int> compare_impl(collate_level level, + const CharT* lb, + const CharT* le, + const CharT* rb, + const CharT* re, + const winlocale& wl) + { + return wcscoll_l(level, + reinterpret_cast<const wchar_t*>(lb), + reinterpret_cast<const wchar_t*>(le), + reinterpret_cast<const wchar_t*>(rb), + reinterpret_cast<const wchar_t*>(re), + wl); + } + + template<typename CharT> + disable_if_sizeof_wchar_t<CharT, int> compare_impl(collate_level level, + const CharT* lb, + const CharT* le, + const CharT* rb, + const CharT* re, + const winlocale& wl) { const std::wstring l = conv::utf_to_utf<wchar_t>(lb, le); const std::wstring r = conv::utf_to_utf<wchar_t>(rb, re); - return wcscoll_l(level, l.c_str(), l.c_str() + l.size(), r.c_str(), r.c_str() + r.size(), lc_); + return wcscoll_l(level, l.c_str(), l.c_str() + l.size(), r.c_str(), r.c_str() + r.size(), wl); } - long do_hash(collate_level level, const char* b, const char* e) const override + + template<typename CharT> + enable_if_sizeof_wchar_t<CharT, std::wstring> + normalize_impl(collate_level level, const CharT* b, const CharT* e, const winlocale& l) { - const std::string key = do_transform(level, b, e); - return gnu_gettext::pj_winberger_hash_function(key.c_str(), key.c_str() + key.size()); + return wcsxfrm_l(level, reinterpret_cast<const wchar_t*>(b), reinterpret_cast<const wchar_t*>(e), l); } - std::string do_transform(collate_level level, const char* b, const char* e) const override + + template<typename CharT> + disable_if_sizeof_wchar_t<CharT, std::wstring> + normalize_impl(collate_level level, const CharT* b, const CharT* e, const winlocale& l) { const std::wstring tmp = conv::utf_to_utf<wchar_t>(b, e); - const std::wstring wkey = wcsxfrm_l(level, tmp.c_str(), tmp.c_str() + tmp.size(), lc_); - std::string key; + return wcsxfrm_l(level, tmp.c_str(), tmp.c_str() + tmp.size(), l); + } + + template<typename CharT> + typename std::enable_if<sizeof(CharT) == 1, std::basic_string<CharT>>::type + transform_impl(collate_level level, const CharT* b, const CharT* e, const winlocale& l) + { + const std::wstring wkey = normalize_impl(level, b, e, l); + + std::basic_string<CharT> key; BOOST_LOCALE_START_CONST_CONDITION if(sizeof(wchar_t) == 2) key.reserve(wkey.size() * 2); @@ -42,46 +80,61 @@ namespace boost { namespace locale { namespace impl_win { for(const wchar_t c : wkey) { if(sizeof(wchar_t) == 2) { const uint16_t tv = static_cast<uint16_t>(c); - key += char(tv >> 8); - key += char(tv & 0xFF); + key += CharT(tv >> 8); + key += CharT(tv & 0xFF); } else { // 4 const uint32_t tv = static_cast<uint32_t>(c); // 21 bit - key += char((tv >> 16) & 0xFF); - key += char((tv >> 8) & 0xFF); - key += char(tv & 0xFF); + key += CharT((tv >> 16) & 0xFF); + key += CharT((tv >> 8) & 0xFF); + key += CharT(tv & 0xFF); } } BOOST_LOCALE_END_CONST_CONDITION return key; } - private: - winlocale lc_; - }; + template<typename CharT> + typename std::enable_if<std::is_same<CharT, wchar_t>::value, std::wstring>::type + transform_impl(collate_level level, const CharT* b, const CharT* e, const winlocale& l) + { + return normalize_impl(level, b, e, l); + } - class utf16_collator : public collator<wchar_t> { + template<typename CharT> + typename std::enable_if<sizeof(CharT) >= sizeof(wchar_t) && !std::is_same<CharT, wchar_t>::value, + std::basic_string<CharT>>::type + transform_impl(collate_level level, const CharT* b, const CharT* e, const winlocale& l) + { + const std::wstring wkey = normalize_impl(level, b, e, l); + return std::basic_string<CharT>(wkey.begin(), wkey.end()); + } + } // namespace + + template<typename CharT> + class utf_collator : public collator<CharT> { public: - typedef std::collate<wchar_t> wfacet; - utf16_collator(winlocale lc, size_t refs = 0) : collator<wchar_t>(refs), lc_(lc) {} + using typename collator<CharT>::string_type; + + explicit utf_collator(winlocale lc) : collator<CharT>(), lc_(lc) {} + int do_compare(collate_level level, - const wchar_t* lb, - const wchar_t* le, - const wchar_t* rb, - const wchar_t* re) const override + const CharT* lb, + const CharT* le, + const CharT* rb, + const CharT* re) const override { - return wcscoll_l(level, lb, le, rb, re, lc_); + return compare_impl(level, lb, le, rb, re, lc_); } - long do_hash(collate_level level, const wchar_t* b, const wchar_t* e) const override + long do_hash(collate_level level, const CharT* b, const CharT* e) const override { - std::wstring key = do_transform(level, b, e); - const char* begin = reinterpret_cast<const char*>(key.c_str()); - const char* end = begin + key.size() * sizeof(wchar_t); - return gnu_gettext::pj_winberger_hash_function(begin, end); + const std::wstring key = normalize_impl(level, b, e, lc_); + return gnu_gettext::pj_winberger_hash_function(reinterpret_cast<const char*>(key.c_str()), + reinterpret_cast<const char*>(key.c_str() + key.size())); } - std::wstring do_transform(collate_level level, const wchar_t* b, const wchar_t* e) const override + string_type do_transform(collate_level level, const CharT* b, const CharT* e) const override { - return wcsxfrm_l(level, b, e, lc_); + return transform_impl(level, b, e, lc_); } private: @@ -95,6 +148,9 @@ namespace boost { namespace locale { namespace impl_win { case char_facet_t::nochar: break; case char_facet_t::char_f: return std::locale(in, new std::collate_byname<char>("C")); case char_facet_t::wchar_f: return std::locale(in, new std::collate_byname<wchar_t>("C")); +#ifdef __cpp_char8_t + case char_facet_t::char8_f: break; // std-facet not available (yet) +#endif #ifdef BOOST_LOCALE_ENABLE_CHAR16_T case char_facet_t::char16_f: return std::locale(in, new collate_byname<char16_t>("C")); #endif @@ -105,13 +161,17 @@ namespace boost { namespace locale { namespace impl_win { } else { switch(type) { case char_facet_t::nochar: break; - case char_facet_t::char_f: return std::locale(in, new utf8_collator(lc)); - case char_facet_t::wchar_f: return std::locale(in, new utf16_collator(lc)); + case char_facet_t::char_f: return impl::create_collators<char, utf_collator<char>>(in, lc); + case char_facet_t::wchar_f: return impl::create_collators<wchar_t, utf_collator<wchar_t>>(in, lc); +#ifdef __cpp_char8_t + case char_facet_t::char8_f: + return std::locale(in, new utf_collator<char8_t>(lc)); // std-facet not available (yet) +#endif #ifdef BOOST_LOCALE_ENABLE_CHAR16_T - case char_facet_t::char16_f: break; + case char_facet_t::char16_f: return impl::create_collators<char16_t, utf_collator<char16_t>>(in, lc); #endif #ifdef BOOST_LOCALE_ENABLE_CHAR32_T - case char_facet_t::char32_f: break; + case char_facet_t::char32_f: return impl::create_collators<char32_t, utf_collator<char32_t>>(in, lc); #endif } } diff --git a/contrib/restricted/boost/locale/src/boost/locale/win32/converter.cpp b/contrib/restricted/boost/locale/src/boost/locale/win32/converter.cpp index ab0af493e4..ed29aedc69 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/win32/converter.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/win32/converter.cpp @@ -15,9 +15,9 @@ namespace boost { namespace locale { namespace impl_win { - class utf16_converter : public converter<wchar_t> { + class wide_converter final : public converter<wchar_t> { public: - utf16_converter(const winlocale& lc, size_t refs = 0) : converter<wchar_t>(refs), lc_(lc) {} + wide_converter(const winlocale& lc, size_t refs = 0) : converter<wchar_t>(refs), lc_(lc) {} std::wstring convert(converter_base::conversion_type how, const wchar_t* begin, const wchar_t* end, @@ -37,38 +37,36 @@ namespace boost { namespace locale { namespace impl_win { winlocale lc_; }; - class utf8_converter : public converter<char> { + template<typename U8Char> + class utf8_converter final : public converter<U8Char> { + static_assert(sizeof(U8Char) == sizeof(char), "Not an UTF-8 char type"); + public: - utf8_converter(const winlocale& lc, size_t refs = 0) : converter<char>(refs), lc_(lc) {} - std::string - convert(converter_base::conversion_type how, const char* begin, const char* end, int flags = 0) const override + utf8_converter(const winlocale& lc, size_t refs = 0) : converter<U8Char>(refs), cvt_(lc) {} + std::basic_string<U8Char> convert(converter_base::conversion_type how, + const U8Char* begin, + const U8Char* end, + int flags = 0) const override { const std::wstring tmp = conv::utf_to_utf<wchar_t>(begin, end); - const wchar_t* wb = tmp.c_str(); - const wchar_t* we = wb + tmp.size(); - - std::wstring res; - - switch(how) { - case upper_case: res = towupper_l(wb, we, lc_); break; - case lower_case: res = towlower_l(wb, we, lc_); break; - case case_folding: res = wcsfold(wb, we); break; - case normalization: res = wcsnormalize(static_cast<norm_type>(flags), wb, we); break; - case title_case: break; - } - return conv::utf_to_utf<char>(res); + return conv::utf_to_utf<U8Char>(cvt_.convert(how, tmp.c_str(), tmp.c_str() + tmp.size(), flags)); } private: - winlocale lc_; + wide_converter cvt_; }; std::locale create_convert(const std::locale& in, const winlocale& lc, char_facet_t type) { switch(type) { case char_facet_t::nochar: break; - case char_facet_t::char_f: return std::locale(in, new utf8_converter(lc)); - case char_facet_t::wchar_f: return std::locale(in, new utf16_converter(lc)); + case char_facet_t::char_f: return std::locale(in, new utf8_converter<char>(lc)); + case char_facet_t::wchar_f: return std::locale(in, new wide_converter(lc)); +#ifndef BOOST_LOCALE_NO_CXX20_STRING8 + case char_facet_t::char8_f: return std::locale(in, new utf8_converter<char8_t>(lc)); +#elif defined(__cpp_char8_t) + case char_facet_t::char8_f: break; +#endif #ifdef BOOST_LOCALE_ENABLE_CHAR16_T case char_facet_t::char16_f: break; #endif diff --git a/contrib/restricted/boost/locale/src/boost/locale/win32/numeric.cpp b/contrib/restricted/boost/locale/src/boost/locale/win32/numeric.cpp index edbb663e78..556de79a85 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/win32/numeric.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/win32/numeric.cpp @@ -175,6 +175,9 @@ namespace boost { namespace locale { namespace impl_win { case char_facet_t::nochar: break; case char_facet_t::char_f: return create_formatting_impl<char>(in, lc); case char_facet_t::wchar_f: return create_formatting_impl<wchar_t>(in, lc); +#ifdef __cpp_char8_t + case char_facet_t::char8_f: break; // std-facet not available (yet) +#endif #ifdef BOOST_LOCALE_ENABLE_CHAR16_T case char_facet_t::char16_f: return create_formatting_impl<char16_t>(in, lc); #endif @@ -191,6 +194,9 @@ namespace boost { namespace locale { namespace impl_win { case char_facet_t::nochar: break; case char_facet_t::char_f: return create_parsing_impl<char>(in, lc); case char_facet_t::wchar_f: return create_parsing_impl<wchar_t>(in, lc); +#ifdef __cpp_char8_t + case char_facet_t::char8_f: break; // std-facet not available (yet) +#endif #ifdef BOOST_LOCALE_ENABLE_CHAR16_T case char_facet_t::char16_f: return create_parsing_impl<char16_t>(in, lc); #endif diff --git a/contrib/restricted/boost/locale/src/boost/locale/win32/win_backend.cpp b/contrib/restricted/boost/locale/src/boost/locale/win32/win_backend.cpp index aa694648d8..48155d6c23 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/win32/win_backend.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/win32/win_backend.cpp @@ -11,6 +11,7 @@ #include <boost/locale/localization_backend.hpp> #include <boost/locale/util.hpp> #include <boost/locale/util/locale_data.hpp> +#include "boost/locale/shared/message.hpp" #include "boost/locale/util/gregorian.hpp" #include "boost/locale/util/make_std_unique.hpp" #include "boost/locale/win32/all_generator.hpp" @@ -57,9 +58,8 @@ namespace boost { namespace locale { namespace impl_win { real_id_ = util::get_system_locale(true); // always UTF-8 else real_id_ = locale_id_; - util::locale_data d; - d.parse(real_id_); - if(!d.is_utf8()) + data_.parse(real_id_); + if(!data_.is_utf8()) lc_ = winlocale(); // Make it C as non-UTF8 locales are not supported else lc_ = winlocale(real_id_); @@ -79,35 +79,7 @@ namespace boost { namespace locale { namespace impl_win { inf.parse(real_id_); return util::install_gregorian_calendar(base, inf.country()); } - case category_t::message: { - gnu_gettext::messages_info minf; - std::locale tmp = util::create_info(std::locale::classic(), real_id_); - const boost::locale::info& inf = std::use_facet<boost::locale::info>(tmp); - minf.language = inf.language(); - minf.country = inf.country(); - minf.variant = inf.variant(); - minf.encoding = inf.encoding(); - std::copy(domains_.begin(), - domains_.end(), - std::back_inserter<gnu_gettext::messages_info::domains_type>(minf.domains)); - minf.paths = paths_; - switch(type) { - case char_facet_t::nochar: break; - case char_facet_t::char_f: - return std::locale(base, gnu_gettext::create_messages_facet<char>(minf)); - case char_facet_t::wchar_f: - return std::locale(base, gnu_gettext::create_messages_facet<wchar_t>(minf)); -#ifdef BOOST_LOCALE_ENABLE_CHAR16_T - case char_facet_t::char16_f: - return std::locale(base, gnu_gettext::create_messages_facet<char16_t>(minf)); -#endif -#ifdef BOOST_LOCALE_ENABLE_CHAR32_T - case char_facet_t::char32_f: - return std::locale(base, gnu_gettext::create_messages_facet<char32_t>(minf)); -#endif - } - return base; - } + case category_t::message: return detail::install_message_facet(base, type, data_, domains_, paths_); case category_t::information: return util::create_info(base, real_id_); case category_t::codepage: return util::create_utf8_codecvt(base, type); case category_t::boundary: break; // Not implemented @@ -120,6 +92,7 @@ namespace boost { namespace locale { namespace impl_win { std::vector<std::string> domains_; std::string locale_id_; std::string real_id_; + util::locale_data data_; bool invalid_; winlocale lc_; diff --git a/contrib/restricted/boost/locale/ya.make b/contrib/restricted/boost/locale/ya.make index 4243abc00d..4625eb30e1 100644 --- a/contrib/restricted/boost/locale/ya.make +++ b/contrib/restricted/boost/locale/ya.make @@ -6,9 +6,9 @@ LICENSE(BSL-1.0) LICENSE_TEXTS(.yandex_meta/licenses.list.txt) -VERSION(1.83.0) +VERSION(1.86.0) -ORIGINAL_SOURCE(https://github.com/boostorg/locale/archive/boost-1.83.0.tar.gz) +ORIGINAL_SOURCE(https://github.com/boostorg/locale/archive/boost-1.86.0.tar.gz) PEERDIR( contrib/libs/icu |