diff options
author | robot-contrib <robot-contrib@yandex-team.com> | 2024-10-27 21:17:12 +0300 |
---|---|---|
committer | robot-contrib <robot-contrib@yandex-team.com> | 2024-10-27 21:29:43 +0300 |
commit | 47d4b17dfee97f26f8495100bf21db6b87f1f2fc (patch) | |
tree | c0c8a30e343639df36a88544d3a4291235dbbf5d | |
parent | 1c41d6078d76a7a377b39d42e99aac3aa034479d (diff) | |
download | ydb-47d4b17dfee97f26f8495100bf21db6b87f1f2fc.tar.gz |
Update contrib/restricted/boost/locale to 1.86.0
commit_hash:f67feab5ae9d126714c39799fa3cc1c08f434ae0
22 files changed, 534 insertions, 252 deletions
diff --git a/contrib/restricted/boost/locale/.yandex_meta/devtools.copyrights.report b/contrib/restricted/boost/locale/.yandex_meta/devtools.copyrights.report index a866314839..b8639e0153 100644 --- a/contrib/restricted/boost/locale/.yandex_meta/devtools.copyrights.report +++ b/contrib/restricted/boost/locale/.yandex_meta/devtools.copyrights.report @@ -56,7 +56,7 @@ 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] @@ -104,7 +104,7 @@ BELONGS ya.make 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] @@ -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,13 +207,13 @@ 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] diff --git a/contrib/restricted/boost/locale/.yandex_meta/devtools.licenses.report b/contrib/restricted/boost/locale/.yandex_meta/devtools.licenses.report index 144f5b1ad7..7173da1354 100644 --- a/contrib/restricted/boost/locale/.yandex_meta/devtools.licenses.report +++ b/contrib/restricted/boost/locale/.yandex_meta/devtools.licenses.report @@ -86,11 +86,12 @@ 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 [6:6] @@ -116,9 +117,10 @@ BELONGS ya.make 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] @@ -159,11 +161,12 @@ 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 [5:5] @@ -189,9 +192,10 @@ BELONGS ya.make 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] @@ -229,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] 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/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/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/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/formatting.hpp b/contrib/restricted/boost/locale/include/boost/locale/formatting.hpp index d14e6f69d1..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 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/icu/collator.cpp b/contrib/restricted/boost/locale/src/boost/locale/icu/collator.cpp index 86f5e51e81..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; @@ -126,7 +128,7 @@ namespace boost { namespace locale { namespace impl_icu { 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,21 +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: break; // std-facet not available (yet) + 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 c9b75b707c..c619dd94a1 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/icu/conversion.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/icu/conversion.cpp @@ -81,10 +81,20 @@ 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; @@ -97,8 +107,24 @@ namespace boost { namespace locale { namespace impl_icu { if(!map_) throw std::runtime_error("Failed to create UCaseMap"); // LCOV_EXCL_LINE } + ~raii_casemap() { ucasemap_close(map_); } + + template<typename 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> - std::basic_string<U8Char> convert(Conv func, const U8Char* begin, const U8Char* end) const + 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> + 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) @@ -125,9 +151,8 @@ namespace boost { namespace locale { namespace impl_icu { &err); } check_and_throw_icu_error(err); - return std::basic_string<U8Char>(buf.data(), size); + return string_type(buf.data(), size); } - ~raii_casemap() { ucasemap_close(map_); } private: UCaseMap* map_; @@ -147,7 +172,11 @@ namespace boost { namespace locale { namespace impl_icu { switch(how) { case converter_base::upper_case: return map_.convert(ucasemap_utf8ToUpper, begin, end); case converter_base::lower_case: return map_.convert(ucasemap_utf8ToLower, begin, end); - case converter_base::title_case: return map_.convert(ucasemap_utf8ToTitle, begin, end); + case converter_base::title_case: { + // Non-const method, so need to create a separate map + raii_casemap<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<U8Char> cvt("UTF-8"); 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 c5cf7ecd2a..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 @@ -63,6 +63,9 @@ namespace boost { namespace locale { namespace impl_icu { { UErrorCode err = U_ZERO_ERROR; 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 @@ -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/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/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/win32/all_generator.hpp b/contrib/restricted/boost/locale/src/boost/locale/win32/all_generator.hpp index c175d5be9a..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); 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 107fed089a..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); + } + + 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 - class utf16_collator : public collator<wchar_t> { + 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: @@ -108,16 +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: break; // std-facet not available (yet) + 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/ya.make b/contrib/restricted/boost/locale/ya.make index 998da594d2..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.84.0) +VERSION(1.86.0) -ORIGINAL_SOURCE(https://github.com/boostorg/locale/archive/boost-1.84.0.tar.gz) +ORIGINAL_SOURCE(https://github.com/boostorg/locale/archive/boost-1.86.0.tar.gz) PEERDIR( contrib/libs/icu |