aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrobot-contrib <robot-contrib@yandex-team.com>2023-08-18 11:52:29 +0300
committerrobot-contrib <robot-contrib@yandex-team.com>2023-08-18 15:18:47 +0300
commitb4f93a19b70aa5276a2ae7e17fc82c37be6c207e (patch)
tree08ddd00d6ab23a377add49eadecc85d7ad5e4e8a
parent8a2b6dd59ef13047ade3ea1bf0827706e42ed699 (diff)
downloadydb-b4f93a19b70aa5276a2ae7e17fc82c37be6c207e.tar.gz
Update contrib/restricted/boost/locale to 1.83.0
-rw-r--r--contrib/restricted/boost/io/include/boost/io/detail/buffer_fill.hpp39
-rw-r--r--contrib/restricted/boost/io/include/boost/io/detail/ostream_guard.hpp45
-rw-r--r--contrib/restricted/boost/io/include/boost/io/ostream_put.hpp50
-rw-r--r--contrib/restricted/boost/locale/CMakeLists.darwin-x86_64.txt1
-rw-r--r--contrib/restricted/boost/locale/CMakeLists.linux-aarch64.txt1
-rw-r--r--contrib/restricted/boost/locale/CMakeLists.linux-x86_64.txt1
-rw-r--r--contrib/restricted/boost/locale/CMakeLists.windows-x86_64.txt1
-rw-r--r--contrib/restricted/boost/locale/README.md6
-rw-r--r--contrib/restricted/boost/locale/include/boost/locale.hpp1
-rw-r--r--contrib/restricted/boost/locale/include/boost/locale/boundary/facets.hpp64
-rw-r--r--contrib/restricted/boost/locale/include/boost/locale/boundary/index.hpp28
-rw-r--r--contrib/restricted/boost/locale/include/boost/locale/boundary/segment.hpp6
-rw-r--r--contrib/restricted/boost/locale/include/boost/locale/boundary/types.hpp2
-rw-r--r--contrib/restricted/boost/locale/include/boost/locale/collator.hpp4
-rw-r--r--contrib/restricted/boost/locale/include/boost/locale/config.hpp10
-rw-r--r--contrib/restricted/boost/locale/include/boost/locale/conversion.hpp98
-rw-r--r--contrib/restricted/boost/locale/include/boost/locale/date_time.hpp33
-rw-r--r--contrib/restricted/boost/locale/include/boost/locale/date_time_facet.hpp13
-rw-r--r--contrib/restricted/boost/locale/include/boost/locale/detail/encoding.hpp58
-rw-r--r--contrib/restricted/boost/locale/include/boost/locale/detail/facet_id.hpp35
-rw-r--r--contrib/restricted/boost/locale/include/boost/locale/detail/is_supported_char.hpp44
-rw-r--r--contrib/restricted/boost/locale/include/boost/locale/encoding.hpp302
-rw-r--r--contrib/restricted/boost/locale/include/boost/locale/encoding_errors.hpp2
-rw-r--r--contrib/restricted/boost/locale/include/boost/locale/encoding_utf.hpp17
-rw-r--r--contrib/restricted/boost/locale/include/boost/locale/format.hpp107
-rw-r--r--contrib/restricted/boost/locale/include/boost/locale/formatting.hpp26
-rw-r--r--contrib/restricted/boost/locale/include/boost/locale/generator.hpp8
-rw-r--r--contrib/restricted/boost/locale/include/boost/locale/generic_codecvt.hpp192
-rw-r--r--contrib/restricted/boost/locale/include/boost/locale/gnu_gettext.hpp48
-rw-r--r--contrib/restricted/boost/locale/include/boost/locale/hold_ptr.hpp5
-rw-r--r--contrib/restricted/boost/locale/include/boost/locale/info.hpp7
-rw-r--r--contrib/restricted/boost/locale/include/boost/locale/localization_backend.hpp26
-rw-r--r--contrib/restricted/boost/locale/include/boost/locale/message.hpp186
-rw-r--r--contrib/restricted/boost/locale/include/boost/locale/utf.hpp30
-rw-r--r--contrib/restricted/boost/locale/include/boost/locale/utf8_codecvt.hpp12
-rw-r--r--contrib/restricted/boost/locale/include/boost/locale/util.hpp26
-rw-r--r--contrib/restricted/boost/locale/include/boost/locale/util/locale_data.hpp18
-rw-r--r--contrib/restricted/boost/locale/include/boost/locale/util/string.hpp13
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/encoding/codepage.cpp282
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/encoding/conv.hpp73
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/encoding/iconv_codepage.ipp175
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/encoding/iconv_converter.hpp145
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/encoding/uconv_converter.hpp (renamed from contrib/restricted/boost/locale/src/boost/locale/encoding/uconv_codepage.ipp)47
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/encoding/wconv_converter.hpp (renamed from contrib/restricted/boost/locale/src/boost/locale/encoding/wconv_codepage.ipp)167
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/icu/boundary.cpp86
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/icu/codecvt.cpp49
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/icu/collator.cpp6
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/icu/conversion.cpp19
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/icu/date_time.cpp35
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/icu/formatter.cpp38
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/icu/formatter.hpp3
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/icu/icu_backend.cpp12
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/icu/icu_backend.hpp3
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/icu/icu_util.hpp4
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/icu/numeric.cpp48
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/icu/time_zone.cpp25
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/icu/time_zone.hpp4
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/icu/uconv.hpp264
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/posix/collate.cpp22
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/posix/converter.cpp43
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/posix/numeric.cpp33
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/posix/posix_backend.cpp24
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/posix/posix_backend.hpp6
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/shared/date_time.cpp40
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/shared/format.cpp47
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/shared/formatting.cpp8
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/shared/generator.cpp31
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/shared/iconv_codecvt.cpp35
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/shared/ids.cpp79
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/shared/localization_backend.cpp172
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/shared/message.cpp570
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/shared/mo_hash.hpp2
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/shared/mo_lambda.cpp472
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/shared/mo_lambda.hpp22
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/std/all_generator.hpp50
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/std/codecvt.cpp11
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/std/collate.cpp82
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/std/converter.cpp61
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/std/numeric.cpp190
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/std/std_backend.cpp155
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/std/std_backend.hpp6
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/util/codecvt_converter.cpp120
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/util/default_locale.cpp7
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/util/encoding.cpp30
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/util/encoding.hpp16
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/util/foreach_char.hpp29
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/util/gregorian.cpp228
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/util/iconv.hpp6
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/util/locale_data.cpp23
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/util/make_std_unique.hpp24
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/util/numeric.hpp97
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/util/timezone.hpp20
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/win32/api.hpp35
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/win32/collate.cpp16
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/win32/converter.cpp4
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/win32/lcid.cpp25
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/win32/numeric.cpp26
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/win32/win_backend.cpp21
-rw-r--r--contrib/restricted/boost/locale/src/boost/locale/win32/win_backend.hpp6
-rw-r--r--contrib/restricted/boost/locale/ya.make5
-rw-r--r--contrib/restricted/boost/utility/include/boost/utility/string_view.hpp694
-rw-r--r--contrib/restricted/boost/utility/include/boost/utility/string_view_fwd.hpp39
102 files changed, 3631 insertions, 3051 deletions
diff --git a/contrib/restricted/boost/io/include/boost/io/detail/buffer_fill.hpp b/contrib/restricted/boost/io/include/boost/io/detail/buffer_fill.hpp
new file mode 100644
index 0000000000..b25a884473
--- /dev/null
+++ b/contrib/restricted/boost/io/include/boost/io/detail/buffer_fill.hpp
@@ -0,0 +1,39 @@
+/*
+Copyright 2019-2020 Glen Joseph Fernandes
+(glenjofe@gmail.com)
+
+Distributed under the Boost Software License, Version 1.0.
+(http://www.boost.org/LICENSE_1_0.txt)
+*/
+#ifndef BOOST_IO_DETAIL_BUFFER_FILL_HPP
+#define BOOST_IO_DETAIL_BUFFER_FILL_HPP
+
+#include <iosfwd>
+#include <cstddef>
+
+namespace boost {
+namespace io {
+namespace detail {
+
+template<class charT, class traits>
+inline bool
+buffer_fill(std::basic_streambuf<charT, traits>& buf, charT ch,
+ std::size_t size)
+{
+ charT fill[] = { ch, ch, ch, ch, ch, ch, ch, ch };
+ enum {
+ chunk = sizeof fill / sizeof(charT)
+ };
+ for (; size > chunk; size -= chunk) {
+ if (static_cast<std::size_t>(buf.sputn(fill, chunk)) != chunk) {
+ return false;
+ }
+ }
+ return static_cast<std::size_t>(buf.sputn(fill, size)) == size;
+}
+
+} /* detail */
+} /* io */
+} /* boost */
+
+#endif
diff --git a/contrib/restricted/boost/io/include/boost/io/detail/ostream_guard.hpp b/contrib/restricted/boost/io/include/boost/io/detail/ostream_guard.hpp
new file mode 100644
index 0000000000..6999d81344
--- /dev/null
+++ b/contrib/restricted/boost/io/include/boost/io/detail/ostream_guard.hpp
@@ -0,0 +1,45 @@
+/*
+Copyright 2019-2020 Glen Joseph Fernandes
+(glenjofe@gmail.com)
+
+Distributed under the Boost Software License, Version 1.0.
+(http://www.boost.org/LICENSE_1_0.txt)
+*/
+#ifndef BOOST_IO_DETAIL_OSTREAM_GUARD_HPP
+#define BOOST_IO_DETAIL_OSTREAM_GUARD_HPP
+
+#include <boost/config.hpp>
+#include <iosfwd>
+
+namespace boost {
+namespace io {
+namespace detail {
+
+template<class Char, class Traits>
+class ostream_guard {
+public:
+ explicit ostream_guard(std::basic_ostream<Char, Traits>& os) BOOST_NOEXCEPT
+ : os_(&os) { }
+
+ ~ostream_guard() BOOST_NOEXCEPT_IF(false) {
+ if (os_) {
+ os_->setstate(std::basic_ostream<Char, Traits>::badbit);
+ }
+ }
+
+ void release() BOOST_NOEXCEPT {
+ os_ = 0;
+ }
+
+private:
+ ostream_guard(const ostream_guard&);
+ ostream_guard& operator=(const ostream_guard&);
+
+ std::basic_ostream<Char, Traits>* os_;
+};
+
+} /* detail */
+} /* io */
+} /* boost */
+
+#endif
diff --git a/contrib/restricted/boost/io/include/boost/io/ostream_put.hpp b/contrib/restricted/boost/io/include/boost/io/ostream_put.hpp
new file mode 100644
index 0000000000..97627f8e81
--- /dev/null
+++ b/contrib/restricted/boost/io/include/boost/io/ostream_put.hpp
@@ -0,0 +1,50 @@
+/*
+Copyright 2019 Glen Joseph Fernandes
+(glenjofe@gmail.com)
+
+Distributed under the Boost Software License, Version 1.0.
+(http://www.boost.org/LICENSE_1_0.txt)
+*/
+#ifndef BOOST_IO_OSTREAM_PUT_HPP
+#define BOOST_IO_OSTREAM_PUT_HPP
+
+#include <boost/io/detail/buffer_fill.hpp>
+#include <boost/io/detail/ostream_guard.hpp>
+
+namespace boost {
+namespace io {
+
+template<class charT, class traits>
+inline std::basic_ostream<charT, traits>&
+ostream_put(std::basic_ostream<charT, traits>& os, const charT* data,
+ std::size_t size)
+{
+ typedef std::basic_ostream<charT, traits> stream;
+ detail::ostream_guard<charT, traits> guard(os);
+ typename stream::sentry entry(os);
+ if (entry) {
+ std::basic_streambuf<charT, traits>& buf = *os.rdbuf();
+ std::size_t width = static_cast<std::size_t>(os.width());
+ if (width <= size) {
+ if (static_cast<std::size_t>(buf.sputn(data, size)) != size) {
+ return os;
+ }
+ } else if ((os.flags() & stream::adjustfield) == stream::left) {
+ if (static_cast<std::size_t>(buf.sputn(data, size)) != size ||
+ !detail::buffer_fill(buf, os.fill(), width - size)) {
+ return os;
+ }
+ } else if (!detail::buffer_fill(buf, os.fill(), width - size) ||
+ static_cast<std::size_t>(buf.sputn(data, size)) != size) {
+ return os;
+ }
+ os.width(0);
+ }
+ guard.release();
+ return os;
+}
+
+} /* io */
+} /* boost */
+
+#endif
diff --git a/contrib/restricted/boost/locale/CMakeLists.darwin-x86_64.txt b/contrib/restricted/boost/locale/CMakeLists.darwin-x86_64.txt
index c712fd71a3..6be36e40a8 100644
--- a/contrib/restricted/boost/locale/CMakeLists.darwin-x86_64.txt
+++ b/contrib/restricted/boost/locale/CMakeLists.darwin-x86_64.txt
@@ -28,6 +28,7 @@ target_link_libraries(restricted-boost-locale PUBLIC
restricted-boost-iterator
restricted-boost-predef
restricted-boost-thread
+ restricted-boost-utility
)
target_sources(restricted-boost-locale PRIVATE
${CMAKE_SOURCE_DIR}/contrib/restricted/boost/locale/src/boost/locale/posix/codecvt.cpp
diff --git a/contrib/restricted/boost/locale/CMakeLists.linux-aarch64.txt b/contrib/restricted/boost/locale/CMakeLists.linux-aarch64.txt
index 49c58834ef..453c9e00ef 100644
--- a/contrib/restricted/boost/locale/CMakeLists.linux-aarch64.txt
+++ b/contrib/restricted/boost/locale/CMakeLists.linux-aarch64.txt
@@ -29,6 +29,7 @@ target_link_libraries(restricted-boost-locale PUBLIC
restricted-boost-iterator
restricted-boost-predef
restricted-boost-thread
+ restricted-boost-utility
)
target_sources(restricted-boost-locale PRIVATE
${CMAKE_SOURCE_DIR}/contrib/restricted/boost/locale/src/boost/locale/posix/codecvt.cpp
diff --git a/contrib/restricted/boost/locale/CMakeLists.linux-x86_64.txt b/contrib/restricted/boost/locale/CMakeLists.linux-x86_64.txt
index 49c58834ef..453c9e00ef 100644
--- a/contrib/restricted/boost/locale/CMakeLists.linux-x86_64.txt
+++ b/contrib/restricted/boost/locale/CMakeLists.linux-x86_64.txt
@@ -29,6 +29,7 @@ target_link_libraries(restricted-boost-locale PUBLIC
restricted-boost-iterator
restricted-boost-predef
restricted-boost-thread
+ restricted-boost-utility
)
target_sources(restricted-boost-locale PRIVATE
${CMAKE_SOURCE_DIR}/contrib/restricted/boost/locale/src/boost/locale/posix/codecvt.cpp
diff --git a/contrib/restricted/boost/locale/CMakeLists.windows-x86_64.txt b/contrib/restricted/boost/locale/CMakeLists.windows-x86_64.txt
index 76b190df2c..62aa96d9ae 100644
--- a/contrib/restricted/boost/locale/CMakeLists.windows-x86_64.txt
+++ b/contrib/restricted/boost/locale/CMakeLists.windows-x86_64.txt
@@ -28,6 +28,7 @@ target_link_libraries(restricted-boost-locale PUBLIC
restricted-boost-iterator
restricted-boost-predef
restricted-boost-thread
+ restricted-boost-utility
)
target_sources(restricted-boost-locale PRIVATE
${CMAKE_SOURCE_DIR}/contrib/restricted/boost/locale/src/boost/locale/win32/collate.cpp
diff --git a/contrib/restricted/boost/locale/README.md b/contrib/restricted/boost/locale/README.md
index a8e73bc55a..2cc876784e 100644
--- a/contrib/restricted/boost/locale/README.md
+++ b/contrib/restricted/boost/locale/README.md
@@ -5,7 +5,7 @@ Part of the [Boost C++ Libraries](http://github.com/boostorg).
Boost.Locale is a library that provides high quality localization facilities in a C++ way.
It was originally designed a part of [CppCMS](http://cppcms.sourceforge.net/) - a C++ Web Framework project and then contributed to Boost.
-Boost.Locale gives powerful tools for development of cross platform localized software - the software that talks to users in their language.
+Boost.Locale gives powerful tools for development of cross-platform localized software - the software that talks to users in their language.
Provided Features:
@@ -21,7 +21,7 @@ Provided Features:
- Support for `char` and `wchar_t`
- Experimental support for C++11 `char16_t` and `char32_t` strings and streams.
-Boost.Locale enhances and unifies the standard library's API the way it becomes useful and convenient for development of cross platform and "cross-culture" software.
+Boost.Locale enhances and unifies the standard library's API the way it becomes useful and convenient for development of cross-platform and "cross-culture" software.
In order to achieve this goal Boost.Locale uses the-state-of-the-art Unicode and Localization library: ICU - International Components for Unicode.
@@ -38,7 +38,7 @@ Distributed under the [Boost Software License, Version 1.0](https://www.boost.or
### Properties
* C++11
-* Formatted with clang-format, see [`tools/format_source.sh`](https://github.com/boostorg/locale/blob/develop/tools/format_source.sh)
+* Formatted with clang-format, see [`tools/format_sources.sh`](https://github.com/boostorg/locale/blob/develop/tools/format_sources.sh)
### Build Status
diff --git a/contrib/restricted/boost/locale/include/boost/locale.hpp b/contrib/restricted/boost/locale/include/boost/locale.hpp
index 1840bf5163..28709aa5ff 100644
--- a/contrib/restricted/boost/locale/include/boost/locale.hpp
+++ b/contrib/restricted/boost/locale/include/boost/locale.hpp
@@ -21,5 +21,6 @@
#include <boost/locale/localization_backend.hpp>
#include <boost/locale/message.hpp>
#include <boost/locale/util.hpp>
+#include <boost/locale/util/locale_data.hpp>
#endif
diff --git a/contrib/restricted/boost/locale/include/boost/locale/boundary/facets.hpp b/contrib/restricted/boost/locale/include/boost/locale/boundary/facets.hpp
index 4d443c9aa8..61dc2bef63 100644
--- a/contrib/restricted/boost/locale/include/boost/locale/boundary/facets.hpp
+++ b/contrib/restricted/boost/locale/include/boost/locale/boundary/facets.hpp
@@ -8,6 +8,8 @@
#define BOOST_LOCALE_BOUNDARY_FACETS_HPP_INCLUDED
#include <boost/locale/boundary/types.hpp>
+#include <boost/locale/detail/facet_id.hpp>
+#include <boost/locale/detail/is_supported_char.hpp>
#include <locale>
#include <vector>
@@ -49,16 +51,14 @@ namespace boost { namespace locale {
/// with marks
typedef std::vector<break_info> index_type;
- template<typename CharType>
- class boundary_indexing;
-
-#ifdef BOOST_LOCALE_DOXYGEN
- /// \brief This facet generates an index for boundary analysis
- /// for a given text.
+ /// \brief This facet generates an index for boundary analysis of a given text.
///
- /// It is specialized for 4 types of characters \c char_t, \c wchar_t, \c char16_t and \c char32_t
+ /// It is implemented for supported character types, at least \c char, \c wchar_t
template<typename Char>
- class BOOST_LOCALE_DECL boundary_indexing : public std::locale::facet {
+ class BOOST_SYMBOL_VISIBLE boundary_indexing : public std::locale::facet,
+ public boost::locale::detail::facet_id<boundary_indexing<Char>> {
+ BOOST_LOCALE_ASSERT_IS_SUPPORTED(Char);
+
public:
/// Default constructor typical for facets
boundary_indexing(size_t refs = 0) : std::locale::facet(refs) {}
@@ -69,56 +69,8 @@ namespace boost { namespace locale {
/// index is never empty, even if the range [begin,end) is empty it consists
/// of at least one boundary point with the offset 0.
virtual index_type map(boundary_type t, const Char* begin, const Char* end) const = 0;
-
- /// Identification of this facet
- static std::locale::id id;
- };
-
-#else
-
- template<>
- class BOOST_LOCALE_DECL boundary_indexing<char> : public std::locale::facet {
- public:
- boundary_indexing(size_t refs = 0) : std::locale::facet(refs) {}
- ~boundary_indexing();
- virtual index_type map(boundary_type t, const char* begin, const char* end) const = 0;
- static std::locale::id id;
};
- template<>
- class BOOST_LOCALE_DECL boundary_indexing<wchar_t> : public std::locale::facet {
- public:
- boundary_indexing(size_t refs = 0) : std::locale::facet(refs) {}
- ~boundary_indexing();
- virtual index_type map(boundary_type t, const wchar_t* begin, const wchar_t* end) const = 0;
-
- static std::locale::id id;
- };
-
-# ifdef BOOST_LOCALE_ENABLE_CHAR16_T
- template<>
- class BOOST_LOCALE_DECL boundary_indexing<char16_t> : public std::locale::facet {
- public:
- boundary_indexing(size_t refs = 0) : std::locale::facet(refs) {}
- ~boundary_indexing();
- virtual index_type map(boundary_type t, const char16_t* begin, const char16_t* end) const = 0;
- static std::locale::id id;
- };
-# endif
-
-# ifdef BOOST_LOCALE_ENABLE_CHAR32_T
- template<>
- class BOOST_LOCALE_DECL boundary_indexing<char32_t> : public std::locale::facet {
- public:
- boundary_indexing(size_t refs = 0) : std::locale::facet(refs) {}
- ~boundary_indexing();
- virtual index_type map(boundary_type t, const char32_t* begin, const char32_t* end) const = 0;
- static std::locale::id id;
- };
-# endif
-
-#endif
-
/// @}
} // namespace boundary
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 6143ac4616..fb4319b1bf 100644
--- a/contrib/restricted/boost/locale/include/boost/locale/boundary/index.hpp
+++ b/contrib/restricted/boost/locale/include/boost/locale/boundary/index.hpp
@@ -11,9 +11,9 @@
#include <boost/locale/boundary/facets.hpp>
#include <boost/locale/boundary/segment.hpp>
#include <boost/locale/boundary/types.hpp>
-#include <boost/cstdint.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <algorithm>
+#include <cstdint>
#include <iterator>
#include <locale>
#include <memory>
@@ -133,7 +133,7 @@ namespace boost { namespace locale { namespace boundary {
typedef mapping<base_iterator> mapping_type;
typedef segment<base_iterator> segment_type;
- segment_index_iterator() : current_(0, 0), map_(0), mask_(0), full_select_(false) {}
+ segment_index_iterator() : current_(0, 0), map_(nullptr), mask_(0), full_select_(false) {}
segment_index_iterator(base_iterator p, const mapping_type* map, rule_type mask, bool full_select) :
map_(map), mask_(mask), full_select_(full_select)
@@ -221,11 +221,10 @@ namespace boost { namespace locale { namespace boundary {
void set(base_iterator p)
{
- size_t dist = std::distance(map_->begin(), p);
- index_type::const_iterator b = map_->index().begin(), e = map_->index().end();
- index_type::const_iterator boundary_point = std::upper_bound(b, e, break_info(dist));
+ const auto b = map_->index().begin(), e = map_->index().end();
+ auto boundary_point = std::upper_bound(b, e, break_info(std::distance(map_->begin(), p)));
while(boundary_point != e && (boundary_point->rule & mask_) == 0)
- boundary_point++;
+ ++boundary_point;
current_.first = current_.second = boundary_point - b;
@@ -259,9 +258,8 @@ namespace boost { namespace locale { namespace boundary {
void update_rule()
{
- if(current_.second != size()) {
+ if(current_.second != size())
value_.rule(index()[current_.second].rule);
- }
}
size_t get_offset(size_t ind) const
{
@@ -297,7 +295,7 @@ namespace boost { namespace locale { namespace boundary {
typedef mapping<base_iterator> mapping_type;
typedef boundary_point<base_iterator> boundary_point_type;
- boundary_point_index_iterator() : current_(0), map_(0), mask_(0) {}
+ boundary_point_index_iterator() : current_(0), map_(nullptr), mask_(0) {}
boundary_point_index_iterator(bool is_begin, const mapping_type* map, rule_type mask) :
map_(map), mask_(mask)
@@ -358,14 +356,13 @@ namespace boost { namespace locale { namespace boundary {
{
size_t dist = std::distance(map_->begin(), p);
- index_type::const_iterator b = index().begin();
- index_type::const_iterator e = index().end();
- index_type::const_iterator ptr = std::lower_bound(b, e, break_info(dist));
+ const auto b = index().begin(), e = index().end();
+ const auto ptr = std::lower_bound(b, e, break_info(dist));
- if(ptr == index().end())
+ if(ptr == e)
current_ = size() - 1;
else
- current_ = ptr - index().begin();
+ current_ = ptr - b;
while(!valid_offset(current_))
current_++;
@@ -388,9 +385,8 @@ namespace boost { namespace locale { namespace boundary {
void update_rule()
{
- if(current_ != size()) {
+ if(current_ != size())
value_.rule(index()[current_].rule);
- }
}
size_t get_offset(size_t ind) const
{
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 796fc19956..9e38188e3f 100644
--- a/contrib/restricted/boost/locale/include/boost/locale/boundary/segment.hpp
+++ b/contrib/restricted/boost/locale/include/boost/locale/boundary/segment.hpp
@@ -359,10 +359,10 @@ namespace boost { namespace locale { namespace boundary {
/// Write the segment to the stream character by character
template<typename CharType, typename TraitsType, typename Iterator>
std::basic_ostream<CharType, TraitsType>& operator<<(std::basic_ostream<CharType, TraitsType>& out,
- const segment<Iterator>& tok)
+ const segment<Iterator>& seg)
{
- for(Iterator p = tok.begin(), e = tok.end(); p != e; ++p)
- out << *p;
+ for(const auto& p : seg)
+ out << p;
return out;
}
diff --git a/contrib/restricted/boost/locale/include/boost/locale/boundary/types.hpp b/contrib/restricted/boost/locale/include/boost/locale/boundary/types.hpp
index 9fac23b172..fa927915aa 100644
--- a/contrib/restricted/boost/locale/include/boost/locale/boundary/types.hpp
+++ b/contrib/restricted/boost/locale/include/boost/locale/boundary/types.hpp
@@ -8,7 +8,7 @@
#define BOOST_LOCALE_BOUNDARY_TYPES_HPP_INCLUDED
#include <boost/locale/config.hpp>
-#include <boost/cstdint.hpp>
+#include <cstdint>
#ifdef BOOST_MSVC
# pragma warning(push)
diff --git a/contrib/restricted/boost/locale/include/boost/locale/collator.hpp b/contrib/restricted/boost/locale/include/boost/locale/collator.hpp
index dfef535d23..b45f15475f 100644
--- a/contrib/restricted/boost/locale/include/boost/locale/collator.hpp
+++ b/contrib/restricted/boost/locale/include/boost/locale/collator.hpp
@@ -17,8 +17,6 @@
namespace boost { namespace locale {
- class info;
-
/// \defgroup collation Collation
///
/// This module introduces collation related classes
@@ -173,7 +171,7 @@ namespace boost { namespace locale {
public:
/// Create a comparator class for locale \a l and with collation leval \a level
///
- /// \note throws std::bad_cast if l does not have \ref collator facet installed
+ /// \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)
{}
diff --git a/contrib/restricted/boost/locale/include/boost/locale/config.hpp b/contrib/restricted/boost/locale/include/boost/locale/config.hpp
index 821ba7fe7d..9c8e6c2f2f 100644
--- a/contrib/restricted/boost/locale/include/boost/locale/config.hpp
+++ b/contrib/restricted/boost/locale/include/boost/locale/config.hpp
@@ -72,6 +72,16 @@
#else
# define BOOST_LOCALE_USE_WIN32_API 0
#endif
+
+// To be used to suppress false positives of UBSAN
+#if defined(__clang__) && defined(__has_attribute)
+# if __has_attribute(no_sanitize)
+# define BOOST_LOCALE_NO_SANITIZE(what) __attribute__((no_sanitize(what)))
+# endif
+#endif
+#if !defined(BOOST_LOCALE_NO_SANITIZE)
+# define BOOST_LOCALE_NO_SANITIZE(what)
+#endif
/// \endcond
#endif // boost/locale/config.hpp
diff --git a/contrib/restricted/boost/locale/include/boost/locale/conversion.hpp b/contrib/restricted/boost/locale/include/boost/locale/conversion.hpp
index 09fa75faf7..f5626fdc61 100644
--- a/contrib/restricted/boost/locale/include/boost/locale/conversion.hpp
+++ b/contrib/restricted/boost/locale/include/boost/locale/conversion.hpp
@@ -7,6 +7,8 @@
#ifndef BOOST_LOCALE_CONVERTER_HPP_INCLUDED
#define BOOST_LOCALE_CONVERTER_HPP_INCLUDED
+#include <boost/locale/detail/facet_id.hpp>
+#include <boost/locale/detail/is_supported_char.hpp>
#include <boost/locale/util/string.hpp>
#include <locale>
@@ -35,76 +37,24 @@ namespace boost { namespace locale {
};
};
- template<typename CharType>
- class converter;
-
-#ifdef BOOST_LOCALE_DOXYGEN
- ///
/// \brief The facet that implements text manipulation
///
- /// It is used to performs text conversion operations defined by \ref converter_base::conversion_type.
- /// It is specialized for four types of characters \c char, \c wchar_t, \c char16_t, \c char32_t
+ /// It is used to perform text conversion operations defined by \ref converter_base::conversion_type.
+ /// It is implemented for supported character types, at least \c char, \c wchar_t
template<typename Char>
- class BOOST_LOCALE_DECL converter : public converter_base, public std::locale::facet {
- public:
- /// Locale identification
- static std::locale::id id;
+ class BOOST_SYMBOL_VISIBLE converter : public converter_base,
+ public std::locale::facet,
+ public detail::facet_id<converter<Char>> {
+ BOOST_LOCALE_ASSERT_IS_SUPPORTED(Char);
+ public:
/// Standard constructor
converter(size_t refs = 0) : std::locale::facet(refs) {}
-
/// Convert text in range [\a begin, \a end) according to conversion method \a how. Parameter
/// \a flags is used for specification of normalization method like nfd, nfc etc.
virtual std::basic_string<Char>
convert(conversion_type how, const Char* begin, const Char* end, int flags = 0) const = 0;
};
-#else
-
- template<>
- class BOOST_LOCALE_DECL converter<char> : public converter_base, public std::locale::facet {
- public:
- static std::locale::id id;
-
- converter(size_t refs = 0) : std::locale::facet(refs) {}
- ~converter();
- virtual std::string convert(conversion_type how, const char* begin, const char* end, int flags = 0) const = 0;
- };
-
- template<>
- class BOOST_LOCALE_DECL converter<wchar_t> : public converter_base, public std::locale::facet {
- public:
- static std::locale::id id;
- converter(size_t refs = 0) : std::locale::facet(refs) {}
- ~converter();
- virtual std::wstring
- convert(conversion_type how, const wchar_t* begin, const wchar_t* end, int flags = 0) const = 0;
- };
-
-# ifdef BOOST_LOCALE_ENABLE_CHAR16_T
- template<>
- class BOOST_LOCALE_DECL converter<char16_t> : public converter_base, public std::locale::facet {
- public:
- static std::locale::id id;
- converter(size_t refs = 0) : std::locale::facet(refs) {}
- ~converter();
- virtual std::u16string
- convert(conversion_type how, const char16_t* begin, const char16_t* end, int flags = 0) const = 0;
- };
-# endif
-
-# ifdef BOOST_LOCALE_ENABLE_CHAR32_T
- template<>
- class BOOST_LOCALE_DECL converter<char32_t> : public converter_base, public std::locale::facet {
- public:
- static std::locale::id id;
- converter(size_t refs = 0) : std::locale::facet(refs) {}
- ~converter();
- virtual std::u32string
- convert(conversion_type how, const char32_t* begin, const char32_t* end, int flags = 0) const = 0;
- };
-# endif
-
-#endif
/// The type that defined <a href="http://unicode.org/reports/tr15/#Norm_Forms">normalization form</a>
enum norm_type {
@@ -121,7 +71,7 @@ namespace boost { namespace locale {
/// in account the locale encoding, because Unicode decomposition and composition are meaningless outside
/// of a Unicode character set.
///
- /// \note throws std::bad_cast if loc does not have \ref converter facet installed
+ /// \throws std::bad_cast: \a loc does not have \ref converter facet installed
template<typename CharType>
std::basic_string<CharType> normalize(const CharType* begin,
const CharType* end,
@@ -137,7 +87,7 @@ namespace boost { namespace locale {
/// in account the locale encoding, because Unicode decomposition and composition are meaningless outside
/// of a Unicode character set.
///
- /// \note throws std::bad_cast if loc does not have \ref converter facet installed
+ /// \throws std::bad_cast: \a loc does not have \ref converter facet installed
template<typename CharType>
std::basic_string<CharType> normalize(const std::basic_string<CharType>& str,
norm_type n = norm_default,
@@ -152,7 +102,7 @@ namespace boost { namespace locale {
/// in account the locale encoding, because Unicode decomposition and composition are meaningless outside
/// of a Unicode character set.
///
- /// \note throws std::bad_cast if loc does not have \ref converter facet installed
+ /// \throws std::bad_cast: \a loc does not have \ref converter facet installed
template<typename CharType>
std::basic_string<CharType>
normalize(const CharType* str, norm_type n = norm_default, const std::locale& loc = std::locale())
@@ -164,7 +114,7 @@ namespace boost { namespace locale {
/// Convert a string in range [begin,end) to upper case according to locale \a loc
///
- /// \note throws std::bad_cast if loc does not have \ref converter facet installed
+ /// \throws std::bad_cast: \a loc does not have \ref converter facet installed
template<typename CharType>
std::basic_string<CharType>
to_upper(const CharType* begin, const CharType* end, const std::locale& loc = std::locale())
@@ -174,7 +124,7 @@ namespace boost { namespace locale {
/// Convert a string \a str to upper case according to locale \a loc
///
- /// \note throws std::bad_cast if loc does not have \ref converter facet installed
+ /// \throws std::bad_cast: \a loc does not have \ref converter facet installed
template<typename CharType>
std::basic_string<CharType> to_upper(const std::basic_string<CharType>& str, const std::locale& loc = std::locale())
{
@@ -183,7 +133,7 @@ namespace boost { namespace locale {
/// Convert a NULL terminated string \a str to upper case according to locale \a loc
///
- /// \note throws std::bad_cast if loc does not have \ref converter facet installed
+ /// \throws std::bad_cast: \a loc does not have \ref converter facet installed
template<typename CharType>
std::basic_string<CharType> to_upper(const CharType* str, const std::locale& loc = std::locale())
{
@@ -194,7 +144,7 @@ namespace boost { namespace locale {
/// Convert a string in range [begin,end) to lower case according to locale \a loc
///
- /// \note throws std::bad_cast if loc does not have \ref converter facet installed
+ /// \throws std::bad_cast: \a loc does not have \ref converter facet installed
template<typename CharType>
std::basic_string<CharType>
to_lower(const CharType* begin, const CharType* end, const std::locale& loc = std::locale())
@@ -204,7 +154,7 @@ namespace boost { namespace locale {
/// Convert a string \a str to lower case according to locale \a loc
///
- /// \note throws std::bad_cast if loc does not have \ref converter facet installed
+ /// \throws std::bad_cast: \a loc does not have \ref converter facet installed
template<typename CharType>
std::basic_string<CharType> to_lower(const std::basic_string<CharType>& str, const std::locale& loc = std::locale())
{
@@ -213,7 +163,7 @@ namespace boost { namespace locale {
/// Convert a NULL terminated string \a str to lower case according to locale \a loc
///
- /// \note throws std::bad_cast if loc does not have \ref converter facet installed
+ /// \throws std::bad_cast: \a loc does not have \ref converter facet installed
template<typename CharType>
std::basic_string<CharType> to_lower(const CharType* str, const std::locale& loc = std::locale())
{
@@ -224,7 +174,7 @@ namespace boost { namespace locale {
/// Convert a string in range [begin,end) to title case according to locale \a loc
///
- /// \note throws std::bad_cast if loc does not have \ref converter facet installed
+ /// \throws std::bad_cast: \a loc does not have \ref converter facet installed
template<typename CharType>
std::basic_string<CharType>
to_title(const CharType* begin, const CharType* end, const std::locale& loc = std::locale())
@@ -234,7 +184,7 @@ namespace boost { namespace locale {
/// Convert a string \a str to title case according to locale \a loc
///
- /// \note throws std::bad_cast if loc does not have \ref converter facet installed
+ /// \throws std::bad_cast: \a loc does not have \ref converter facet installed
template<typename CharType>
std::basic_string<CharType> to_title(const std::basic_string<CharType>& str, const std::locale& loc = std::locale())
{
@@ -243,7 +193,7 @@ namespace boost { namespace locale {
/// Convert a NULL terminated string \a str to title case according to locale \a loc
///
- /// \note throws std::bad_cast if loc does not have \ref converter facet installed
+ /// \throws std::bad_cast: \a loc does not have \ref converter facet installed
template<typename CharType>
std::basic_string<CharType> to_title(const CharType* str, const std::locale& loc = std::locale())
{
@@ -254,7 +204,7 @@ namespace boost { namespace locale {
/// Fold case of a string in range [begin,end) according to locale \a loc
///
- /// \note throws std::bad_cast if loc does not have \ref converter facet installed
+ /// \throws std::bad_cast: \a loc does not have \ref converter facet installed
template<typename CharType>
std::basic_string<CharType>
fold_case(const CharType* begin, const CharType* end, const std::locale& loc = std::locale())
@@ -264,7 +214,7 @@ namespace boost { namespace locale {
/// Fold case of a string \a str according to locale \a loc
///
- /// \note throws std::bad_cast if loc does not have \ref converter facet installed
+ /// \throws std::bad_cast: \a loc does not have \ref converter facet installed
template<typename CharType>
std::basic_string<CharType> fold_case(const std::basic_string<CharType>& str,
const std::locale& loc = std::locale())
@@ -274,7 +224,7 @@ namespace boost { namespace locale {
/// Fold case of a NULL terminated string \a str according to locale \a loc
///
- /// \note throws std::bad_cast if loc does not have \ref converter facet installed
+ /// \throws std::bad_cast: \a loc does not have \ref converter facet installed
template<typename CharType>
std::basic_string<CharType> fold_case(const CharType* str, const std::locale& loc = std::locale())
{
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 8006c60e89..46b171bc35 100644
--- a/contrib/restricted/boost/locale/include/boost/locale/date_time.hpp
+++ b/contrib/restricted/boost/locale/include/boost/locale/date_time.hpp
@@ -470,29 +470,29 @@ namespace boost { namespace locale {
public:
/// Create calendar taking locale and timezone information from ios_base instance.
///
- /// \note throws std::bad_cast if ios does not have a locale with installed \ref calendar_facet
+ /// \throws std::bad_cast: \a ios does not have a locale with installed \ref calendar_facet
/// facet installed
calendar(std::ios_base& ios);
/// Create calendar with locale \a l and time_zone \a zone
///
- /// \note throws std::bad_cast if loc does not have \ref calendar_facet facet installed
+ /// \throws std::bad_cast: \a l does not have \ref calendar_facet facet installed
calendar(const std::locale& l, const std::string& zone);
/// Create calendar with locale \a l and default timezone
///
- /// \note throws std::bad_cast if loc does not have \ref calendar_facet facet installed
+ /// \throws std::bad_cast: \a l does not have \ref calendar_facet facet installed
calendar(const std::locale& l);
/// Create calendar with default locale and timezone \a zone
///
- /// \note throws std::bad_cast if global locale does not have \ref calendar_facet facet installed
+ /// \throws std::bad_cast: global locale does not have \ref calendar_facet facet installed
calendar(const std::string& zone);
/// Create calendar with default locale and timezone
///
- /// \note throws std::bad_cast if global locale does not have \ref calendar_facet facet installed
+ /// \throws std::bad_cast: global locale does not have \ref calendar_facet facet installed
calendar();
~calendar();
@@ -515,9 +515,9 @@ namespace boost { namespace locale {
int first_day_of_week() const;
/// get calendar's locale
- std::locale get_locale() const;
+ const std::locale& get_locale() const;
/// get calendar's time zone
- std::string get_time_zone() const;
+ const std::string& get_time_zone() const;
/// Check if the calendar is Gregorian
bool is_gregorian() const;
@@ -562,13 +562,13 @@ namespace boost { namespace locale {
public:
/// Default constructor, uses default calendar initialized date_time object to current time.
///
- /// \note throws std::bad_cast if the global locale does not have \ref calendar_facet facet installed
+ /// \throws std::bad_cast: Global locale does not have \ref calendar_facet facet installed
date_time();
/// Copy a date_time
date_time(const date_time& other);
- // Move construct a new date_time
- date_time(date_time&&) = default;
+ // Move construct a date_time
+ date_time(date_time&&) noexcept = default;
/// copy date_time and change some fields according to the \a set
date_time(const date_time& other, const date_time_period_set& set);
@@ -576,11 +576,11 @@ namespace boost { namespace locale {
/// assign the date_time
date_time& operator=(const date_time& other);
// Move assign a date_time
- date_time& operator=(date_time&&) = default;
+ date_time& operator=(date_time&&) noexcept = default;
/// Create a date_time object using POSIX time \a time and default calendar
///
- /// \note throws std::bad_cast if the global locale does not have \ref calendar_facet facet installed
+ /// \throws std::bad_cast: Global locale does not have \ref calendar_facet facet installed
date_time(double time);
/// Create a date_time object using POSIX time \a time and calendar \a cal
@@ -591,7 +591,7 @@ namespace boost { namespace locale {
/// Create a date_time object using default calendar and define values given in \a set
///
- /// \note throws std::bad_cast if the global locale does not have \ref calendar_facet facet installed
+ /// \throws std::bad_cast: Global locale does not have \ref calendar_facet facet installed
date_time(const date_time_period_set& set);
/// Create a date_time object using calendar \a cal and define values given in \a set
@@ -672,6 +672,9 @@ namespace boost { namespace locale {
/// This time can be fetched from Operating system clock using C function time, gettimeofday and others.
void time(double v);
+ /// Get the name of the associated timezone
+ std::string timezone() const;
+
/// compare date_time in the timeline (ignores difference in calendar, timezone etc)
bool operator==(const date_time& other) const;
/// compare date_time in the timeline (ignores difference in calendar, timezone etc)
@@ -686,7 +689,7 @@ namespace boost { namespace locale {
bool operator>=(const date_time& other) const;
/// swaps two dates - efficient, does not throw
- void swap(date_time& other);
+ void swap(date_time& other) noexcept;
/// calculate the distance from this date_time to \a other in terms of periods \a f
int difference(const date_time& other, period::period_type f) const;
@@ -710,7 +713,7 @@ namespace boost { namespace locale {
///
/// For example:
/// \code
- /// date_time now(time(0),hebrew_calendar)
+ /// date_time now(time(nullptr),hebrew_calendar)
/// std::cout << "Year: " << period::year(now) << " Full Date:" << now;
/// \endcode
///
diff --git a/contrib/restricted/boost/locale/include/boost/locale/date_time_facet.hpp b/contrib/restricted/boost/locale/include/boost/locale/date_time_facet.hpp
index c67efc7c2c..2f3344ba6e 100644
--- a/contrib/restricted/boost/locale/include/boost/locale/date_time_facet.hpp
+++ b/contrib/restricted/boost/locale/include/boost/locale/date_time_facet.hpp
@@ -8,7 +8,8 @@
#define BOOST_LOCALE_DATE_TIME_FACET_HPP_INCLUDED
#include <boost/locale/config.hpp>
-#include <boost/cstdint.hpp>
+#include <boost/locale/detail/facet_id.hpp>
+#include <cstdint>
#include <locale>
#ifdef BOOST_MSVC
@@ -91,7 +92,7 @@ namespace boost { namespace locale {
/// This class defines generic calendar class, it is used by date_time and calendar
/// objects internally. It is less useful for end users, but it is build for localization
/// backend implementation
- class BOOST_LOCALE_DECL abstract_calendar {
+ class BOOST_SYMBOL_VISIBLE abstract_calendar {
public:
/// Type that defines how to fetch the value
enum value_type {
@@ -163,20 +164,16 @@ namespace boost { namespace locale {
/// Check of two calendars have same rules
virtual bool same(const abstract_calendar* other) const = 0;
- virtual ~abstract_calendar();
+ virtual ~abstract_calendar() = default;
};
/// \brief the facet that generates calendar for specific locale
- class BOOST_LOCALE_DECL calendar_facet : public std::locale::facet {
+ class BOOST_SYMBOL_VISIBLE calendar_facet : public std::locale::facet, public detail::facet_id<calendar_facet> {
public:
/// Basic constructor
calendar_facet(size_t refs = 0) : std::locale::facet(refs) {}
- ~calendar_facet();
/// Create a new calendar that points to current point of time.
virtual abstract_calendar* create_calendar() const = 0;
-
- /// Locale id (needed to work with std::locale)
- static std::locale::id id;
};
}} // namespace boost::locale
diff --git a/contrib/restricted/boost/locale/include/boost/locale/detail/encoding.hpp b/contrib/restricted/boost/locale/include/boost/locale/detail/encoding.hpp
new file mode 100644
index 0000000000..ee669349a1
--- /dev/null
+++ b/contrib/restricted/boost/locale/include/boost/locale/detail/encoding.hpp
@@ -0,0 +1,58 @@
+//
+// Copyright (c) 2022-2023 Alexander Grund
+//
+// Distributed under the Boost Software License, Version 1.0.
+// https://www.boost.org/LICENSE_1_0.txt
+
+#ifndef BOOST_LOCALE_DETAIL_ENCODING_HPP_INCLUDED
+#define BOOST_LOCALE_DETAIL_ENCODING_HPP_INCLUDED
+
+#include <boost/locale/config.hpp>
+#include <boost/locale/encoding_errors.hpp>
+#include <boost/utility/string_view.hpp>
+#include <memory>
+#include <string>
+
+/// \cond INTERNAL
+namespace boost { namespace locale { namespace conv { namespace detail {
+ template<typename CharIn, typename CharOut>
+ class BOOST_SYMBOL_VISIBLE charset_converter {
+ public:
+ using char_out_type = CharOut;
+ using char_in_type = CharIn;
+ using string_type = std::basic_string<CharOut>;
+
+ virtual ~charset_converter() = default;
+ virtual string_type convert(const CharIn* begin, const CharIn* end) = 0;
+ string_type convert(const boost::basic_string_view<CharIn>& text)
+ {
+ return convert(text.data(), text.data() + text.length());
+ }
+ };
+
+ using narrow_converter = charset_converter<char, char>;
+
+ template<typename CharType>
+ using utf_encoder = charset_converter<char, CharType>;
+
+ template<typename CharType>
+ using utf_decoder = charset_converter<CharType, char>;
+
+ enum class conv_backend { Default, IConv, ICU, WinAPI };
+
+ template<typename Char>
+ BOOST_LOCALE_DECL std::unique_ptr<utf_encoder<Char>>
+ make_utf_encoder(const std::string& charset, method_type how, conv_backend impl = conv_backend::Default);
+ template<typename Char>
+ BOOST_LOCALE_DECL std::unique_ptr<utf_decoder<Char>>
+ make_utf_decoder(const std::string& charset, method_type how, conv_backend impl = conv_backend::Default);
+ BOOST_LOCALE_DECL std::unique_ptr<narrow_converter>
+ make_narrow_converter(const std::string& src_encoding,
+ const std::string& target_encoding,
+ method_type how,
+ conv_backend impl = conv_backend::Default);
+}}}} // namespace boost::locale::conv::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
new file mode 100644
index 0000000000..7405149905
--- /dev/null
+++ b/contrib/restricted/boost/locale/include/boost/locale/detail/facet_id.hpp
@@ -0,0 +1,35 @@
+//
+// Copyright (c) 2022-2023 Alexander Grund
+//
+// Distributed under the Boost Software License, Version 1.0.
+// https://www.boost.org/LICENSE_1_0.txt
+
+#ifndef BOOST_LOCALE_DETAIL_FACET_ID_HPP_INCLUDED
+#define BOOST_LOCALE_DETAIL_FACET_ID_HPP_INCLUDED
+
+#include <boost/locale/config.hpp>
+#include <locale>
+
+/// \cond INTERNAL
+namespace boost { namespace locale { namespace detail {
+#if defined(__clang__)
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wundefined-var-template"
+#endif
+ /// CRTP base class to hold the id required for facets
+ ///
+ /// Required because the id needs to be defined in a CPP file and hence ex/imported for shared libraries.
+ /// However the virtual classes need to be declared as BOOST_VISIBLE to combine the VTables because otherwise
+ /// casts/virtual-calls might be flagged as invalid by UBSAN
+ template<class Derived>
+ struct BOOST_LOCALE_DECL facet_id {
+ static std::locale::id id;
+ };
+#if defined(__clang__)
+# pragma clang diagnostic pop
+#endif
+}}} // namespace boost::locale::detail
+
+/// \endcond
+
+#endif
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
new file mode 100644
index 0000000000..d9fb092e5a
--- /dev/null
+++ b/contrib/restricted/boost/locale/include/boost/locale/detail/is_supported_char.hpp
@@ -0,0 +1,44 @@
+//
+// Copyright (c) 2022-2023 Alexander Grund
+//
+// Distributed under the Boost Software License, Version 1.0.
+// https://www.boost.org/LICENSE_1_0.txt
+
+#ifndef BOOST_LOCALE_DETAIL_IS_SUPPORTED_CHAR_HPP_INCLUDED
+#define BOOST_LOCALE_DETAIL_IS_SUPPORTED_CHAR_HPP_INCLUDED
+
+#include <boost/locale/config.hpp>
+#include <type_traits>
+
+/// \cond INTERNAL
+namespace boost { namespace locale { namespace detail {
+ /// Trait, returns true iff the argument is a supported character type
+ template<typename Char>
+ struct is_supported_char : std::false_type {};
+
+ template<>
+ struct is_supported_char<char> : std::true_type {};
+ template<>
+ struct is_supported_char<wchar_t> : std::true_type {};
+
+#ifdef BOOST_LOCALE_ENABLE_CHAR16_T
+ template<>
+ struct is_supported_char<char16_t> : std::true_type {};
+#endif
+
+#ifdef BOOST_LOCALE_ENABLE_CHAR32_T
+ template<>
+ struct is_supported_char<char32_t> : std::true_type {};
+#endif
+
+ template<typename Char>
+ using enable_if_is_supported_char = typename std::enable_if<is_supported_char<Char>::value>::type;
+
+}}} // namespace boost::locale::detail
+
+#define BOOST_LOCALE_ASSERT_IS_SUPPORTED(Char) \
+ static_assert(boost::locale::detail::is_supported_char<Char>::value, "Unsupported Char type")
+
+/// \endcond
+
+#endif
diff --git a/contrib/restricted/boost/locale/include/boost/locale/encoding.hpp b/contrib/restricted/boost/locale/include/boost/locale/encoding.hpp
index 0947028cdf..d0e1d9d07e 100644
--- a/contrib/restricted/boost/locale/include/boost/locale/encoding.hpp
+++ b/contrib/restricted/boost/locale/include/boost/locale/encoding.hpp
@@ -8,10 +8,12 @@
#define BOOST_LOCALE_ENCODING_HPP_INCLUDED
#include <boost/locale/config.hpp>
+#include <boost/locale/detail/encoding.hpp>
#include <boost/locale/encoding_errors.hpp>
#include <boost/locale/encoding_utf.hpp>
#include <boost/locale/info.hpp>
#include <boost/locale/util/string.hpp>
+#include <memory>
#ifdef BOOST_MSVC
# pragma warning(push)
@@ -22,114 +24,161 @@ namespace boost { namespace locale {
/// \brief Namespace that contains all functions related to character set conversion
namespace conv {
- /// \defgroup codepage Character conversion functions
+
+ /// \defgroup Charset conversion functions
///
/// @{
- /// convert text in range [begin,end) encoded with \a charset to UTF string according to policy \a how
+ /// convert text in range [begin,end) encoded with \a charset to UTF according to policy \a how
+ ///
+ /// \throws invalid_charset_error: Character set is not supported
+ /// \throws conversion_error: Conversion failed (e.g. \a how is \c stop and any character cannot be
+ /// encoded or decoded)
template<typename CharType>
- std::basic_string<CharType>
+ BOOST_LOCALE_DECL std::basic_string<CharType>
to_utf(const char* begin, const char* end, const std::string& charset, method_type how = default_method);
- /// convert UTF text in range [begin,end) to a text encoded with \a charset according to policy \a how
+ /// convert UTF text in range [begin,end) to text encoded with \a charset according to policy \a how
+ ///
+ /// \throws invalid_charset_error: Character set is not supported
+ /// \throws conversion_error: Conversion failed (e.g. \a how is \c stop and any character cannot be
+ /// encoded or decoded)
template<typename CharType>
- std::string from_utf(const CharType* begin,
- const CharType* end,
- const std::string& charset,
- method_type how = default_method);
+ BOOST_LOCALE_DECL std::string from_utf(const CharType* begin,
+ const CharType* end,
+ const std::string& charset,
+ method_type how = default_method);
- /// convert string to UTF string from text in range [begin,end) encoded according to locale \a loc according to
- /// policy \a how
+ /// convert \a text encoded with \a charset to UTF according to policy \a how
///
- /// \note throws std::bad_cast if the loc does not have \ref info facet installed
+ /// \throws invalid_charset_error: Character set is not supported
+ /// \throws conversion_error: Conversion failed (e.g. \a how is \c stop and any character cannot be
+ /// encoded or decoded)
template<typename CharType>
std::basic_string<CharType>
- to_utf(const char* begin, const char* end, const std::locale& loc, method_type how = default_method)
+ to_utf(const std::string& text, const std::string& charset, method_type how = default_method)
{
- return to_utf<CharType>(begin, end, std::use_facet<info>(loc).encoding(), how);
+ return to_utf<CharType>(text.c_str(), text.c_str() + text.size(), charset, how);
}
- /// convert UTF text in range [begin,end) to a text encoded according to locale \a loc according to policy \a
- /// how
+ /// Convert \a text encoded with \a charset to UTF according to policy \a how
///
- /// \note throws std::bad_cast if the loc does not have \ref info facet installed
+ /// \throws invalid_charset_error: Character set is not supported
+ /// \throws conversion_error: Conversion failed (e.g. \a how is \c stop and any character cannot be
+ /// encoded or decoded)
template<typename CharType>
- std::string
- from_utf(const CharType* begin, const CharType* end, const std::locale& loc, method_type how = default_method)
+ std::basic_string<CharType>
+ to_utf(const char* text, const std::string& charset, method_type how = default_method)
{
- return from_utf(begin, end, std::use_facet<info>(loc).encoding(), how);
+ return to_utf<CharType>(text, util::str_end(text), charset, how);
}
- /// convert a string \a text encoded with \a charset to UTF string
+ /// convert text in range [begin,end) in locale encoding given by \a loc to UTF according to
+ /// policy \a how
+ ///
+ /// \throws std::bad_cast: \a loc does not have \ref info facet installed
+ /// \throws invalid_charset_error: Character set is not supported
+ /// \throws conversion_error: Conversion failed (e.g. \a how is \c stop and any character cannot be
+ /// encoded or decoded)
template<typename CharType>
std::basic_string<CharType>
- to_utf(const std::string& text, const std::string& charset, method_type how = default_method)
+ to_utf(const char* begin, const char* end, const std::locale& loc, method_type how = default_method)
{
- return to_utf<CharType>(text.c_str(), text.c_str() + text.size(), charset, how);
+ return to_utf<CharType>(begin, end, std::use_facet<info>(loc).encoding(), how);
}
- /// Convert a \a text from \a charset to UTF string
+ /// Convert \a text in locale encoding given by \a loc to UTF according to policy \a how
+ ///
+ /// \throws std::bad_cast: \a loc does not have \ref info facet installed
+ /// \throws invalid_charset_error: Character set is not supported
+ /// \throws conversion_error: Conversion failed (e.g. \a how is \c stop and any character cannot be
+ /// encoded or decoded)
template<typename CharType>
- std::string
- from_utf(const std::basic_string<CharType>& text, const std::string& charset, method_type how = default_method)
+ std::basic_string<CharType>
+ to_utf(const std::string& text, const std::locale& loc, method_type how = default_method)
{
- return from_utf(text.c_str(), text.c_str() + text.size(), charset, how);
+ return to_utf<CharType>(text, std::use_facet<info>(loc).encoding(), how);
}
- /// Convert a \a text from \a charset to UTF string
+ /// Convert \a text in locale encoding given by \a loc to UTF according to policy \a how
+ ///
+ /// \throws std::bad_cast: \a loc does not have \ref info facet installed
+ /// \throws invalid_charset_error: Character set is not supported
+ /// \throws conversion_error: Conversion failed (e.g. \a how is \c stop and any character cannot be
+ /// encoded or decoded)
template<typename CharType>
- std::basic_string<CharType>
- to_utf(const char* text, const std::string& charset, method_type how = default_method)
+ std::basic_string<CharType> to_utf(const char* text, const std::locale& loc, method_type how = default_method)
{
- return to_utf<CharType>(text, util::str_end(text), charset, how);
+ return to_utf<CharType>(text, std::use_facet<info>(loc).encoding(), how);
}
- /// Convert a \a text from UTF to \a charset
+ /// convert \a text from UTF to text encoded with \a charset according to policy \a how
+ ///
+ /// \throws invalid_charset_error: Character set is not supported
+ /// \throws conversion_error: Conversion failed (e.g. \a how is \c stop and any character cannot be
+ /// encoded or decoded)
template<typename CharType>
- std::string from_utf(const CharType* text, const std::string& charset, method_type how = default_method)
+ std::string
+ from_utf(const std::basic_string<CharType>& text, const std::string& charset, method_type how = default_method)
{
- return from_utf(text, util::str_end(text), charset, how);
+ return from_utf(text.c_str(), text.c_str() + text.size(), charset, how);
}
- /// Convert a \a text in locale encoding given by \a loc to UTF
+ /// Convert \a text from UTF to \a charset according to policy \a how
///
- /// \note throws std::bad_cast if the loc does not have \ref info facet installed
+ /// \throws invalid_charset_error: Character set is not supported
+ /// \throws conversion_error: Conversion failed (e.g. \a how is \c stop and any character cannot be
+ /// encoded or decoded)
template<typename CharType>
- std::basic_string<CharType>
- to_utf(const std::string& text, const std::locale& loc, method_type how = default_method)
+ std::string from_utf(const CharType* text, const std::string& charset, method_type how = default_method)
{
- return to_utf<CharType>(text.c_str(), text.c_str() + text.size(), loc, how);
+ return from_utf(text, util::str_end(text), charset, how);
}
- /// Convert a \a text in UTF to locale encoding given by \a loc
+ /// Convert UTF text in range [begin,end) to text in locale encoding given by \a loc according to policy \a how
///
- /// \note throws std::bad_cast if the loc does not have \ref info facet installed
+ /// \throws std::bad_cast: \a loc does not have \ref info facet installed
+ /// \throws invalid_charset_error: Character set is not supported
+ /// \throws conversion_error: Conversion failed (e.g. \a how is \c stop and any character cannot be
+ /// encoded or decoded)
template<typename CharType>
std::string
- from_utf(const std::basic_string<CharType>& text, const std::locale& loc, method_type how = default_method)
+ from_utf(const CharType* begin, const CharType* end, const std::locale& loc, method_type how = default_method)
{
- return from_utf(text.c_str(), text.c_str() + text.size(), loc, how);
+ return from_utf(begin, end, std::use_facet<info>(loc).encoding(), how);
}
- /// Convert a \a text in locale encoding given by \a loc to UTF
+ /// Convert \a text from UTF to locale encoding given by \a loc according to policy \a how
///
- /// \note throws std::bad_cast if the loc does not have \ref info facet installed
+ /// \throws std::bad_cast: \a loc does not have \ref info facet installed
+ /// \throws invalid_charset_error: Character set is not supported
+ /// \throws conversion_error: Conversion failed (e.g. \a how is \c stop and any character cannot be
+ /// encoded or decoded)
template<typename CharType>
- std::basic_string<CharType> to_utf(const char* text, const std::locale& loc, method_type how = default_method)
+ std::string
+ from_utf(const std::basic_string<CharType>& text, const std::locale& loc, method_type how = default_method)
{
- return to_utf<CharType>(text, util::str_end(text), loc, how);
+ return from_utf(text, std::use_facet<info>(loc).encoding(), how);
}
- /// Convert a \a text in UTF to locale encoding given by \a loc
+ /// Convert \a text from UTF to locale encoding given by \a loc according to policy \a how
///
- /// \note throws std::bad_cast if the loc does not have \ref info facet installed
+ /// \throws std::bad_cast: \a loc does not have \ref info facet installed
+ /// \throws invalid_charset_error: Character set is not supported
+ /// \throws conversion_error: Conversion failed (e.g. \a how is \c stop and any character cannot be
+ /// encoded or decoded)
template<typename CharType>
std::string from_utf(const CharType* text, const std::locale& loc, method_type how = default_method)
{
- return from_utf(text, util::str_end(text), loc, how);
+ return from_utf(text, std::use_facet<info>(loc).encoding(), how);
}
- /// Convert a text in range [begin,end) to \a to_encoding from \a from_encoding
+ /// Convert a text in range [begin,end) to \a to_encoding from \a from_encoding according to
+ /// policy \a how
+ ///
+ /// \throws invalid_charset_error: Either character set is not supported
+ /// \throws conversion_error: when the conversion fails (e.g. \a how is \c stop and any character cannot be
+ /// encoded or decoded)
BOOST_LOCALE_DECL
std::string between(const char* begin,
const char* end,
@@ -137,73 +186,126 @@ namespace boost { namespace locale {
const std::string& from_encoding,
method_type how = default_method);
- /// Convert a \a text to \a to_encoding from \a from_encoding
+ /// Convert \a text to \a to_encoding from \a from_encoding according to
+ /// policy \a how
+ ///
+ /// \throws invalid_charset_error: Either character set is not supported
+ /// \throws conversion_error: Conversion failed (e.g. \a how is \c stop and any character cannot be
+ /// encoded or decoded)
inline std::string between(const char* text,
const std::string& to_encoding,
const std::string& from_encoding,
method_type how = default_method)
{
- return boost::locale::conv::between(text, util::str_end(text), to_encoding, from_encoding, how);
+ return between(text, util::str_end(text), to_encoding, from_encoding, how);
}
- /// Convert a \a text to \a to_encoding from \a from_encoding
+ /// Convert \a text to \a to_encoding from \a from_encoding according to
+ /// policy \a how
+ ///
+ /// \throws invalid_charset_error: Either character set is not supported
+ /// \throws conversion_error: Conversion failed (e.g. \a how is \c stop and any character cannot be
+ /// encoded or decoded)
inline std::string between(const std::string& text,
const std::string& to_encoding,
const std::string& from_encoding,
method_type how = default_method)
{
- return boost::locale::conv::between(text.c_str(),
- text.c_str() + text.size(),
- to_encoding,
- from_encoding,
- how);
+ return between(text.c_str(), text.c_str() + text.size(), to_encoding, from_encoding, how);
}
- /// \cond INTERNAL
-
- template<>
- BOOST_LOCALE_DECL std::basic_string<char>
- to_utf(const char* begin, const char* end, const std::string& charset, method_type how);
-
- template<>
- BOOST_LOCALE_DECL std::string
- from_utf(const char* begin, const char* end, const std::string& charset, method_type how);
-
- template<>
- BOOST_LOCALE_DECL std::basic_string<wchar_t>
- to_utf(const char* begin, const char* end, const std::string& charset, method_type how);
-
- template<>
- BOOST_LOCALE_DECL std::string
- from_utf(const wchar_t* begin, const wchar_t* end, const std::string& charset, method_type how);
-
-#ifdef BOOST_LOCALE_ENABLE_CHAR16_T
- template<>
- BOOST_LOCALE_DECL std::basic_string<char16_t>
- to_utf(const char* begin, const char* end, const std::string& charset, method_type how);
-
- template<>
- BOOST_LOCALE_DECL std::string
- from_utf(const char16_t* begin, const char16_t* end, const std::string& charset, method_type how);
-#endif
-
-#ifdef BOOST_LOCALE_ENABLE_CHAR32_T
- template<>
- BOOST_LOCALE_DECL std::basic_string<char32_t>
- to_utf(const char* begin, const char* end, const std::string& charset, method_type how);
-
- template<>
- BOOST_LOCALE_DECL std::string
- from_utf(const char32_t* begin, const char32_t* end, const std::string& charset, method_type how);
-#endif
-
- /// \endcond
-
/// @}
+ /// Converter class to decode a narrow string using a local encoding and encode it with UTF
+ template<typename CharType>
+ class utf_encoder {
+ std::unique_ptr<detail::utf_encoder<CharType>> impl_;
+
+ public:
+ using char_type = CharType;
+ using string_type = std::basic_string<CharType>;
+
+ /// Create an instance to convert text encoded with \a charset to UTF according to policy \a how
+ ///
+ /// Note: When converting only a single text \ref to_utf is likely faster.
+ /// \throws invalid_charset_error: Character set is not supported
+ utf_encoder(const std::string& charset, method_type how = default_method) :
+ impl_(detail::make_utf_encoder<CharType>(charset, how))
+ {}
+
+ /// Convert text in range [begin,end) to UTF
+ ///
+ /// \throws conversion_error: Conversion failed
+ string_type convert(const char* begin, const char* end) const { return impl_->convert(begin, end); }
+ /// Convert \a text to UTF
+ ///
+ /// \throws conversion_error: Conversion failed
+ string_type convert(const boost::string_view& text) const { return impl_->convert(text); }
+ /// Convert \a text to UTF
+ ///
+ /// \throws conversion_error: Conversion failed
+ string_type operator()(const boost::string_view& text) const { return convert(text); }
+ };
+
+ /// Converter class to decode an UTF string and encode it using a local encoding
+ template<typename CharType>
+ class utf_decoder {
+ std::unique_ptr<detail::utf_decoder<CharType>> impl_;
+
+ public:
+ using char_type = CharType;
+ using stringview_type = boost::basic_string_view<CharType>;
+
+ /// Create an instance to convert UTF text to text encoded with \a charset according to policy \a how
+ ///
+ /// Note: When converting only a single text \ref from_utf is likely faster.
+ /// \throws invalid_charset_error: Character set is not supported
+ utf_decoder(const std::string& charset, method_type how = default_method) :
+ impl_(detail::make_utf_decoder<CharType>(charset, how))
+ {}
+
+ /// Convert UTF text in range [begin,end) to local encoding
+ ///
+ /// \throws conversion_error: Conversion failed
+ std::string convert(const CharType* begin, const CharType* end) const { return impl_->convert(begin, end); }
+ /// Convert \a text from UTF to local encoding
+ ///
+ /// \throws conversion_error: Conversion failed
+ std::string convert(const stringview_type& text) const { return impl_->convert(text); }
+ /// Convert \a text from UTF to local encoding
+ ///
+ /// \throws conversion_error: Conversion failed
+ std::string operator()(const stringview_type& text) const { return convert(text); }
+ };
+
+ class narrow_converter {
+ std::unique_ptr<detail::narrow_converter> impl_;
+
+ public:
+ /// Create converter to convert text from \a src_encoding to \a target_encoding according to policy \a how
+ ///
+ /// \throws invalid_charset_error: Either character set is not supported
+ narrow_converter(const std::string& src_encoding,
+ const std::string& target_encoding,
+ method_type how = default_method) :
+ impl_(detail::make_narrow_converter(src_encoding, target_encoding, how))
+ {}
+
+ /// Convert text in range [begin,end)
+ ///
+ /// \throws conversion_error: Conversion failed
+ std::string convert(const char* begin, const char* end) const { return impl_->convert(begin, end); }
+ /// Convert \a text
+ ///
+ /// \throws conversion_error: Conversion failed
+ std::string convert(const boost::string_view& text) const { return impl_->convert(text); }
+ /// Convert \a text
+ ///
+ /// \throws conversion_error: Conversion failed
+ std::string operator()(const boost::string_view& text) const { return convert(text); }
+ };
} // namespace conv
-
-}} // namespace boost::locale
+}} // namespace boost::locale
#ifdef BOOST_MSVC
# pragma warning(pop)
diff --git a/contrib/restricted/boost/locale/include/boost/locale/encoding_errors.hpp b/contrib/restricted/boost/locale/include/boost/locale/encoding_errors.hpp
index 6643a6394e..97f0f6b4eb 100644
--- a/contrib/restricted/boost/locale/include/boost/locale/encoding_errors.hpp
+++ b/contrib/restricted/boost/locale/include/boost/locale/encoding_errors.hpp
@@ -33,7 +33,7 @@ namespace boost { namespace locale { namespace conv {
public:
/// Create an error for charset \a charset
invalid_charset_error(const std::string& charset) :
- std::runtime_error("Invalid or unsupported charset:" + charset)
+ std::runtime_error("Invalid or unsupported charset: " + charset)
{}
};
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 ed1e5db3c4..c19e67d3b8 100644
--- a/contrib/restricted/boost/locale/include/boost/locale/encoding_utf.hpp
+++ b/contrib/restricted/boost/locale/include/boost/locale/encoding_utf.hpp
@@ -23,27 +23,28 @@ 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)
{
std::basic_string<CharOut> result;
result.reserve(end - begin);
- typedef std::back_insert_iterator<std::basic_string<CharOut>> inserter_type;
- inserter_type inserter(result);
- utf::code_point c;
+ std::back_insert_iterator<std::basic_string<CharOut>> inserter(result);
while(begin != end) {
- c = utf::utf_traits<CharIn>::template decode<const CharIn*>(begin, end);
+ const utf::code_point c = utf::utf_traits<CharIn>::decode(begin, end);
if(c == utf::illegal || c == utf::incomplete) {
if(how == stop)
throw conversion_error();
- } else {
- utf::utf_traits<CharOut>::template encode<inserter_type>(c, inserter);
- }
+ } else
+ utf::utf_traits<CharOut>::encode(c, inserter);
}
return result;
}
/// Convert a Unicode NULL terminated string \a str 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)
{
@@ -51,6 +52,8 @@ namespace boost { namespace locale { namespace conv {
}
/// Convert a Unicode string \a str 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)
{
diff --git a/contrib/restricted/boost/locale/include/boost/locale/format.hpp b/contrib/restricted/boost/locale/include/boost/locale/format.hpp
index 67a925da2d..266b65c735 100644
--- a/contrib/restricted/boost/locale/include/boost/locale/format.hpp
+++ b/contrib/restricted/boost/locale/include/boost/locale/format.hpp
@@ -1,5 +1,6 @@
//
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+// Copyright (c) 2021-2023 Alexander Grund
//
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
@@ -12,6 +13,7 @@
#include <boost/locale/message.hpp>
#include <sstream>
#include <stdexcept>
+#include <string>
#include <vector>
#ifdef BOOST_MSVC
@@ -35,15 +37,15 @@ namespace boost { namespace locale {
typedef std::basic_ostream<CharType> stream_type;
typedef void (*writer_type)(stream_type& output, const void* ptr);
- formattible() : pointer_(0), writer_(&formattible::void_write) {}
+ formattible() noexcept : pointer_(nullptr), writer_(&formattible::void_write) {}
- formattible(const formattible&) = default;
- formattible(formattible&&) = default;
- formattible& operator=(const formattible&) = default;
- formattible& operator=(formattible&&) = default;
+ formattible(const formattible&) noexcept = default;
+ formattible(formattible&&) noexcept = default;
+ formattible& operator=(const formattible&) noexcept = default;
+ formattible& operator=(formattible&&) noexcept = default;
template<typename Type>
- explicit formattible(const Type& value)
+ explicit formattible(const Type& value) noexcept
{
pointer_ = static_cast<const void*>(&value);
writer_ = &write<Type>;
@@ -173,10 +175,12 @@ namespace boost { namespace locale {
/// \endcode
///
///
- /// Invalid formatting strings are slightly ignored. This would prevent from translator
- /// to crash the program in unexpected location.
+ /// Invalid formatting strings are silently ignored.
+ /// This protects against a translator crashing the program in an unexpected location.
template<typename CharType>
class basic_format {
+ int throw_if_params_bound() const;
+
public:
typedef CharType char_type; ///< Underlying character type
typedef basic_message<char_type> message_type; ///< The translation message type
@@ -199,16 +203,12 @@ namespace boost { namespace locale {
void operator=(const basic_format& other) = delete;
/// Moveable
basic_format(basic_format&& other) :
- message_(std::move(other.message_)), format_(std::move(other.format_)), translate_(other.translate_),
- parameters_count_(0)
- {
- if(other.parameters_count_)
- throw std::invalid_argument("Can't move a basic_format with bound parameters");
- }
+ message_((other.throw_if_params_bound(), std::move(other.message_))), format_(std::move(other.format_)),
+ translate_(other.translate_), parameters_count_(0)
+ {}
basic_format& operator=(basic_format&& other)
{
- if(other.parameters_count_)
- throw std::invalid_argument("Can't move a basic_format with bound parameters");
+ other.throw_if_params_bound();
message_ = std::move(other.message_);
format_ = std::move(other.format_);
translate_ = other.translate_;
@@ -262,39 +262,37 @@ namespace boost { namespace locale {
private:
class format_guard {
public:
- format_guard(detail::format_parser& fmt) : fmt_(&fmt), restored_(false) {}
+ format_guard(detail::format_parser& fmt) : fmt_(fmt), restored_(false) {}
void restore()
{
if(restored_)
return;
- fmt_->restore();
+ fmt_.restore();
restored_ = true;
}
~format_guard()
{
- try {
- restore();
- } catch(...) {
- }
+ // clang-format off
+ try { restore(); } catch(...) {}
+ // clang-format on
}
private:
- detail::format_parser* fmt_;
+ detail::format_parser& fmt_;
bool restored_;
};
void format_output(stream_type& out, const string_type& sformat) const
{
- char_type obrk = '{';
- char_type cbrk = '}';
- char_type eq = '=';
- char_type comma = ',';
- char_type quote = '\'';
-
- size_t pos = 0;
- size_t size = sformat.size();
+ constexpr char_type obrk = '{';
+ constexpr char_type cbrk = '}';
+ constexpr char_type eq = '=';
+ constexpr char_type comma = ',';
+ constexpr char_type quote = '\'';
+
+ const size_t size = sformat.size();
const CharType* format = sformat.c_str();
- while(format[pos] != 0) {
+ for(size_t pos = 0; format[pos];) {
if(format[pos] != obrk) {
if(format[pos] == cbrk && format[pos + 1] == cbrk) {
out << cbrk;
@@ -305,13 +303,11 @@ namespace boost { namespace locale {
}
continue;
}
-
- if(pos + 1 < size && format[pos + 1] == obrk) {
+ pos++;
+ if(format[pos] == obrk) {
out << obrk;
- pos += 2;
continue;
}
- pos++;
detail::format_parser fmt(out, static_cast<void*>(&out), &basic_format::imbue_locale);
@@ -322,13 +318,8 @@ namespace boost { namespace locale {
std::string svalue;
string_type value;
bool use_svalue = true;
- for(; format[pos]; pos++) {
- char_type c = format[pos];
- if(c == comma || c == eq || c == cbrk)
- break;
- else {
- key += static_cast<char>(c);
- }
+ for(char_type c = format[pos]; !(c == 0 || c == comma || c == eq || c == cbrk); c = format[++pos]) {
+ key += static_cast<char>(c);
}
if(format[pos] == eq) {
@@ -359,22 +350,19 @@ namespace boost { namespace locale {
}
}
- if(use_svalue) {
+ if(use_svalue)
fmt.set_one_flag(key, svalue);
- } else
+ else
fmt.set_flag_with_str(key, value);
- if(format[pos] == comma) {
- pos++;
- continue;
- } else if(format[pos] == cbrk) {
- unsigned position = fmt.get_position();
- out << get(position);
- guard.restore();
+ if(format[pos] == comma)
pos++;
- break;
- } else {
- guard.restore();
+ else {
+ if(format[pos] == cbrk) {
+ unsigned position = fmt.get_position();
+ out << get(position);
+ pos++;
+ }
break;
}
}
@@ -400,7 +388,7 @@ namespace boost { namespace locale {
return parameters_[id];
}
- static void imbue_locale(void* ptr, const std::locale& l) { reinterpret_cast<stream_type*>(ptr)->imbue(l); }
+ static void imbue_locale(void* ptr, const std::locale& l) { static_cast<stream_type*>(ptr)->imbue(l); }
static constexpr unsigned base_params_ = 8;
@@ -438,6 +426,13 @@ namespace boost { namespace locale {
typedef basic_format<char32_t> u32format;
#endif
+ template<typename CharType>
+ int basic_format<CharType>::throw_if_params_bound() const
+ {
+ if(parameters_count_)
+ throw std::invalid_argument("Can't move a basic_format with bound parameters");
+ return 0;
+ }
/// @}
}} // namespace boost::locale
diff --git a/contrib/restricted/boost/locale/include/boost/locale/formatting.hpp b/contrib/restricted/boost/locale/include/boost/locale/formatting.hpp
index 70397eed89..936ce7e12d 100644
--- a/contrib/restricted/boost/locale/include/boost/locale/formatting.hpp
+++ b/contrib/restricted/boost/locale/include/boost/locale/formatting.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
@@ -8,9 +9,9 @@
#define BOOST_LOCALE_FORMATTING_HPP_INCLUDED
#include <boost/locale/time_zone.hpp>
-#include <boost/locale/util/string.hpp>
#include <boost/assert.hpp>
-#include <boost/cstdint.hpp>
+#include <boost/utility/string_view.hpp>
+#include <cstdint>
#include <cstring>
#include <istream>
#include <ostream>
@@ -129,15 +130,13 @@ namespace boost { namespace locale {
template<typename CharType>
void date_time_pattern(const std::basic_string<CharType>& str)
{
- string_set& s = date_time_pattern_set();
- s.set(str.c_str());
+ date_time_pattern_set().set<CharType>(str);
}
/// Get date/time pattern (strftime like)
template<typename CharType>
std::basic_string<CharType> date_time_pattern() const
{
- const string_set& s = date_time_pattern_set();
- return s.get<CharType>();
+ return date_time_pattern_set().get<CharType>();
}
/// \cond INTERNAL
@@ -159,23 +158,24 @@ namespace boost { namespace locale {
void swap(string_set& other);
template<typename Char>
- void set(const Char* s)
+ void set(const boost::basic_string_view<Char> s)
{
- BOOST_ASSERT(s);
+ BOOST_ASSERT(!s.empty());
delete[] ptr;
ptr = nullptr;
type = &typeid(Char);
- size = sizeof(Char) * (util::str_end(s) - s + 1);
- ptr = new char[size];
- memcpy(ptr, s, size);
+ 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 == 0 || *type != typeid(Char))
+ if(type == nullptr || *type != typeid(Char))
throw std::bad_cast();
- std::basic_string<Char> result = reinterpret_cast<const Char*>(ptr);
+ std::basic_string<Char> result(size / sizeof(Char), Char(0));
+ memcpy(&result.front(), ptr, size);
return result;
}
diff --git a/contrib/restricted/boost/locale/include/boost/locale/generator.hpp b/contrib/restricted/boost/locale/include/boost/locale/generator.hpp
index bfbd528071..f9ae9c777d 100644
--- a/contrib/restricted/boost/locale/include/boost/locale/generator.hpp
+++ b/contrib/restricted/boost/locale/include/boost/locale/generator.hpp
@@ -8,7 +8,7 @@
#define BOOST_LOCALE_GENERATOR_HPP
#include <boost/locale/hold_ptr.hpp>
-#include <boost/cstdint.hpp>
+#include <cstdint>
#include <locale>
#include <memory>
#include <string>
@@ -182,12 +182,6 @@ namespace locale {
/// Shortcut to generate(id)
std::locale operator()(const std::string& id) const { return generate(id); }
- /// Set backend specific option
- void set_option(const std::string& name, const std::string& value);
-
- /// Clear backend specific options
- void clear_options();
-
private:
void set_all_options(localization_backend& backend, const std::string& id) const;
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 428a9f0914..449b1de728 100644
--- a/contrib/restricted/boost/locale/include/boost/locale/generic_codecvt.hpp
+++ b/contrib/restricted/boost/locale/include/boost/locale/generic_codecvt.hpp
@@ -1,5 +1,6 @@
//
// Copyright (c) 2015 Artyom Beilis (Tonkikh)
+// Copyright (c) 2021-2023 Alexander Grund
//
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
@@ -8,28 +9,37 @@
#define BOOST_LOCALE_GENERIC_CODECVT_HPP
#include <boost/locale/utf.hpp>
-#include <boost/cstdint.hpp>
+#include <cstdint>
#include <locale>
namespace boost { namespace locale {
-#ifndef BOOST_LOCALE_DOXYGEN
- //
- // Make sure that mbstate can keep 16 bit of UTF-16 sequence
- //
- static_assert(sizeof(std::mbstate_t) >= 2, "std::mbstate_t is to small");
-#endif
-
-#if defined(_MSC_VER) && _MSC_VER < 1700
-// up to MSVC 11 (2012) do_length is non-standard it counts wide characters instead of narrow and does not change
-// mbstate
-# define BOOST_LOCALE_DO_LENGTH_MBSTATE_CONST
-#endif
+ static_assert(sizeof(std::mbstate_t) >= 2, "std::mbstate_t is to small to store an UTF-16 codepoint");
+ namespace detail {
+ // Avoid including cstring for std::memcpy
+ inline void copy_uint16_t(void* dst, const void* src)
+ {
+ unsigned char* cdst = static_cast<unsigned char*>(dst);
+ const unsigned char* csrc = static_cast<const unsigned char*>(src);
+ cdst[0] = csrc[0];
+ cdst[1] = csrc[1];
+ }
+ inline uint16_t read_state(const std::mbstate_t& src)
+ {
+ uint16_t dst;
+ copy_uint16_t(&dst, &src);
+ return dst;
+ }
+ inline void write_state(std::mbstate_t& dst, const uint16_t src)
+ {
+ copy_uint16_t(&dst, &src);
+ }
+ } // namespace detail
/// \brief A base class that used to define constants for generic_codecvt
class generic_codecvt_base {
public:
- /// Initial state for converting to or from unicode code points, used by initial_state in derived classes
+ /// Initial state for converting to or from Unicode code points, used by initial_state in derived classes
enum initial_convertion_state {
to_unicode_state, ///< The state would be used by to_unicode functions
from_unicode_state ///< The state would be used by from_unicode functions
@@ -47,13 +57,13 @@ namespace boost { namespace locale {
/// that creates initial state
/// - `int max_encoding_length() const` - a maximal length that one Unicode code point is represented, for UTF-8 for
/// example it is 4 from ISO-8859-1 it is 1
- /// - `utf::code_point to_unicode(state_type &state,char const *&begin,char const *end)` - extract first code point
- /// from the text in range [begin,end), in case of success begin would point to the next character sequence to be
- /// encoded to next code point, in case of incomplete sequence - utf::incomplete shell be returned, and in case of
- /// invalid input sequence utf::illegal shell be returned and begin would remain unmodified
- /// - `utf::code_point from_unicode(state_type &state,utf::code_point u,char *begin,char const *end)` - convert a
- /// unicode code point `u` into a character sequence at [begin,end). Return the length of the sequence in case of
- /// success, utf::incomplete in case of not enough room to encode the code point of utf::illegal in case conversion
+ /// - `utf::code_point to_unicode(state_type& state, const char*& begin, const char* end)` - extract first code
+ /// point from the text in range [begin,end), in case of success begin would point to the next character sequence to
+ /// be encoded to next code point, in case of incomplete sequence - utf::incomplete shell be returned, and in case
+ /// of invalid input sequence utf::illegal shell be returned and begin would remain unmodified
+ /// - `utf::len_or_error from_unicode(state_type &state, utf::code_point u, char* begin, const char* end)` - convert
+ /// a Unicode code point `u` into a character sequence at [begin,end). Return the length of the sequence in case of
+ /// success, utf::incomplete in case of not enough room to encode the code point, or utf::illegal in case conversion
/// can not be performed
///
///
@@ -62,7 +72,7 @@ namespace boost { namespace locale {
/// \code
///
/// template<typename CharType>
- /// class latin1_codecvt :boost::locale::generic_codecvt<CharType,latin1_codecvt<CharType> >
+ /// class latin1_codecvt: boost::locale::generic_codecvt<CharType,latin1_codecvt<CharType> >
/// {
/// public:
///
@@ -84,15 +94,15 @@ namespace boost { namespace locale {
/// return 1;
/// }
///
- /// boost::locale::utf::code_point to_unicode(state_type &,char const *&begin,char const *end) const
+ /// boost::locale::utf::code_point to_unicode(state_type&, const char*& begin, const char* end) const
/// {
/// if(begin == end)
/// return boost::locale::utf::incomplete;
/// return *begin++;
/// }
///
- /// boost::locale::utf::code_point from_unicode(state_type &,boost::locale::utf::code_point u,char *begin,char
- /// const *end) const
+ /// boost::locale::utf::len_or_error from_unicode(state_type&, boost::locale::utf::code_point u,
+ /// char* begin, const char* end) const
/// {
/// if(u >= 256)
/// return boost::locale::utf::illegal;
@@ -110,23 +120,21 @@ namespace boost { namespace locale {
///
/// \code
/// template<typename CharType>
- /// class icu_codecvt :boost::locale::generic_codecvt<CharType,icu_codecvt<CharType> >
+ /// class icu_codecvt: boost::locale::generic_codecvt<CharType,icu_codecvt<CharType>>
/// {
/// public:
///
/// /* Standard codecvt constructor */
/// icu_codecvt(std::string const &name,refs = 0):
- /// boost::locale::generic_codecvt<CharType,latin1_codecvt<CharType> >(refs)
+ /// boost::locale::generic_codecvt<CharType,icu_codecvt<CharType>>(refs)
/// { ... }
///
- /// /* State is unused but required by generic_codecvt */
- /// struct std::unique_ptr<UConverter,void (*)(UConverter*)> state_type;
+ /// using state_type = std::unique_ptr<UConverter,void (*)(UConverter*)>;
///
- /// state_type &&initial_state(generic_codecvt_base::initial_convertion_state /*unused*/) const
+ /// state_type initial_state(generic_codecvt_base::initial_convertion_state /*unused*/) const
/// {
/// UErrorCode err = U_ZERO_ERROR;
- /// state_type ptr(ucnv_safeClone(converter_,0,0,&err,ucnv_close);
- /// return std::move(ptr);
+ /// return state_type(ucnv_safeClone(converter_,0,0,&err),ucnv_close);
/// }
///
/// boost::locale::utf::code_point to_unicode(state_type &ptr,char const *&begin,char const *end) const
@@ -160,8 +168,7 @@ namespace boost { namespace locale {
protected:
std::codecvt_base::result do_unshift(std::mbstate_t& s, char* from, char* /*to*/, char*& next) const override
{
- boost::uint16_t& state = *reinterpret_cast<boost::uint16_t*>(&s);
- if(state != 0)
+ if(*reinterpret_cast<char*>(&s) != 0)
return std::codecvt_base::error;
next = from;
return std::codecvt_base::ok;
@@ -170,47 +177,28 @@ namespace boost { namespace locale {
int do_max_length() const noexcept override { return implementation().max_encoding_length(); }
bool do_always_noconv() const noexcept override { return false; }
- int do_length(
-#ifdef BOOST_LOCALE_DO_LENGTH_MBSTATE_CONST
- const
-#endif
- std::mbstate_t& std_state,
- const char* from,
- const char* from_end,
- size_t max) const override
+ int do_length(std::mbstate_t& std_state, const char* from, const char* from_end, size_t max) const override
{
-#ifndef BOOST_LOCALE_DO_LENGTH_MBSTATE_CONST
+ bool state = *reinterpret_cast<char*>(&std_state) != 0;
const char* save_from = from;
- boost::uint16_t& state = *reinterpret_cast<boost::uint16_t*>(&std_state);
-#else
- const size_t start_max = max;
- boost::uint16_t state = *reinterpret_cast<const boost::uint16_t*>(&std_state);
-#endif
- typename CodecvtImpl::state_type cvt_state =
- implementation().initial_state(generic_codecvt_base::to_unicode_state);
+ auto cvt_state = implementation().initial_state(to_unicode_state);
while(max > 0 && from < from_end) {
const char* prev_from = from;
- boost::uint32_t ch = implementation().to_unicode(cvt_state, from, from_end);
+ const utf::code_point ch = implementation().to_unicode(cvt_state, from, from_end);
if(ch == boost::locale::utf::incomplete || ch == boost::locale::utf::illegal) {
from = prev_from;
break;
}
max--;
if(ch > 0xFFFF) {
- if(state == 0) {
+ if(!state)
from = prev_from;
- state = 1;
- } else {
- state = 0;
- }
+ state = !state;
}
}
-#ifndef BOOST_LOCALE_DO_LENGTH_MBSTATE_CONST
+ *reinterpret_cast<char*>(&std_state) = state;
return static_cast<int>(from - save_from);
-#else
- return static_cast<int>(start_max - max);
-#endif
}
std::codecvt_base::result do_in(std::mbstate_t& std_state,
@@ -226,15 +214,14 @@ namespace boost { namespace locale {
// mbstate_t is POD type and should be initialized to 0 (i.a. state = stateT())
// according to standard. We use it to keep a flag 0/1 for surrogate pair writing
//
- // if 0 no code above >0xFFFF observed, of 1 a code above 0xFFFF observed
+ // if 0/false no codepoint above >0xFFFF observed, else a codepoint above 0xFFFF was observed
// and first pair is written, but no input consumed
- boost::uint16_t& state = *reinterpret_cast<boost::uint16_t*>(&std_state);
- typename CodecvtImpl::state_type cvt_state =
- implementation().initial_state(generic_codecvt_base::to_unicode_state);
+ bool state = *reinterpret_cast<char*>(&std_state) != 0;
+ auto cvt_state = implementation().initial_state(to_unicode_state);
while(to < to_end && from < from_end) {
const char* from_saved = from;
- uint32_t ch = implementation().to_unicode(cvt_state, from, from_end);
+ utf::code_point ch = implementation().to_unicode(cvt_state, from, from_end);
if(ch == boost::locale::utf::illegal) {
from = from_saved;
@@ -247,9 +234,9 @@ namespace boost { namespace locale {
break;
}
// Normal codepoints go directly to stream
- if(ch <= 0xFFFF) {
+ if(ch <= 0xFFFF)
*to++ = static_cast<uchar>(ch);
- } else {
+ else {
// For other codepoints we do the following
//
// 1. We can't consume our input as we may find ourselves
@@ -260,22 +247,21 @@ namespace boost { namespace locale {
// once again and then we would consume our input together with writing
// second surrogate pair
ch -= 0x10000;
- boost::uint16_t w1 = static_cast<boost::uint16_t>(0xD800 | (ch >> 10));
- boost::uint16_t w2 = static_cast<boost::uint16_t>(0xDC00 | (ch & 0x3FF));
- if(state == 0) {
+ std::uint16_t w1 = static_cast<std::uint16_t>(0xD800 | (ch >> 10));
+ std::uint16_t w2 = static_cast<std::uint16_t>(0xDC00 | (ch & 0x3FF));
+ if(!state) {
from = from_saved;
*to++ = w1;
- state = 1;
- } else {
+ } else
*to++ = w2;
- state = 0;
- }
+ state = !state;
}
}
from_next = from;
to_next = to;
- if(r == std::codecvt_base::ok && (from != from_end || state != 0))
+ if(r == std::codecvt_base::ok && (from != from_end || state))
r = std::codecvt_base::partial;
+ *reinterpret_cast<char*>(&std_state) = state;
return r;
}
@@ -294,22 +280,21 @@ namespace boost { namespace locale {
//
// State: state!=0 - a first surrogate pair was observed (state = first pair),
// we expect the second one to come and then zero the state
- boost::uint16_t& state = *reinterpret_cast<boost::uint16_t*>(&std_state);
- typename CodecvtImpl::state_type cvt_state =
- implementation().initial_state(generic_codecvt_base::from_unicode_state);
+ std::uint16_t state = detail::read_state(std_state);
+ auto cvt_state = implementation().initial_state(from_unicode_state);
while(to < to_end && from < from_end) {
- boost::uint32_t ch = 0;
+ utf::code_point ch = 0;
if(state != 0) {
// if the state indicates that 1st surrogate pair was written
// we should make sure that the second one that comes is actually
// second surrogate
- boost::uint16_t w1 = state;
- boost::uint16_t w2 = *from;
+ std::uint16_t w1 = state;
+ std::uint16_t w2 = *from;
// we don't forward from as writing may fail to incomplete or
// partial conversion
if(0xDC00 <= w2 && w2 <= 0xDFFF) {
- boost::uint16_t vh = w1 - 0xD800;
- boost::uint16_t vl = w2 - 0xDC00;
+ std::uint16_t vh = w1 - 0xD800;
+ std::uint16_t vl = w2 - 0xDC00;
ch = ((uint32_t(vh) << 10) | vl) + 0x10000;
} else {
// Invalid surrogate
@@ -338,7 +323,7 @@ namespace boost { namespace locale {
r = std::codecvt_base::error;
break;
}
- boost::uint32_t len = implementation().from_unicode(cvt_state, ch, to, to_end);
+ const utf::code_point len = implementation().from_unicode(cvt_state, ch, to, to_end);
if(len == boost::locale::utf::incomplete) {
r = std::codecvt_base::partial;
break;
@@ -354,6 +339,7 @@ namespace boost { namespace locale {
to_next = to;
if(r == std::codecvt_base::ok && (from != from_end || state != 0))
r = std::codecvt_base::partial;
+ detail::write_state(std_state, state);
return r;
}
};
@@ -383,25 +369,13 @@ namespace boost { namespace locale {
int do_max_length() const noexcept override { return implementation().max_encoding_length(); }
bool do_always_noconv() const noexcept override { return false; }
- int do_length(
-#ifdef BOOST_LOCALE_DO_LENGTH_MBSTATE_CONST
- const
-#endif
- std::mbstate_t& /*state*/,
- const char* from,
- const char* from_end,
- size_t max) const override
+ int do_length(std::mbstate_t& /*state*/, const char* from, const char* from_end, size_t max) const override
{
-#ifndef BOOST_LOCALE_DO_LENGTH_MBSTATE_CONST
const char* start_from = from;
-#else
- const size_t start_max = max;
-#endif
- typename CodecvtImpl::state_type cvt_state =
- implementation().initial_state(generic_codecvt_base::to_unicode_state);
+ auto cvt_state = implementation().initial_state(to_unicode_state);
while(max > 0 && from < from_end) {
const char* save_from = from;
- boost::uint32_t ch = implementation().to_unicode(cvt_state, from, from_end);
+ const utf::code_point ch = implementation().to_unicode(cvt_state, from, from_end);
if(ch == boost::locale::utf::incomplete || ch == boost::locale::utf::illegal) {
from = save_from;
break;
@@ -409,11 +383,7 @@ namespace boost { namespace locale {
max--;
}
-#ifndef BOOST_LOCALE_DO_LENGTH_MBSTATE_CONST
return static_cast<int>(from - start_from);
-#else
- return static_cast<int>(start_max - max);
-#endif
}
std::codecvt_base::result do_in(std::mbstate_t& /*state*/,
@@ -426,16 +396,11 @@ namespace boost { namespace locale {
{
std::codecvt_base::result r = std::codecvt_base::ok;
- // mbstate_t is POD type and should be initialized to 0 (i.a. state = stateT())
- // according to standard. We use it to keep a flag 0/1 for surrogate pair writing
- //
- // if 0 no code above >0xFFFF observed, of 1 a code above 0xFFFF observed
- // and first pair is written, but no input consumed
- auto cvt_state = implementation().initial_state(generic_codecvt_base::to_unicode_state);
+ auto cvt_state = implementation().initial_state(to_unicode_state);
while(to < to_end && from < from_end) {
const char* from_saved = from;
- uint32_t ch = implementation().to_unicode(cvt_state, from, from_end);
+ const utf::code_point ch = implementation().to_unicode(cvt_state, from, from_end);
if(ch == boost::locale::utf::illegal) {
r = std::codecvt_base::error;
@@ -465,15 +430,14 @@ namespace boost { namespace locale {
char*& to_next) const override
{
std::codecvt_base::result r = std::codecvt_base::ok;
- auto cvt_state = implementation().initial_state(generic_codecvt_base::from_unicode_state);
+ auto cvt_state = implementation().initial_state(from_unicode_state);
while(to < to_end && from < from_end) {
- boost::uint32_t ch = 0;
- ch = *from;
+ const std::uint32_t ch = *from;
if(!boost::locale::utf::is_valid_codepoint(ch)) {
r = std::codecvt_base::error;
break;
}
- boost::uint32_t len = implementation().from_unicode(cvt_state, ch, to, to_end);
+ const utf::code_point len = implementation().from_unicode(cvt_state, ch, to, to_end);
if(len == boost::locale::utf::incomplete) {
r = std::codecvt_base::partial;
break;
diff --git a/contrib/restricted/boost/locale/include/boost/locale/gnu_gettext.hpp b/contrib/restricted/boost/locale/include/boost/locale/gnu_gettext.hpp
index 675f5192c4..aff76b1cdc 100644
--- a/contrib/restricted/boost/locale/include/boost/locale/gnu_gettext.hpp
+++ b/contrib/restricted/boost/locale/include/boost/locale/gnu_gettext.hpp
@@ -7,11 +7,18 @@
#ifndef BOOST_LOCLAE_GNU_GETTEXT_HPP
#define BOOST_LOCLAE_GNU_GETTEXT_HPP
+#include <boost/locale/detail/is_supported_char.hpp>
#include <boost/locale/message.hpp>
#include <functional>
#include <stdexcept>
+#include <type_traits>
#include <vector>
+#ifdef BOOST_MSVC
+# pragma warning(push)
+# pragma warning(disable : 4251) // "identifier" : class "type" needs to have dll-interface...
+#endif
+
namespace boost { namespace locale {
/// \addtogroup message
/// @{
@@ -25,7 +32,7 @@ namespace boost { namespace locale {
/// also allows providing functions for charset conversion. Note, you need to provide them,
/// so this structure is not useful for wide characters without subclassing and it will also
/// ignore gettext catalogs that use a charset different from \a encoding.
- struct messages_info {
+ struct BOOST_LOCALE_DECL messages_info {
messages_info() : language("C"), locale_category("LC_MESSAGES") {}
std::string language; ///< The language we load the catalog for, like "ru", "en", "de"
@@ -53,7 +60,7 @@ namespace boost { namespace locale {
/// "UTF-8"
domain(const std::string& n)
{
- size_t pos = n.find('/');
+ const size_t pos = n.find('/');
if(pos == std::string::npos) {
name = n;
encoding = "UTF-8";
@@ -80,7 +87,7 @@ namespace boost { namespace locale {
/// encoded in \a encoding character set into std::vector<char> and return it.
///
/// - If the file does not exist, it should return an empty vector.
- /// - If a error occurs during file read it should throw a error.
+ /// - If an error occurs during file read it should throw an exception.
///
/// \note The user should support only the encodings the locales are created for. So if the user
/// uses only one encoding or the file system is encoding agnostic, he may ignore the \a encoding parameter.
@@ -90,32 +97,19 @@ namespace boost { namespace locale {
/// The callback for handling custom file systems, if it is empty, the real OS file-system
/// is being used.
callback_type callback;
+
+ /// Get paths to folders which may contain catalog files
+ std::vector<std::string> get_catalog_paths() const;
+
+ private:
+ /// Get a list of folder names for the language, country and variant
+ std::vector<std::string> get_lang_folders() const;
};
/// Create a message_format facet using GNU Gettext catalogs. It uses \a info structure to get
/// information about where to read them from and uses it for character set conversion (if needed)
- template<typename CharType>
- message_format<CharType>* create_messages_facet(const messages_info& info);
-
- /// \cond INTERNAL
-
- template<>
- BOOST_LOCALE_DECL message_format<char>* create_messages_facet(const messages_info& info);
-
- template<>
- BOOST_LOCALE_DECL message_format<wchar_t>* create_messages_facet(const messages_info& info);
-
-#ifdef BOOST_LOCALE_ENABLE_CHAR16_T
- template<>
- BOOST_LOCALE_DECL message_format<char16_t>* create_messages_facet(const messages_info& info);
-#endif
-
-#ifdef BOOST_LOCALE_ENABLE_CHAR32_T
- template<>
- BOOST_LOCALE_DECL message_format<char32_t>* create_messages_facet(const messages_info& info);
-#endif
-
- /// \endcond
+ template<typename CharType, class = boost::locale::detail::enable_if_is_supported_char<CharType>>
+ BOOST_LOCALE_DECL message_format<CharType>* create_messages_facet(const messages_info& info);
} // namespace gnu_gettext
@@ -123,4 +117,8 @@ namespace boost { namespace locale {
}} // namespace boost::locale
+#ifdef BOOST_MSVC
+# pragma warning(pop)
+#endif
+
#endif
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 851ddbf210..c421b29013 100644
--- a/contrib/restricted/boost/locale/include/boost/locale/hold_ptr.hpp
+++ b/contrib/restricted/boost/locale/include/boost/locale/hold_ptr.hpp
@@ -8,6 +8,7 @@
#define BOOST_LOCALE_HOLD_PTR_H
#include <boost/locale/config.hpp>
+#include <boost/core/exchange.hpp>
namespace boost { namespace locale {
/// \brief a smart pointer similar to std::unique_ptr but the
@@ -28,7 +29,7 @@ namespace boost { namespace locale {
hold_ptr(const hold_ptr&) = delete;
hold_ptr& operator=(const hold_ptr&) = delete;
// Movable
- hold_ptr(hold_ptr&& other) noexcept : ptr_(other.ptr_) { other.ptr_ = nullptr; }
+ hold_ptr(hold_ptr&& other) noexcept : ptr_(exchange(other.ptr_, nullptr)) {}
hold_ptr& operator=(hold_ptr&& other) noexcept
{
swap(other);
@@ -70,7 +71,7 @@ namespace boost { namespace locale {
}
/// Swap two pointers
- void swap(hold_ptr& other)
+ void swap(hold_ptr& other) noexcept
{
T* tmp = other.ptr_;
other.ptr_ = ptr_;
diff --git a/contrib/restricted/boost/locale/include/boost/locale/info.hpp b/contrib/restricted/boost/locale/include/boost/locale/info.hpp
index e10f134f86..37b5358d5f 100644
--- a/contrib/restricted/boost/locale/include/boost/locale/info.hpp
+++ b/contrib/restricted/boost/locale/include/boost/locale/info.hpp
@@ -8,6 +8,7 @@
#define BOOST_LOCALE_INFO_HPP_INCLUDED
#include <boost/locale/config.hpp>
+#include <boost/locale/detail/facet_id.hpp>
#include <locale>
#include <string>
@@ -21,12 +22,8 @@ namespace boost { namespace locale {
/// \brief a facet that holds general information about locale
///
/// This facet should be always created in order to make all Boost.Locale functions work
- class BOOST_LOCALE_DECL info : public std::locale::facet {
+ class BOOST_SYMBOL_VISIBLE info : public std::locale::facet, public detail::facet_id<info> {
public:
- ~info();
-
- static std::locale::id id; ///< This member uniquely defines this facet, required by STL
-
/// String information about the locale
enum string_propery {
language_property, ///< ISO 639 language id
diff --git a/contrib/restricted/boost/locale/include/boost/locale/localization_backend.hpp b/contrib/restricted/boost/locale/include/boost/locale/localization_backend.hpp
index 37df24e283..bb163cd245 100644
--- a/contrib/restricted/boost/locale/include/boost/locale/localization_backend.hpp
+++ b/contrib/restricted/boost/locale/include/boost/locale/localization_backend.hpp
@@ -70,29 +70,31 @@ namespace boost { namespace locale {
localization_backend_manager(const localization_backend_manager&);
/// Assign localization_backend_manager
localization_backend_manager& operator=(const localization_backend_manager&);
+ /// Move construct localization_backend_manager
+ localization_backend_manager(localization_backend_manager&&) noexcept;
+ /// Move assign localization_backend_manager
+ localization_backend_manager& operator=(localization_backend_manager&&) noexcept;
/// Destructor
~localization_backend_manager();
- /// Create new localization backend according to current settings.
- std::unique_ptr<localization_backend> get() const;
+ /// Create new localization backend according to current settings. Ownership is passed to caller
+ std::unique_ptr<localization_backend> create() const;
- BOOST_DEPRECATED("This function is deprecated, use 'get()' instead")
- std::unique_ptr<localization_backend> get_unique_ptr() const { return get(); }
+ BOOST_DEPRECATED("This function is deprecated, use 'create()' instead")
+ std::unique_ptr<localization_backend> get() const { return create(); } // LCOV_EXCL_LINE
+ BOOST_DEPRECATED("This function is deprecated, use 'create()' instead")
+ std::unique_ptr<localization_backend> get_unique_ptr() const { return create(); } // LCOV_EXCL_LINE
/// Add new backend to the manager, each backend should be uniquely defined by its name.
///
/// This library provides: "icu", "posix", "winapi" and "std" backends.
void add_backend(const std::string& name, std::unique_ptr<localization_backend> backend);
- /// Create new localization backend according to current settings. Ownership is passed to caller
- localization_backend* create() const;
-
- /// Add new backend to the manager, each backend should be uniquely defined by its name.
- /// ownership on backend is transfered
- ///
- /// This library provides: "icu", "posix", "winapi" and "std" backends.
- void adopt_backend(const std::string& name, localization_backend* backend);
+ // clang-format off
+ BOOST_DEPRECATED("This function is deprecated, use 'add_backend' instead")
+ void adopt_backend(const std::string& name, localization_backend* backend) { add_backend(name, std::unique_ptr<localization_backend>(backend)); } // LCOV_EXCL_LINE
+ // clang-format on
/// Clear backend
void remove_all_backends();
diff --git a/contrib/restricted/boost/locale/include/boost/locale/message.hpp b/contrib/restricted/boost/locale/include/boost/locale/message.hpp
index 3aacc5801a..b0a512c18a 100644
--- a/contrib/restricted/boost/locale/include/boost/locale/message.hpp
+++ b/contrib/restricted/boost/locale/include/boost/locale/message.hpp
@@ -1,5 +1,6 @@
//
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+// Copyright (c) 2021-2023 Alexander Grund
//
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
@@ -7,12 +8,15 @@
#ifndef BOOST_LOCALE_MESSAGE_HPP_INCLUDED
#define BOOST_LOCALE_MESSAGE_HPP_INCLUDED
+#include <boost/locale/detail/facet_id.hpp>
+#include <boost/locale/detail/is_supported_char.hpp>
#include <boost/locale/formatting.hpp>
#include <boost/locale/util/string.hpp>
#include <locale>
#include <memory>
#include <set>
#include <string>
+#include <type_traits>
#ifdef BOOST_MSVC
# pragma warning(push)
@@ -36,24 +40,23 @@ namespace boost { namespace locale {
/// @{
///
- /// \cond INTERNAL
-
- template<typename CharType>
- struct base_message_format;
-
- /// \endcond
+ /// Type used for the count/n argument to the translation functions choosing between singular and plural forms
+ using count_type = long long;
/// \brief This facet provides message formatting abilities
template<typename CharType>
- class BOOST_SYMBOL_VISIBLE message_format : public base_message_format<CharType> {
+ class BOOST_SYMBOL_VISIBLE message_format : public std::locale::facet,
+ public detail::facet_id<message_format<CharType>> {
+ BOOST_LOCALE_ASSERT_IS_SUPPORTED(CharType);
+
public:
/// Character type
typedef CharType char_type;
/// String type
typedef std::basic_string<CharType> string_type;
- /// Default constructor
- message_format(size_t refs = 0) : base_message_format<CharType>(refs) {}
+ /// Standard constructor
+ message_format(size_t refs = 0) : std::locale::facet(refs) {}
/// This function returns a pointer to the string for a message defined by a \a context
/// and identification string \a id. Both create a single key for message lookup in
@@ -75,7 +78,7 @@ namespace boost { namespace locale {
///
/// If a translated string is found, it is returned, otherwise NULL is returned
virtual const char_type*
- get(int domain_id, const char_type* context, const char_type* single_id, int n) const = 0;
+ get(int domain_id, const char_type* context, const char_type* single_id, count_type n) const = 0;
/// Convert a string that defines \a domain to the integer id used by \a get functions
virtual int domain(const std::string& domain) const = 0;
@@ -87,9 +90,6 @@ namespace boost { namespace locale {
/// Note: for char_type that is char16_t, char32_t and wchar_t it is no-op, returns
/// msg
virtual const char_type* convert(const char_type* msg, string_type& buffer) const = 0;
-
- protected:
- virtual ~message_format() = default;
};
/// \cond INTERNAL
@@ -146,48 +146,54 @@ namespace boost { namespace locale {
typedef message_format<char_type> facet_type; ///< The type of the facet the messages are fetched with
/// Create default empty message
- basic_message() : n_(0), c_id_(0), c_context_(0), c_plural_(0) {}
+ basic_message() : n_(0), c_id_(nullptr), c_context_(nullptr), c_plural_(nullptr) {}
/// Create a simple message from 0 terminated string. The string should exist
/// until the message is destroyed. Generally useful with static constant strings
- explicit basic_message(const char_type* id) : n_(0), c_id_(id), c_context_(0), c_plural_(0) {}
+ explicit basic_message(const char_type* id) : n_(0), c_id_(id), c_context_(nullptr), c_plural_(nullptr) {}
/// Create a simple plural form message from 0 terminated strings. The strings should exist
/// until the message is destroyed. Generally useful with static constant strings.
///
/// \a n is the number, \a single and \a plural are singular and plural forms of the message
- explicit basic_message(const char_type* single, const char_type* plural, int n) :
- n_(n), c_id_(single), c_context_(0), c_plural_(plural)
+ explicit basic_message(const char_type* single, const char_type* plural, count_type n) :
+ n_(n), c_id_(single), c_context_(nullptr), c_plural_(plural)
{}
/// Create a simple message from 0 terminated strings, with context
/// information. The string should exist
/// until the message is destroyed. Generally useful with static constant strings
explicit basic_message(const char_type* context, const char_type* id) :
- n_(0), c_id_(id), c_context_(context), c_plural_(0)
+ n_(0), c_id_(id), c_context_(context), c_plural_(nullptr)
{}
/// Create a simple plural form message from 0 terminated strings, with context. The strings should exist
/// until the message is destroyed. Generally useful with static constant strings.
///
/// \a n is the number, \a single and \a plural are singular and plural forms of the message
- explicit basic_message(const char_type* context, const char_type* single, const char_type* plural, int n) :
- n_(n), c_id_(single), c_context_(context), c_plural_(plural)
+ explicit basic_message(const char_type* context,
+ const char_type* single,
+ const char_type* plural,
+ count_type n) :
+ n_(n),
+ c_id_(single), c_context_(context), c_plural_(plural)
{}
/// Create a simple message from a string.
- explicit basic_message(const string_type& id) : n_(0), c_id_(0), c_context_(0), c_plural_(0), id_(id) {}
+ explicit basic_message(const string_type& id) :
+ n_(0), c_id_(nullptr), c_context_(nullptr), c_plural_(nullptr), id_(id)
+ {}
/// Create a simple plural form message from strings.
///
/// \a n is the number, \a single and \a plural are single and plural forms of the message
- explicit basic_message(const string_type& single, const string_type& plural, int number) :
- n_(number), c_id_(0), c_context_(0), c_plural_(0), id_(single), plural_(plural)
+ explicit basic_message(const string_type& single, const string_type& plural, count_type number) :
+ n_(number), c_id_(nullptr), c_context_(nullptr), c_plural_(nullptr), id_(single), plural_(plural)
{}
/// Create a simple message from a string with context.
explicit basic_message(const string_type& context, const string_type& id) :
- n_(0), c_id_(0), c_context_(0), c_plural_(0), id_(id), context_(context)
+ n_(0), c_id_(nullptr), c_context_(nullptr), c_plural_(nullptr), id_(id), context_(context)
{}
/// Create a simple plural form message from strings.
@@ -196,41 +202,40 @@ namespace boost { namespace locale {
explicit basic_message(const string_type& context,
const string_type& single,
const string_type& plural,
- int number) :
+ count_type number) :
n_(number),
- c_id_(0), c_context_(0), c_plural_(0), id_(single), context_(context), plural_(plural)
+ c_id_(nullptr), c_context_(nullptr), c_plural_(nullptr), id_(single), context_(context), plural_(plural)
{}
/// Copy an object
basic_message(const basic_message&) = default;
- basic_message(basic_message&&) = default;
+ basic_message(basic_message&&) noexcept = default;
/// Assign other message object to this one
basic_message& operator=(const basic_message&) = default;
- basic_message& operator=(basic_message&&) = default;
+ basic_message&
+ operator=(basic_message&&) noexcept(std::is_nothrow_move_assignable<string_type>::value) = default;
/// Swap two message objects
- void swap(basic_message& other)
+ void
+ swap(basic_message& other) noexcept(noexcept(std::declval<string_type&>().swap(std::declval<string_type&>())))
{
- std::swap(n_, other.n_);
- std::swap(c_id_, other.c_id_);
- std::swap(c_context_, other.c_context_);
- std::swap(c_plural_, other.c_plural_);
-
- id_.swap(other.id_);
- context_.swap(other.context_);
- plural_.swap(other.plural_);
+ using std::swap;
+ swap(n_, other.n_);
+ swap(c_id_, other.c_id_);
+ swap(c_context_, other.c_context_);
+ swap(c_plural_, other.c_plural_);
+ swap(id_, other.id_);
+ swap(context_, other.context_);
+ swap(plural_, other.plural_);
}
+ friend void swap(basic_message& x, basic_message& y) noexcept(noexcept(x.swap(y))) { x.swap(y); }
/// Message class can be explicitly converted to string class
operator string_type() const { return str(); }
/// Translate message to a string in the default global locale, using default domain
- string_type str() const
- {
- std::locale loc;
- return str(loc, 0);
- }
+ string_type str() const { return str(std::locale()); }
/// Translate message to a string in the locale \a locale, using default domain
string_type str(const std::locale& locale) const { return str(locale, 0); }
@@ -245,23 +250,14 @@ namespace boost { namespace locale {
}
/// Translate message to a string using the default locale and message domain \a domain_id
- string_type str(const std::string& domain_id) const
- {
- int id = 0;
- std::locale loc;
- if(std::has_facet<facet_type>(loc))
- id = std::use_facet<facet_type>(loc).domain(domain_id);
- return str(loc, id);
- }
+ string_type str(const std::string& domain_id) const { return str(std::locale(), domain_id); }
/// Translate message to a string using locale \a loc and message domain index \a id
string_type str(const std::locale& loc, int id) const
{
string_type buffer;
const char_type* ptr = write(loc, id, buffer);
- if(ptr == buffer.c_str())
- return buffer;
- else
+ if(ptr != buffer.c_str())
buffer = ptr;
return buffer;
}
@@ -282,7 +278,7 @@ namespace boost { namespace locale {
if(c_plural_)
return c_plural_;
if(plural_.empty())
- return 0;
+ return nullptr;
return plural_.c_str();
}
const char_type* context() const
@@ -290,7 +286,7 @@ namespace boost { namespace locale {
if(c_context_)
return c_context_;
if(context_.empty())
- return 0;
+ return nullptr;
return context_.c_str();
}
@@ -298,7 +294,6 @@ namespace boost { namespace locale {
const char_type* write(const std::locale& loc, int domain_id, string_type& buffer) const
{
- const char_type* translated = 0;
static const char_type empty_string[1] = {0};
const char_type* id = this->id();
@@ -308,33 +303,32 @@ namespace boost { namespace locale {
if(*id == 0)
return empty_string;
- const facet_type* facet = 0;
+ const facet_type* facet = nullptr;
if(std::has_facet<facet_type>(loc))
facet = &std::use_facet<facet_type>(loc);
+ const char_type* translated = nullptr;
if(facet) {
- if(!plural) {
+ if(!plural)
translated = facet->get(domain_id, context, id);
- } else {
+ else
translated = facet->get(domain_id, context, id, n_);
- }
}
if(!translated) {
const char_type* msg = plural ? (n_ == 1 ? id : plural) : id;
- if(facet) {
+ if(facet)
translated = facet->convert(msg, buffer);
- } else {
+ else
translated = detail::string_cast_traits<char_type>::cast(msg, buffer);
- }
}
return translated;
}
/// members
- int n_;
+ count_type n_;
const char_type* c_id_;
const char_type* c_context_;
const char_type* c_plural_;
@@ -383,15 +377,15 @@ namespace boost { namespace locale {
/// \brief Translate a plural message form, \a single and \a plural are not copied
template<typename CharType>
- inline basic_message<CharType> translate(const CharType* single, const CharType* plural, int n)
+ inline basic_message<CharType> translate(const CharType* single, const CharType* plural, count_type n)
{
return basic_message<CharType>(single, plural, n);
}
- /// \brief Translate a plural message from in constext, \a context, \a single and \a plural are not copied
+ /// \brief Translate a plural message from in context, \a context, \a single and \a plural are not copied
template<typename CharType>
inline basic_message<CharType>
- translate(const CharType* context, const CharType* single, const CharType* plural, int n)
+ translate(const CharType* context, const CharType* single, const CharType* plural, count_type n)
{
return basic_message<CharType>(context, single, plural, n);
}
@@ -411,12 +405,12 @@ namespace boost { namespace locale {
return basic_message<CharType>(context, msg);
}
- /// \brief Translate a plural message form in constext, \a context, \a single and \a plural are copied
+ /// \brief Translate a plural message form in context, \a context, \a single and \a plural are copied
template<typename CharType>
inline basic_message<CharType> translate(const std::basic_string<CharType>& context,
const std::basic_string<CharType>& single,
const std::basic_string<CharType>& plural,
- int n)
+ count_type n)
{
return basic_message<CharType>(context, single, plural, n);
}
@@ -424,7 +418,7 @@ namespace boost { namespace locale {
/// \brief Translate a plural message form, \a single and \a plural are copied
template<typename CharType>
inline basic_message<CharType>
- translate(const std::basic_string<CharType>& single, const std::basic_string<CharType>& plural, int n)
+ translate(const std::basic_string<CharType>& single, const std::basic_string<CharType>& plural, count_type n)
{
return basic_message<CharType>(single, plural, n);
}
@@ -442,7 +436,7 @@ namespace boost { namespace locale {
/// Translate plural form according to locale \a loc
template<typename CharType>
std::basic_string<CharType>
- ngettext(const CharType* s, const CharType* p, int n, const std::locale& loc = std::locale())
+ ngettext(const CharType* s, const CharType* p, count_type n, const std::locale& loc = std::locale())
{
return basic_message<CharType>(s, p, n).str(loc);
}
@@ -456,8 +450,11 @@ namespace boost { namespace locale {
/// Translate plural form according to locale \a loc in domain \a domain
template<typename CharType>
- std::basic_string<CharType>
- dngettext(const char* domain, const CharType* s, const CharType* p, int n, const std::locale& loc = std::locale())
+ std::basic_string<CharType> dngettext(const char* domain,
+ const CharType* s,
+ const CharType* p,
+ count_type n,
+ const std::locale& loc = std::locale())
{
return basic_message<CharType>(s, p, n).str(loc, domain);
}
@@ -475,7 +472,7 @@ namespace boost { namespace locale {
std::basic_string<CharType> npgettext(const CharType* context,
const CharType* s,
const CharType* p,
- int n,
+ count_type n,
const std::locale& loc = std::locale())
{
return basic_message<CharType>(context, s, p, n).str(loc);
@@ -495,51 +492,12 @@ namespace boost { namespace locale {
const CharType* context,
const CharType* s,
const CharType* p,
- int n,
+ count_type n,
const std::locale& loc = std::locale())
{
return basic_message<CharType>(context, s, p, n).str(loc, domain);
}
- /// \cond INTERNAL
-
- template<>
- struct BOOST_LOCALE_DECL base_message_format<char> : public std::locale::facet {
- base_message_format(size_t refs = 0) : std::locale::facet(refs) {}
- ~base_message_format();
- static std::locale::id id;
- };
-
- template<>
- struct BOOST_LOCALE_DECL base_message_format<wchar_t> : public std::locale::facet {
- base_message_format(size_t refs = 0) : std::locale::facet(refs) {}
- ~base_message_format();
- static std::locale::id id;
- };
-
-#ifdef BOOST_LOCALE_ENABLE_CHAR16_T
-
- template<>
- struct BOOST_LOCALE_DECL base_message_format<char16_t> : public std::locale::facet {
- base_message_format(size_t refs = 0) : std::locale::facet(refs) {}
- ~base_message_format();
- static std::locale::id id;
- };
-
-#endif
-
-#ifdef BOOST_LOCALE_ENABLE_CHAR32_T
-
- template<>
- struct BOOST_LOCALE_DECL base_message_format<char32_t> : public std::locale::facet {
- base_message_format(size_t refs = 0) : std::locale::facet(refs) {}
- ~base_message_format();
- static std::locale::id id;
- };
-
-#endif
-
- /// \endcond
/// @}
namespace as {
diff --git a/contrib/restricted/boost/locale/include/boost/locale/utf.hpp b/contrib/restricted/boost/locale/include/boost/locale/utf.hpp
index 841b10f67e..a30f736b21 100644
--- a/contrib/restricted/boost/locale/include/boost/locale/utf.hpp
+++ b/contrib/restricted/boost/locale/include/boost/locale/utf.hpp
@@ -8,7 +8,7 @@
#define BOOST_LOCALE_UTF_HPP_INCLUDED
#include <boost/locale/config.hpp>
-#include <boost/cstdint.hpp>
+#include <cstdint>
namespace boost { namespace locale {
/// \brief Namespace that holds basic operations on UTF encoded sequences
@@ -16,13 +16,16 @@ namespace boost { namespace locale {
/// All functions defined in this namespace do not require linking with Boost.Locale library
namespace utf {
/// \brief The integral type that can hold a Unicode code point
- typedef uint32_t code_point;
+ using code_point = uint32_t;
/// \brief Special constant that defines illegal code point
constexpr code_point illegal = 0xFFFFFFFFu;
/// \brief Special constant that defines incomplete code point
constexpr code_point incomplete = 0xFFFFFFFEu;
+ /// Either a length/size or an error (illegal/incomplete)
+ using len_or_error = code_point;
+
/// \brief the function checks if \a v is a valid code point
inline bool is_valid_codepoint(code_point v)
{
@@ -125,15 +128,14 @@ namespace boost { namespace locale {
static int width(code_point value)
{
- if(value <= 0x7F) {
+ if(value <= 0x7F)
return 1;
- } else if(value <= 0x7FF) {
+ else if(value <= 0x7FF)
return 2;
- } else if(BOOST_LIKELY(value <= 0xFFFF)) {
+ else if(BOOST_LIKELY(value <= 0xFFFF))
return 3;
- } else {
+ else
return 4;
- }
}
static bool is_trail(char_type ci)
@@ -235,9 +237,9 @@ namespace boost { namespace locale {
template<typename Iterator>
static Iterator encode(code_point value, Iterator out)
{
- if(value <= 0x7F) {
+ if(value <= 0x7F)
*out++ = static_cast<char_type>(value);
- } else if(value <= 0x7FF) {
+ else if(value <= 0x7FF) {
*out++ = static_cast<char_type>((value >> 6) | 0xC0);
*out++ = static_cast<char_type>((value & 0x3F) | 0x80);
} else if(BOOST_LIKELY(value <= 0xFFFF)) {
@@ -285,9 +287,8 @@ namespace boost { namespace locale {
if(BOOST_UNLIKELY(current == last))
return incomplete;
uint16_t w1 = *current++;
- if(BOOST_LIKELY(w1 < 0xD800 || 0xDFFF < w1)) {
+ if(BOOST_LIKELY(w1 < 0xD800 || 0xDFFF < w1))
return w1;
- }
if(w1 > 0xDBFF)
return illegal;
if(current == last)
@@ -301,9 +302,8 @@ namespace boost { namespace locale {
static code_point decode_valid(It& current)
{
uint16_t w1 = *current++;
- if(BOOST_LIKELY(w1 < 0xD800 || 0xDFFF < w1)) {
+ if(BOOST_LIKELY(w1 < 0xD800 || 0xDFFF < w1))
return w1;
- }
uint16_t w2 = *current++;
return combine_surrogate(w1, w2);
}
@@ -313,9 +313,9 @@ namespace boost { namespace locale {
template<typename It>
static It encode(code_point u, It out)
{
- if(BOOST_LIKELY(u <= 0xFFFF)) {
+ if(BOOST_LIKELY(u <= 0xFFFF))
*out++ = static_cast<char_type>(u);
- } else {
+ else {
u -= 0x10000;
*out++ = static_cast<char_type>(0xD800 | (u >> 10));
*out++ = static_cast<char_type>(0xDC00 | (u & 0x3FF));
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 d2884c6770..797d907346 100644
--- a/contrib/restricted/boost/locale/include/boost/locale/utf8_codecvt.hpp
+++ b/contrib/restricted/boost/locale/include/boost/locale/utf8_codecvt.hpp
@@ -9,7 +9,8 @@
#include <boost/locale/generic_codecvt.hpp>
#include <boost/locale/utf.hpp>
-#include <boost/cstdint.hpp>
+#include <boost/assert.hpp>
+#include <cstdint>
#include <locale>
namespace boost { namespace locale {
@@ -39,12 +40,11 @@ namespace boost { namespace locale {
return c;
}
- static utf::code_point from_unicode(state_type&, utf::code_point u, char* begin, const char* end)
+ static utf::len_or_error from_unicode(state_type&, utf::code_point u, char* begin, const char* end)
{
- if(!utf::is_valid_codepoint(u))
- return utf::illegal;
- int width;
- if((width = utf::utf_traits<char>::width(u)) > end - begin)
+ BOOST_ASSERT(utf::is_valid_codepoint(u));
+ const auto width = utf::utf_traits<char>::width(u);
+ if(width > end - begin)
return utf::incomplete;
utf::utf_traits<char>::encode(u, begin);
return width;
diff --git a/contrib/restricted/boost/locale/include/boost/locale/util.hpp b/contrib/restricted/boost/locale/include/boost/locale/util.hpp
index d5bf8ddcca..5eaf450556 100644
--- a/contrib/restricted/boost/locale/include/boost/locale/util.hpp
+++ b/contrib/restricted/boost/locale/include/boost/locale/util.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
@@ -10,7 +11,7 @@
#include <boost/locale/generator.hpp>
#include <boost/locale/utf.hpp>
#include <boost/assert.hpp>
-#include <boost/cstdint.hpp>
+#include <cstdint>
#include <locale>
#include <memory>
#include <typeinfo>
@@ -68,11 +69,11 @@ namespace boost { namespace locale {
/// This value should be returned when an illegal input sequence or code-point is observed:
/// For example if a UCS-32 code-point is in the range reserved for UTF-16 surrogates
/// or an invalid UTF-8 sequence is found
- static constexpr uint32_t illegal = utf::illegal;
+ static constexpr utf::code_point illegal = utf::illegal;
/// This value is returned in following cases: The of incomplete input sequence was found or
/// insufficient output buffer was provided so complete output could not be written.
- static constexpr uint32_t incomplete = utf::incomplete;
+ static constexpr utf::code_point incomplete = utf::incomplete;
virtual ~base_converter();
@@ -110,7 +111,7 @@ namespace boost { namespace locale {
/// if invalid input sequence found, i.e. there is a sequence [\a begin, \a code_point_end) such as \a
/// code_point_end <= \a end that is illegal for this encoding, \a illegal is returned and begin stays
/// unchanged. For example if *begin = 0xFF and begin < end for UTF-8, then \a illegal is returned.
- virtual uint32_t to_unicode(const char*& begin, const char* end)
+ virtual utf::code_point to_unicode(const char*& begin, const char* end)
{
if(begin == end)
return incomplete;
@@ -132,7 +133,7 @@ namespace boost { namespace locale {
/// -# If end - begin >= N, c1, ... cN are written starting at begin and N is returned
/// -# If end - begin < N, incomplete is returned, it is unspecified what would be
/// stored in bytes in range [begin,end)
- virtual uint32_t from_unicode(uint32_t u, char* begin, const char* end)
+ virtual utf::len_or_error from_unicode(utf::code_point u, char* begin, const char* end)
{
if(begin == end)
return incomplete;
@@ -144,7 +145,7 @@ namespace boost { namespace locale {
};
/// This function creates a \a base_converter that can be used for conversion between UTF-8 and
- /// unicode code points
+ /// Unicode code points
BOOST_LOCALE_DECL std::unique_ptr<base_converter> create_utf8_converter();
BOOST_DEPRECATED("This function is deprecated, use 'create_utf8_converter()'")
@@ -185,15 +186,10 @@ namespace boost { namespace locale {
return create_codecvt(in, std::unique_ptr<base_converter>(cvt), type);
}
- /// This function creates a \a base_converter that can be used for conversion between UTF-8 and
- /// unicode code points
+ BOOST_DEPRECATED("This function is deprecated, use 'create_utf8_converter()'")
BOOST_LOCALE_DECL base_converter* create_utf8_converter_new_ptr();
- /// This function creates a \a base_converter that can be used for conversion between single byte
- /// character encodings like ISO-8859-1, koi8-r, windows-1255 and Unicode code points,
- ///
- /// If \a encoding is not supported, empty pointer is returned. You should check if
- /// the returned pointer is NULL.
+ BOOST_DEPRECATED("This function is deprecated, use 'create_simple_converter()'")
BOOST_LOCALE_DECL base_converter* create_simple_converter_new_ptr(const std::string& encoding);
/// Install utf8 codecvt to UTF-16 or UTF-32 into locale \a in and return
@@ -204,8 +200,8 @@ namespace boost { namespace locale {
/// This function installs codecvt that can be used for conversion between single byte
/// character encodings like ISO-8859-1, koi8-r, windows-1255 and Unicode code points,
///
- /// Throws boost::locale::conv::invalid_charset_error if the character set is not supported or isn't single byte
- /// character set
+ /// \throws boost::locale::conv::invalid_charset_error: Character set is not supported or isn't a single
+ /// byte character set
BOOST_LOCALE_DECL
std::locale create_simple_codecvt(const std::locale& in, const std::string& encoding, char_facet_t type);
} // namespace util
diff --git a/contrib/restricted/boost/locale/include/boost/locale/util/locale_data.hpp b/contrib/restricted/boost/locale/include/boost/locale/util/locale_data.hpp
index 2a04bdcba9..397c404d60 100644
--- a/contrib/restricted/boost/locale/include/boost/locale/util/locale_data.hpp
+++ b/contrib/restricted/boost/locale/include/boost/locale/util/locale_data.hpp
@@ -27,10 +27,11 @@ namespace boost { namespace locale { namespace util {
bool utf8_;
public:
- // Default to C locale with US-ASCII encoding
+ /// Default to C locale with US-ASCII encoding
locale_data();
- // Construct from the parsed locale \see \ref parse
- // Throws `std::invalid_argument` if parsing fails
+ /// Construct from the parsed locale \see \ref parse
+ ///
+ /// \throws std::invalid_argument: parsing failed
explicit locale_data(const std::string& locale_name);
/// Return language (usually 2 lowercase letters, i.e. ISO-639 or 'C')
@@ -39,24 +40,25 @@ namespace boost { namespace locale { namespace util {
const std::string& country() const { return country_; }
/// Return encoding/codeset, e.g. ISO8859-1 or UTF-8
const std::string& encoding() const { return encoding_; }
+ /// Set encoding, will be made uppercase by default as-if it was parsed
+ /// Returns \c *this for chaining
+ locale_data& encoding(std::string new_encoding, bool uppercase = true);
/// Return variant/modifier, e.g. euro or stroke
const std::string& variant() const { return variant_; }
/// Return iff the encoding is UTF-8
bool is_utf8() const { return utf8_; }
- /// <summary>
- /// Parse a locale identifier of the form [language[_territory][.codeset][@modifier]]
- /// Allows a dash as the delimiter: [language-territory]
+ /// Parse a locale identifier of the form `[language[_territory][.codeset][@modifier]]`
///
+ /// Allows a dash as the delimiter: `[language-territory]`
/// Return true if the identifier is valid:
/// - `language` is given and consists of ASCII letters
/// - `territory`, if given, consists of ASCII letters
/// - Any field started by a delimiter (`_`, `-`, `.`, `@`) is not empty
/// Otherwise parsing is aborted. Valid values already parsed stay set, other are defaulted.
- /// </summary>
bool parse(const std::string& locale_name);
- /// Get a representation in the form [language[_territory][.codeset][@modifier]]
+ /// Get a representation in the form `[language[_territory][.codeset][@modifier]]`
/// codeset is omitted if it is US-ASCII
std::string to_string() const;
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 14e52e65af..9ab9521c55 100644
--- a/contrib/restricted/boost/locale/include/boost/locale/util/string.hpp
+++ b/contrib/restricted/boost/locale/include/boost/locale/util/string.hpp
@@ -8,6 +8,7 @@
#define BOOST_LOCALE_UTIL_STRING_HPP
#include <boost/locale/config.hpp>
+#include <limits>
namespace boost { namespace locale { namespace util {
/// Return the end of a C-string, i.e. the pointer to the trailing NULL byte
@@ -19,21 +20,27 @@ namespace boost { namespace locale { namespace util {
return str;
}
- inline bool is_upper_ascii(const char c)
+ inline constexpr bool is_upper_ascii(const char c)
{
return 'A' <= c && c <= 'Z';
}
- inline bool is_lower_ascii(const char c)
+ inline constexpr bool is_lower_ascii(const char c)
{
return 'a' <= c && c <= 'z';
}
- inline bool is_numeric_ascii(const char c)
+ inline constexpr bool is_numeric_ascii(const char c)
{
return '0' <= c && c <= '9';
}
+ /// 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());
+ }
+
}}} // namespace boost::locale::util
#endif \ No newline at end of file
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 631b526161..34b01395bc 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/encoding/codepage.cpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/encoding/codepage.cpp
@@ -1,163 +1,235 @@
//
// 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
#include <boost/locale/encoding.hpp>
-#include <boost/locale/hold_ptr.hpp>
-#include <memory>
-#include <string>
+#include "boost/locale/util/make_std_unique.hpp"
-#include "boost/locale/encoding/conv.hpp"
#if BOOST_LOCALE_USE_WIN32_API
# define BOOST_LOCALE_WITH_WCONV
#endif
#ifdef BOOST_LOCALE_WITH_ICONV
-# include "boost/locale/encoding/iconv_codepage.ipp"
+# include "boost/locale/encoding/iconv_converter.hpp"
#endif
#ifdef BOOST_LOCALE_WITH_ICU
-# include "boost/locale/encoding/uconv_codepage.ipp"
+# include "boost/locale/encoding/uconv_converter.hpp"
#endif
#ifdef BOOST_LOCALE_WITH_WCONV
-# include "boost/locale/encoding/wconv_codepage.ipp"
+# include "boost/locale/encoding/wconv_converter.hpp"
#endif
namespace boost { namespace locale { namespace conv {
- namespace impl {
- std::string convert_between(const char* begin,
- const char* end,
- const char* to_charset,
- const char* from_charset,
- method_type how)
+ std::string between(const char* begin,
+ const char* end,
+ const std::string& to_charset,
+ const std::string& from_charset,
+ method_type how)
+ {
+#ifdef BOOST_LOCALE_WITH_ICONV
+ {
+ impl::iconv_between cvt;
+ if(cvt.open(to_charset, from_charset, how))
+ return cvt.convert(begin, end);
+ }
+#endif
+#ifdef BOOST_LOCALE_WITH_ICU
{
- hold_ptr<converter_between> cvt;
+ impl::uconv_between cvt;
+ if(cvt.open(to_charset, from_charset, how))
+ return cvt.convert(begin, end);
+ }
+#endif
+#ifdef BOOST_LOCALE_WITH_WCONV
+ {
+ impl::wconv_between cvt;
+ if(cvt.open(to_charset, from_charset, how))
+ return cvt.convert(begin, end);
+ }
+#endif
+ throw invalid_charset_error(std::string(to_charset) + " or " + from_charset);
+ }
+
+ template<typename CharType>
+ std::basic_string<CharType> to_utf(const char* begin, const char* end, const std::string& charset, method_type how)
+ {
#ifdef BOOST_LOCALE_WITH_ICONV
- cvt.reset(new iconv_between());
- if(cvt->open(to_charset, from_charset, how))
- return cvt->convert(begin, end);
+ {
+ impl::iconv_to_utf<CharType> cvt;
+ if(cvt.open(charset, how))
+ return cvt.convert(begin, end);
+ }
+#endif
+#ifdef BOOST_LOCALE_WITH_ICU
+ {
+ impl::uconv_to_utf<CharType> cvt;
+ if(cvt.open(charset, how))
+ return cvt.convert(begin, end);
+ }
+#endif
+#ifdef BOOST_LOCALE_WITH_WCONV
+ {
+ impl::wconv_to_utf<CharType> cvt;
+ if(cvt.open(charset, how))
+ return cvt.convert(begin, end);
+ }
+#endif
+ throw invalid_charset_error(charset);
+ }
+
+ template<typename CharType>
+ std::string from_utf(const CharType* begin, const CharType* end, const std::string& charset, method_type how)
+ {
+#ifdef BOOST_LOCALE_WITH_ICONV
+ {
+ impl::iconv_from_utf<CharType> cvt;
+ if(cvt.open(charset, how))
+ return cvt.convert(begin, end);
+ }
#endif
#ifdef BOOST_LOCALE_WITH_ICU
- cvt.reset(new uconv_between());
- if(cvt->open(to_charset, from_charset, how))
- return cvt->convert(begin, end);
+ {
+ impl::uconv_from_utf<CharType> cvt;
+ if(cvt.open(charset, how))
+ return cvt.convert(begin, end);
+ }
#endif
#ifdef BOOST_LOCALE_WITH_WCONV
- cvt.reset(new wconv_between());
- if(cvt->open(to_charset, from_charset, how))
- return cvt->convert(begin, end);
+ {
+ impl::wconv_from_utf<CharType> cvt;
+ if(cvt.open(charset, how))
+ return cvt.convert(begin, end);
+ }
#endif
- throw invalid_charset_error(std::string(to_charset) + " or " + from_charset);
+ throw invalid_charset_error(charset);
+ }
+
+ namespace detail {
+ template<class T>
+ static std::unique_ptr<T> move_to_ptr(T& c)
+ {
+ return make_std_unique<T>(std::move(c));
}
- template<typename CharType>
- std::basic_string<CharType> convert_to(const char* begin, const char* end, const char* charset, method_type how)
+ template<typename Char>
+ std::unique_ptr<utf_encoder<Char>>
+ make_utf_encoder(const std::string& charset, method_type how, conv_backend impl)
{
- hold_ptr<converter_to_utf<CharType>> cvt;
#ifdef BOOST_LOCALE_WITH_ICONV
- cvt.reset(new iconv_to_utf<CharType>());
- if(cvt->open(charset, how))
- return cvt->convert(begin, end);
+ if(impl == conv_backend::Default || impl == conv_backend::IConv) {
+ impl::iconv_to_utf<Char> cvt;
+ if(cvt.open(charset, how))
+ return move_to_ptr(cvt);
+ }
#endif
#ifdef BOOST_LOCALE_WITH_ICU
- cvt.reset(new uconv_to_utf<CharType>());
- if(cvt->open(charset, how))
- return cvt->convert(begin, end);
+ if(impl == conv_backend::Default || impl == conv_backend::ICU) {
+ impl::uconv_to_utf<Char> cvt;
+ if(cvt.open(charset, how))
+ return move_to_ptr(cvt);
+ }
#endif
#ifdef BOOST_LOCALE_WITH_WCONV
- cvt.reset(new wconv_to_utf<CharType>());
- if(cvt->open(charset, how))
- return cvt->convert(begin, end);
+ if(impl == conv_backend::Default || impl == conv_backend::WinAPI) {
+ impl::wconv_to_utf<Char> cvt;
+ if(cvt.open(charset, how))
+ return move_to_ptr(cvt);
+ }
#endif
throw invalid_charset_error(charset);
}
- template<typename CharType>
- std::string convert_from(const CharType* begin, const CharType* end, const char* charset, method_type how)
+ template<typename Char>
+ std::unique_ptr<utf_decoder<Char>>
+ make_utf_decoder(const std::string& charset, method_type how, conv_backend impl)
{
- hold_ptr<converter_from_utf<CharType>> cvt;
#ifdef BOOST_LOCALE_WITH_ICONV
- cvt.reset(new iconv_from_utf<CharType>());
- if(cvt->open(charset, how))
- return cvt->convert(begin, end);
+ if(impl == conv_backend::Default || impl == conv_backend::IConv) {
+ impl::iconv_from_utf<Char> cvt;
+ if(cvt.open(charset, how))
+ return move_to_ptr(cvt);
+ }
#endif
#ifdef BOOST_LOCALE_WITH_ICU
- cvt.reset(new uconv_from_utf<CharType>());
- if(cvt->open(charset, how))
- return cvt->convert(begin, end);
+ if(impl == conv_backend::Default || impl == conv_backend::ICU) {
+ impl::uconv_from_utf<Char> cvt;
+ if(cvt.open(charset, how))
+ return move_to_ptr(cvt);
+ }
#endif
#ifdef BOOST_LOCALE_WITH_WCONV
- cvt.reset(new wconv_from_utf<CharType>());
- if(cvt->open(charset, how))
- return cvt->convert(begin, end);
+ if(impl == conv_backend::Default || impl == conv_backend::WinAPI) {
+ impl::wconv_from_utf<Char> cvt;
+ if(cvt.open(charset, how))
+ return move_to_ptr(cvt);
+ }
#endif
throw invalid_charset_error(charset);
}
-
- } // namespace impl
-
- using namespace impl;
-
- std::string between(const char* begin,
- const char* end,
- const std::string& to_charset,
- const std::string& from_charset,
- method_type how)
- {
- return convert_between(begin, end, to_charset.c_str(), from_charset.c_str(), how);
- }
-
- template<>
- std::basic_string<char> to_utf(const char* begin, const char* end, const std::string& charset, method_type how)
- {
- return convert_to<char>(begin, end, charset.c_str(), how);
- }
-
- template<>
- std::string from_utf(const char* begin, const char* end, const std::string& charset, method_type how)
- {
- return convert_from<char>(begin, end, charset.c_str(), how);
- }
-
- template<>
- std::basic_string<wchar_t> to_utf(const char* begin, const char* end, const std::string& charset, method_type how)
- {
- return convert_to<wchar_t>(begin, end, charset.c_str(), how);
+ std::unique_ptr<narrow_converter> make_narrow_converter(const std::string& src_encoding,
+ const std::string& target_encoding,
+ method_type how,
+ conv_backend impl)
+ {
+#ifdef BOOST_LOCALE_WITH_ICONV
+ if(impl == conv_backend::Default || impl == conv_backend::IConv) {
+ impl::iconv_between cvt;
+ if(cvt.open(target_encoding, src_encoding, how))
+ return move_to_ptr(cvt);
+ }
+#endif
+#ifdef BOOST_LOCALE_WITH_ICU
+ if(impl == conv_backend::Default || impl == conv_backend::ICU) {
+ impl::uconv_between cvt;
+ if(cvt.open(target_encoding, src_encoding, how))
+ return move_to_ptr(cvt);
+ }
+#endif
+#ifdef BOOST_LOCALE_WITH_WCONV
+ if(impl == conv_backend::Default || impl == conv_backend::WinAPI) {
+ impl::wconv_between cvt;
+ if(cvt.open(target_encoding, src_encoding, how))
+ return move_to_ptr(cvt);
+ }
+#endif
+ throw invalid_charset_error(std::string(src_encoding) + " or " + target_encoding);
+ }
+ } // namespace detail
+
+#define BOOST_LOCALE_INSTANTIATE(CHARTYPE) \
+ namespace detail { \
+ template class charset_converter<char, CHARTYPE>; \
+ template BOOST_LOCALE_DECL std::unique_ptr<utf_encoder<CHARTYPE>> \
+ make_utf_encoder(const std::string& charset, method_type how, conv_backend impl); \
+ template BOOST_LOCALE_DECL std::unique_ptr<utf_decoder<CHARTYPE>> \
+ make_utf_decoder(const std::string& charset, method_type how, conv_backend impl); \
+ } \
+ template BOOST_LOCALE_DECL std::basic_string<CHARTYPE> to_utf<CHARTYPE>(const char* begin, \
+ const char* end, \
+ const std::string& charset, \
+ method_type how); \
+ template BOOST_LOCALE_DECL std::string from_utf<CHARTYPE>(const CHARTYPE* begin, \
+ const CHARTYPE* end, \
+ const std::string& charset, \
+ method_type how)
+#define BOOST_LOCALE_INSTANTIATE_NO_CHAR(CHARTYPE) \
+ BOOST_LOCALE_INSTANTIATE(CHARTYPE); \
+ namespace detail { \
+ template class charset_converter<CHARTYPE, char>; \
}
- template<>
- std::string from_utf(const wchar_t* begin, const wchar_t* end, const std::string& charset, method_type how)
- {
- return convert_from<wchar_t>(begin, end, charset.c_str(), how);
- }
+ BOOST_LOCALE_INSTANTIATE(char);
+ BOOST_LOCALE_INSTANTIATE_NO_CHAR(wchar_t);
#ifdef BOOST_LOCALE_ENABLE_CHAR16_T
- template<>
- std::basic_string<char16_t> to_utf(const char* begin, const char* end, const std::string& charset, method_type how)
- {
- return convert_to<char16_t>(begin, end, charset.c_str(), how);
- }
-
- template<>
- std::string from_utf(const char16_t* begin, const char16_t* end, const std::string& charset, method_type how)
- {
- return convert_from<char16_t>(begin, end, charset.c_str(), how);
- }
+ BOOST_LOCALE_INSTANTIATE_NO_CHAR(char16_t);
#endif
#ifdef BOOST_LOCALE_ENABLE_CHAR32_T
- template<>
- std::basic_string<char32_t> to_utf(const char* begin, const char* end, const std::string& charset, method_type how)
- {
- return convert_to<char32_t>(begin, end, charset.c_str(), how);
- }
-
- template<>
- std::string from_utf(const char32_t* begin, const char32_t* end, const std::string& charset, method_type how)
- {
- return convert_from<char32_t>(begin, end, charset.c_str(), how);
- }
+ BOOST_LOCALE_INSTANTIATE_NO_CHAR(char32_t);
#endif
}}} // namespace boost::locale::conv
diff --git a/contrib/restricted/boost/locale/src/boost/locale/encoding/conv.hpp b/contrib/restricted/boost/locale/src/boost/locale/encoding/conv.hpp
deleted file mode 100644
index 6d2ab68cac..0000000000
--- a/contrib/restricted/boost/locale/src/boost/locale/encoding/conv.hpp
+++ /dev/null
@@ -1,73 +0,0 @@
-//
-// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
-//
-// Distributed under the Boost Software License, Version 1.0.
-// https://www.boost.org/LICENSE_1_0.txt
-
-#ifndef BOOST_LOCALE_CONV_IMPL_HPP
-#define BOOST_LOCALE_CONV_IMPL_HPP
-
-#include <boost/locale/config.hpp>
-#include <boost/locale/encoding.hpp>
-
-namespace boost { namespace locale { namespace conv { namespace impl {
-
- template<typename CharType>
- const char* utf_name()
- {
- switch(sizeof(CharType)) {
- case 1: return "UTF-8";
- case 2: {
- const int16_t endianMark = 1;
- const bool isLittleEndian = reinterpret_cast<const char*>(&endianMark)[0] == 1;
- return isLittleEndian ? "UTF-16LE" : "UTF-16BE";
- }
- case 4: {
- const int32_t endianMark = 1;
- const bool isLittleEndian = reinterpret_cast<const char*>(&endianMark)[0] == 1;
- return isLittleEndian ? "UTF-32LE" : "UTF-32BE";
- }
- }
- return "Unknown Character Encoding";
- }
-
- class converter_between {
- public:
- typedef char char_type;
- typedef std::string string_type;
-
- virtual bool open(const char* to_charset, const char* from_charset, method_type how) = 0;
-
- virtual std::string convert(const char* begin, const char* end) = 0;
-
- virtual ~converter_between() = default;
- };
-
- template<typename CharType>
- class converter_from_utf {
- public:
- typedef CharType char_type;
- typedef std::basic_string<char_type> string_type;
-
- virtual bool open(const char* charset, method_type how) = 0;
-
- virtual std::string convert(const CharType* begin, const CharType* end) = 0;
-
- virtual ~converter_from_utf() = default;
- };
-
- template<typename CharType>
- class converter_to_utf {
- public:
- typedef CharType char_type;
- typedef std::basic_string<char_type> string_type;
-
- virtual bool open(const char* charset, method_type how) = 0;
-
- virtual string_type convert(const char* begin, const char* end) = 0;
-
- virtual ~converter_to_utf() = default;
- };
-}}}} // namespace boost::locale::conv::impl
-
-#endif
diff --git a/contrib/restricted/boost/locale/src/boost/locale/encoding/iconv_codepage.ipp b/contrib/restricted/boost/locale/src/boost/locale/encoding/iconv_codepage.ipp
deleted file mode 100644
index a5f7ab3f00..0000000000
--- a/contrib/restricted/boost/locale/src/boost/locale/encoding/iconv_codepage.ipp
+++ /dev/null
@@ -1,175 +0,0 @@
-//
-// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
-//
-// Distributed under the Boost Software License, Version 1.0.
-// https://www.boost.org/LICENSE_1_0.txt
-
-#ifndef BOOST_LOCALE_IMPL_ICONV_CODEPAGE_HPP
-#define BOOST_LOCALE_IMPL_ICONV_CODEPAGE_HPP
-
-#include <boost/locale/encoding.hpp>
-#include "boost/locale/encoding/conv.hpp"
-#include "boost/locale/util/iconv.hpp"
-#include <cerrno>
-
-namespace boost { namespace locale { namespace conv { namespace impl {
-
- class iconverter_base {
- public:
- iconverter_base() : cvt_((iconv_t)(-1)) {}
- ~iconverter_base() { close(); }
-
- bool do_open(const char* to, const char* from, method_type how)
- {
- close();
- cvt_ = iconv_open(to, from);
- how_ = how;
- return cvt_ != (iconv_t)(-1);
- }
-
- template<typename OutChar, typename InChar>
- std::basic_string<OutChar> real_convert(const InChar* ubegin, const InChar* uend)
- {
- std::basic_string<OutChar> sresult;
-
- sresult.reserve(uend - ubegin);
-
- OutChar result[64];
-
- char* out_start = reinterpret_cast<char*>(&result[0]);
- const char* begin = reinterpret_cast<const char*>(ubegin);
- const char* end = reinterpret_cast<const char*>(uend);
-
- enum { normal, unshifting, done } state = normal;
-
- while(state != done) {
- size_t in_left = end - begin;
- size_t out_left = sizeof(result);
-
- char* out_ptr = out_start;
- size_t res = 0;
- if(in_left == 0)
- state = unshifting;
-
- if(state == normal)
- res = conv(&begin, &in_left, &out_ptr, &out_left);
- else
- res = conv(0, 0, &out_ptr, &out_left);
-
- int err = errno;
-
- size_t output_count = (out_ptr - out_start) / sizeof(OutChar);
-
- if(res != 0 && res != (size_t)(-1)) {
- if(how_ == stop) {
- throw conversion_error();
- }
- }
-
- sresult.append(&result[0], output_count);
-
- if(res == (size_t)(-1)) {
- if(err == EILSEQ || err == EINVAL) {
- if(how_ == stop) {
- throw conversion_error();
- }
-
- if(begin != end) {
- begin += sizeof(InChar);
- if(begin >= end)
- break;
- } else {
- break;
- }
- } else if(err == E2BIG) {
- continue;
- } else {
- // We should never get there
- // but if we do
- if(how_ == stop)
- throw conversion_error();
- else
- break;
- }
- }
- if(state == unshifting)
- state = done;
- }
- return sresult;
- }
-
- private:
- void close()
- {
- if(cvt_ != (iconv_t)(-1)) {
- iconv_close(cvt_);
- cvt_ = (iconv_t)(-1);
- }
- }
-
- size_t conv(const char** inbuf, size_t* inchar_left, char** outbuf, size_t* outchar_left)
- {
- return call_iconv(cvt_, inbuf, inchar_left, outbuf, outchar_left);
- }
-
- iconv_t cvt_;
- method_type how_;
- };
-
- template<typename CharType>
- class iconv_from_utf : public converter_from_utf<CharType> {
- public:
- typedef CharType char_type;
-
- bool open(const char* charset, method_type how) override
- {
- return self_.do_open(charset, utf_name<CharType>(), how);
- }
-
- std::string convert(const char_type* ubegin, const char_type* uend) override
- {
- return self_.template real_convert<char, char_type>(ubegin, uend);
- }
-
- private:
- iconverter_base self_;
- };
-
- class iconv_between : public converter_between {
- public:
- bool open(const char* to_charset, const char* from_charset, method_type how) override
- {
- return self_.do_open(to_charset, from_charset, how);
- }
- std::string convert(const char* begin, const char* end) override
- {
- return self_.real_convert<char, char>(begin, end);
- }
-
- private:
- iconverter_base self_;
- };
-
- template<typename CharType>
- class iconv_to_utf : public converter_to_utf<CharType> {
- public:
- typedef CharType char_type;
- typedef std::basic_string<char_type> string_type;
-
- bool open(const char* charset, method_type how) override
- {
- return self_.do_open(utf_name<CharType>(), charset, how);
- }
-
- string_type convert(const char* begin, const char* end) override
- {
- return self_.template real_convert<char_type, char>(begin, end);
- }
-
- private:
- iconverter_base self_;
- };
-
-}}}} // namespace boost::locale::conv::impl
-
-#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
new file mode 100644
index 0000000000..38a8f485ea
--- /dev/null
+++ b/contrib/restricted/boost/locale/src/boost/locale/encoding/iconv_converter.hpp
@@ -0,0 +1,145 @@
+//
+// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0.
+// https://www.boost.org/LICENSE_1_0.txt
+
+#ifndef BOOST_LOCALE_IMPL_ICONV_CODEPAGE_HPP
+#define BOOST_LOCALE_IMPL_ICONV_CODEPAGE_HPP
+
+#include <boost/locale/encoding.hpp>
+#include "boost/locale/util/encoding.hpp"
+#include "boost/locale/util/iconv.hpp"
+#include <cerrno>
+#include <string>
+
+namespace boost { namespace locale { namespace conv { namespace impl {
+
+ class iconverter_base {
+ public:
+ bool do_open(const char* to, const char* from, method_type how)
+ {
+ cvt_ = iconv_open(to, from);
+ how_ = how;
+ return static_cast<bool>(cvt_);
+ }
+
+ template<typename OutChar, typename InChar>
+ std::basic_string<OutChar> real_convert(const InChar* ubegin, const InChar* uend)
+ {
+ std::basic_string<OutChar> sresult;
+
+ sresult.reserve(uend - ubegin);
+
+ OutChar tmp_buf[64];
+
+ char* out_start = reinterpret_cast<char*>(tmp_buf);
+ const char* begin = reinterpret_cast<const char*>(ubegin);
+ const char* end = reinterpret_cast<const char*>(uend);
+
+ bool is_unshifting = false;
+
+ for(;;) {
+ size_t in_left = end - begin;
+ size_t out_left = sizeof(tmp_buf);
+ char* out_ptr = out_start;
+
+ if(in_left == 0)
+ is_unshifting = true;
+
+ const size_t res = (!is_unshifting) ? conv(&begin, &in_left, &out_ptr, &out_left) :
+ conv(nullptr, nullptr, &out_ptr, &out_left);
+
+ if(res != 0 && res != (size_t)(-1)) {
+ if(how_ == stop)
+ throw conversion_error();
+ }
+
+ const size_t output_count = (out_ptr - out_start) / sizeof(OutChar);
+ sresult.append(tmp_buf, output_count);
+
+ if(res == (size_t)(-1)) {
+ const int err = errno;
+ if(err == EILSEQ || err == EINVAL) {
+ if(how_ == stop)
+ throw conversion_error();
+
+ if(begin != end) {
+ begin += sizeof(InChar);
+ if(begin >= end)
+ break;
+ } else
+ break;
+ } else if(err == E2BIG)
+ continue;
+ else // Invalid error code, shouldn't ever happen or iconv has a bug
+ throw conversion_error(); // LCOV_EXCL_LINE
+ }
+ if(is_unshifting)
+ break;
+ }
+ return sresult;
+ }
+
+ private:
+ size_t conv(const char** inbuf, size_t* inchar_left, char** outbuf, size_t* outchar_left)
+ {
+ return call_iconv(cvt_, inbuf, inchar_left, outbuf, outchar_left);
+ }
+
+ iconv_handle cvt_;
+ method_type how_;
+ };
+
+ template<typename CharType>
+ class iconv_from_utf final : public detail::utf_decoder<CharType> {
+ public:
+ bool open(const std::string& charset, method_type how)
+ {
+ return self_.do_open(charset.c_str(), util::utf_name<CharType>(), how);
+ }
+
+ std::string convert(const CharType* ubegin, const CharType* uend) override
+ {
+ return self_.template real_convert<char>(ubegin, uend);
+ }
+
+ private:
+ iconverter_base self_;
+ };
+
+ class iconv_between final : public detail::narrow_converter {
+ public:
+ bool open(const std::string& to_charset, const std::string& from_charset, method_type how)
+ {
+ return self_.do_open(to_charset.c_str(), from_charset.c_str(), how);
+ }
+ std::string convert(const char* begin, const char* end) override
+ {
+ return self_.real_convert<char, char>(begin, end);
+ }
+
+ private:
+ iconverter_base self_;
+ };
+
+ template<typename CharType>
+ class iconv_to_utf final : public detail::utf_encoder<CharType> {
+ public:
+ bool open(const std::string& charset, method_type how)
+ {
+ return self_.do_open(util::utf_name<CharType>(), charset.c_str(), how);
+ }
+
+ std::basic_string<CharType> convert(const char* begin, const char* end) override
+ {
+ return self_.template real_convert<CharType>(begin, end);
+ }
+
+ private:
+ iconverter_base self_;
+ };
+
+}}}} // namespace boost::locale::conv::impl
+
+#endif
diff --git a/contrib/restricted/boost/locale/src/boost/locale/encoding/uconv_codepage.ipp b/contrib/restricted/boost/locale/src/boost/locale/encoding/uconv_converter.hpp
index 1c2b7ed73b..53a1405532 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/encoding/uconv_codepage.ipp
+++ b/contrib/restricted/boost/locale/src/boost/locale/encoding/uconv_converter.hpp
@@ -8,7 +8,6 @@
#define BOOST_LOCALE_IMPL_UCONV_CODEPAGE_HPP
#include <boost/locale/encoding.hpp>
#include <boost/locale/hold_ptr.hpp>
-#include "boost/locale/encoding/conv.hpp"
#include "boost/locale/icu/icu_util.hpp"
#include "boost/locale/icu/uconv.hpp"
#include <unicode/ucnv.h>
@@ -16,32 +15,23 @@
namespace boost { namespace locale { namespace conv { namespace impl {
template<typename CharType>
- class uconv_to_utf : public converter_to_utf<CharType> {
+ class uconv_to_utf final : public detail::utf_encoder<CharType> {
public:
- typedef CharType char_type;
-
- typedef std::basic_string<char_type> string_type;
-
- bool open(const char* charset, method_type how) override
+ bool open(const std::string& charset, method_type how)
{
- close();
try {
using impl_icu::cpcvt_type;
cvt_from_.reset(new from_type(charset, how == skip ? cpcvt_type::skip : cpcvt_type::stop));
cvt_to_.reset(new to_type("UTF-8", how == skip ? cpcvt_type::skip : cpcvt_type::stop));
} catch(const std::exception& /*e*/) {
- close();
+ cvt_from_.reset();
+ cvt_to_.reset();
return false;
}
return true;
}
- void close()
- {
- cvt_from_.reset();
- cvt_to_.reset();
- }
- string_type convert(const char* begin, const char* end) override
+ std::basic_string<CharType> convert(const char* begin, const char* end) override
{
try {
return cvt_to_->std(cvt_from_->icu_checked(begin, end));
@@ -59,27 +49,21 @@ namespace boost { namespace locale { namespace conv { namespace impl {
};
template<typename CharType>
- class uconv_from_utf : public converter_from_utf<CharType> {
+ class uconv_from_utf final : public detail::utf_decoder<CharType> {
public:
- typedef CharType char_type;
- bool open(const char* charset, method_type how) override
+ bool open(const std::string& charset, method_type how)
{
- close();
try {
using impl_icu::cpcvt_type;
cvt_from_.reset(new from_type("UTF-8", how == skip ? cpcvt_type::skip : cpcvt_type::stop));
cvt_to_.reset(new to_type(charset, how == skip ? cpcvt_type::skip : cpcvt_type::stop));
} catch(const std::exception& /*e*/) {
- close();
+ cvt_from_.reset();
+ cvt_to_.reset();
return false;
}
return true;
}
- void close()
- {
- cvt_from_.reset();
- cvt_to_.reset();
- }
std::string convert(const CharType* begin, const CharType* end) override
{
@@ -98,26 +82,21 @@ namespace boost { namespace locale { namespace conv { namespace impl {
hold_ptr<to_type> cvt_to_;
};
- class uconv_between : public converter_between {
+ class uconv_between final : public detail::narrow_converter {
public:
- bool open(const char* to_charset, const char* from_charset, method_type how) override
+ bool open(const std::string& to_charset, const std::string& from_charset, method_type how)
{
- close();
try {
using impl_icu::cpcvt_type;
cvt_from_.reset(new from_type(from_charset, how == skip ? cpcvt_type::skip : cpcvt_type::stop));
cvt_to_.reset(new to_type(to_charset, how == skip ? cpcvt_type::skip : cpcvt_type::stop));
} catch(const std::exception& /*e*/) {
- close();
+ cvt_from_.reset();
+ cvt_to_.reset();
return false;
}
return true;
}
- void close()
- {
- cvt_from_.reset();
- cvt_to_.reset();
- }
std::string convert(const char* begin, const char* end) override
{
diff --git a/contrib/restricted/boost/locale/src/boost/locale/encoding/wconv_codepage.ipp b/contrib/restricted/boost/locale/src/boost/locale/encoding/wconv_converter.hpp
index bf97fd5070..1a0325565e 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/encoding/wconv_codepage.ipp
+++ b/contrib/restricted/boost/locale/src/boost/locale/encoding/wconv_converter.hpp
@@ -11,7 +11,6 @@
# define NOMINMAX
#endif
#include <boost/locale/encoding.hpp>
-#include "boost/locale/encoding/conv.hpp"
#include "boost/locale/util/encoding.hpp"
#include <algorithm>
#include <cstddef>
@@ -23,21 +22,6 @@
namespace boost { namespace locale { namespace conv { namespace impl {
- size_t remove_substitutions(std::vector<char>& v)
- {
- if(std::find(v.begin(), v.end(), 0) == v.end()) {
- return v.size();
- }
- std::vector<char> v2;
- v2.reserve(v.size());
- for(unsigned i = 0; i < v.size(); i++) {
- if(v[i] != 0)
- v2.push_back(v[i]);
- }
- v.swap(v2);
- return v.size();
- }
-
void multibyte_to_wide_one_by_one(int codepage, const char* begin, const char* end, std::vector<wchar_t>& buf)
{
buf.reserve(end - begin);
@@ -82,7 +66,7 @@ namespace boost { namespace locale { namespace conv { namespace impl {
}
buf.resize(n);
- if(MultiByteToWideChar(codepage, flags, begin, static_cast<int>(num_chars), &buf.front(), n) == 0)
+ if(MultiByteToWideChar(codepage, flags, begin, static_cast<int>(num_chars), buf.data(), n) == 0)
throw conversion_error();
}
@@ -92,33 +76,31 @@ namespace boost { namespace locale { namespace conv { namespace impl {
bool do_skip,
std::vector<char>& buf)
{
+ buf.clear();
if(begin == end)
return;
BOOL substitute = FALSE;
- BOOL* substitute_ptr = codepage == 65001 || codepage == 65000 ? 0 : &substitute;
+ BOOL* substitute_ptr = (codepage == CP_UTF7 || codepage == CP_UTF8) ? nullptr : &substitute;
char subst_char = 0;
- char* subst_char_ptr = codepage == 65001 || codepage == 65000 ? 0 : &subst_char;
+ char* subst_char_ptr = (codepage == CP_UTF7 || codepage == CP_UTF8) ? nullptr : &subst_char;
- const std::ptrdiff_t num_chars = end - begin;
- if(num_chars > std::numeric_limits<int>::max())
+ if((end - begin) > std::numeric_limits<int>::max())
throw conversion_error();
- int n =
- WideCharToMultiByte(codepage, 0, begin, static_cast<int>(num_chars), 0, 0, subst_char_ptr, substitute_ptr);
+ const int num_chars = static_cast<int>(end - begin);
+ int n = WideCharToMultiByte(codepage, 0, begin, num_chars, nullptr, 0, subst_char_ptr, substitute_ptr);
+ // Some codepages don't support substitutions
+ if(n == 0 && GetLastError() == ERROR_INVALID_PARAMETER) {
+ subst_char_ptr = nullptr;
+ substitute_ptr = nullptr;
+ n = WideCharToMultiByte(codepage, 0, begin, num_chars, nullptr, 0, subst_char_ptr, substitute_ptr);
+ }
buf.resize(n);
- if(WideCharToMultiByte(codepage,
- 0,
- begin,
- static_cast<int>(num_chars),
- &buf[0],
- n,
- subst_char_ptr,
- substitute_ptr)
- == 0)
+ if(WideCharToMultiByte(codepage, 0, begin, num_chars, buf.data(), n, subst_char_ptr, substitute_ptr) == 0)
throw conversion_error();
if(substitute) {
if(do_skip)
- remove_substitutions(buf);
+ buf.erase(std::remove(buf.begin(), buf.end(), subst_char), buf.end());
else
throw conversion_error();
}
@@ -131,18 +113,17 @@ namespace boost { namespace locale { namespace conv { namespace impl {
buf.reserve(end - begin);
const wchar_t* e = std::find(begin, end, L'\0');
const wchar_t* b = begin;
+ std::vector<char> tmp;
for(;;) {
- std::vector<char> tmp;
wide_to_multibyte_non_zero(codepage, b, e, do_skip, tmp);
- size_t osize = buf.size();
+ const size_t osize = buf.size();
buf.resize(osize + tmp.size());
std::copy(tmp.begin(), tmp.end(), buf.begin() + osize);
- if(e != end) {
- buf.push_back('\0');
- b = e + 1;
- e = std::find(b, end, L'0');
- } else
+ if(e == end)
break;
+ buf.push_back('\0');
+ b = e + 1;
+ e = std::find(b, end, L'0');
}
}
@@ -152,7 +133,7 @@ namespace boost { namespace locale { namespace conv { namespace impl {
const CharType* begin = str;
const CharType* end = str + len;
while(begin != end) {
- utf::code_point c = utf::utf_traits<CharType, 2>::template decode<const CharType*>(begin, end);
+ utf::code_point c = utf::utf_traits<CharType, 2>::decode(begin, end);
if(c == utf::illegal || c == utf::incomplete)
return false;
}
@@ -182,10 +163,10 @@ namespace boost { namespace locale { namespace conv { namespace impl {
}
}
- class wconv_between : public converter_between {
+ class wconv_between final : public detail::narrow_converter {
public:
wconv_between() : how_(skip), to_code_page_(-1), from_code_page_(-1) {}
- bool open(const char* to_charset, const char* from_charset, method_type how) override
+ bool open(const std::string& to_charset, const std::string& from_charset, method_type how)
{
how_ = how;
to_code_page_ = util::encoding_to_windows_codepage(to_charset);
@@ -196,17 +177,17 @@ namespace boost { namespace locale { namespace conv { namespace impl {
}
std::string convert(const char* begin, const char* end) override
{
- if(to_code_page_ == 65001 && from_code_page_ == 65001)
+ if(to_code_page_ == CP_UTF8 && from_code_page_ == CP_UTF8)
return utf_to_utf<char>(begin, end, how_);
std::string res;
std::vector<wchar_t> tmp; // buffer for mb2w
std::wstring tmps; // buffer for utf_to_utf
- const wchar_t* wbegin = 0;
- const wchar_t* wend = 0;
+ const wchar_t* wbegin = nullptr;
+ const wchar_t* wend = nullptr;
- if(from_code_page_ == 65001) {
+ if(from_code_page_ == CP_UTF8) {
tmps = utf_to_utf<wchar_t>(begin, end, how_);
if(tmps.empty())
return res;
@@ -216,19 +197,18 @@ namespace boost { namespace locale { namespace conv { namespace impl {
multibyte_to_wide(from_code_page_, begin, end, how_ == skip, tmp);
if(tmp.empty())
return res;
- wbegin = &tmp[0];
+ wbegin = tmp.data();
wend = wbegin + tmp.size();
}
- if(to_code_page_ == 65001) {
+ if(to_code_page_ == CP_UTF8)
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.front(), ctmp.size());
+ res.assign(ctmp.data(), ctmp.size());
return res;
}
@@ -245,9 +225,9 @@ namespace boost { namespace locale { namespace conv { namespace impl {
class wconv_from_utf;
template<>
- class wconv_to_utf<char, 1> : public converter_to_utf<char> {
+ class wconv_to_utf<char, 1> final : public detail::utf_encoder<char> {
public:
- bool open(const char* cs, method_type how) override { return cvt.open("UTF-8", cs, how); }
+ 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); }
private:
@@ -255,9 +235,9 @@ namespace boost { namespace locale { namespace conv { namespace impl {
};
template<>
- class wconv_from_utf<char, 1> : public converter_from_utf<char> {
+ class wconv_from_utf<char, 1> final : public detail::utf_decoder<char> {
public:
- bool open(const char* cs, method_type how) override { return cvt.open(cs, "UTF-8", how); }
+ 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); }
private:
@@ -265,15 +245,13 @@ namespace boost { namespace locale { namespace conv { namespace impl {
};
template<typename CharType>
- class wconv_to_utf<CharType, 2> : public converter_to_utf<CharType> {
+ class wconv_to_utf<CharType, 2> final : public detail::utf_encoder<CharType> {
public:
- typedef CharType char_type;
-
- typedef std::basic_string<char_type> string_type;
+ using string_type = std::basic_string<CharType>;
wconv_to_utf() : how_(skip), code_page_(-1) {}
- bool open(const char* charset, method_type how) override
+ bool open(const std::string& charset, method_type how)
{
how_ = how;
code_page_ = util::encoding_to_windows_codepage(charset);
@@ -282,14 +260,15 @@ namespace boost { namespace locale { namespace conv { namespace impl {
string_type convert(const char* begin, const char* end) override
{
- if(code_page_ == 65001) {
- return utf_to_utf<char_type>(begin, end, how_);
- }
+ if(code_page_ == CP_UTF8)
+ return utf_to_utf<CharType>(begin, end, how_);
std::vector<wchar_t> tmp;
multibyte_to_wide(code_page_, begin, end, how_ == skip, tmp);
string_type res;
- if(!tmp.empty())
- res.assign(reinterpret_cast<char_type*>(&tmp.front()), tmp.size());
+ if(!tmp.empty()) {
+ static_assert(sizeof(CharType) == sizeof(wchar_t), "Cast not possible");
+ res.assign(reinterpret_cast<CharType*>(tmp.data()), tmp.size());
+ }
return res;
}
@@ -299,15 +278,11 @@ namespace boost { namespace locale { namespace conv { namespace impl {
};
template<typename CharType>
- class wconv_from_utf<CharType, 2> : public converter_from_utf<CharType> {
+ class wconv_from_utf<CharType, 2> final : public detail::utf_decoder<CharType> {
public:
- typedef CharType char_type;
-
- typedef std::basic_string<char_type> string_type;
-
wconv_from_utf() : how_(skip), code_page_(-1) {}
- bool open(const char* charset, method_type how) override
+ bool open(const std::string& charset, method_type how)
{
how_ = how;
code_page_ = util::encoding_to_windows_codepage(charset);
@@ -316,24 +291,24 @@ namespace boost { namespace locale { namespace conv { namespace impl {
std::string convert(const CharType* begin, const CharType* end) override
{
- if(code_page_ == 65001) {
+ if(code_page_ == CP_UTF8)
return utf_to_utf<char>(begin, end, how_);
- }
- const wchar_t* wbegin = 0;
- const wchar_t* wend = 0;
+ const wchar_t* wbegin;
+ const wchar_t* wend;
std::vector<wchar_t> buffer; // if needed
- if(begin == end)
- return std::string();
if(validate_utf16(begin, end - begin)) {
+ static_assert(sizeof(CharType) == sizeof(wchar_t), "Cast not possible");
wbegin = reinterpret_cast<const wchar_t*>(begin);
wend = reinterpret_cast<const wchar_t*>(end);
} else {
- if(how_ == stop) {
+ if(how_ == stop)
throw conversion_error();
- } else {
+ else {
clean_invalid_utf16(begin, end - begin, buffer);
- if(!buffer.empty()) {
- wbegin = &buffer[0];
+ if(buffer.empty())
+ wbegin = wend = nullptr;
+ else {
+ wbegin = buffer.data();
wend = wbegin + buffer.size();
}
}
@@ -345,7 +320,7 @@ namespace boost { namespace locale { namespace conv { namespace impl {
wide_to_multibyte(code_page_, wbegin, wend, how_ == skip, ctmp);
if(ctmp.empty())
return res;
- res.assign(&ctmp.front(), ctmp.size());
+ res.assign(ctmp.data(), ctmp.size());
return res;
}
@@ -355,15 +330,13 @@ namespace boost { namespace locale { namespace conv { namespace impl {
};
template<typename CharType>
- class wconv_to_utf<CharType, 4> : public converter_to_utf<CharType> {
+ class wconv_to_utf<CharType, 4> final : public detail::utf_encoder<CharType> {
public:
- typedef CharType char_type;
-
- typedef std::basic_string<char_type> string_type;
+ using string_type = std::basic_string<CharType>;
wconv_to_utf() : how_(skip), code_page_(-1) {}
- bool open(const char* charset, method_type how) override
+ bool open(const std::string& charset, method_type how)
{
how_ = how;
code_page_ = util::encoding_to_windows_codepage(charset);
@@ -372,16 +345,15 @@ namespace boost { namespace locale { namespace conv { namespace impl {
string_type convert(const char* begin, const char* end) override
{
- if(code_page_ == 65001) {
- return utf_to_utf<char_type>(begin, end, how_);
- }
+ if(code_page_ == CP_UTF8)
+ return utf_to_utf<CharType>(begin, end, how_);
std::vector<wchar_t> buf;
multibyte_to_wide(code_page_, begin, end, how_ == skip, buf);
if(buf.empty())
return string_type();
- return utf_to_utf<CharType>(&buf[0], &buf[0] + buf.size(), how_);
+ return utf_to_utf<CharType>(buf.data(), buf.data() + buf.size(), how_);
}
private:
@@ -390,15 +362,11 @@ namespace boost { namespace locale { namespace conv { namespace impl {
};
template<typename CharType>
- class wconv_from_utf<CharType, 4> : public converter_from_utf<CharType> {
+ class wconv_from_utf<CharType, 4> final : public detail::utf_decoder<CharType> {
public:
- typedef CharType char_type;
-
- typedef std::basic_string<char_type> string_type;
-
wconv_from_utf() : how_(skip), code_page_(-1) {}
- bool open(const char* charset, method_type how) override
+ bool open(const std::string& charset, method_type how)
{
how_ = how;
code_page_ = util::encoding_to_windows_codepage(charset);
@@ -407,9 +375,8 @@ namespace boost { namespace locale { namespace conv { namespace impl {
std::string convert(const CharType* begin, const CharType* end) override
{
- if(code_page_ == 65001) {
+ if(code_page_ == CP_UTF8)
return utf_to_utf<char>(begin, end, how_);
- }
std::wstring tmp = utf_to_utf<wchar_t>(begin, end, how_);
std::vector<char> ctmp;
@@ -417,7 +384,7 @@ namespace boost { namespace locale { namespace conv { namespace impl {
std::string res;
if(ctmp.empty())
return res;
- res.assign(&ctmp.front(), ctmp.size());
+ res.assign(ctmp.data(), ctmp.size());
return res;
}
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 a992048f75..a26dfc98cf 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/icu/boundary.cpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/icu/boundary.cpp
@@ -7,12 +7,12 @@
#include <boost/locale/boundary.hpp>
#include <boost/locale/generator.hpp>
-#include "boost/locale//util/encoding.hpp"
#include "boost/locale/icu/all_generator.hpp"
#include "boost/locale/icu/cdata.hpp"
#include "boost/locale/icu/icu_util.hpp"
#include "boost/locale/icu/uconv.hpp"
-#if BOOST_LOCALE_ICU_VERSION >= 306
+#include "boost/locale/util/encoding.hpp"
+#if BOOST_LOCALE_ICU_VERSION >= 5502
# include <unicode/utext.h>
#endif
#include <memory>
@@ -25,6 +25,16 @@
# pragma warning(disable : 4267) // 'argument' : conversion from 'size_t'
#endif
+#if BOOST_LOCALE_ICU_VERSION >= 5502
+namespace std {
+template<>
+struct default_delete<UText> {
+ using pointer = UText*;
+ void operator()(pointer ptr) { utext_close(ptr); }
+};
+} // namespace std
+#endif
+
namespace boost { namespace locale {
namespace boundary { namespace impl_icu {
@@ -45,12 +55,8 @@ namespace boost { namespace locale {
int pos = 0;
while((pos = it->next()) != icu::BreakIterator::DONE) {
indx.push_back(break_info(pos));
- /// Character does not have any specific break types
+ // Character does not have any specific break types
if(t != character && rbbi) {
- //
- // There is a collapse for MSVC: int32_t defined by both boost::cstdint and icu...
- // So need to pick one ;(
- //
std::vector<int32_t> buffer;
int32_t membuf[8] = {0}; // try not to use memory allocation if possible
int32_t* buf = membuf;
@@ -59,8 +65,8 @@ namespace boost { namespace locale {
int n = rbbi->getRuleStatusVec(buf, 8, err);
if(err == U_BUFFER_OVERFLOW_ERROR) {
- buf = &buffer.front();
buffer.resize(n, 0);
+ buf = buffer.data();
n = rbbi->getRuleStatusVec(buf, buffer.size(), err);
}
@@ -97,9 +103,8 @@ namespace boost { namespace locale {
case character: BOOST_UNREACHABLE_RETURN(0);
}
}
- } else {
- indx.back().rule |= character_any; // Baisc mark... for character
- }
+ } else
+ indx.back().rule |= character_any; // Basic mark... for character
}
return indx;
}
@@ -127,52 +132,45 @@ namespace boost { namespace locale {
const icu::Locale& loc,
const std::string& encoding)
{
- index_type indx;
std::unique_ptr<icu::BreakIterator> bi = get_iterator(t, loc);
-
-#if BOOST_LOCALE_ICU_VERSION >= 306
+ // Versions prior to ICU 55.2 returned wrong splits when used with UText input
+#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")) {
- UText* ut = 0;
- try {
- if(sizeof(CharType) == 1)
- ut = utext_openUTF8(0, reinterpret_cast<const char*>(begin), end - begin, &err);
- else // sizeof(CharType)==2
- ut = utext_openUChars(0, reinterpret_cast<const UChar*>(begin), end - begin, &err);
- BOOST_LOCALE_END_CONST_CONDITION
-
- check_and_throw_icu_error(err);
- err = U_ZERO_ERROR;
- if(!ut)
- throw std::runtime_error("Failed to create UText");
- bi->setText(ut, err);
- check_and_throw_icu_error(err);
- index_type res = map_direct(t, bi.get(), end - begin);
- indx.swap(res);
- } catch(...) {
- if(ut)
- utext_close(ut);
- throw;
+ UText ut_stack = UTEXT_INITIALIZER;
+ std::unique_ptr<UText> ut;
+ if(sizeof(CharType) == 1)
+ ut.reset(utext_openUTF8(&ut_stack, reinterpret_cast<const char*>(begin), end - begin, &err));
+ else {
+ static_assert(sizeof(UChar) == 2, "!");
+ ut.reset(utext_openUChars(&ut_stack, reinterpret_cast<const UChar*>(begin), end - begin, &err));
}
- if(ut)
- utext_close(ut);
+ BOOST_LOCALE_END_CONST_CONDITION
+
+ check_and_throw_icu_error(err);
+ err = U_ZERO_ERROR;
+ if(!ut)
+ throw std::runtime_error("Failed to create UText");
+ bi->setText(ut.get(), err);
+ check_and_throw_icu_error(err);
+ return map_direct(t, bi.get(), end - begin);
} else
#endif
{
icu_std_converter<CharType> cvt(encoding);
- icu::UnicodeString str = cvt.icu(begin, end);
+ const icu::UnicodeString str = cvt.icu(begin, end);
bi->setText(str);
- index_type indirect = map_direct(t, bi.get(), str.length());
- indx = indirect;
+ const index_type indirect = map_direct(t, bi.get(), str.length());
+ index_type indx = indirect;
for(size_t i = 1; i < indirect.size(); i++) {
- size_t offset_inderect = indirect[i - 1].offset;
- size_t diff = indirect[i].offset - offset_inderect;
- size_t offset_direct = indx[i - 1].offset;
- indx[i].offset = offset_direct + cvt.cut(str, begin, end, diff, offset_inderect, offset_direct);
+ const size_t offset_indirect = indirect[i - 1].offset;
+ const size_t diff = indirect[i].offset - offset_indirect;
+ const size_t offset_direct = indx[i - 1].offset;
+ indx[i].offset = offset_direct + cvt.cut(str, begin, end, diff, offset_indirect, offset_direct);
}
+ return indx;
}
- return indx;
} // do_map
template<typename CharType>
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 b62a542fb0..9e7de6db21 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/icu/codecvt.cpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/icu/codecvt.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
@@ -9,11 +10,11 @@
#include <boost/locale/encoding_errors.hpp>
#include <boost/locale/hold_ptr.hpp>
#include <boost/locale/util.hpp>
-#include "boost/locale/encoding/conv.hpp"
#include "boost/locale/icu/all_generator.hpp"
#include "boost/locale/icu/icu_util.hpp"
#include "boost/locale/icu/uconv.hpp"
#include "boost/locale/util/encoding.hpp"
+#include "boost/locale/util/make_std_unique.hpp"
#include <unicode/ucnv.h>
#include <unicode/ucnv_err.h>
@@ -24,49 +25,28 @@
namespace boost { namespace locale { namespace impl_icu {
class uconv_converter : public util::base_converter {
public:
- uconv_converter(const std::string& encoding) : encoding_(encoding)
- {
- UErrorCode err = U_ZERO_ERROR;
-
- // No need to check err each time, this
- // is how ICU works.
- cvt_ = ucnv_open(encoding.c_str(), &err);
- ucnv_setFromUCallBack(cvt_, UCNV_FROM_U_CALLBACK_STOP, 0, 0, 0, &err);
- ucnv_setToUCallBack(cvt_, UCNV_TO_U_CALLBACK_STOP, 0, 0, 0, &err);
-
- if(!cvt_ || U_FAILURE(err)) {
- if(cvt_)
- ucnv_close(cvt_);
- throw conv::invalid_charset_error(encoding);
- }
-
- max_len_ = ucnv_getMaxCharSize(cvt_);
- }
-
- ~uconv_converter() { ucnv_close(cvt_); }
+ uconv_converter(const std::string& encoding) : encoding_(encoding), cvt_(encoding, cpcvt_type::stop) {}
bool is_thread_safe() const override { return false; }
uconv_converter* clone() const override { return new uconv_converter(encoding_); }
- uint32_t to_unicode(const char*& begin, const char* end) override
+ utf::code_point to_unicode(const char*& begin, const char* end) override
{
UErrorCode err = U_ZERO_ERROR;
const char* tmp = begin;
- UChar32 c = ucnv_getNextUChar(cvt_, &tmp, end, &err);
- ucnv_reset(cvt_);
- if(err == U_TRUNCATED_CHAR_FOUND) {
+ const UChar32 c = ucnv_getNextUChar(cvt_.cvt(), &tmp, end, &err);
+ ucnv_reset(cvt_.cvt());
+ if(err == U_TRUNCATED_CHAR_FOUND)
return incomplete;
- }
- if(U_FAILURE(err)) {
+ if(U_FAILURE(err))
return illegal;
- }
begin = tmp;
return c;
}
- uint32_t from_unicode(uint32_t u, char* begin, const char* end) override
+ utf::len_or_error from_unicode(utf::code_point u, char* begin, const char* end) override
{
UChar code_point[2] = {0};
int len;
@@ -82,8 +62,8 @@ namespace boost { namespace locale { namespace impl_icu {
len = 2;
}
UErrorCode err = U_ZERO_ERROR;
- int olen = ucnv_fromUChars(cvt_, begin, end - begin, code_point, len, &err);
- ucnv_reset(cvt_);
+ const auto olen = ucnv_fromUChars(cvt_.cvt(), begin, end - begin, code_point, len, &err);
+ ucnv_reset(cvt_.cvt());
if(err == U_BUFFER_OVERFLOW_ERROR)
return incomplete;
if(U_FAILURE(err))
@@ -91,18 +71,17 @@ namespace boost { namespace locale { namespace impl_icu {
return olen;
}
- int max_len() const override { return max_len_; }
+ int max_len() const override { return cvt_.max_char_size(); }
private:
std::string encoding_;
- UConverter* cvt_;
- int max_len_;
+ uconv cvt_;
};
std::unique_ptr<util::base_converter> create_uconv_converter(const std::string& encoding)
{
try {
- return std::unique_ptr<util::base_converter>(new uconv_converter(encoding));
+ return make_std_unique<uconv_converter>(encoding);
} catch(const std::exception& /*e*/) {
return nullptr;
}
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 c199ba9312..8a20950cb7 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/icu/collator.cpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/icu/collator.cpp
@@ -102,10 +102,10 @@ namespace boost { namespace locale { namespace impl_icu {
std::vector<uint8_t> tmp;
tmp.resize(str.length() + 1u);
icu::Collator* collate = get_collator(level);
- const int len = collate->getSortKey(str, &tmp[0], tmp.size());
+ const int len = collate->getSortKey(str, tmp.data(), tmp.size());
if(len > int(tmp.size())) {
tmp.resize(len);
- collate->getSortKey(str, &tmp[0], tmp.size());
+ collate->getSortKey(str, tmp.data(), tmp.size());
} else
tmp.resize(len);
return tmp;
@@ -121,7 +121,7 @@ namespace boost { namespace locale { namespace impl_icu {
{
std::vector<uint8_t> tmp = do_basic_transform(level, b, e);
tmp.push_back(0);
- return gnu_gettext::pj_winberger_hash_function(reinterpret_cast<char*>(&tmp.front()));
+ 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) {}
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 89609c127d..9f45db5cc1 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/icu/conversion.cpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/icu/conversion.cpp
@@ -44,23 +44,22 @@ namespace boost { namespace locale { namespace impl_icu {
template<typename CharType>
class converter_impl : public converter<CharType> {
public:
- typedef CharType char_type;
- typedef std::basic_string<char_type> string_type;
+ typedef std::basic_string<CharType> string_type;
converter_impl(const cdata& d) : locale_(d.locale), encoding_(d.encoding) {}
string_type convert(converter_base::conversion_type how,
- const char_type* begin,
- const char_type* end,
+ const CharType* begin,
+ const CharType* end,
int flags = 0) const override
{
- icu_std_converter<char_type> cvt(encoding_);
+ icu_std_converter<CharType> cvt(encoding_);
icu::UnicodeString str = cvt.icu(begin, end);
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(0, locale_); break;
+ case converter_base::title_case: str.toTitle(nullptr, locale_); break;
case converter_base::case_folding: str.foldCase(); break;
}
return cvt.std(str);
@@ -85,7 +84,7 @@ namespace boost { namespace locale { namespace impl_icu {
raii_casemap(const raii_casemap&) = delete;
void operator=(const raii_casemap&) = delete;
- raii_casemap(const std::string& locale_id) : map_(0)
+ raii_casemap(const std::string& locale_id) : map_(nullptr)
{
UErrorCode err = U_ZERO_ERROR;
map_ = ucasemap_open(locale_id.c_str(), 0, &err);
@@ -105,7 +104,7 @@ namespace boost { namespace locale { namespace impl_icu {
std::vector<char> buf(max_converted_size);
UErrorCode err = U_ZERO_ERROR;
auto size = func(map_,
- &buf.front(),
+ buf.data(),
static_cast<size_type>(buf.size()),
begin,
static_cast<size_type>(end - begin),
@@ -114,14 +113,14 @@ namespace boost { namespace locale { namespace impl_icu {
err = U_ZERO_ERROR;
buf.resize(size + 1);
size = func(map_,
- &buf.front(),
+ buf.data(),
static_cast<size_type>(buf.size()),
begin,
static_cast<size_type>(end - begin),
&err);
}
check_and_throw_icu_error(err);
- return std::string(&buf.front(), size);
+ return std::string(buf.data(), size);
}
~raii_casemap() { ucasemap_close(map_); }
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 450e7eadfa..c488390ad9 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
@@ -25,9 +25,8 @@ namespace boost { namespace locale { namespace impl_icu {
static void check_and_throw_dt(UErrorCode& e)
{
- if(U_FAILURE(e)) {
+ if(U_FAILURE(e))
throw date_time_error(u_errorName(e));
- }
}
using period::marks::period_mark;
@@ -55,7 +54,7 @@ namespace boost { namespace locale { namespace impl_icu {
case first_day_of_week:
case invalid: break;
}
- throw std::invalid_argument("Invalid date_time period type");
+ throw std::invalid_argument("Invalid date_time period type"); // LCOV_EXCL_LINE
}
class calendar_impl : public abstract_calendar {
@@ -95,16 +94,16 @@ namespace boost { namespace locale { namespace impl_icu {
guard l(lock_);
v = calendar_->getFirstDayOfWeek(err);
} else {
- UCalendarDateFields uper = to_icu(p);
+ UCalendarDateFields field = to_icu(p);
guard l(lock_);
switch(type) {
- case absolute_minimum: v = calendar_->getMinimum(uper); break;
- case actual_minimum: v = calendar_->getActualMinimum(uper, err); break;
- case greatest_minimum: v = calendar_->getGreatestMinimum(uper); break;
- case current: v = calendar_->get(uper, err); break;
- case least_maximum: v = calendar_->getLeastMaximum(uper); break;
- case actual_maximum: v = calendar_->getActualMaximum(uper, err); break;
- case absolute_maximum: v = calendar_->getMaximum(uper); break;
+ case absolute_minimum: v = calendar_->getMinimum(field); break;
+ case actual_minimum: v = calendar_->getActualMinimum(field, err); break;
+ case greatest_minimum: v = calendar_->getGreatestMinimum(field); break;
+ case current: v = calendar_->get(field, err); break;
+ case least_maximum: v = calendar_->getLeastMaximum(field); break;
+ case actual_maximum: v = calendar_->getActualMaximum(field, err); break;
+ case absolute_maximum: v = calendar_->getMaximum(field); break;
}
}
check_and_throw_dt(err);
@@ -153,11 +152,12 @@ namespace boost { namespace locale { namespace impl_icu {
case is_gregorian: throw date_time_error("is_gregorian is not settable options for calendar");
case is_dst: throw date_time_error("is_dst is not settable options for calendar");
}
+ throw std::invalid_argument("Invalid option type"); // LCOV_EXCL_LINE
}
int get_option(calendar_option_type opt) const override
{
switch(opt) {
- case is_gregorian: return icu_cast<const icu::GregorianCalendar>(calendar_.get()) != 0;
+ case is_gregorian: return icu_cast<const icu::GregorianCalendar>(calendar_.get()) != nullptr;
case is_dst: {
guard l(lock_);
UErrorCode err = U_ZERO_ERROR;
@@ -166,7 +166,7 @@ namespace boost { namespace locale { namespace impl_icu {
return res;
}
}
- return 0;
+ throw std::invalid_argument("Invalid option type"); // LCOV_EXCL_LINE
}
void adjust_value(period::marks::period_mark p, update_type u, int difference) override
{
@@ -179,15 +179,18 @@ namespace boost { namespace locale { namespace impl_icu {
}
int difference(const abstract_calendar& other, period::marks::period_mark m) const override
{
- UErrorCode err = U_ZERO_ERROR;
+ // era can't be queried via fieldDifference
+ if(BOOST_UNLIKELY(m == period::marks::era))
+ return get_value(m, value_type::current) - other.get_value(m, value_type::current);
+
const double other_time_ms = other.get_time_ms();
// fieldDifference has side effect of moving calendar (WTF?)
// So we clone it for performing this operation
hold_ptr<icu::Calendar> self(calendar_->clone());
- int diff = self->fieldDifference(other_time_ms, to_icu(m), err);
-
+ UErrorCode err = U_ZERO_ERROR;
+ const int diff = self->fieldDifference(other_time_ms, to_icu(m), err);
check_and_throw_dt(err);
return diff;
}
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 6167852bb6..89763d39ba 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/icu/formatter.cpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/icu/formatter.cpp
@@ -1,6 +1,6 @@
//
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
-// Copyright (c) 2021-2022 Alexander Grund
+// Copyright (c) 2021-2023 Alexander Grund
//
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
@@ -12,8 +12,13 @@
#include "boost/locale/icu/icu_util.hpp"
#include "boost/locale/icu/time_zone.hpp"
#include "boost/locale/icu/uconv.hpp"
+#include "boost/locale/util/foreach_char.hpp"
#include <limits>
#include <memory>
+#ifdef BOOST_MSVC
+# pragma warning(push)
+# pragma warning(disable : 4251) // "identifier" : class "type" needs to have dll-interface...
+#endif
#include <unicode/datefmt.h>
#include <unicode/decimfmt.h>
#include <unicode/numfmt.h>
@@ -21,6 +26,7 @@
#include <unicode/smpdtfmt.h>
#ifdef BOOST_MSVC
+# pragma warning(pop)
# pragma warning(disable : 4244) // lose data
#endif
@@ -36,18 +42,16 @@ namespace boost { namespace locale { namespace impl_icu {
precision += nf.getMaximumIntegerDigits();
#endif
nf.setMaximumFractionDigits(precision);
- if(how == std::ios_base::scientific || how == std::ios_base::fixed) {
+ if(how == std::ios_base::scientific || how == std::ios_base::fixed)
nf.setMinimumFractionDigits(precision);
- } else {
+ else
nf.setMinimumFractionDigits(0);
- }
}
} // namespace
template<typename CharType>
class number_format : public formatter<CharType> {
public:
- typedef CharType char_type;
typedef std::basic_string<CharType> string_type;
number_format(icu::NumberFormat& fmt, std::string codepage) : cvt_(codepage), icu_fmt_(fmt) {}
@@ -123,7 +127,6 @@ namespace boost { namespace locale { namespace impl_icu {
template<typename CharType>
class date_format : public formatter<CharType> {
public:
- typedef CharType char_type;
typedef std::basic_string<CharType> string_type;
string_type format(double value, size_t& code_points) const override { return do_format(value, code_points); }
@@ -171,7 +174,7 @@ namespace boost { namespace locale { namespace impl_icu {
string_type do_format(double value, size_t& codepoints) const
{
- UDate date = value * 1000.0; /// UDate is time_t in milliseconds
+ UDate date = value * 1000.0; // UDate is time_t in milliseconds
icu::UnicodeString tmp;
icu_fmt_.format(date, tmp);
codepoints = tmp.countChar32();
@@ -270,9 +273,9 @@ namespace boost { namespace locale { namespace impl_icu {
escaped = false;
}
result += strftime_symbol_to_icu(c, cache);
- } else if(c == '\'') {
+ } else if(c == '\'')
result += "''";
- } else {
+ else {
if(!escaped) {
result += "'";
escaped = true;
@@ -374,7 +377,7 @@ namespace boost { namespace locale { namespace impl_icu {
case strftime: {
using namespace flags;
std::unique_ptr<icu::DateFormat> new_df;
- icu::DateFormat* df = 0;
+ icu::DateFormat* df = nullptr;
// try to use cached first
{
icu::SimpleDateFormat* sdf = cache.date_formatter();
@@ -389,7 +392,7 @@ namespace boost { namespace locale { namespace impl_icu {
break;
case strftime: {
icu_std_converter<CharType> cvt_(encoding);
- const std::basic_string<CharType>& f = info.date_time_pattern<CharType>();
+ const std::basic_string<CharType> f = info.date_time_pattern<CharType>();
pattern = strftime_to_icu(cvt_.icu(f.c_str(), f.c_str() + f.size()), locale);
} break;
}
@@ -418,7 +421,7 @@ namespace boost { namespace locale { namespace impl_icu {
break;
case strftime: {
icu_std_converter<CharType> cvt_(encoding);
- const std::basic_string<CharType>& f = info.date_time_pattern<CharType>();
+ const std::basic_string<CharType> f = info.date_time_pattern<CharType>();
icu::UnicodeString pattern =
strftime_to_icu(cvt_.icu(f.data(), f.data() + f.size()), locale);
UErrorCode err = U_ZERO_ERROR;
@@ -444,16 +447,9 @@ namespace boost { namespace locale { namespace impl_icu {
return nullptr; // LCOV_EXCL_LINE
}
- template class formatter<char>;
- template class formatter<wchar_t>;
+#define BOOST_LOCALE_INSTANTIATE(CHAR) template class formatter<CHAR>;
+ BOOST_LOCALE_FOREACH_CHAR(BOOST_LOCALE_INSTANTIATE)
-#ifdef BOOST_LOCALE_ENABLE_CHAR16_T
- template class formatter<char16_t>;
-#endif
-
-#ifdef BOOST_LOCALE_ENABLE_CHAR32_T
- template class formatter<char32_t>;
-#endif
}}} // namespace boost::locale::impl_icu
// boostinspect:nominmax
diff --git a/contrib/restricted/boost/locale/src/boost/locale/icu/formatter.hpp b/contrib/restricted/boost/locale/src/boost/locale/icu/formatter.hpp
index cc55e76e2e..110a031551 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/icu/formatter.hpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/icu/formatter.hpp
@@ -8,7 +8,7 @@
#define BOOST_LOCALE_FORMATTER_HPP_INCLUDED
#include <boost/locale/config.hpp>
-#include <boost/cstdint.hpp>
+#include <cstdint>
#include <memory>
#include <string>
#include <unicode/locid.h>
@@ -26,7 +26,6 @@ namespace boost { namespace locale { namespace impl_icu {
template<typename CharType>
class formatter : public base_formatter {
public:
- typedef CharType char_type;
typedef std::basic_string<CharType> string_type;
/// Format the value and return the number of Unicode code points
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 acf1afccff..e5d5eb78ec 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
@@ -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
@@ -11,8 +12,7 @@
#include <boost/locale/util/locale_data.hpp>
#include "boost/locale/icu/all_generator.hpp"
#include "boost/locale/icu/cdata.hpp"
-#include <algorithm>
-#include <iterator>
+#include "boost/locale/util/make_std_unique.hpp"
#include <unicode/ucnv.h>
@@ -85,9 +85,7 @@ namespace boost { namespace locale { namespace impl_icu {
minf.country = country_;
minf.variant = variant_;
minf.encoding = data_.encoding;
- std::copy(domains_.begin(),
- domains_.end(),
- std::back_inserter<gnu_gettext::messages_info::domains_type>(minf.domains));
+ minf.domains = gnu_gettext::messages_info::domains_type(domains_.begin(), domains_.end());
minf.paths = paths_;
switch(type) {
case char_facet_t::nochar: break;
@@ -127,9 +125,9 @@ namespace boost { namespace locale { namespace impl_icu {
bool use_ansi_encoding_;
};
- localization_backend* create_localization_backend()
+ std::unique_ptr<localization_backend> create_localization_backend()
{
- return new icu_localization_backend();
+ return make_std_unique<icu_localization_backend>();
}
}}} // namespace boost::locale::impl_icu
diff --git a/contrib/restricted/boost/locale/src/boost/locale/icu/icu_backend.hpp b/contrib/restricted/boost/locale/src/boost/locale/icu/icu_backend.hpp
index 3dc2ca53ea..8266856dc1 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/icu/icu_backend.hpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/icu/icu_backend.hpp
@@ -8,11 +8,12 @@
#define BOOST_LOCALE_IMPL_ICU_LOCALIZATION_BACKEND_HPP
#include <boost/locale/config.hpp>
+#include <memory>
namespace boost { namespace locale {
class localization_backend;
namespace impl_icu {
- localization_backend* create_localization_backend();
+ std::unique_ptr<localization_backend> create_localization_backend();
} // namespace impl_icu
}} // namespace boost::locale
#endif
diff --git a/contrib/restricted/boost/locale/src/boost/locale/icu/icu_util.hpp b/contrib/restricted/boost/locale/src/boost/locale/icu/icu_util.hpp
index 871e3f8488..70f4cefa36 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/icu/icu_util.hpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/icu/icu_util.hpp
@@ -9,9 +9,7 @@
#define BOOST_SRC_ICU_UTIL_HPP
#include <boost/locale/config.hpp>
-#ifdef BOOST_HAS_STDINT_H
-# include <stdint.h> // Avoid ICU defining e.g. INT8_MIN causing macro redefinition warnings
-#endif
+#include <cstdint> // Avoid ICU defining e.g. INT8_MIN causing macro redefinition warnings
#include <stdexcept>
#include <string>
#include <unicode/utypes.h>
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 d3fdaaa2b8..963af7ba5b 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/icu/numeric.cpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/icu/numeric.cpp
@@ -58,9 +58,8 @@ namespace boost { namespace locale { namespace impl_icu {
if(!std::numeric_limits<ValueType>::is_integer)
return false;
- if(flg == flags::number && (ios.flags() & std::ios_base::basefield) != std::ios_base::dec) {
+ if(flg == flags::number && (ios.flags() & std::ios_base::basefield) != std::ios_base::dec)
return true;
- }
return false;
}
} // namespace detail
@@ -70,49 +69,48 @@ namespace boost { namespace locale { namespace impl_icu {
public:
typedef typename std::num_put<CharType>::iter_type iter_type;
typedef std::basic_string<CharType> string_type;
- typedef CharType char_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) {}
protected:
- iter_type do_put(iter_type out, std::ios_base& ios, char_type fill, long val) const override
+ iter_type do_put(iter_type out, std::ios_base& ios, CharType fill, long val) const override
{
return do_real_put(out, ios, fill, val);
}
- iter_type do_put(iter_type out, std::ios_base& ios, char_type fill, unsigned long val) const override
+ iter_type do_put(iter_type out, std::ios_base& ios, CharType fill, unsigned long val) const override
{
return do_real_put(out, ios, fill, val);
}
- iter_type do_put(iter_type out, std::ios_base& ios, char_type fill, double val) const override
+ iter_type do_put(iter_type out, std::ios_base& ios, CharType fill, double val) const override
{
return do_real_put(out, ios, fill, val);
}
- iter_type do_put(iter_type out, std::ios_base& ios, char_type fill, long double val) const override
+ iter_type do_put(iter_type out, std::ios_base& ios, CharType fill, long double val) const override
{
return do_real_put(out, ios, fill, val);
}
- iter_type do_put(iter_type out, std::ios_base& ios, char_type fill, long long val) const override
+ iter_type do_put(iter_type out, std::ios_base& ios, CharType fill, long long val) const override
{
return do_real_put(out, ios, fill, val);
}
- iter_type do_put(iter_type out, std::ios_base& ios, char_type fill, unsigned long long val) const override
+ iter_type do_put(iter_type out, std::ios_base& ios, CharType fill, unsigned long long val) const override
{
return do_real_put(out, ios, fill, val);
}
private:
template<typename ValueType>
- iter_type do_real_put(iter_type out, std::ios_base& ios, char_type fill, ValueType val) const
+ iter_type do_real_put(iter_type out, std::ios_base& ios, CharType fill, ValueType val) const
{
if(detail::use_parent(ios, val))
- return std::num_put<char_type>::do_put(out, ios, fill, val);
+ return std::num_put<CharType>::do_put(out, ios, fill, val);
const auto formatter = formatter_type::create(ios, loc_, enc_);
if(!formatter)
- return std::num_put<char_type>::do_put(out, ios, fill, val);
+ return std::num_put<CharType>::do_put(out, ios, fill, val);
size_t code_points;
typedef typename detail::icu_format_type<ValueType>::type icu_type;
@@ -145,7 +143,7 @@ namespace boost { namespace locale { namespace impl_icu {
icu::Locale loc_;
std::string enc_;
- }; /// num_format
+ }; // num_format
template<typename CharType>
class num_parse : public std::num_get<CharType> {
@@ -155,7 +153,6 @@ namespace boost { namespace locale { namespace impl_icu {
protected:
typedef typename std::num_get<CharType>::iter_type iter_type;
typedef std::basic_string<CharType> string_type;
- typedef CharType char_type;
typedef formatter<CharType> formatter_type;
typedef std::basic_istream<CharType> stream_type;
@@ -240,14 +237,12 @@ namespace boost { namespace locale { namespace impl_icu {
do_real_get(iter_type in, iter_type end, std::ios_base& ios, std::ios_base::iostate& err, ValueType& val) const
{
stream_type* stream_ptr = dynamic_cast<stream_type*>(&ios);
- if(!stream_ptr || detail::use_parent(ios, ValueType(0))) {
+ if(!stream_ptr || detail::use_parent(ios, ValueType(0)))
return std::num_get<CharType>::do_get(in, end, ios, err, val);
- }
const auto formatter = formatter_type::create(ios, loc_, enc_);
- if(!formatter) {
+ if(!formatter)
return std::num_get<CharType>::do_get(in, end, ios, err, val);
- }
string_type tmp;
tmp.reserve(64);
@@ -256,23 +251,20 @@ namespace boost { namespace locale { namespace impl_icu {
while(in != end && (((c = *in) <= 32 && (c > 0)) || c == 127)) // Assuming that ASCII is a subset
++in;
- while(tmp.size() < 4096 && in != end && *in != '\n') {
+ while(tmp.size() < 4096 && in != end && *in != '\n')
tmp += *in++;
- }
typedef typename detail::icu_format_type<ValueType>::type icu_type;
icu_type value;
size_t parsed_chars;
- if((parsed_chars = formatter->parse(tmp, value)) == 0 || !is_losless_castable<ValueType>(value)) {
+ if((parsed_chars = formatter->parse(tmp, value)) == 0 || !is_losless_castable<ValueType>(value))
err |= std::ios_base::failbit;
- } else {
+ else
val = static_cast<ValueType>(value);
- }
- for(size_t n = tmp.size(); n > parsed_chars; n--) {
+ for(size_t n = tmp.size(); n > parsed_chars; n--)
stream_ptr->putback(tmp[n - 1]);
- }
in = iter_type(*stream_ptr);
@@ -314,9 +306,8 @@ namespace boost { namespace locale { namespace impl_icu {
std::locale install_formatting_facets(const std::locale& in, const cdata& cd)
{
std::locale tmp = std::locale(in, new num_format<CharType>(cd));
- if(!std::has_facet<formatters_cache>(in)) {
+ if(!std::has_facet<formatters_cache>(in))
tmp = std::locale(tmp, new formatters_cache(cd.locale));
- }
return tmp;
}
@@ -324,9 +315,8 @@ namespace boost { namespace locale { namespace impl_icu {
std::locale install_parsing_facets(const std::locale& in, const cdata& cd)
{
std::locale tmp = std::locale(in, new num_parse<CharType>(cd));
- if(!std::has_facet<formatters_cache>(in)) {
+ if(!std::has_facet<formatters_cache>(in))
tmp = std::locale(tmp, new formatters_cache(cd.locale));
- }
return tmp;
}
diff --git a/contrib/restricted/boost/locale/src/boost/locale/icu/time_zone.cpp b/contrib/restricted/boost/locale/src/boost/locale/icu/time_zone.cpp
index dc69f2dd90..2f11862a59 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/icu/time_zone.cpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/icu/time_zone.cpp
@@ -45,12 +45,10 @@ namespace boost { namespace locale { namespace impl_icu {
icu::TimeZone* get_time_zone(const std::string& time_zone)
{
- if(time_zone.empty()) {
+ if(time_zone.empty())
return icu::TimeZone::createDefault();
- } else {
- icu::TimeZone* icu_tz = icu::TimeZone::createTimeZone(time_zone.c_str());
- return icu_tz;
- }
+ else
+ return icu::TimeZone::createTimeZone(time_zone.c_str());
}
#else
@@ -83,7 +81,7 @@ namespace boost { namespace locale { namespace impl_icu {
{
if(d && readdir_r(d, &de, &read_result) == 0 && read_result != 0)
return de.d_name;
- return 0;
+ return nullptr;
}
private:
@@ -95,10 +93,10 @@ namespace boost { namespace locale { namespace impl_icu {
bool files_equal(const std::string& left, const std::string& right)
{
char l[256], r[256];
- std::ifstream ls(left.c_str());
+ std::ifstream ls(left);
if(!ls)
return false;
- std::ifstream rs(right.c_str());
+ std::ifstream rs(right);
if(!rs)
return false;
do {
@@ -121,12 +119,11 @@ namespace boost { namespace locale { namespace impl_icu {
if(!d.is_open())
return std::string();
- const char* name = 0;
+ const char* name = nullptr;
while((name = d.next()) != 0) {
std::string file_name = name;
- if(file_name == "." || file_name == ".." || file_name == "posixrules" || file_name == "localtime") {
+ if(file_name == "." || file_name == ".." || file_name == "posixrules" || file_name == "localtime")
continue;
- }
struct stat st;
std::string path = dir + "/" + file_name;
if(stat(path.c_str(), &st) == 0) {
@@ -135,9 +132,8 @@ namespace boost { namespace locale { namespace impl_icu {
if(!res.empty())
return file_name + "/" + res;
} else {
- if(size_t(st.st_size) == size && files_equal(path, ref)) {
+ if(size_t(st.st_size) == size && files_equal(path, ref))
return file_name;
- }
}
}
}
@@ -194,9 +190,8 @@ namespace boost { namespace locale { namespace impl_icu {
icu::TimeZone* get_time_zone(const std::string& time_zone)
{
- if(!time_zone.empty()) {
+ if(!time_zone.empty())
return icu::TimeZone::createTimeZone(time_zone.c_str());
- }
hold_ptr<icu::TimeZone> tz(icu::TimeZone::createDefault());
icu::UnicodeString id;
tz->getID(id);
diff --git a/contrib/restricted/boost/locale/src/boost/locale/icu/time_zone.hpp b/contrib/restricted/boost/locale/src/boost/locale/icu/time_zone.hpp
index 132c5dbb64..87ab0c4416 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/icu/time_zone.hpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/icu/time_zone.hpp
@@ -8,9 +8,7 @@
#define BOOST_LOCALE_IMPL_ICU_GET_TIME_ZONE_HPP
#include <boost/locale/config.hpp>
-#ifdef BOOST_HAS_STDINT_H
-# include <stdint.h> // Avoid ICU defining e.g. INT8_MIN causing macro redefinition warnings
-#endif
+#include <cstdint> // Avoid ICU defining e.g. INT8_MIN causing macro redefinition warnings
#include <string>
#include <unicode/timezone.h>
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 ac8278235b..7f3c88b5d2 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/icu/uconv.hpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/icu/uconv.hpp
@@ -1,5 +1,6 @@
//
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+// Copyright (c) 2020-2023 Alexander Grund
//
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
@@ -9,6 +10,7 @@
#include <boost/locale/encoding.hpp>
#include "boost/locale/icu/icu_util.hpp"
+#include <boost/core/exchange.hpp>
#include <memory>
#include <string>
@@ -26,165 +28,158 @@
namespace boost { namespace locale { namespace impl_icu {
- enum class cpcvt_type { skip, stop };
+ class icu_handle {
+ UConverter* h_;
+ void close()
+ {
+ if(h_)
+ ucnv_close(h_);
+ }
- template<typename CharType, int char_size = sizeof(CharType)>
- class icu_std_converter {
public:
- typedef CharType char_type;
- typedef std::basic_string<char_type> string_type;
+ explicit icu_handle(UConverter* h = nullptr) : h_(h) {}
- icu_std_converter(std::string charset, cpcvt_type cv = cpcvt_type::skip);
- icu::UnicodeString icu(const char_type* begin, const char_type* end) const;
- string_type std(const icu::UnicodeString& str) const;
- size_t cut(const icu::UnicodeString& str,
- const char_type* begin,
- const char_type* end,
- size_t n,
- size_t from_u = 0,
- size_t from_c = 0) const;
+ icu_handle(const icu_handle& rhs) = delete;
+ icu_handle(icu_handle&& rhs) noexcept : h_(exchange(rhs.h_, nullptr)) {}
+
+ icu_handle& operator=(const icu_handle& rhs) = delete;
+ icu_handle& operator=(icu_handle&& rhs) noexcept
+ {
+ h_ = exchange(rhs.h_, nullptr);
+ return *this;
+ }
+ icu_handle& operator=(UConverter* h)
+ {
+ close();
+ h_ = h;
+ return *this;
+ }
+ ~icu_handle() { close(); }
+
+ operator UConverter*() const { return h_; }
+ explicit operator bool() const { return h_ != nullptr; }
};
+ enum class cpcvt_type { skip, stop };
+
+ struct uconv {
+ uconv(const uconv& other) = delete;
+ void operator=(const uconv& other) = delete;
+
+ uconv(const std::string& charset, cpcvt_type cvt_type = cpcvt_type::skip)
+ {
+ UErrorCode err = U_ZERO_ERROR;
+ cvt_ = ucnv_open(charset.c_str(), &err);
+ if(!cvt_ || U_FAILURE(err))
+ throw conv::invalid_charset_error(charset);
+
+ if(cvt_type == cpcvt_type::skip) {
+ ucnv_setFromUCallBack(cvt_, UCNV_FROM_U_CALLBACK_SKIP, nullptr, nullptr, nullptr, &err);
+ ucnv_setToUCallBack(cvt_, UCNV_TO_U_CALLBACK_SKIP, nullptr, nullptr, nullptr, &err);
+ check_and_throw_icu_error(err);
+ } else {
+ ucnv_setFromUCallBack(cvt_, UCNV_FROM_U_CALLBACK_STOP, nullptr, nullptr, nullptr, &err);
+ ucnv_setToUCallBack(cvt_, UCNV_TO_U_CALLBACK_STOP, nullptr, nullptr, nullptr, &err);
+ check_and_throw_icu_error(err);
+ }
+ }
+
+ int max_char_size() const { return ucnv_getMaxCharSize(cvt_); }
+
+ std::string go(const UChar* buf, int length, int max_size) const
+ {
+ std::string res;
+ res.resize(UCNV_GET_MAX_BYTES_FOR_STRING(length, max_size));
+ char* ptr = reinterpret_cast<char*>(&res[0]);
+ UErrorCode err = U_ZERO_ERROR;
+ int n = ucnv_fromUChars(cvt_, ptr, res.size(), buf, length, &err);
+ check_and_throw_icu_error(err);
+ res.resize(n);
+ return res;
+ }
+
+ size_t cut(size_t n, const char* begin, const char* end) const
+ {
+ const char* saved = begin;
+ while(n > 0 && begin < end) {
+ UErrorCode err = U_ZERO_ERROR;
+ ucnv_getNextUChar(cvt_, &begin, end, &err);
+ if(U_FAILURE(err))
+ return 0;
+ n--;
+ }
+ return begin - saved;
+ }
+
+ UConverter* cvt() const { return cvt_; }
+
+ private:
+ icu_handle cvt_;
+ };
+
+ template<typename CharType, int char_size = sizeof(CharType)>
+ class icu_std_converter;
+
template<typename CharType>
class icu_std_converter<CharType, 1> {
public:
- typedef CharType char_type;
- typedef std::basic_string<char_type> string_type;
+ typedef std::basic_string<CharType> string_type;
- icu::UnicodeString icu_checked(const char_type* vb, const char_type* ve) const
+ icu::UnicodeString icu_checked(const CharType* vb, const CharType* ve) const
{
return icu(vb, ve); // Already done
}
- icu::UnicodeString icu(const char_type* vb, const char_type* ve) const
+ icu::UnicodeString icu(const CharType* vb, const CharType* ve) const
{
const char* begin = reinterpret_cast<const char*>(vb);
const char* end = reinterpret_cast<const char*>(ve);
- uconv cvt(charset_, cvt_type_);
UErrorCode err = U_ZERO_ERROR;
- icu::UnicodeString tmp(begin, end - begin, cvt.cvt(), err);
+ icu::UnicodeString tmp(begin, end - begin, cvt_.cvt(), err);
check_and_throw_icu_error(err);
return tmp;
}
string_type std(const icu::UnicodeString& str) const
{
- uconv cvt(charset_, cvt_type_);
- return cvt.go(str.getBuffer(), str.length(), max_len_);
+ return cvt_.go(str.getBuffer(), str.length(), max_len_);
}
- icu_std_converter(std::string charset, cpcvt_type cvt_type = cpcvt_type::skip) :
- charset_(charset), cvt_type_(cvt_type)
- {
- uconv cvt(charset_, cvt_type);
- max_len_ = cvt.max_char_size();
- }
+ icu_std_converter(const std::string& charset, cpcvt_type cvt_type = cpcvt_type::skip) :
+ cvt_(charset, cvt_type), max_len_(cvt_.max_char_size())
+ {}
size_t cut(const icu::UnicodeString& str,
- const char_type* begin,
- const char_type* end,
+ const CharType* begin,
+ const CharType* end,
size_t n,
size_t from_u = 0,
size_t from_char = 0) const
{
size_t code_points = str.countChar32(from_u, n);
- uconv cvt(charset_, cvt_type_);
- return cvt.cut(code_points, begin + from_char, end);
+ return cvt_.cut(code_points, begin + from_char, end);
}
- struct uconv {
- uconv(const uconv& other) = delete;
- void operator=(const uconv& other) = delete;
-
- uconv(const std::string& charset, cpcvt_type cvt_type = cpcvt_type::skip)
- {
- UErrorCode err = U_ZERO_ERROR;
- cvt_ = ucnv_open(charset.c_str(), &err);
- if(!cvt_ || U_FAILURE(err)) {
- if(cvt_)
- ucnv_close(cvt_);
- throw conv::invalid_charset_error(charset);
- }
-
- try {
- if(cvt_type == cpcvt_type::skip) {
- ucnv_setFromUCallBack(cvt_, UCNV_FROM_U_CALLBACK_SKIP, 0, 0, 0, &err);
- check_and_throw_icu_error(err);
-
- err = U_ZERO_ERROR;
- ucnv_setToUCallBack(cvt_, UCNV_TO_U_CALLBACK_SKIP, 0, 0, 0, &err);
- check_and_throw_icu_error(err);
- } else {
- ucnv_setFromUCallBack(cvt_, UCNV_FROM_U_CALLBACK_STOP, 0, 0, 0, &err);
- check_and_throw_icu_error(err);
-
- err = U_ZERO_ERROR;
- ucnv_setToUCallBack(cvt_, UCNV_TO_U_CALLBACK_STOP, 0, 0, 0, &err);
- check_and_throw_icu_error(err);
- }
- } catch(...) {
- ucnv_close(cvt_);
- throw;
- }
- }
-
- int max_char_size() { return ucnv_getMaxCharSize(cvt_); }
-
- string_type go(const UChar* buf, int length, int max_size)
- {
- string_type res;
- res.resize(UCNV_GET_MAX_BYTES_FOR_STRING(length, max_size));
- char* ptr = reinterpret_cast<char*>(&res[0]);
- UErrorCode err = U_ZERO_ERROR;
- int n = ucnv_fromUChars(cvt_, ptr, res.size(), buf, length, &err);
- check_and_throw_icu_error(err);
- res.resize(n);
- return res;
- }
-
- size_t cut(size_t n, const char_type* begin, const char_type* end)
- {
- const char_type* saved = begin;
- while(n > 0 && begin < end) {
- UErrorCode err = U_ZERO_ERROR;
- ucnv_getNextUChar(cvt_, &begin, end, &err);
- if(U_FAILURE(err))
- return 0;
- n--;
- }
- return begin - saved;
- }
-
- UConverter* cvt() { return cvt_; }
-
- ~uconv() { ucnv_close(cvt_); }
-
- private:
- UConverter* cvt_;
- };
-
private:
- int max_len_;
- std::string charset_;
- cpcvt_type cvt_type_;
+ uconv cvt_;
+ const int max_len_;
};
template<typename CharType>
class icu_std_converter<CharType, 2> {
public:
- typedef CharType char_type;
- typedef std::basic_string<char_type> string_type;
+ typedef std::basic_string<CharType> string_type;
- icu::UnicodeString icu_checked(const char_type* begin, const char_type* end) const
+ icu::UnicodeString icu_checked(const CharType* begin, const CharType* end) const
{
- icu::UnicodeString tmp(end - begin, 0, 0); // make inital capacity
+ icu::UnicodeString tmp(end - begin, 0, 0); // make initial capacity
while(begin != end) {
UChar cl = *begin++;
if(U16_IS_SINGLE(cl))
tmp.append(static_cast<UChar32>(cl));
else if(U16_IS_LEAD(cl)) {
- if(begin == end) {
+ if(begin == end)
throw_if_needed();
- } else {
+ else {
UChar ct = *begin++;
if(!U16_IS_TRAIL(ct))
throw_if_needed();
@@ -203,8 +198,9 @@ namespace boost { namespace locale { namespace impl_icu {
if(mode_ == cpcvt_type::stop)
throw conv::conversion_error();
}
- icu::UnicodeString icu(const char_type* vb, const char_type* ve) const
+ icu::UnicodeString icu(const CharType* vb, const CharType* ve) const
{
+ static_assert(sizeof(CharType) == sizeof(UChar), "Size mismatch!");
const UChar* begin = reinterpret_cast<const UChar*>(vb);
const UChar* end = reinterpret_cast<const UChar*>(ve);
icu::UnicodeString tmp(begin, end - begin);
@@ -213,12 +209,13 @@ namespace boost { namespace locale { namespace impl_icu {
string_type std(const icu::UnicodeString& str) const
{
- const char_type* ptr = reinterpret_cast<const char_type*>(str.getBuffer());
+ static_assert(sizeof(CharType) == sizeof(UChar), "Size mismatch!");
+ const CharType* ptr = reinterpret_cast<const CharType*>(str.getBuffer());
return string_type(ptr, str.length());
}
size_t cut(const icu::UnicodeString& /*str*/,
- const char_type* /*begin*/,
- const char_type* /*end*/,
+ const CharType* /*begin*/,
+ const CharType* /*end*/,
size_t n,
size_t /*from_u*/ = 0,
size_t /*from_c*/ = 0) const
@@ -235,18 +232,29 @@ namespace boost { namespace locale { namespace impl_icu {
template<typename CharType>
class icu_std_converter<CharType, 4> {
public:
- typedef CharType char_type;
- typedef std::basic_string<char_type> string_type;
+ typedef std::basic_string<CharType> string_type;
- icu::UnicodeString icu_checked(const char_type* begin, const char_type* end) const
+ icu::UnicodeString icu_checked(const CharType* begin, const CharType* end) const
{
- icu::UnicodeString tmp(end - begin, 0, 0); // make inital capacity
+ // Fast path checking if the full string is already valid
+ {
+ UErrorCode err = U_ZERO_ERROR;
+ static_assert(sizeof(CharType) == sizeof(UChar32), "Size mismatch!");
+ u_strFromUTF32(nullptr, 0, nullptr, reinterpret_cast<const UChar32*>(begin), end - begin, &err);
+ if(err != U_INVALID_CHAR_FOUND)
+ return icu::UnicodeString::fromUTF32(reinterpret_cast<const UChar32*>(begin), end - begin);
+ }
+ // Any char is invalid
+ throw_if_needed();
+ // If not thrown skip invalid chars
+ icu::UnicodeString tmp(end - begin, 0, 0); // make initial capacity
while(begin != end) {
- UChar32 c = static_cast<UChar32>(*begin++);
- if(U_IS_UNICODE_CHAR(c))
+ const UChar32 c = static_cast<UChar32>(*begin++);
+ // Maybe simply: UCHAR_MIN_VALUE <= c && c <= UCHAR_MAX_VALUE && !U_IS_SURROGATE(c)
+ UErrorCode err = U_ZERO_ERROR;
+ u_strFromUTF32(nullptr, 0, nullptr, &c, 1, &err);
+ if(err != U_INVALID_CHAR_FOUND)
tmp.append(c);
- else
- throw_if_needed();
}
return tmp;
}
@@ -256,9 +264,9 @@ namespace boost { namespace locale { namespace impl_icu {
throw conv::conversion_error();
}
- icu::UnicodeString icu(const char_type* begin, const char_type* end) const
+ icu::UnicodeString icu(const CharType* begin, const CharType* end) const
{
- icu::UnicodeString tmp(end - begin, 0, 0); // make inital capacity
+ icu::UnicodeString tmp(end - begin, 0, 0); // make initial capacity
while(begin != end) {
UChar32 c = static_cast<UChar32>(*begin++);
tmp.append(c);
@@ -283,8 +291,8 @@ namespace boost { namespace locale { namespace impl_icu {
}
size_t cut(const icu::UnicodeString& str,
- const char_type* /*begin*/,
- const char_type* /*end*/,
+ const CharType* /*begin*/,
+ const CharType* /*end*/,
size_t n,
size_t from_u = 0,
size_t /*from_c*/ = 0) const
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 410d8bed45..e5c46ac248 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/posix/collate.cpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/posix/collate.cpp
@@ -40,39 +40,37 @@ namespace boost { namespace locale { namespace impl_posix {
template<typename CharType>
class collator : public std::collate<CharType> {
public:
- typedef CharType char_type;
- typedef std::basic_string<char_type> string_type;
+ typedef std::basic_string<CharType> string_type;
collator(std::shared_ptr<locale_t> l, size_t refs = 0) : std::collate<CharType>(refs), lc_(std::move(l)) {}
- int
- do_compare(const char_type* lb, const char_type* le, const char_type* rb, const char_type* re) const override
+ int do_compare(const CharType* lb, const CharType* le, const CharType* rb, const CharType* re) const override
{
string_type left(lb, le - lb);
string_type right(rb, re - rb);
- int res = coll_traits<char_type>::coll(left.c_str(), right.c_str(), *lc_);
+ int res = coll_traits<CharType>::coll(left.c_str(), right.c_str(), *lc_);
if(res < 0)
return -1;
if(res > 0)
return 1;
return 0;
}
- long do_hash(const char_type* b, const char_type* e) const override
+ long do_hash(const CharType* b, const CharType* e) const override
{
string_type s(do_transform(b, e));
const char* begin = reinterpret_cast<const char*>(s.c_str());
- const char* end = begin + s.size() * sizeof(char_type);
+ const char* end = begin + s.size() * sizeof(CharType);
return gnu_gettext::pj_winberger_hash_function(begin, end);
}
- string_type do_transform(const char_type* b, const char_type* e) const override
+ string_type do_transform(const CharType* b, const CharType* e) const override
{
string_type s(b, e - b);
- std::vector<char_type> buf((e - b) * 2 + 1);
- size_t n = coll_traits<char_type>::xfrm(&buf.front(), s.c_str(), buf.size(), *lc_);
+ std::vector<CharType> buf((e - b) * 2 + 1);
+ size_t n = coll_traits<CharType>::xfrm(buf.data(), s.c_str(), buf.size(), *lc_);
if(n > buf.size()) {
buf.resize(n);
- coll_traits<char_type>::xfrm(&buf.front(), s.c_str(), n, *lc_);
+ coll_traits<CharType>::xfrm(buf.data(), s.c_str(), n, *lc_);
}
- return string_type(&buf.front(), n);
+ return string_type(buf.data(), n);
}
private:
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 4dfa6babee..f769c7259e 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/posix/converter.cpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/posix/converter.cpp
@@ -7,6 +7,7 @@
#include <boost/locale/conversion.hpp>
#include <boost/locale/encoding.hpp>
#include <boost/locale/generator.hpp>
+#include "boost/locale/util/encoding.hpp"
#include <cctype>
#include <cstring>
#include <langinfo.h>
@@ -39,31 +40,28 @@ namespace boost { namespace locale { namespace impl_posix {
template<typename CharType>
class std_converter : public converter<CharType> {
public:
- typedef CharType char_type;
- typedef std::basic_string<char_type> string_type;
- typedef std::ctype<char_type> ctype_type;
+ typedef std::basic_string<CharType> string_type;
+ typedef std::ctype<CharType> ctype_type;
std_converter(std::shared_ptr<locale_t> lc, size_t refs = 0) : converter<CharType>(refs), lc_(std::move(lc)) {}
string_type convert(converter_base::conversion_type how,
- const char_type* begin,
- const char_type* end,
+ const CharType* begin,
+ const CharType* end,
int /*flags*/ = 0) const override
{
switch(how) {
case converter_base::upper_case: {
string_type res;
res.reserve(end - begin);
- while(begin != end) {
- res += case_traits<char_type>::upper(*begin++, *lc_);
- }
+ while(begin != end)
+ res += case_traits<CharType>::upper(*begin++, *lc_);
return res;
}
case converter_base::lower_case:
case converter_base::case_folding: {
string_type res;
res.reserve(end - begin);
- while(begin != end) {
- res += case_traits<char_type>::lower(*begin++, *lc_);
- }
+ while(begin != end)
+ res += case_traits<CharType>::lower(*begin++, *lc_);
return res;
}
case converter_base::normalization:
@@ -86,22 +84,22 @@ namespace boost { namespace locale { namespace impl_posix {
{
switch(how) {
case upper_case: {
- std::wstring tmp = conv::to_utf<wchar_t>(begin, end, "UTF-8");
+ const std::wstring tmp = conv::utf_to_utf<wchar_t>(begin, end);
std::wstring wres;
wres.reserve(tmp.size());
- for(unsigned i = 0; i < tmp.size(); i++)
- wres += towupper_l(tmp[i], *lc_);
- return conv::from_utf<wchar_t>(wres, "UTF-8");
+ for(const wchar_t c : tmp)
+ wres += towupper_l(c, *lc_);
+ return conv::utf_to_utf<char>(wres);
}
case lower_case:
case case_folding: {
- std::wstring tmp = conv::to_utf<wchar_t>(begin, end, "UTF-8");
+ const std::wstring tmp = conv::utf_to_utf<wchar_t>(begin, end);
std::wstring wres;
wres.reserve(tmp.size());
- for(unsigned i = 0; i < tmp.size(); i++)
- wres += towlower_l(tmp[i], *lc_);
- return conv::from_utf<wchar_t>(wres, "UTF-8");
+ for(const wchar_t c : tmp)
+ wres += towlower_l(c, *lc_);
+ return conv::utf_to_utf<char>(wres);
}
case normalization:
case title_case: break;
@@ -118,13 +116,8 @@ namespace boost { namespace locale { namespace impl_posix {
switch(type) {
case char_facet_t::nochar: break;
case char_facet_t::char_f: {
- std::string encoding = nl_langinfo_l(CODESET, *lc);
- for(unsigned i = 0; i < encoding.size(); i++)
- if('A' <= encoding[i] && encoding[i] <= 'Z')
- encoding[i] = encoding[i] - 'A' + 'a';
- if(encoding == "utf-8" || encoding == "utf8" || encoding == "utf_8") {
+ 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 std_converter<char>(std::move(lc)));
}
case char_facet_t::wchar_f: return std::locale(in, new std_converter<wchar_t>(std::move(lc)));
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 6c63a88810..031ce81463 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/posix/numeric.cpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/posix/numeric.cpp
@@ -11,6 +11,7 @@
#include <boost/locale/formatting.hpp>
#include <boost/locale/generator.hpp>
#include <boost/predef/os.h>
+#include <algorithm>
#include <cctype>
#include <cerrno>
#include <cstdlib>
@@ -36,7 +37,6 @@ namespace boost { namespace locale { namespace impl_posix {
public:
typedef typename std::num_put<CharType>::iter_type iter_type;
typedef std::basic_string<CharType> string_type;
- typedef CharType char_type;
num_format(std::shared_ptr<locale_t> lc, size_t refs = 0) :
util::base_num_format<CharType>(refs), lc_(std::move(lc))
@@ -46,7 +46,7 @@ namespace boost { namespace locale { namespace impl_posix {
iter_type do_format_currency(bool intl,
iter_type out,
std::ios_base& /*ios*/,
- char_type /*fill*/,
+ CharType /*fill*/,
long double val) const override
{
char buf[4] = {};
@@ -57,33 +57,29 @@ namespace boost { namespace locale { namespace impl_posix {
return write_it(out, buf, n);
for(std::vector<char> tmp(sizeof(buf) * 2); tmp.size() <= 4098; tmp.resize(tmp.size() * 2)) {
- n = strfmon_l(&tmp.front(), tmp.size(), *lc_, format, static_cast<double>(val));
+ n = strfmon_l(tmp.data(), tmp.size(), *lc_, format, static_cast<double>(val));
if(n >= 0)
- return write_it(out, &tmp.front(), n);
+ return write_it(out, tmp.data(), n);
}
return out;
}
std::ostreambuf_iterator<char> write_it(std::ostreambuf_iterator<char> out, const char* ptr, size_t n) const
{
- for(size_t i = 0; i < n; i++)
- *out++ = *ptr++;
- return out;
+ return std::copy_n(ptr, n, out);
}
std::ostreambuf_iterator<wchar_t>
write_it(std::ostreambuf_iterator<wchar_t> out, const char* ptr, size_t n) const
{
- std::wstring tmp = conv::to_utf<wchar_t>(ptr, ptr + n, nl_langinfo_l(CODESET, *lc_));
- for(size_t i = 0; i < tmp.size(); i++)
- *out++ = tmp[i];
- return out;
+ const std::wstring tmp = conv::to_utf<wchar_t>(ptr, ptr + n, nl_langinfo_l(CODESET, *lc_));
+ return std::copy(tmp.begin(), tmp.end(), out);
}
private:
std::shared_ptr<locale_t> lc_;
- }; /// num_format
+ }; // num_format
namespace {
std::string do_ftime(const char* format, const struct tm* t, locale_t lc)
@@ -119,8 +115,7 @@ namespace boost { namespace locale { namespace impl_posix {
std::time_put<CharType>(refs), lc_(std::move(lc))
{}
typedef typename std::time_put<CharType>::iter_type iter_type;
- typedef CharType char_type;
- typedef std::basic_string<char_type> string_type;
+ typedef std::basic_string<CharType> string_type;
iter_type do_put(iter_type out,
std::ios_base& /*ios*/,
@@ -129,13 +124,11 @@ namespace boost { namespace locale { namespace impl_posix {
char format,
char modifier) const override
{
- char_type fmt[4] = {'%',
- static_cast<char_type>(modifier != 0 ? modifier : format),
- static_cast<char_type>(modifier == 0 ? '\0' : format)};
+ CharType fmt[4] = {'%',
+ static_cast<CharType>(modifier != 0 ? modifier : format),
+ static_cast<CharType>(modifier == 0 ? '\0' : format)};
string_type res = do_ftime(fmt, tm, *lc_);
- for(unsigned i = 0; i < res.size(); i++)
- *out++ = res[i];
- return out;
+ return std::copy(res.begin(), res.end(), out);
}
private:
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 df87fa14f7..14d864bbf9 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
@@ -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
@@ -20,6 +21,7 @@
#include "boost/locale/posix/all_generator.hpp"
#include "boost/locale/util/gregorian.hpp"
+#include "boost/locale/util/make_std_unique.hpp"
namespace boost { namespace locale { namespace impl_posix {
@@ -66,25 +68,19 @@ namespace boost { namespace locale { namespace impl_posix {
if(real_id_.empty())
real_id_ = util::get_system_locale();
- locale_t tmp = newlocale(LC_ALL_MASK, real_id_.c_str(), 0);
-
- if(!tmp) {
- tmp = newlocale(LC_ALL_MASK, "C", 0);
- }
- if(!tmp) {
+ locale_t tmp = newlocale(LC_ALL_MASK, real_id_.c_str(), nullptr);
+ if(!tmp)
+ tmp = newlocale(LC_ALL_MASK, "C", nullptr);
+ if(!tmp)
throw std::runtime_error("newlocale failed");
- }
-
- locale_t* tmp_p = 0;
+ locale_t* tmp_p;
try {
- tmp_p = new locale_t();
+ tmp_p = new locale_t(tmp);
} catch(...) {
freelocale(tmp);
throw;
}
-
- *tmp_p = tmp;
lc_ = std::shared_ptr<locale_t>(tmp_p, free_locale_by_ptr);
}
@@ -148,9 +144,9 @@ namespace boost { namespace locale { namespace impl_posix {
std::shared_ptr<locale_t> lc_;
};
- localization_backend* create_localization_backend()
+ std::unique_ptr<localization_backend> create_localization_backend()
{
- return new posix_localization_backend();
+ return make_std_unique<posix_localization_backend>();
}
}}} // namespace boost::locale::impl_posix
diff --git a/contrib/restricted/boost/locale/src/boost/locale/posix/posix_backend.hpp b/contrib/restricted/boost/locale/src/boost/locale/posix/posix_backend.hpp
index e172fe4103..925c9580d5 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/posix/posix_backend.hpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/posix/posix_backend.hpp
@@ -6,10 +6,14 @@
#ifndef BOOST_LOCALE_IMPL_POSIX_LOCALIZATION_BACKEND_HPP
#define BOOST_LOCALE_IMPL_POSIX_LOCALIZATION_BACKEND_HPP
+
+#include <boost/locale/config.hpp>
+#include <memory>
+
namespace boost { namespace locale {
class localization_backend;
namespace impl_posix {
- localization_backend* create_localization_backend();
+ std::unique_ptr<localization_backend> create_localization_backend();
} // namespace impl_posix
}} // namespace boost::locale
#endif
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 1970fec8bb..60f96feb7b 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
@@ -6,6 +6,7 @@
#include <boost/locale/date_time.hpp>
#include <boost/locale/formatting.hpp>
+#include <boost/core/exchange.hpp>
#include <boost/thread/locks.hpp>
#include <boost/thread/mutex.hpp>
#include <cmath>
@@ -66,12 +67,12 @@ namespace boost { namespace locale {
return impl_->get_option(abstract_calendar::is_gregorian) != 0;
}
- std::string calendar::get_time_zone() const
+ const std::string& calendar::get_time_zone() const
{
return tz_;
}
- std::locale calendar::get_locale() const
+ const std::locale& calendar::get_locale() const
{
return locale_;
}
@@ -125,9 +126,8 @@ namespace boost { namespace locale {
date_time::date_time(const date_time& other, const date_time_period_set& s)
{
impl_.reset(other.impl_->clone());
- for(unsigned i = 0; i < s.size(); i++) {
+ for(unsigned i = 0; i < s.size(); i++)
impl_->set_value(s[i].type.mark(), s[i].value);
- }
impl_->normalize();
}
@@ -154,16 +154,14 @@ namespace boost { namespace locale {
impl_(std::use_facet<calendar_facet>(std::locale()).create_calendar())
{
impl_->set_timezone(time_zone::global());
- for(unsigned i = 0; i < s.size(); i++) {
+ for(unsigned i = 0; i < s.size(); i++)
impl_->set_value(s[i].type.mark(), s[i].value);
- }
impl_->normalize();
}
date_time::date_time(const date_time_period_set& s, const calendar& cal) : impl_(cal.impl_->clone())
{
- for(unsigned i = 0; i < s.size(); i++) {
+ for(unsigned i = 0; i < s.size(); i++)
impl_->set_value(s[i].type.mark(), s[i].value);
- }
impl_->normalize();
}
@@ -268,33 +266,29 @@ namespace boost { namespace locale {
date_time& date_time::operator+=(const date_time_period_set& v)
{
- for(unsigned i = 0; i < v.size(); i++) {
+ for(unsigned i = 0; i < v.size(); i++)
*this += v[i];
- }
return *this;
}
date_time& date_time::operator-=(const date_time_period_set& v)
{
- for(unsigned i = 0; i < v.size(); i++) {
+ for(unsigned i = 0; i < v.size(); i++)
*this -= v[i];
- }
return *this;
}
date_time& date_time::operator<<=(const date_time_period_set& v)
{
- for(unsigned i = 0; i < v.size(); i++) {
+ for(unsigned i = 0; i < v.size(); i++)
*this <<= v[i];
- }
return *this;
}
date_time& date_time::operator>>=(const date_time_period_set& v)
{
- for(unsigned i = 0; i < v.size(); i++) {
+ for(unsigned i = 0; i < v.size(); i++)
*this >>= v[i];
- }
return *this;
}
@@ -325,6 +319,11 @@ namespace boost { namespace locale {
impl_->set_time(ptime);
}
+ std::string date_time::timezone() const
+ {
+ return impl_->get_timezone();
+ }
+
namespace {
int compare(const posix_time& left, const posix_time& right)
{
@@ -370,7 +369,7 @@ namespace boost { namespace locale {
return !(*this > other);
}
- void date_time::swap(date_time& other)
+ void date_time::swap(date_time& other) noexcept
{
impl_.swap(other.impl_);
}
@@ -409,15 +408,12 @@ namespace boost { namespace locale {
std::string global()
{
boost::unique_lock<boost::mutex> lock(tz_mutex());
- std::string id = tz_id();
- return id;
+ return tz_id();
}
std::string global(const std::string& new_id)
{
boost::unique_lock<boost::mutex> lock(tz_mutex());
- std::string id = tz_id();
- tz_id() = new_id;
- return id;
+ return boost::exchange(tz_id(), new_id);
}
} // namespace time_zone
diff --git a/contrib/restricted/boost/locale/src/boost/locale/shared/format.cpp b/contrib/restricted/boost/locale/src/boost/locale/shared/format.cpp
index 8d3f7406af..7ee809fe70 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/shared/format.cpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/shared/format.cpp
@@ -7,11 +7,13 @@
#include <boost/locale/format.hpp>
#include <boost/locale/generator.hpp>
#include <boost/locale/info.hpp>
-#include <cstdlib>
+#include "boost/locale/util/numeric.hpp"
+#include <algorithm>
#include <iostream>
#include <limits>
namespace boost { namespace locale { namespace detail {
+
struct format_parser::data {
unsigned position;
std::streamsize precision;
@@ -61,17 +63,11 @@ namespace boost { namespace locale { namespace detail {
{
if(key.empty())
return;
- unsigned i;
- for(i = 0; i < key.size(); i++) {
- if(key[i] < '0' || '9' < key[i])
- break;
- }
- if(i == key.size()) {
- d->position = atoi(key.c_str()) - 1;
- return;
- }
-
- if(key == "num" || key == "number") {
+ int position;
+ if(util::try_to_int(key, position) && position > 0) {
+ static_assert(sizeof(unsigned) <= sizeof(decltype(d->position)), "Possible lossy conversion");
+ d->position = static_cast<unsigned>(position - 1);
+ } else if(key == "num" || key == "number") {
as::number(ios_);
if(value == "hex")
@@ -88,9 +84,9 @@ namespace boost { namespace locale { namespace detail {
as::currency_iso(ios_);
else if(value == "nat" || value == "national")
as::currency_national(ios_);
- } else if(key == "per" || key == "percent") {
+ } else if(key == "per" || key == "percent")
as::percent(ios_);
- } else if(key == "date") {
+ else if(key == "date") {
as::date(ios_);
if(value == "s" || value == "short")
as::date_short(ios_);
@@ -125,11 +121,11 @@ namespace boost { namespace locale { namespace detail {
as::date_full(ios_);
as::time_full(ios_);
}
- } else if(key == "spell" || key == "spellout") {
+ } else if(key == "spell" || key == "spellout")
as::spellout(ios_);
- } else if(key == "ord" || key == "ordinal") {
+ else if(key == "ord" || key == "ordinal")
as::ordinal(ios_);
- } else if(key == "left" || key == "<")
+ else if(key == "left" || key == "<")
ios_.setf(std::ios_base::left, std::ios_base::adjustfield);
else if(key == "right" || key == ">")
ios_.setf(std::ios_base::right, std::ios_base::adjustfield);
@@ -139,23 +135,26 @@ namespace boost { namespace locale { namespace detail {
as::local_time(ios_);
else if(key == "timezone" || key == "tz")
ios_info::get(ios_).time_zone(value);
- else if(key == "w" || key == "width")
- ios_.width(atoi(value.c_str()));
- else if(key == "p" || key == "precision")
- ios_.precision(atoi(value.c_str()));
- else if(key == "locale") {
+ else if(key == "w" || key == "width") {
+ int v;
+ if(util::try_to_int(value, v))
+ ios_.width(v);
+ } else if(key == "p" || key == "precision") {
+ int v;
+ if(util::try_to_int(value, v))
+ ios_.precision(v);
+ } else if(key == "locale") {
if(!d->restore_locale) {
d->saved_locale = ios_.getloc();
d->restore_locale = true;
}
- std::string encoding = std::use_facet<info>(d->saved_locale).encoding();
generator gen;
gen.categories(category_t::formatting);
std::locale new_loc;
if(value.find('.') == std::string::npos)
- new_loc = gen(value + "." + encoding);
+ new_loc = gen(value + "." + std::use_facet<info>(d->saved_locale).encoding());
else
new_loc = gen(value);
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 5c1e5e7ab5..489d1fd5a0 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/shared/formatting.cpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/shared/formatting.cpp
@@ -12,22 +12,22 @@
namespace boost { namespace locale {
- ios_info::string_set::string_set() : type(0), size(0), ptr(0) {}
+ 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 != 0) {
+ if(other.ptr != nullptr) {
ptr = new char[other.size];
size = other.size;
type = other.type;
memcpy(ptr, other.ptr, size);
} else {
- ptr = 0;
+ ptr = nullptr;
size = 0;
- type = 0;
+ type = nullptr;
}
}
diff --git a/contrib/restricted/boost/locale/src/boost/locale/shared/generator.cpp b/contrib/restricted/boost/locale/src/boost/locale/shared/generator.cpp
index fe4e20c3c8..baf424bea8 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/shared/generator.cpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/shared/generator.cpp
@@ -20,8 +20,7 @@ namespace boost { namespace locale {
backend_manager(mgr)
{}
- typedef std::map<std::string, std::locale> cached_type;
- mutable cached_type cached;
+ mutable std::map<std::string, std::locale> cached;
mutable boost::mutex cached_lock;
category_t cats;
@@ -69,10 +68,9 @@ namespace boost { namespace locale {
void generator::set_default_messages_domain(const std::string& domain)
{
- std::vector<std::string>::iterator p;
- if((p = std::find(d->domains.begin(), d->domains.end(), domain)) != d->domains.end()) {
+ const auto p = std::find(d->domains.begin(), d->domains.end(), domain);
+ if(p != d->domains.end())
d->domains.erase(p);
- }
d->domains.insert(d->domains.begin(), domain);
}
@@ -104,12 +102,11 @@ namespace boost { namespace locale {
{
if(d->caching_enabled) {
boost::unique_lock<boost::mutex> guard(d->cached_lock);
- data::cached_type::const_iterator p = d->cached.find(id);
- if(p != d->cached.end()) {
+ const auto p = d->cached.find(id);
+ if(p != d->cached.end())
return p->second;
- }
}
- hold_ptr<localization_backend> backend(d->backend_manager.create());
+ auto backend = d->backend_manager.create();
set_all_options(*backend, id);
std::locale result = base;
@@ -130,10 +127,9 @@ namespace boost { namespace locale {
}
if(d->caching_enabled) {
boost::unique_lock<boost::mutex> guard(d->cached_lock);
- data::cached_type::const_iterator p = d->cached.find(id);
- if(p == d->cached.end()) {
+ const auto p = d->cached.find(id);
+ if(p == d->cached.end())
d->cached[id] = result;
- }
}
return result;
}
@@ -160,12 +156,11 @@ namespace boost { namespace locale {
void generator::set_all_options(localization_backend& backend, const std::string& id) const
{
backend.set_option("locale", id);
- if(d->use_ansi_encoding)
- backend.set_option("use_ansi_encoding", "true");
- for(size_t i = 0; i < d->domains.size(); i++)
- backend.set_option("message_application", d->domains[i]);
- for(size_t i = 0; i < d->paths.size(); i++)
- backend.set_option("message_path", d->paths[i]);
+ backend.set_option("use_ansi_encoding", d->use_ansi_encoding ? "true" : "false");
+ for(const std::string& domain : d->domains)
+ backend.set_option("message_application", domain);
+ for(const std::string& path : d->paths)
+ backend.set_option("message_path", path);
}
// Sanity check
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 764fe3c686..d34cb738be 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
@@ -12,27 +12,19 @@
#include <limits>
#include <vector>
#ifdef BOOST_LOCALE_WITH_ICONV
+# include "boost/locale/util/encoding.hpp"
# include "boost/locale/util/iconv.hpp"
+# include "boost/locale/util/make_std_unique.hpp"
#endif
namespace boost { namespace locale {
#ifdef BOOST_LOCALE_WITH_ICONV
- static const char* utf32_encoding()
- {
- union {
- char one;
- uint32_t value;
- } test;
- test.value = 1;
- return (test.one == 1) ? "UTF-32LE" : "UTF-32BE";
- }
-
class mb2_iconv_converter : public util::base_converter {
public:
mb2_iconv_converter(const std::string& encoding) : encoding_(encoding)
{
- iconv_handle d = iconv_open(utf32_encoding(), encoding.c_str());
+ iconv_handle d(iconv_open(util::utf_name<uint32_t>(), encoding.c_str()));
if(!d)
throw std::runtime_error("Unsupported encoding" + encoding);
@@ -68,7 +60,7 @@ namespace boost { namespace locale {
mb2_iconv_converter* clone() const override { return new mb2_iconv_converter(*this); }
- uint32_t to_unicode(const char*& begin, const char* end) override
+ utf::code_point to_unicode(const char*& begin, const char* end) override
{
if(begin == end)
return incomplete;
@@ -95,7 +87,7 @@ namespace boost { namespace locale {
} else if(begin + 1 == end)
return incomplete;
- open(to_utf_, utf32_encoding(), encoding_.c_str());
+ open(to_utf_, util::utf_name<uint32_t>(), encoding_.c_str());
// maybe illegal or may be double byte
@@ -111,20 +103,19 @@ namespace boost { namespace locale {
return illegal;
}
- uint32_t from_unicode(uint32_t cp, char* begin, const char* end) override
+ utf::len_or_error from_unicode(utf::code_point cp, char* begin, const char* end) override
{
if(cp == 0) {
if(begin != end) {
*begin = 0;
return 1;
- } else {
+ } else
return incomplete;
- }
}
- open(from_utf_, encoding_.c_str(), utf32_encoding());
+ open(from_utf_, encoding_.c_str(), util::utf_name<utf::code_point>());
- const uint32_t inbuf[2] = {cp, 0};
+ const utf::code_point inbuf[2] = {cp, 0};
size_t insize = sizeof(inbuf);
char outseq[3] = {0};
size_t outsize = 3;
@@ -133,13 +124,13 @@ namespace boost { namespace locale {
if(insize != 0 || outsize > 1)
return illegal;
- size_t len = 2 - outsize;
- size_t reminder = end - begin;
+ const size_t len = 2 - outsize;
+ const size_t reminder = end - begin;
if(reminder < len)
return incomplete;
for(unsigned i = 0; i < len; i++)
*begin++ = outseq[i];
- return static_cast<uint32_t>(len);
+ return static_cast<utf::code_point>(len);
}
int max_len() const override
@@ -163,7 +154,7 @@ namespace boost { namespace locale {
std::unique_ptr<util::base_converter> create_iconv_converter(const std::string& encoding)
{
try {
- return std::unique_ptr<util::base_converter>(new mb2_iconv_converter(encoding));
+ return make_std_unique<mb2_iconv_converter>(encoding);
} catch(const std::exception&) {
return nullptr;
}
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 30d91d7454..95a64ff19a 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/shared/ids.cpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/shared/ids.cpp
@@ -10,81 +10,36 @@
#include <boost/locale/date_time_facet.hpp>
#include <boost/locale/info.hpp>
#include <boost/locale/message.hpp>
+#include "boost/locale/util/foreach_char.hpp"
#include <boost/core/ignore_unused.hpp>
namespace boost { namespace locale {
+ namespace detail {
+ template<class Derived>
+ std::locale::id facet_id<Derived>::id;
+ } // namespace detail
+#define BOOST_LOCALE_DEFINE_ID(CLASS) template struct detail::facet_id<CLASS>
- std::locale::id info::id;
- // Make sure we have the VTable here (Export/Import issues)
- info::~info() = default;
+ BOOST_LOCALE_DEFINE_ID(info);
+ BOOST_LOCALE_DEFINE_ID(calendar_facet);
- std::locale::id calendar_facet::id;
- calendar_facet::~calendar_facet() = default;
+#define BOOST_LOCALE_INSTANTIATE(CHARTYPE) \
+ BOOST_LOCALE_DEFINE_ID(converter<CHARTYPE>); \
+ BOOST_LOCALE_DEFINE_ID(message_format<CHARTYPE>); \
+ BOOST_LOCALE_DEFINE_ID(boundary::boundary_indexing<CHARTYPE>);
- abstract_calendar::~abstract_calendar() = default;
-
- std::locale::id converter<char>::id;
- converter<char>::~converter() = default;
- std::locale::id base_message_format<char>::id;
- base_message_format<char>::~base_message_format() = default;
-
- std::locale::id converter<wchar_t>::id;
- converter<wchar_t>::~converter() = default;
- std::locale::id base_message_format<wchar_t>::id;
- base_message_format<wchar_t>::~base_message_format() = default;
-
-#ifdef BOOST_LOCALE_ENABLE_CHAR16_T
-
- std::locale::id converter<char16_t>::id;
- converter<char16_t>::~converter() = default;
- std::locale::id base_message_format<char16_t>::id;
- base_message_format<char16_t>::~base_message_format() = default;
-
-#endif
-
-#ifdef BOOST_LOCALE_ENABLE_CHAR32_T
-
- std::locale::id converter<char32_t>::id;
- converter<char32_t>::~converter() = default;
- std::locale::id base_message_format<char32_t>::id;
- base_message_format<char32_t>::~base_message_format() = default;
-
-#endif
-
- namespace boundary {
-
- std::locale::id boundary_indexing<char>::id;
- boundary_indexing<char>::~boundary_indexing() = default;
-
- std::locale::id boundary_indexing<wchar_t>::id;
- boundary_indexing<wchar_t>::~boundary_indexing() = default;
-
-#ifdef BOOST_LOCALE_ENABLE_CHAR16_T
- std::locale::id boundary_indexing<char16_t>::id;
- boundary_indexing<char16_t>::~boundary_indexing() = default;
-#endif
-
-#ifdef BOOST_LOCALE_ENABLE_CHAR32_T
- std::locale::id boundary_indexing<char32_t>::id;
- boundary_indexing<char32_t>::~boundary_indexing() = default;
-#endif
- } // namespace boundary
+ BOOST_LOCALE_FOREACH_CHAR(BOOST_LOCALE_INSTANTIATE)
+#undef BOOST_LOCALE_INSTANTIATE
namespace {
// Initialize each facet once to avoid issues where doing so
- // in a multithreaded environment could cause problems (races)
+ // in a multi threaded environment could cause problems (races)
struct init_all {
init_all()
{
const std::locale& l = std::locale::classic();
- init_by<char>(l);
- init_by<wchar_t>(l);
-#ifdef BOOST_LOCALE_ENABLE_CHAR16_T
- init_by<char16_t>(l);
-#endif
-#ifdef BOOST_LOCALE_ENABLE_CHAR32_T
- init_by<char32_t>(l);
-#endif
+#define BOOST_LOCALE_INIT_BY(CHAR) init_by<CHAR>(l);
+ BOOST_LOCALE_FOREACH_CHAR(BOOST_LOCALE_INIT_BY)
init_facet<info>(l);
init_facet<calendar_facet>(l);
diff --git a/contrib/restricted/boost/locale/src/boost/locale/shared/localization_backend.cpp b/contrib/restricted/boost/locale/src/boost/locale/shared/localization_backend.cpp
index e15de171a6..951cb3beb4 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/shared/localization_backend.cpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/shared/localization_backend.cpp
@@ -4,10 +4,10 @@
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
-#include <boost/locale/hold_ptr.hpp>
#include <boost/locale/localization_backend.hpp>
#include <boost/thread/locks.hpp>
#include <boost/thread/mutex.hpp>
+#include <functional>
#include <memory>
#include <vector>
@@ -28,19 +28,19 @@
#endif
namespace boost { namespace locale {
+ static std::unique_ptr<localization_backend> clone(const localization_backend& backend)
+ {
+ return std::unique_ptr<localization_backend>(backend.clone());
+ }
+
localization_backend::~localization_backend() = default;
class localization_backend_manager::impl {
public:
impl(const impl& other) : default_backends_(other.default_backends_)
{
- for(all_backends_type::const_iterator p = other.all_backends_.begin(); p != other.all_backends_.end(); ++p)
- {
- all_backends_type::value_type v;
- v.first = p->first;
- v.second.reset(p->second->clone());
- all_backends_.push_back(v);
- }
+ for(const auto& i : other.all_backends_)
+ all_backends_.push_back({i.first, clone(*i.second)});
}
impl() : default_backends_(32, -1) {}
@@ -48,39 +48,40 @@ namespace boost { namespace locale {
localization_backend* create() const
{
- std::vector<std::shared_ptr<localization_backend>> backends;
- for(unsigned i = 0; i < all_backends_.size(); i++)
- backends.push_back(all_backends_[i].second);
+ std::vector<std::reference_wrapper<const localization_backend>> backends;
+ for(const auto& i : all_backends_)
+ backends.push_back(std::cref(*i.second));
return new actual_backend(backends, default_backends_);
}
- void adopt_backend(const std::string& name, localization_backend* backend_ptr)
+
+ int find_backend(const std::string& name) const
{
- std::shared_ptr<localization_backend> sptr(backend_ptr);
- if(all_backends_.empty()) {
- all_backends_.push_back(std::make_pair(name, sptr));
- for(unsigned i = 0; i < default_backends_.size(); i++)
- default_backends_[i] = 0;
- } else {
- for(unsigned i = 0; i < all_backends_.size(); i++)
- if(all_backends_[i].first == name)
- return;
- all_backends_.push_back(std::make_pair(name, sptr));
+ int id = 0;
+ for(const auto& i : all_backends_) {
+ if(i.first == name)
+ return id;
+ ++id;
}
+ return -1;
+ }
+
+ void add_backend(const std::string& name, std::unique_ptr<localization_backend> ptr)
+ {
+ if(all_backends_.empty())
+ std::fill(default_backends_.begin(), default_backends_.end(), 0);
+ if(BOOST_LIKELY(find_backend(name) < 0))
+ all_backends_.push_back(std::make_pair(name, std::move(ptr)));
}
void select(const std::string& backend_name, category_t category = all_categories)
{
- unsigned id;
- for(id = 0; id < all_backends_.size(); ++id) {
- if(all_backends_[id].first == backend_name)
- break;
- }
- if(id == all_backends_.size())
- return;
- category_t flag = category_first;
- for(unsigned i = 0; i < default_backends_.size(); ++flag, ++i) {
- if(category & flag) {
- default_backends_[i] = id;
+ const int id = find_backend(backend_name);
+ if(id >= 0) {
+ category_t flag = category_first;
+ for(int& defBackend : default_backends_) {
+ if(category & flag)
+ defBackend = id;
+ ++flag;
}
}
}
@@ -88,42 +89,42 @@ namespace boost { namespace locale {
void remove_all_backends()
{
all_backends_.clear();
- for(unsigned i = 0; i < default_backends_.size(); i++) {
- default_backends_[i] = -1;
- }
+ std::fill(default_backends_.begin(), default_backends_.end(), -1);
}
std::vector<std::string> get_all_backends() const
{
std::vector<std::string> res;
- all_backends_type::const_iterator p;
- for(p = all_backends_.begin(); p != all_backends_.end(); ++p) {
- res.push_back(p->first);
- }
+ for(const auto& i : all_backends_)
+ res.push_back(i.first);
return res;
}
private:
class actual_backend : public localization_backend {
public:
- actual_backend(const std::vector<std::shared_ptr<localization_backend>>& backends,
+ actual_backend(const std::vector<std::reference_wrapper<const localization_backend>>& backends,
const std::vector<int>& index) :
index_(index)
{
- backends_.resize(backends.size());
- for(unsigned i = 0; i < backends.size(); i++) {
- backends_[i].reset(backends[i]->clone());
- }
+ for(const localization_backend& b : backends)
+ backends_.push_back(boost::locale::clone(b));
+ }
+ actual_backend* clone() const override
+ {
+ std::vector<std::reference_wrapper<const localization_backend>> backends;
+ for(const auto& b : backends_)
+ backends.push_back(std::cref(*b));
+ return new actual_backend(backends, index_);
}
- actual_backend* clone() const override { return new actual_backend(backends_, index_); }
void set_option(const std::string& name, const std::string& value) override
{
- for(unsigned i = 0; i < backends_.size(); i++)
- backends_[i]->set_option(name, value);
+ for(const auto& b : backends_)
+ b->set_option(name, value);
}
void clear_options() override
{
- for(unsigned i = 0; i < backends_.size(); i++)
- backends_[i]->clear_options();
+ for(const auto& b : backends_)
+ b->clear_options();
}
std::locale install(const std::locale& l, category_t category, char_facet_t type) override
{
@@ -138,12 +139,11 @@ namespace boost { namespace locale {
}
private:
- std::vector<std::shared_ptr<localization_backend>> backends_;
+ std::vector<std::unique_ptr<localization_backend>> backends_;
std::vector<int> index_;
};
- typedef std::vector<std::pair<std::string, std::shared_ptr<localization_backend>>> all_backends_type;
- all_backends_type all_backends_;
+ std::vector<std::pair<std::string, std::unique_ptr<localization_backend>>> all_backends_;
std::vector<int> default_backends_;
};
@@ -161,23 +161,18 @@ namespace boost { namespace locale {
return *this;
}
- std::unique_ptr<localization_backend> localization_backend_manager::get() const
+ localization_backend_manager::localization_backend_manager(localization_backend_manager&&) noexcept = default;
+ localization_backend_manager&
+ localization_backend_manager::operator=(localization_backend_manager&&) noexcept = default;
+
+ std::unique_ptr<localization_backend> localization_backend_manager::create() const
{
return std::unique_ptr<localization_backend>(pimpl_->create());
}
void localization_backend_manager::add_backend(const std::string& name,
std::unique_ptr<localization_backend> backend)
{
- pimpl_->adopt_backend(name, backend.release());
- }
-
- localization_backend* localization_backend_manager::create() const
- {
- return pimpl_->create();
- }
- void localization_backend_manager::adopt_backend(const std::string& name, localization_backend* backend)
- {
- pimpl_->adopt_backend(name, backend);
+ pimpl_->add_backend(name, std::move(backend));
}
void localization_backend_manager::remove_all_backends()
@@ -194,56 +189,49 @@ namespace boost { namespace locale {
}
namespace {
- // prevent initialization order fiasco
- boost::mutex& localization_backend_manager_mutex()
+ localization_backend_manager make_default_backend_mgr()
{
- static boost::mutex the_mutex;
- return the_mutex;
- }
- // prevent initialization order fiasco
- localization_backend_manager& localization_backend_manager_global()
- {
- static localization_backend_manager the_manager;
- return the_manager;
- }
-
- struct init {
- init()
- {
- localization_backend_manager mgr;
+ localization_backend_manager mgr;
#ifdef BOOST_LOCALE_WITH_ICU
- mgr.adopt_backend("icu", impl_icu::create_localization_backend());
+ mgr.add_backend("icu", impl_icu::create_localization_backend());
#endif
#ifndef BOOST_LOCALE_NO_POSIX_BACKEND
- mgr.adopt_backend("posix", impl_posix::create_localization_backend());
+ mgr.add_backend("posix", impl_posix::create_localization_backend());
#endif
#ifndef BOOST_LOCALE_NO_WINAPI_BACKEND
- mgr.adopt_backend("winapi", impl_win::create_localization_backend());
+ mgr.add_backend("winapi", impl_win::create_localization_backend());
#endif
#ifndef BOOST_LOCALE_NO_STD_BACKEND
- mgr.adopt_backend("std", impl_std::create_localization_backend());
+ mgr.add_backend("std", impl_std::create_localization_backend());
#endif
- localization_backend_manager::global(mgr);
- }
- } do_init;
+ return mgr;
+ }
+
+ boost::mutex& localization_backend_manager_mutex()
+ {
+ static boost::mutex the_mutex;
+ return the_mutex;
+ }
+ localization_backend_manager& localization_backend_manager_global()
+ {
+ static localization_backend_manager the_manager = make_default_backend_mgr();
+ return the_manager;
+ }
} // namespace
localization_backend_manager localization_backend_manager::global()
{
boost::unique_lock<boost::mutex> lock(localization_backend_manager_mutex());
- localization_backend_manager mgr = localization_backend_manager_global();
- return mgr;
+ return localization_backend_manager_global();
}
localization_backend_manager localization_backend_manager::global(const localization_backend_manager& in)
{
boost::unique_lock<boost::mutex> lock(localization_backend_manager_mutex());
- localization_backend_manager mgr = localization_backend_manager_global();
- localization_backend_manager_global() = in;
- return mgr;
+ return exchange(localization_backend_manager_global(), in);
}
}} // namespace boost::locale
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 424e77a197..75dd905b09 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/shared/message.cpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/shared/message.cpp
@@ -1,5 +1,6 @@
//
// Copyright (c) 2009-2015 Artyom Beilis (Tonkikh)
+// Copyright (c) 2021-2023 Alexander Grund
//
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
@@ -15,154 +16,188 @@
# endif
#endif
-#include <boost/locale/encoding.hpp>
#include <boost/locale/gnu_gettext.hpp>
-#include <boost/locale/hold_ptr.hpp>
+
+#include <boost/locale/encoding.hpp>
#include <boost/locale/message.hpp>
#include "boost/locale/shared/mo_hash.hpp"
#include "boost/locale/shared/mo_lambda.hpp"
#include "boost/locale/util/encoding.hpp"
-#include <boost/version.hpp>
-#include <algorithm>
+#include "boost/locale/util/foreach_char.hpp"
+#include <boost/assert.hpp>
+#include <boost/utility/string_view.hpp>
#include <cstdio>
-#include <cstring>
-#include <iostream>
#include <map>
#include <memory>
+#include <stdexcept>
#include <unordered_map>
#include <vector>
namespace boost { namespace locale { namespace gnu_gettext {
- class c_file {
- c_file(const c_file&);
- void operator=(const c_file&);
+ std::vector<std::string> messages_info::get_lang_folders() const
+ {
+ // List of fallbacks: en_US@euro, en@euro, en_US, en.
+ std::vector<std::string> result;
+ if(!language.empty()) {
+ if(!variant.empty() && !country.empty())
+ result.push_back(language + "_" + country + "@" + variant);
+
+ if(!variant.empty())
+ result.push_back(language + "@" + variant);
+ if(!country.empty())
+ result.push_back(language + "_" + country);
+
+ result.push_back(language);
+ }
+ return result;
+ }
+
+ std::vector<std::string> messages_info::get_catalog_paths() const
+ {
+ const auto lang_folders = get_lang_folders();
+ std::vector<std::string> result;
+ result.reserve(lang_folders.size() * paths.size());
+ for(const std::string& lang_folder : lang_folders) {
+ for(const std::string& search_path : paths)
+ result.push_back(search_path + "/" + lang_folder + "/" + locale_category);
+ }
+ return result;
+ }
+
+ class c_file {
public:
- FILE* file;
+ FILE* handle;
- c_file() : file(0) {}
- ~c_file() { close(); }
+ c_file(const c_file&) = delete;
+ void operator=(const c_file&) = delete;
- void close()
+ ~c_file()
{
- if(file) {
- fclose(file);
- file = 0;
- }
+ if(handle)
+ fclose(handle);
}
#if defined(BOOST_WINDOWS)
- bool open(const std::string& file_name, const std::string& encoding)
+ c_file(const std::string& file_name, const std::string& encoding)
{
- close();
-
- // Under windows we have to use "_wfopen" to get
- // access to path's with Unicode in them
+ // Under windows we have to use "_wfopen" to get access to path's with Unicode in them
//
// As not all standard C++ libraries support nonstandard std::istream::open(wchar_t const *)
// we would use old and good stdio and _wfopen CRTL functions
std::wstring wfile_name = conv::to_utf<wchar_t>(file_name, encoding);
- file = _wfopen(wfile_name.c_str(), L"rb");
-
- return file != 0;
+ handle = _wfopen(wfile_name.c_str(), L"rb");
}
#else // POSIX systems do not have all this Wide API crap, as native codepages are UTF-8
// We do not use encoding as we use native file name encoding
- bool open(const std::string& file_name, const std::string& /* encoding */)
- {
- close();
-
- file = fopen(file_name.c_str(), "rb");
-
- return file != 0;
- }
-
+ c_file(const std::string& file_name, const std::string& /* encoding */) : handle(fopen(file_name.c_str(), "rb"))
+ {}
#endif
};
+ std::vector<char> read_file(FILE* file)
+ {
+ fseek(file, 0, SEEK_END);
+ const auto len = ftell(file);
+ if(BOOST_UNLIKELY(len < 0))
+ throw std::runtime_error("Wrong file object"); // LCOV_EXCL_LINE
+ else {
+ fseek(file, 0, SEEK_SET);
+ std::vector<char> data(len);
+ if(BOOST_LIKELY(!data.empty()) && fread(data.data(), 1, data.size(), file) != data.size())
+ throw std::runtime_error("Failed to read file"); // LCOV_EXCL_LINE
+ return data;
+ }
+ }
+
class mo_file {
public:
- typedef std::pair<const char*, const char*> pair_type;
-
- mo_file(std::vector<char>& file) : native_byteorder_(true), size_(0)
+ mo_file(std::vector<char> data) : data_(std::move(data))
{
- load_file(file);
- init();
- }
+ if(data_.size() < 4)
+ throw std::runtime_error("invalid 'mo' file format - the file is too short");
+ uint32_t magic;
+ static_assert(sizeof(magic) == 4, "!");
+ memcpy(&magic, data_.data(), sizeof(magic));
+ if(magic == 0x950412de)
+ native_byteorder_ = true;
+ else if(magic == 0xde120495)
+ native_byteorder_ = false;
+ else
+ throw std::runtime_error("Invalid file format - invalid magic number");
- mo_file(FILE* file) : native_byteorder_(true), size_(0)
- {
- load_file(file);
- init();
+ // Read all format sizes
+ size_ = get(8);
+ keys_offset_ = get(12);
+ translations_offset_ = get(16);
+ hash_size_ = get(20);
+ hash_offset_ = get(24);
}
- pair_type find(const char* context_in, const char* key_in) const
+ string_view find(const char* context_in, const char* key_in) const
{
- pair_type null_pair((const char*)0, (const char*)0);
- if(hash_size_ == 0)
- return null_pair;
- uint32_t hkey = 0;
- if(context_in == 0)
- hkey = pj_winberger_hash_function(key_in);
- else {
- pj_winberger_hash::state_type st = pj_winberger_hash::initial_state;
+ if(!has_hash())
+ return {};
+
+ pj_winberger_hash::state_type st = pj_winberger_hash::initial_state;
+ if(context_in) {
st = pj_winberger_hash::update_state(st, context_in);
st = pj_winberger_hash::update_state(st, '\4'); // EOT
- st = pj_winberger_hash::update_state(st, key_in);
- hkey = st;
}
- uint32_t incr = 1 + hkey % (hash_size_ - 2);
+ st = pj_winberger_hash::update_state(st, key_in);
+ uint32_t hkey = st;
+ const uint32_t incr = 1 + hkey % (hash_size_ - 2);
hkey %= hash_size_;
- uint32_t orig = hkey;
+ const uint32_t orig_hkey = hkey;
do {
- uint32_t idx = get(hash_offset_ + 4 * hkey);
- /// Not found
+ const uint32_t idx = get(hash_offset_ + 4 * hkey);
+ // Not found
if(idx == 0)
- return null_pair;
- /// If equal values return translation
+ return {};
+ // If equal values return translation
if(key_equals(key(idx - 1), context_in, key_in))
return value(idx - 1);
- /// Rehash
+ // Rehash
hkey = (hkey + incr) % hash_size_;
- } while(hkey != orig);
- return null_pair;
+ } while(hkey != orig_hkey);
+ return {};
}
static bool key_equals(const char* real_key, const char* cntx, const char* key)
{
- if(cntx == 0)
+ if(!cntx)
return strcmp(real_key, key) == 0;
else {
- size_t real_len = strlen(real_key);
- size_t cntx_len = strlen(cntx);
- size_t key_len = strlen(key);
- if(cntx_len + 1 + key_len != real_len)
+ const size_t real_key_len = strlen(real_key);
+ const size_t cntx_len = strlen(cntx);
+ const size_t key_len = strlen(key);
+ if(cntx_len + 1 + key_len != real_key_len)
return false;
return memcmp(real_key, cntx, cntx_len) == 0 && real_key[cntx_len] == '\4'
&& memcmp(real_key + cntx_len + 1, key, key_len) == 0;
}
}
- const char* key(int id) const
+ const char* key(unsigned id) const
{
- uint32_t off = get(keys_offset_ + id * 8 + 4);
- return data_ + off;
+ const uint32_t off = get(keys_offset_ + id * 8 + 4);
+ return data_.data() + off;
}
- pair_type value(int id) const
+ string_view value(unsigned id) const
{
- uint32_t len = get(translations_offset_ + id * 8);
- uint32_t off = get(translations_offset_ + id * 8 + 4);
- if(off >= file_size_ || off + len >= file_size_)
+ const uint32_t len = get(translations_offset_ + id * 8);
+ const uint32_t off = get(translations_offset_ + id * 8 + 4);
+ if(len > data_.size() || off > data_.size() - len)
throw std::runtime_error("Bad mo-file format");
- return pair_type(&data_[off], &data_[off] + len);
+ return string_view(&data_[off], len);
}
bool has_hash() const { return hash_size_ != 0; }
@@ -172,77 +207,16 @@ namespace boost { namespace locale { namespace gnu_gettext {
bool empty() { return size_ == 0; }
private:
- void init()
- {
- // Read all format sizes
- size_ = get(8);
- keys_offset_ = get(12);
- translations_offset_ = get(16);
- hash_size_ = get(20);
- hash_offset_ = get(24);
- }
-
- void load_file(std::vector<char>& data)
- {
- vdata_.swap(data);
- file_size_ = vdata_.size();
- data_ = &vdata_[0];
- if(file_size_ < 4)
- throw std::runtime_error("invalid 'mo' file format - the file is too short");
- uint32_t magic = 0;
- memcpy(&magic, data_, 4);
- if(magic == 0x950412de)
- native_byteorder_ = true;
- else if(magic == 0xde120495)
- native_byteorder_ = false;
- else
- throw std::runtime_error("Invalid file format - invalid magic number");
- }
-
- void load_file(FILE* file)
- {
- uint32_t magic = 0;
- // if the size is wrong magic would be wrong
- // ok to ignore fread result
- size_t four_bytes = fread(&magic, 4, 1, file);
- (void)four_bytes; // shut GCC
-
- if(magic == 0x950412de)
- native_byteorder_ = true;
- else if(magic == 0xde120495)
- native_byteorder_ = false;
- else
- throw std::runtime_error("Invalid file format");
-
- fseek(file, 0, SEEK_END);
- long len = ftell(file);
- if(len < 0) {
- throw std::runtime_error("Wrong file object");
- }
- fseek(file, 0, SEEK_SET);
- vdata_.resize(len + 1, 0); // +1 to make sure the vector is not empty
- if(fread(&vdata_.front(), 1, len, file) != unsigned(len))
- throw std::runtime_error("Failed to read file");
- data_ = &vdata_[0];
- file_size_ = len;
- }
-
uint32_t get(unsigned offset) const
{
- uint32_t tmp;
- if(offset > file_size_ - 4) {
+ if(offset > data_.size() - 4)
throw std::runtime_error("Bad mo-file format");
- }
- memcpy(&tmp, data_ + offset, 4);
- convert(tmp);
- return tmp;
- }
+ uint32_t v;
+ memcpy(&v, &data_[offset], 4);
+ if(!native_byteorder_)
+ v = ((v & 0xFF) << 24) | ((v & 0xFF00) << 8) | ((v & 0xFF0000) >> 8) | ((v & 0xFF000000) >> 24);
- void convert(uint32_t& v) const
- {
- if(native_byteorder_)
- return;
- v = ((v & 0xFF) << 24) | ((v & 0xFF00) << 8) | ((v & 0xFF0000) >> 8) | ((v & 0xFF000000) >> 24);
+ return v;
}
uint32_t keys_offset_;
@@ -250,9 +224,7 @@ namespace boost { namespace locale { namespace gnu_gettext {
uint32_t hash_size_;
uint32_t hash_offset_;
- const char* data_;
- size_t file_size_;
- std::vector<char> vdata_;
+ const std::vector<char> data_;
bool native_byteorder_;
size_t size_;
};
@@ -260,76 +232,67 @@ namespace boost { namespace locale { namespace gnu_gettext {
template<typename CharType>
struct mo_file_use_traits {
static constexpr bool in_use = false;
- typedef CharType char_type;
- typedef std::pair<const char_type*, const char_type*> pair_type;
- static pair_type use(const mo_file& /*mo*/, const char_type* /*context*/, const char_type* /*key*/)
+ using string_view_type = basic_string_view<CharType>;
+ static string_view_type use(const mo_file&, const CharType*, const CharType*)
{
- return pair_type((const char_type*)(0), (const char_type*)(0));
+ throw std::logic_error("Unexpected call"); // LCOV_EXCL_LINE
}
};
template<>
struct mo_file_use_traits<char> {
static constexpr bool in_use = true;
- typedef char char_type;
- typedef std::pair<const char_type*, const char_type*> pair_type;
- static pair_type use(const mo_file& mo, const char* context, const char* key) { return mo.find(context, key); }
+ typedef char CharType;
+ using string_view_type = basic_string_view<CharType>;
+ static string_view_type use(const mo_file& mo, const char* context, const char* key)
+ {
+ return mo.find(context, key);
+ }
};
template<typename CharType>
- class converter {
- public:
- converter(std::string /*out_enc*/, std::string in_enc) : in_(in_enc) {}
+ class converter : conv::utf_encoder<CharType> {
+ using encoder = conv::utf_encoder<CharType>;
- std::basic_string<CharType> operator()(const char* begin, const char* end)
- {
- return conv::to_utf<CharType>(begin, end, in_, conv::stop);
- }
+ public:
+ converter(std::string /*out_enc*/, std::string in_enc) : encoder(in_enc, conv::stop) {}
- private:
- std::string in_;
+ using encoder::operator();
};
template<>
- class converter<char> {
+ class converter<char> : conv::narrow_converter {
public:
- converter(std::string out_enc, std::string in_enc) : out_(out_enc), in_(in_enc) {}
-
- std::string operator()(const char* begin, const char* end)
- {
- return conv::between(begin, end, out_, in_, conv::stop);
- }
+ converter(const std::string& out_enc, const std::string& in_enc) : narrow_converter(in_enc, out_enc) {}
- private:
- std::string out_, in_;
+ using narrow_converter::operator();
};
template<typename CharType>
struct message_key {
- typedef CharType char_type;
- typedef std::basic_string<char_type> string_type;
+ typedef std::basic_string<CharType> string_type;
- message_key(const string_type& c = string_type()) : c_context_(0), c_key_(0)
+ message_key(const string_type& c = string_type()) : c_context_(nullptr), c_key_(nullptr)
{
- size_t pos = c.find(char_type(4));
- if(pos == string_type::npos) {
+ const size_t pos = c.find(CharType(4));
+ if(pos == string_type::npos)
key_ = c;
- } else {
+ else {
context_ = c.substr(0, pos);
key_ = c.substr(pos + 1);
}
}
- message_key(const char_type* c, const char_type* k) : c_key_(k)
+ message_key(const CharType* c, const CharType* k) : c_key_(k)
{
- static const char_type empty = 0;
- if(c != 0)
+ static const CharType empty = 0;
+ if(c != nullptr)
c_context_ = c;
else
c_context_ = &empty;
}
bool operator<(const message_key& other) const
{
- int cc = compare(context(), other.context());
+ const int cc = compare(context(), other.context());
if(cc != 0)
return cc < 0;
return compare(key(), other.key()) < 0;
@@ -339,13 +302,13 @@ namespace boost { namespace locale { namespace gnu_gettext {
return compare(context(), other.context()) == 0 && compare(key(), other.key()) == 0;
}
bool operator!=(const message_key& other) const { return !(*this == other); }
- const char_type* context() const
+ const CharType* context() const
{
if(c_context_)
return c_context_;
return context_.c_str();
}
- const char_type* key() const
+ const CharType* key() const
{
if(c_key_)
return c_key_;
@@ -353,12 +316,12 @@ namespace boost { namespace locale { namespace gnu_gettext {
}
private:
- static int compare(const char_type* l, const char_type* r)
+ static int compare(const CharType* l, const CharType* r)
{
- typedef std::char_traits<char_type> traits_type;
+ typedef std::char_traits<CharType> traits_type;
for(;;) {
- char_type cl = *l++;
- char_type cr = *r++;
+ const CharType cl = *l++;
+ const CharType cr = *r++;
if(cl == 0 && cr == 0)
return 0;
if(traits_type::lt(cl, cr))
@@ -369,8 +332,8 @@ namespace boost { namespace locale { namespace gnu_gettext {
}
string_type context_;
string_type key_;
- const char_type* c_context_;
- const char_type* c_key_;
+ const CharType* c_context_;
+ const CharType* c_key_;
};
template<typename CharType>
@@ -418,54 +381,57 @@ namespace boost { namespace locale { namespace gnu_gettext {
return msg;
if(detail::is_us_ascii_string(msg))
return msg;
- std::string tmp = conv::between(msg, locale_encoding, key_encoding, conv::skip);
- buffer.swap(tmp);
+ buffer = conv::between(msg, locale_encoding, key_encoding, conv::skip);
return buffer.c_str();
}
template<typename CharType>
class mo_message : public message_format<CharType> {
- typedef CharType char_type;
typedef std::basic_string<CharType> string_type;
typedef message_key<CharType> key_type;
typedef std::unordered_map<key_type, string_type, hash_function<CharType>> catalog_type;
- typedef std::vector<catalog_type> catalogs_set_type;
- typedef std::map<std::string, int> domains_map_type;
+ struct domain_data_type {
+ std::unique_ptr<mo_file> mo_catalog; /// Message catalog (.mo file) if it can be directly used
+ catalog_type catalog; /// Converted message catalog when .mo file cannot be directly used
+ lambda::plural_expr plural_form; /// Expression to determine the plural form index
+ };
public:
- typedef std::pair<const CharType*, const CharType*> pair_type;
+ using string_view_type = typename mo_file_use_traits<CharType>::string_view_type;
- const char_type* get(int domain_id, const char_type* context, const char_type* in_id) const override
+ const CharType* get(int domain_id, const CharType* context, const CharType* in_id) const override
{
- return get_string(domain_id, context, in_id).first;
+ const auto result = get_string(domain_id, context, in_id);
+ return result.empty() ? nullptr : result.data();
}
- const char_type* get(int domain_id, const char_type* context, const char_type* single_id, int n) const override
+ const CharType*
+ get(int domain_id, const CharType* context, const CharType* single_id, count_type n) const override
{
- pair_type ptr = get_string(domain_id, context, single_id);
- if(!ptr.first)
+ auto result = get_string(domain_id, context, single_id);
+ if(result.empty())
return nullptr;
- int form = 0;
- if(plural_forms_.at(domain_id))
- form = (*plural_forms_[domain_id])(n);
+
+ // domain_id is already checked by get_string -> Would return a null-pair
+ BOOST_ASSERT(domain_id >= 0 && static_cast<size_t>(domain_id) < domain_data_.size());
+ lambda::expr::value_type plural_idx;
+ if(domain_data_[domain_id].plural_form)
+ plural_idx = domain_data_[domain_id].plural_form(n);
else
- form = n == 1 ? 0 : 1; // Fallback to English plural form
+ plural_idx = n == 1 ? 0 : 1; // Fallback to English plural form
- const CharType* p = ptr.first;
- for(int i = 0; p < ptr.second && i < form; i++) {
- p = std::find(p, ptr.second, CharType(0));
- if(p == ptr.second)
+ for(decltype(plural_idx) i = 0; i < plural_idx; ++i) {
+ const auto pos = result.find(CharType(0));
+ if(BOOST_UNLIKELY(pos == string_view_type::npos))
return nullptr;
- ++p;
+ result.remove_prefix(pos + 1);
}
- if(p >= ptr.second)
- return nullptr;
- return p;
+ return result.empty() ? nullptr : result.data();
}
int domain(const std::string& domain) const override
{
- domains_map_type::const_iterator p = domains_.find(domain);
+ const auto p = domains_.find(domain);
if(p == domains_.end())
return -1;
return p->second;
@@ -473,61 +439,32 @@ namespace boost { namespace locale { namespace gnu_gettext {
mo_message(const messages_info& inf) : key_conversion_required_(false)
{
- std::string language = inf.language;
- std::string variant = inf.variant;
- std::string country = inf.country;
- std::string encoding = inf.encoding;
- std::string lc_cat = inf.locale_category;
const std::vector<messages_info::domain>& domains = inf.domains;
- const std::vector<std::string>& search_paths = inf.paths;
-
- // List of fallbacks: en_US@euro, en@euro, en_US, en.
- std::vector<std::string> paths;
-
- if(!variant.empty() && !country.empty())
- paths.push_back(language + "_" + country + "@" + variant);
-
- if(!variant.empty())
- paths.push_back(language + "@" + variant);
-
- if(!country.empty())
- paths.push_back(language + "_" + country);
-
- paths.push_back(language);
-
- catalogs_.resize(domains.size());
- mo_catalogs_.resize(domains.size());
- plural_forms_.resize(domains.size());
+ domain_data_.resize(domains.size());
+ const auto catalog_paths = inf.get_catalog_paths();
for(unsigned i = 0; i < domains.size(); i++) {
- std::string domain = domains[i].name;
- std::string key_encoding = domains[i].encoding;
- domains_[domain] = i;
-
- bool found = false;
- for(unsigned j = 0; !found && j < paths.size(); j++) {
- for(unsigned k = 0; !found && k < search_paths.size(); k++) {
- std::string full_path = search_paths[k] + "/" + paths[j] + "/" + lc_cat + "/" + domain + ".mo";
- found = load_file(full_path, encoding, key_encoding, i, inf.callback);
- }
+ const auto& domain = domains[i];
+ domains_[domain.name] = i;
+ const std::string filename = domain.name + ".mo";
+ for(std::string path : catalog_paths) {
+ path += "/" + filename;
+ if(load_file(path, inf.encoding, domain.encoding, domain_data_[i], inf.callback))
+ break;
}
}
}
- const char_type* convert(const char_type* msg, string_type& buffer) const override
+ const CharType* convert(const CharType* msg, string_type& buffer) const override
{
- return runtime_conversion<char_type>(msg,
- buffer,
- key_conversion_required_,
- locale_encoding_,
- key_encoding_);
+ return runtime_conversion<CharType>(msg, buffer, key_conversion_required_, locale_encoding_, key_encoding_);
}
private:
bool load_file(const std::string& file_name,
const std::string& locale_encoding,
const std::string& key_encoding,
- int idx,
+ domain_data_type& data,
const messages_info::callback_type& callback)
{
locale_encoding_ = locale_encoding;
@@ -536,44 +473,42 @@ namespace boost { namespace locale { namespace gnu_gettext {
key_conversion_required_ =
sizeof(CharType) == 1 && !util::are_encodings_equal(locale_encoding, key_encoding);
- std::shared_ptr<mo_file> mo;
-
- if(callback) {
- std::vector<char> vfile = callback(file_name, locale_encoding);
- if(vfile.empty())
- return false;
- mo.reset(new mo_file(vfile));
- } else {
- c_file the_file;
- the_file.open(file_name, locale_encoding);
- if(!the_file.file)
+ std::unique_ptr<mo_file> mo;
+
+ {
+ std::vector<char> file_data;
+ if(callback)
+ file_data = callback(file_name, locale_encoding);
+ else {
+ c_file the_file(file_name, locale_encoding);
+ if(!the_file.handle)
+ return false;
+ file_data = read_file(the_file.handle);
+ }
+ if(file_data.empty())
return false;
- mo.reset(new mo_file(the_file.file));
+ mo.reset(new mo_file(std::move(file_data)));
}
- std::string plural = extract(mo->value(0).first, "plural=", "\r\n;");
-
- std::string mo_encoding = extract(mo->value(0).first, "charset=", " \r\n;");
+ const std::string plural = extract(mo->value(0), "plural=", "\r\n;");
+ const std::string mo_encoding = extract(mo->value(0), "charset=", " \r\n;");
if(mo_encoding.empty())
throw std::runtime_error("Invalid mo-format, encoding is not specified");
if(!plural.empty())
- plural_forms_[idx] = lambda::compile(plural.c_str());
+ data.plural_form = lambda::compile(plural.c_str());
if(mo_useable_directly(mo_encoding, *mo))
- mo_catalogs_[idx] = mo;
+ data.mo_catalog = std::move(mo);
else {
converter<CharType> cvt_value(locale_encoding, mo_encoding);
converter<CharType> cvt_key(key_encoding, mo_encoding);
for(unsigned i = 0; i < mo->size(); i++) {
const char* ckey = mo->key(i);
- string_type skey = cvt_key(ckey, ckey + strlen(ckey));
- key_type key(skey);
+ const key_type key(cvt_key(ckey));
- mo_file::pair_type tmp = mo->value(i);
- string_type value = cvt_value(tmp.first, tmp.second);
- catalogs_[idx][key].swap(value);
+ data.catalog[key] = cvt_value(mo->value(i));
}
}
return true;
@@ -594,85 +529,62 @@ namespace boost { namespace locale { namespace gnu_gettext {
return false;
if(!util::are_encodings_equal(mo_encoding, locale_encoding_))
return false;
- if(util::are_encodings_equal(mo_encoding, key_encoding_)) {
+ if(util::are_encodings_equal(mo_encoding, key_encoding_))
return true;
- }
for(unsigned i = 0; i < mo.size(); i++) {
- if(!detail::is_us_ascii_string(mo.key(i))) {
+ if(!detail::is_us_ascii_string(mo.key(i)))
return false;
- }
}
return true;
}
- static std::string extract(const std::string& meta, const std::string& key, const char* separator)
+ static std::string extract(boost::string_view meta, const std::string& key, const boost::string_view separators)
{
- size_t pos = meta.find(key);
- if(pos == std::string::npos)
+ const size_t pos = meta.find(key);
+ if(pos == boost::string_view::npos)
return "";
- pos += key.size(); /// size of charset=
- size_t end_pos = meta.find_first_of(separator, pos);
- return meta.substr(pos, end_pos - pos);
+ meta.remove_prefix(pos + key.size());
+ const size_t end_pos = meta.find_first_of(separators);
+ return std::string(meta.substr(0, end_pos));
}
- pair_type get_string(int domain_id, const char_type* context, const char_type* in_id) const
+ string_view_type get_string(int domain_id, const CharType* context, const CharType* in_id) const
{
- pair_type null_pair((const CharType*)0, (const CharType*)0);
- if(domain_id < 0 || size_t(domain_id) >= catalogs_.size())
- return null_pair;
+ if(domain_id < 0 || static_cast<size_t>(domain_id) >= domain_data_.size())
+ return {};
+ const auto& data = domain_data_[domain_id];
+
BOOST_LOCALE_START_CONST_CONDITION
- if(mo_file_use_traits<char_type>::in_use && mo_catalogs_[domain_id]) {
+ if(mo_file_use_traits<CharType>::in_use && data.mo_catalog) {
BOOST_LOCALE_END_CONST_CONDITION
- return mo_file_use_traits<char_type>::use(*mo_catalogs_[domain_id], context, in_id);
+ return mo_file_use_traits<CharType>::use(*data.mo_catalog, context, in_id);
} else {
- key_type key(context, in_id);
- const catalog_type& cat = catalogs_[domain_id];
- typename catalog_type::const_iterator p = cat.find(key);
- if(p == cat.end()) {
- return null_pair;
- }
- return pair_type(p->second.data(), p->second.data() + p->second.size());
+ const key_type key(context, in_id);
+ const catalog_type& cat = data.catalog;
+ const auto p = cat.find(key);
+ if(p == cat.end())
+ return {};
+ return p->second;
}
}
- catalogs_set_type catalogs_;
- std::vector<std::shared_ptr<mo_file>> mo_catalogs_;
- std::vector<std::shared_ptr<lambda::plural>> plural_forms_;
- domains_map_type domains_;
+ std::map<std::string, unsigned> domains_;
+ std::vector<domain_data_type> domain_data_;
std::string locale_encoding_;
std::string key_encoding_;
bool key_conversion_required_;
};
- template<>
- message_format<char>* create_messages_facet(const messages_info& info)
- {
- return new mo_message<char>(info);
- }
-
- template<>
- message_format<wchar_t>* create_messages_facet(const messages_info& info)
- {
- return new mo_message<wchar_t>(info);
- }
-
-#ifdef BOOST_LOCALE_ENABLE_CHAR16_T
-
- template<>
- message_format<char16_t>* create_messages_facet(const messages_info& info)
+ template<typename CharType, class /* enable_if */>
+ message_format<CharType>* create_messages_facet(const messages_info& info)
{
- return new mo_message<char16_t>(info);
+ return new mo_message<CharType>(info);
}
-#endif
-#ifdef BOOST_LOCALE_ENABLE_CHAR32_T
+#define BOOST_LOCALE_INSTANTIATE(CHARTYPE) \
+ template BOOST_LOCALE_DECL message_format<CHARTYPE>* create_messages_facet(const messages_info& info);
- template<>
- message_format<char32_t>* create_messages_facet(const messages_info& info)
- {
- return new mo_message<char32_t>(info);
- }
-#endif
+ BOOST_LOCALE_FOREACH_CHAR(BOOST_LOCALE_INSTANTIATE)
}}} // namespace boost::locale::gnu_gettext
diff --git a/contrib/restricted/boost/locale/src/boost/locale/shared/mo_hash.hpp b/contrib/restricted/boost/locale/src/boost/locale/shared/mo_hash.hpp
index ad417641f9..702ea7aece 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/shared/mo_hash.hpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/shared/mo_hash.hpp
@@ -4,7 +4,7 @@
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
-#include <boost/cstdint.hpp>
+#include <cstdint>
namespace boost { namespace locale { namespace gnu_gettext {
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 90d0c232cb..a6d2eb6a44 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
@@ -1,12 +1,18 @@
//
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+// Copyright (c) 2021-2023 Alexander Grund
//
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include "boost/locale/shared/mo_lambda.hpp"
+#include <boost/assert.hpp>
+#include <algorithm>
#include <cstdlib>
#include <cstring>
+#include <functional>
+#include <limits>
+#include <stdexcept>
#ifdef BOOST_MSVC
# pragma warning(disable : 4512) // assignment operator could not be generated
@@ -15,359 +21,283 @@
namespace boost { namespace locale { namespace gnu_gettext { namespace lambda {
namespace { // anon
- struct identity : public plural {
- int operator()(int n) const override { return n; };
- identity* clone() const override { return new identity(); }
+ template<class TExp, typename... Ts>
+ expr_ptr make_expr(Ts... ts)
+ {
+ return expr_ptr(new TExp(std::forward<Ts>(ts)...));
+ }
+
+ struct identity final : expr {
+ value_type operator()(value_type n) const override { return n; }
};
- struct unary : public plural {
- unary(plural_ptr ptr) : op1(ptr) {}
+ using sub_expr_type = plural_expr;
+
+ template<class Functor>
+ struct unary final : expr, Functor {
+ unary(expr_ptr p) : op1(std::move(p)) {}
+ value_type operator()(value_type n) const override { return Functor::operator()(op1(n)); }
protected:
- plural_ptr op1;
+ sub_expr_type op1;
};
- struct binary : public plural {
- binary(plural_ptr p1, plural_ptr p2) : op1(p1), op2(p2) {}
+ template<class Functor, bool returnZeroOnZero2ndArg = false>
+ struct binary final : expr, Functor {
+ binary(expr_ptr p1, expr_ptr p2) : op1(std::move(p1)), op2(std::move(p2)) {}
+ value_type operator()(value_type n) const override
+ {
+ const auto v1 = op1(n);
+ const auto v2 = op2(n);
+ BOOST_LOCALE_START_CONST_CONDITION
+ if(returnZeroOnZero2ndArg && v2 == 0)
+ return 0;
+ BOOST_LOCALE_END_CONST_CONDITION
+ return Functor::operator()(v1, v2);
+ }
protected:
- plural_ptr op1, op2;
+ sub_expr_type op1, op2;
};
- struct number : public plural {
- number(int v) : val(v) {}
- int operator()(int /*n*/) const override { return val; }
- number* clone() const override { return new number(val); }
+ struct number final : expr {
+ number(value_type v) : val(v) {}
+ value_type operator()(value_type /*n*/) const override { return val; }
private:
- int val;
+ value_type val;
};
-#define UNOP(name, oper) \
- struct name : public unary { \
- name(plural_ptr op) : unary(op) {} \
- int operator()(int n) const override { return oper(*op1)(n); } \
- name* clone() const override \
- { \
- plural_ptr op1_copy(op1->clone()); \
- return new name(op1_copy); \
- } \
- };
-
-#define BINOP(name, oper) \
- struct name : public binary { \
- name(plural_ptr p1, plural_ptr p2) : binary(p1, p2) {} \
- \
- int operator()(int n) const override { return (*op1)(n)oper(*op2)(n); } \
- name* clone() const override \
- { \
- plural_ptr op1_copy(op1->clone()); \
- plural_ptr op2_copy(op2->clone()); \
- return new name(op1_copy, op2_copy); \
- } \
- };
-
-#define BINOPD(name, oper) \
- struct name : public binary { \
- name(plural_ptr p1, plural_ptr p2) : binary(p1, p2) {} \
- int operator()(int n) const override \
- { \
- int v1 = (*op1)(n); \
- int v2 = (*op2)(n); \
- return v2 == 0 ? 0 : v1 oper v2; \
- } \
- name* clone() const override \
- { \
- plural_ptr op1_copy(op1->clone()); \
- plural_ptr op2_copy(op2->clone()); \
- return new name(op1_copy, op2_copy); \
- } \
- };
-
- enum { END = 0, SHL = 256, SHR, GTE, LTE, EQ, NEQ, AND, OR, NUM, VARIABLE };
-
- UNOP(l_not, !)
- UNOP(minus, -)
- UNOP(bin_not, ~)
-
- BINOP(mul, *)
- BINOPD(div, /)
- BINOPD(mod, %)
- static int level10[] = {3, '*', '/', '%'};
-
- BINOP(add, +)
- BINOP(sub, -)
- static int level9[] = {2, '+', '-'};
-
- BINOP(shl, <<)
- BINOP(shr, >>)
- static int level8[] = {2, SHL, SHR};
-
- BINOP(gt, >)
- BINOP(lt, <)
- BINOP(gte, >=)
- BINOP(lte, <=)
- static int level7[] = {4, '<', '>', GTE, LTE};
-
- BINOP(eq, ==)
- BINOP(neq, !=)
- static int level6[] = {2, EQ, NEQ};
-
- BINOP(bin_and, &)
- static int level5[] = {1, '&'};
-
- BINOP(bin_xor, ^)
- static int level4[] = {1, '^'};
-
- BINOP(bin_or, |)
- static int level3[] = {1, '|'};
-
- BINOP(l_and, &&)
- static int level2[] = {1, AND};
-
- BINOP(l_or, ||)
- static int level1[] = {1, OR};
-
- struct conditional : public plural {
- conditional(plural_ptr p1, plural_ptr p2, plural_ptr p3) : op1(p1), op2(p2), op3(p3) {}
- int operator()(int n) const override { return (*op1)(n) ? (*op2)(n) : (*op3)(n); }
- conditional* clone() const override
- {
- plural_ptr op1_copy(op1->clone());
- plural_ptr op2_copy(op2->clone());
- plural_ptr op3_copy(op3->clone());
- return new conditional(op1_copy, op2_copy, op3_copy);
- }
+ struct conditional final : public expr {
+ conditional(expr_ptr p1, expr_ptr p2, expr_ptr p3) :
+ op1(std::move(p1)), op2(std::move(p2)), op3(std::move(p3))
+ {}
+ value_type operator()(value_type n) const override { return op1(n) ? op2(n) : op3(n); }
private:
- plural_ptr op1, op2, op3;
+ sub_expr_type op1, op2, op3;
};
- plural_ptr bin_factory(int value, plural_ptr left, plural_ptr right)
+ using token_t = int;
+ enum : token_t { END = 0, GTE = 256, LTE, EQ, NEQ, AND, OR, NUM, VARIABLE };
+
+ expr_ptr bin_factory(const token_t value, expr_ptr left, expr_ptr right)
{
+#define BINOP_CASE(match, cls) \
+ case match: return make_expr<cls>(std::move(left), std::move(right))
+ // Special cases: Avoid division by zero
+ using divides = binary<std::divides<expr::value_type>, true>;
+ using modulus = binary<std::modulus<expr::value_type>, true>;
switch(value) {
- case '/': return plural_ptr(new div(left, right));
- case '*': return plural_ptr(new mul(left, right));
- case '%': return plural_ptr(new mod(left, right));
- case '+': return plural_ptr(new add(left, right));
- case '-': return plural_ptr(new sub(left, right));
- case SHL: return plural_ptr(new shl(left, right));
- case SHR: return plural_ptr(new shr(left, right));
- case '>': return plural_ptr(new gt(left, right));
- case '<': return plural_ptr(new lt(left, right));
- case GTE: return plural_ptr(new gte(left, right));
- case LTE: return plural_ptr(new lte(left, right));
- case EQ: return plural_ptr(new eq(left, right));
- case NEQ: return plural_ptr(new neq(left, right));
- case '&': return plural_ptr(new bin_and(left, right));
- case '^': return plural_ptr(new bin_xor(left, right));
- case '|': return plural_ptr(new bin_or(left, right));
- case AND: return plural_ptr(new l_and(left, right));
- case OR: return plural_ptr(new l_or(left, right));
- default: return plural_ptr();
+ BINOP_CASE('/', divides);
+ BINOP_CASE('*', binary<std::multiplies<expr::value_type>>);
+ BINOP_CASE('%', modulus);
+ BINOP_CASE('+', binary<std::plus<expr::value_type>>);
+ BINOP_CASE('-', binary<std::minus<expr::value_type>>);
+ BINOP_CASE('>', binary<std::greater<expr::value_type>>);
+ BINOP_CASE('<', binary<std::less<expr::value_type>>);
+ BINOP_CASE(GTE, binary<std::greater_equal<expr::value_type>>);
+ BINOP_CASE(LTE, binary<std::less_equal<expr::value_type>>);
+ BINOP_CASE(EQ, binary<std::equal_to<expr::value_type>>);
+ BINOP_CASE(NEQ, binary<std::not_equal_to<expr::value_type>>);
+ BINOP_CASE(AND, binary<std::logical_and<expr::value_type>>);
+ BINOP_CASE(OR, binary<std::logical_or<expr::value_type>>);
+ default: throw std::logic_error("Unexpected binary operator"); // LCOV_EXCL_LINE
}
+#undef BINOP_CASE
}
- static inline bool is_in(int v, int* p)
+ template<size_t size>
+ bool is_in(const token_t token, const token_t (&tokens)[size])
{
- int len = *p;
- p++;
- while(len && *p != v) {
- p++;
- len--;
+ for(const auto el : tokens) {
+ if(token == el)
+ return true;
}
- return len != 0;
+ return false;
}
class tokenizer {
public:
- tokenizer(const char* s)
+ tokenizer(const char* s) : text_(s), next_tocken_(0), numeric_value_(0) { step(); }
+ token_t get(long long* val = nullptr)
{
- text = s;
- pos = 0;
+ const token_t res = next(val);
step();
- };
- int get(int* val = NULL)
- {
- int iv = int_value;
- int res = next_tocken;
- step();
- if(val && res == NUM) {
- *val = iv;
- }
return res;
- };
- int next(int* val = NULL)
+ }
+ token_t next(long long* val = nullptr) const
{
- if(val && next_tocken == NUM) {
- *val = int_value;
- return NUM;
- }
- return next_tocken;
+ if(val && next_tocken_ == NUM)
+ *val = numeric_value_;
+ return next_tocken_;
}
private:
- const char* text;
- size_t pos;
- int next_tocken;
- int int_value;
- bool is_blank(char c) { return c == ' ' || c == '\r' || c == '\n' || c == '\t'; }
- bool isdigit(char c) { return '0' <= c && c <= '9'; }
+ const char* text_;
+ token_t next_tocken_;
+ long long numeric_value_;
+
+ static constexpr bool is_blank(char c) { return c == ' ' || c == '\r' || c == '\n' || c == '\t'; }
+ static constexpr bool is_digit(char c) { return '0' <= c && c <= '9'; }
+ template<size_t size>
+ static bool is(const char* s, const char (&search)[size])
+ {
+ return strncmp(s, search, size - 1) == 0;
+ }
void step()
{
- while(text[pos] && is_blank(text[pos]))
- pos++;
- const char* ptr = text + pos;
- char* tmp_ptr;
- if(strncmp(ptr, "<<", 2) == 0) {
- pos += 2;
- next_tocken = SHL;
- } else if(strncmp(ptr, ">>", 2) == 0) {
- pos += 2;
- next_tocken = SHR;
- } else if(strncmp(ptr, "&&", 2) == 0) {
- pos += 2;
- next_tocken = AND;
- } else if(strncmp(ptr, "||", 2) == 0) {
- pos += 2;
- next_tocken = OR;
- } else if(strncmp(ptr, "<=", 2) == 0) {
- pos += 2;
- next_tocken = LTE;
- } else if(strncmp(ptr, ">=", 2) == 0) {
- pos += 2;
- next_tocken = GTE;
- } else if(strncmp(ptr, "==", 2) == 0) {
- pos += 2;
- next_tocken = EQ;
- } else if(strncmp(ptr, "!=", 2) == 0) {
- pos += 2;
- next_tocken = NEQ;
- } else if(*ptr == 'n') {
- pos++;
- next_tocken = VARIABLE;
- } else if(isdigit(*ptr)) {
- int_value = strtol(text + pos, &tmp_ptr, 0);
- pos = tmp_ptr - text;
- next_tocken = NUM;
- } else if(*ptr == '\0') {
- next_tocken = 0;
- } else {
- next_tocken = *ptr;
- pos++;
+ while(is_blank(*text_))
+ text_++;
+ const char* text = text_;
+ if(is(text, "&&")) {
+ text_ += 2;
+ next_tocken_ = AND;
+ } else if(is(text, "||")) {
+ text_ += 2;
+ next_tocken_ = OR;
+ } else if(is(text, "<=")) {
+ text_ += 2;
+ next_tocken_ = LTE;
+ } else if(is(text, ">=")) {
+ text_ += 2;
+ next_tocken_ = GTE;
+ } else if(is(text, "==")) {
+ text_ += 2;
+ next_tocken_ = EQ;
+ } else if(is(text, "!=")) {
+ text_ += 2;
+ next_tocken_ = NEQ;
+ } else if(*text == 'n') {
+ text_++;
+ next_tocken_ = VARIABLE;
+ } else if(is_digit(*text)) {
+ char* tmp_ptr;
+ // strtoll not always available -> parse as unsigned long
+ const auto value = std::strtoul(text, &tmp_ptr, 10);
+ // Saturate in case long=long long
+ numeric_value_ = std::min<unsigned long long>(std::numeric_limits<long long>::max(), value);
+ text_ = tmp_ptr;
+ next_tocken_ = NUM;
+ } else if(*text == '\0')
+ next_tocken_ = END;
+ else {
+ next_tocken_ = *text;
+ text_++;
}
}
};
-#define BINARY_EXPR(expr, hexpr, list) \
- plural_ptr expr() \
- { \
- plural_ptr op1, op2; \
- if((op1 = hexpr()).get() == 0) \
- return plural_ptr(); \
- while(is_in(t.next(), list)) { \
- int o = t.get(); \
- if((op2 = hexpr()).get() == 0) \
- return plural_ptr(); \
- op1 = bin_factory(o, op1, op2); \
- } \
- return op1; \
- }
+ constexpr token_t level6[] = {'*', '/', '%'};
+ constexpr token_t level5[] = {'+', '-'};
+ constexpr token_t level4[] = {'<', '>', GTE, LTE};
+ constexpr token_t level3[] = {EQ, NEQ};
+ constexpr token_t level2[] = {AND};
+ constexpr token_t level1[] = {OR};
class parser {
public:
- parser(tokenizer& tin) : t(tin){};
+ parser(const char* str) : t(str) {}
- plural_ptr compile()
+ expr_ptr compile()
{
- plural_ptr res = cond_expr();
- if(res.get() && t.next() != END) {
- return plural_ptr();
- };
+ expr_ptr res = cond_expr();
+ if(res && t.next() != END)
+ return expr_ptr();
return res;
}
private:
- plural_ptr value_expr()
+ expr_ptr value_expr()
{
- plural_ptr op;
+ expr_ptr op;
if(t.next() == '(') {
t.get();
- if((op = cond_expr()).get() == 0)
- return plural_ptr();
+ if(!(op = cond_expr()))
+ return expr_ptr();
if(t.get() != ')')
- return plural_ptr();
+ return expr_ptr();
return op;
} else if(t.next() == NUM) {
- int value;
+ expr::value_type value;
t.get(&value);
- return plural_ptr(new number(value));
+ return make_expr<number>(value);
} else if(t.next() == VARIABLE) {
t.get();
- return plural_ptr(new identity());
+ return make_expr<identity>();
}
- return plural_ptr();
- };
+ return expr_ptr();
+ }
- plural_ptr un_expr()
+ expr_ptr unary_expr()
{
- plural_ptr op1;
- static int level_unary[] = {3, '-', '!', '~'};
+ constexpr token_t level_unary[] = {'!', '-'};
if(is_in(t.next(), level_unary)) {
- int op = t.get();
- if((op1 = un_expr()).get() == 0)
- return plural_ptr();
- switch(op) {
- case '-': return plural_ptr(new minus(op1));
- case '!': return plural_ptr(new l_not(op1));
- case '~': return plural_ptr(new bin_not(op1));
- default: return plural_ptr();
+ const token_t op = t.get();
+ expr_ptr op1 = unary_expr();
+ if(!op1)
+ return expr_ptr();
+ if(BOOST_LIKELY(op == '!'))
+ return make_expr<unary<std::logical_not<expr::value_type>>>(std::move(op1));
+ else {
+ BOOST_ASSERT(op == '-');
+ return make_expr<unary<std::negate<expr::value_type>>>(std::move(op1));
}
- } else {
+ } else
return value_expr();
- }
- };
+ }
+
+#define BINARY_EXPR(lvl, nextLvl, list) \
+ expr_ptr lvl() \
+ { \
+ expr_ptr op1 = nextLvl(); \
+ if(!op1) \
+ return expr_ptr(); \
+ while(is_in(t.next(), list)) { \
+ const token_t o = t.get(); \
+ expr_ptr op2 = nextLvl(); \
+ if(!op2) \
+ return expr_ptr(); \
+ op1 = bin_factory(o, std::move(op1), std::move(op2)); \
+ } \
+ return op1; \
+ }
- BINARY_EXPR(l10, un_expr, level10);
- BINARY_EXPR(l9, l10, level9);
- BINARY_EXPR(l8, l9, level8);
- BINARY_EXPR(l7, l8, level7);
- BINARY_EXPR(l6, l7, level6);
+ BINARY_EXPR(l6, unary_expr, level6);
BINARY_EXPR(l5, l6, level5);
BINARY_EXPR(l4, l5, level4);
BINARY_EXPR(l3, l4, level3);
BINARY_EXPR(l2, l3, level2);
BINARY_EXPR(l1, l2, level1);
+#undef BINARY_EXPR
- plural_ptr cond_expr()
+ expr_ptr cond_expr()
{
- plural_ptr cond, case1, case2;
- if((cond = l1()).get() == 0)
- return plural_ptr();
- if(t.next() == '?') {
- t.get();
- if((case1 = cond_expr()).get() == 0)
- return plural_ptr();
- if(t.get() != ':')
- return plural_ptr();
- if((case2 = cond_expr()).get() == 0)
- return plural_ptr();
- } else {
+ expr_ptr cond;
+ if(!(cond = l1()))
+ return expr_ptr();
+ if(t.next() != '?')
return cond;
- }
- return plural_ptr(new conditional(cond, case1, case2));
+ t.get();
+ expr_ptr case1, case2;
+ if(!(case1 = cond_expr()))
+ return expr_ptr();
+ if(t.get() != ':')
+ return expr_ptr();
+ if(!(case2 = cond_expr()))
+ return expr_ptr();
+ return make_expr<conditional>(std::move(cond), std::move(case1), std::move(case2));
}
- tokenizer& t;
+ tokenizer t;
};
} // namespace
- plural_ptr compile(const char* str)
+ plural_expr compile(const char* str)
{
- tokenizer t(str);
- parser p(t);
- return p.compile();
+ parser p(str);
+ return plural_expr(p.compile());
}
}}}} // namespace boost::locale::gnu_gettext::lambda
diff --git a/contrib/restricted/boost/locale/src/boost/locale/shared/mo_lambda.hpp b/contrib/restricted/boost/locale/src/boost/locale/shared/mo_lambda.hpp
index 71ae35a174..ff415175de 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/shared/mo_lambda.hpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/shared/mo_lambda.hpp
@@ -1,5 +1,6 @@
//
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
+// Copyright (c) 2021-2023 Alexander Grund
//
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
@@ -12,15 +13,24 @@
namespace boost { namespace locale { namespace gnu_gettext { namespace lambda {
- struct plural {
- virtual int operator()(int n) const = 0;
- virtual plural* clone() const = 0;
- virtual ~plural() = default;
+ struct BOOST_SYMBOL_VISIBLE expr {
+ using value_type = long long;
+ virtual value_type operator()(value_type n) const = 0;
+ virtual ~expr() = default;
};
+ using expr_ptr = std::unique_ptr<expr>;
- typedef std::shared_ptr<plural> plural_ptr;
+ class plural_expr {
+ expr_ptr p_;
- plural_ptr compile(const char* c_expression);
+ public:
+ plural_expr() = default;
+ explicit plural_expr(expr_ptr p) : p_(std::move(p)) {}
+ expr::value_type operator()(expr::value_type n) const { return (*p_)(n); }
+ explicit operator bool() const { return static_cast<bool>(p_); }
+ };
+
+ BOOST_LOCALE_DECL plural_expr compile(const char* c_expression);
}}}} // namespace boost::locale::gnu_gettext::lambda
diff --git a/contrib/restricted/boost/locale/src/boost/locale/std/all_generator.hpp b/contrib/restricted/boost/locale/src/boost/locale/std/all_generator.hpp
index 81e3102974..5dd020815b 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/std/all_generator.hpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/std/all_generator.hpp
@@ -12,32 +12,30 @@
#include <string>
namespace boost { namespace locale { namespace impl_std {
- enum class utf8_support { none, native, native_with_wide, from_wide };
-
- std::locale create_convert(const std::locale& in,
- const std::string& locale_name,
- char_facet_t type,
- utf8_support utf = utf8_support::none);
-
- std::locale create_collate(const std::locale& in,
- const std::string& locale_name,
- char_facet_t type,
- utf8_support utf = utf8_support::none);
-
- std::locale create_formatting(const std::locale& in,
- const std::string& locale_name,
- char_facet_t type,
- utf8_support utf = utf8_support::none);
-
- std::locale create_parsing(const std::locale& in,
- const std::string& locale_name,
- char_facet_t type,
- utf8_support utf = utf8_support::none);
-
- std::locale create_codecvt(const std::locale& in,
- const std::string& locale_name,
- char_facet_t type,
- utf8_support utf = utf8_support::none);
+ /// UTF-8 support of the standard library for the requested locale
+ enum class utf8_support {
+ /// No UTF-8 requested or required (e.g. other narrow encoding)
+ none,
+ /// UTF-8 encoding supported by the std-locale
+ native,
+ /// UTF-8 encoding has to be emulated using wchar_t
+ from_wide
+ };
+
+ std::locale
+ create_convert(const std::locale& in, const std::string& locale_name, char_facet_t type, utf8_support utf);
+
+ std::locale
+ create_collate(const std::locale& in, const std::string& locale_name, char_facet_t type, utf8_support utf);
+
+ std::locale
+ create_formatting(const std::locale& in, const std::string& locale_name, char_facet_t type, utf8_support utf);
+
+ std::locale
+ create_parsing(const std::locale& in, const std::string& locale_name, char_facet_t type, utf8_support utf);
+
+ std::locale
+ create_codecvt(const std::locale& in, const std::string& locale_name, char_facet_t type, utf8_support utf);
}}} // namespace boost::locale::impl_std
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 e5f702afb0..95a5171fe3 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/std/codecvt.cpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/std/codecvt.cpp
@@ -12,15 +12,22 @@ namespace boost { namespace locale { namespace impl_std {
template<typename CharType>
std::locale codecvt_bychar(const std::locale& in, const std::string& locale_name)
{
- return std::locale(in, new std::codecvt_byname<CharType, char, std::mbstate_t>(locale_name.c_str()));
+ return std::locale(in, new std::codecvt_byname<CharType, char, std::mbstate_t>(locale_name));
}
std::locale
create_codecvt(const std::locale& in, const std::string& locale_name, char_facet_t type, utf8_support utf)
{
+#if defined(BOOST_WINDOWS)
+ // This isn't fully correct:
+ // It will treat the 2-Byte wchar_t as UTF-16 encoded while it may be UCS-2
+ // std::basic_filebuf explicitely disallows using suche multi-byte codecvts
+ // but it works in practice so far, so use it instead of failing for codepoints above U+FFFF
+ if(utf != utf8_support::none)
+ return util::create_utf8_codecvt(in, type);
+#endif
if(utf == utf8_support::from_wide)
return util::create_utf8_codecvt(in, type);
-
switch(type) {
case char_facet_t::nochar: break;
case char_facet_t::char_f: return codecvt_bychar<char>(in, locale_name);
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 ced58ec597..ee249bfa5f 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/std/collate.cpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/std/collate.cpp
@@ -6,20 +6,24 @@
#include <boost/locale/encoding.hpp>
#include "boost/locale/std/all_generator.hpp"
+#include <boost/assert.hpp>
#include <ios>
#include <locale>
#include <string>
+#include <type_traits>
namespace boost { namespace locale { namespace impl_std {
class utf8_collator_from_wide : public std::collate<char> {
public:
typedef std::collate<wchar_t> wfacet;
- utf8_collator_from_wide(const std::locale& base, size_t refs = 0) : std::collate<char>(refs), base_(base) {}
+ utf8_collator_from_wide(const std::string& locale_name) :
+ base_(std::locale::classic(), new std::collate_byname<wchar_t>(locale_name))
+ {}
int do_compare(const char* lb, const char* le, const char* rb, const char* re) const override
{
- std::wstring l = conv::to_utf<wchar_t>(lb, le, "UTF-8");
- std::wstring r = conv::to_utf<wchar_t>(rb, re, "UTF-8");
+ 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 std::use_facet<wfacet>(base_).compare(l.c_str(),
l.c_str() + l.size(),
r.c_str(),
@@ -27,33 +31,22 @@ namespace boost { namespace locale { namespace impl_std {
}
long do_hash(const char* b, const char* e) const override
{
- std::wstring tmp = conv::to_utf<wchar_t>(b, e, "UTF-8");
+ const std::wstring tmp = conv::utf_to_utf<wchar_t>(b, e);
return std::use_facet<wfacet>(base_).hash(tmp.c_str(), tmp.c_str() + tmp.size());
}
std::string do_transform(const char* b, const char* e) const override
{
- std::wstring tmp = conv::to_utf<wchar_t>(b, e, "UTF-8");
- std::wstring wkey = std::use_facet<wfacet>(base_).transform(tmp.c_str(), tmp.c_str() + tmp.size());
+ const std::wstring tmp = conv::utf_to_utf<wchar_t>(b, e);
+ const std::wstring wkey = std::use_facet<wfacet>(base_).transform(tmp.c_str(), tmp.c_str() + tmp.size());
+ // wkey is only for lexicographical sorting, so may no be valid UTF
+ // --> Convert to char array in big endian order so sorting stays the same
std::string key;
- BOOST_LOCALE_START_CONST_CONDITION
- if(sizeof(wchar_t) == 2)
- key.reserve(wkey.size() * 2);
- else
- key.reserve(wkey.size() * 3);
- for(unsigned i = 0; i < wkey.size(); i++) {
- if(sizeof(wchar_t) == 2) {
- uint16_t tv = static_cast<uint16_t>(wkey[i]);
- key += char(tv >> 8);
- key += char(tv & 0xFF);
- } else { // 4
- uint32_t tv = static_cast<uint32_t>(wkey[i]);
- // 21 bit
- key += char((tv >> 16) & 0xFF);
- key += char((tv >> 8) & 0xFF);
- key += char(tv & 0xFF);
- }
+ key.reserve(wkey.size() * sizeof(wchar_t));
+ for(const wchar_t c : wkey) {
+ const auto tv = static_cast<std::make_unsigned<wchar_t>::type>(c);
+ for(unsigned i = 1; i <= sizeof(tv); ++i)
+ key += char((tv >> (sizeof(tv) - i) * 8) & 0xFF);
}
- BOOST_LOCALE_END_CONST_CONDITION
return key;
}
@@ -61,29 +54,48 @@ namespace boost { namespace locale { namespace impl_std {
std::locale base_;
};
+ // Workaround for a bug in the C++ or C standard library so far observed on the Appveyor VS2017 image
+ bool collation_works(const std::locale& l)
+ {
+ const auto& col = std::use_facet<std::collate<char>>(l);
+ const std::string a = "a";
+ const std::string b = "b";
+ try {
+ // On some broken system libs transform throws an exception
+ const auto ta = col.transform(a.c_str(), a.c_str() + a.size());
+ const auto tb = col.transform(b.c_str(), b.c_str() + b.size());
+ // This should always be true but on some broken system libs `l(a,b) == !l(b,a) == false`
+ return l(a, b) == !l(b, a) && (l(a, b) == (ta < tb));
+ } catch(const std::exception&) { // LCOV_EXCL_LINE
+ return false; // LCOV_EXCL_LINE
+ }
+ }
+
std::locale
create_collate(const std::locale& in, const std::string& locale_name, char_facet_t type, utf8_support utf)
{
switch(type) {
case char_facet_t::nochar: break;
- case char_facet_t::char_f: {
- if(utf == utf8_support::from_wide) {
- std::locale base =
- std::locale(std::locale::classic(), new std::collate_byname<wchar_t>(locale_name.c_str()));
- return std::locale(in, new utf8_collator_from_wide(base));
- } else {
- return std::locale(in, new std::collate_byname<char>(locale_name.c_str()));
+ case char_facet_t::char_f:
+ if(utf == utf8_support::from_wide)
+ return std::locale(in, new utf8_collator_from_wide(locale_name));
+ else {
+ std::locale res = std::locale(in, new std::collate_byname<char>(locale_name));
+ if(utf != utf8_support::none && !collation_works(res)) {
+ res = std::locale(res, new utf8_collator_from_wide(locale_name)); // LCOV_EXCL_LINE
+ }
+ BOOST_ASSERT_MSG(collation_works(res), "Broken collation");
+ return res;
}
- }
- case char_facet_t::wchar_f: return std::locale(in, new std::collate_byname<wchar_t>(locale_name.c_str()));
+ case char_facet_t::wchar_f: return std::locale(in, new std::collate_byname<wchar_t>(locale_name));
#ifdef BOOST_LOCALE_ENABLE_CHAR16_T
- case char_facet_t::char16_f: return std::locale(in, new std::collate_byname<char16_t>(locale_name.c_str()));
+ 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.c_str()));
+ case char_facet_t::char32_f: return std::locale(in, new std::collate_byname<char32_t>(locale_name));
#endif
}
return in;
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 a883ef7430..477c76f657 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/std/converter.cpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/std/converter.cpp
@@ -18,13 +18,15 @@ namespace boost { namespace locale { namespace impl_std {
template<typename CharType>
class std_converter : public converter<CharType> {
public:
- typedef CharType char_type;
- typedef std::basic_string<char_type> string_type;
- typedef std::ctype<char_type> ctype_type;
- std_converter(const std::locale& base, size_t refs = 0) : converter<CharType>(refs), base_(base) {}
+ typedef std::basic_string<CharType> string_type;
+ typedef std::ctype<CharType> ctype_type;
+
+ std_converter(const std::string& locale_name) :
+ base_(std::locale::classic(), new std::ctype_byname<CharType>(locale_name))
+ {}
string_type convert(converter_base::conversion_type how,
- const char_type* begin,
- const char_type* end,
+ const CharType* begin,
+ const CharType* end,
int /*flags*/ = 0) const override
{
switch(how) {
@@ -33,8 +35,8 @@ namespace boost { namespace locale { namespace impl_std {
case converter_base::case_folding: {
const ctype_type& ct = std::use_facet<ctype_type>(base_);
size_t len = end - begin;
- std::vector<char_type> res(len + 1, 0);
- char_type* lbegin = &res[0];
+ std::vector<CharType> res(len + 1, 0);
+ CharType* lbegin = res.data();
std::copy(begin, end, lbegin);
if(how == converter_base::upper_case)
ct.toupper(lbegin, lbegin + len);
@@ -54,9 +56,10 @@ namespace boost { namespace locale { namespace impl_std {
class utf8_converter : public converter<char> {
public:
- typedef std::ctype<char> ctype_type;
typedef std::ctype<wchar_t> wctype_type;
- utf8_converter(const std::locale& base, size_t refs = 0) : converter<char>(refs), base_(base) {}
+ 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,
@@ -66,17 +69,15 @@ namespace boost { namespace locale { namespace impl_std {
case upper_case:
case lower_case:
case case_folding: {
- std::wstring tmp = conv::to_utf<wchar_t>(begin, end, "UTF-8");
+ std::wstring tmp = conv::utf_to_utf<wchar_t>(begin, end);
const wctype_type& ct = std::use_facet<wctype_type>(base_);
- size_t len = tmp.size();
- std::vector<wchar_t> res(len + 1, 0);
- wchar_t* lbegin = &res[0];
- std::copy(tmp.c_str(), tmp.c_str() + len, lbegin);
+ wchar_t* lbegin = &tmp.front();
+ const size_t len = tmp.size();
if(how == upper_case)
ct.toupper(lbegin, lbegin + len);
else
ct.tolower(lbegin, lbegin + len);
- return conv::from_utf<wchar_t>(lbegin, lbegin + len, "UTF-8");
+ return conv::utf_to_utf<char>(lbegin, lbegin + len);
}
case title_case:
case normalization: break;
@@ -93,29 +94,17 @@ namespace boost { namespace locale { namespace impl_std {
{
switch(type) {
case char_facet_t::nochar: break;
- case char_facet_t::char_f: {
- if(utf == utf8_support::native_with_wide || utf == utf8_support::from_wide) {
- std::locale base(std::locale::classic(), new std::ctype_byname<wchar_t>(locale_name.c_str()));
- return std::locale(in, new utf8_converter(base));
- }
- std::locale base(std::locale::classic(), new std::ctype_byname<char>(locale_name.c_str()));
- return std::locale(in, new std_converter<char>(base));
- }
- case char_facet_t::wchar_f: {
- std::locale base(std::locale::classic(), new std::ctype_byname<wchar_t>(locale_name.c_str()));
- return std::locale(in, new std_converter<wchar_t>(base));
- }
+ case char_facet_t::char_f:
+ if(utf != utf8_support::none)
+ return std::locale(in, new utf8_converter(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));
#ifdef BOOST_LOCALE_ENABLE_CHAR16_T
- case char_facet_t::char16_f: {
- std::locale base(std::locale::classic(), new std::ctype_byname<char16_t>(locale_name.c_str()));
- return std::locale(in, new std_converter<char16_t>(base));
- }
+ case char_facet_t::char16_f: return std::locale(in, new std_converter<char16_t>(locale_name));
#endif
#ifdef BOOST_LOCALE_ENABLE_CHAR32_T
- case char_facet_t::char32_f: {
- std::locale base(std::locale::classic(), new std::ctype_byname<char32_t>(locale_name.c_str()));
- return std::locale(in, new std_converter<char32_t>(base));
- }
+ case char_facet_t::char32_f: return std::locale(in, new std_converter<char32_t>(locale_name));
#endif
}
return in;
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 2f93d2c88a..d8c7d5aff8 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/std/numeric.cpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/std/numeric.cpp
@@ -7,6 +7,7 @@
#include <boost/locale/encoding.hpp>
#include <boost/locale/formatting.hpp>
#include <boost/locale/generator.hpp>
+#include <algorithm>
#include <cstdlib>
#include <ios>
#include <locale>
@@ -17,12 +18,20 @@
#include "boost/locale/util/numeric.hpp"
namespace boost { namespace locale { namespace impl_std {
-
+ /// Forwarding time_put facet
+ /// Almost the same as `std::time_put_byname` but replaces the locale of the `ios_base` in `do_put` so that e.g.
+ /// weekday names are translated and formatting is as per the language of the base locale
template<typename CharType>
class time_put_from_base : public std::time_put<CharType> {
public:
- time_put_from_base(const std::locale& base, size_t refs = 0) : std::time_put<CharType>(refs), base_(base) {}
- typedef typename std::time_put<CharType>::iter_type iter_type;
+ using iter_type = typename std::time_put<CharType>::iter_type;
+
+ time_put_from_base(const std::locale& base) :
+ base_facet_(std::use_facet<std::time_put<CharType>>(base)), base_ios_(nullptr)
+ {
+ // Imbue the ios with the base locale so the facets `do_put` uses its formatting information
+ base_ios_.imbue(base);
+ }
iter_type do_put(iter_type out,
std::ios_base& /*ios*/,
@@ -31,13 +40,12 @@ namespace boost { namespace locale { namespace impl_std {
char format,
char modifier) const override
{
- std::basic_stringstream<CharType> ss;
- ss.imbue(base_);
- return std::use_facet<std::time_put<CharType>>(base_).put(out, ss, fill, tm, format, modifier);
+ return base_facet_.put(out, base_ios_, fill, tm, format, modifier);
}
private:
- std::locale base_;
+ const std::time_put<CharType>& base_facet_;
+ mutable std::basic_ios<CharType> base_ios_;
};
class utf8_time_put_from_wide : public std::time_put<char> {
@@ -54,12 +62,8 @@ namespace boost { namespace locale { namespace impl_std {
wtmps.imbue(base_);
std::use_facet<std::time_put<wchar_t>>(base_)
.put(wtmps, wtmps, wchar_t(fill), tm, wchar_t(format), wchar_t(modifier));
- std::wstring wtmp = wtmps.str();
- std::string const tmp = conv::from_utf<wchar_t>(wtmp, "UTF-8");
- for(unsigned i = 0; i < tmp.size(); i++) {
- *out++ = tmp[i];
- }
- return out;
+ const std::string tmp = conv::utf_to_utf<char>(wtmps.str());
+ return std::copy(tmp.begin(), tmp.end(), out);
}
private:
@@ -73,8 +77,8 @@ namespace boost { namespace locale { namespace impl_std {
typedef std::numpunct<wchar_t> wfacet_type;
const wfacet_type& wfacet = std::use_facet<wfacet_type>(base);
- truename_ = conv::from_utf<wchar_t>(wfacet.truename(), "UTF-8");
- falsename_ = conv::from_utf<wchar_t>(wfacet.falsename(), "UTF-8");
+ truename_ = conv::utf_to_utf<char>(wfacet.truename());
+ falsename_ = conv::utf_to_utf<char>(wfacet.falsename());
wchar_t tmp_decimal_point = wfacet.decimal_point();
wchar_t tmp_thousands_sep = wfacet.thousands_sep();
@@ -123,9 +127,9 @@ namespace boost { namespace locale { namespace impl_std {
typedef std::moneypunct<wchar_t, Intl> wfacet_type;
const wfacet_type& wfacet = std::use_facet<wfacet_type>(base);
- curr_symbol_ = conv::from_utf<wchar_t>(wfacet.curr_symbol(), "UTF-8");
- positive_sign_ = conv::from_utf<wchar_t>(wfacet.positive_sign(), "UTF-8");
- negative_sign_ = conv::from_utf<wchar_t>(wfacet.negative_sign(), "UTF-8");
+ curr_symbol_ = conv::utf_to_utf<char>(wfacet.curr_symbol());
+ positive_sign_ = conv::utf_to_utf<char>(wfacet.positive_sign());
+ negative_sign_ = conv::utf_to_utf<char>(wfacet.negative_sign());
frac_digits_ = wfacet.frac_digits();
pos_format_ = wfacet.pos_format();
neg_format_ = wfacet.neg_format();
@@ -184,7 +188,7 @@ namespace boost { namespace locale { namespace impl_std {
class utf8_numpunct : public std::numpunct_byname<char> {
public:
typedef std::numpunct_byname<char> base_type;
- utf8_numpunct(const char* name, size_t refs = 0) : std::numpunct_byname<char>(name, refs) {}
+ utf8_numpunct(const std::string& name, size_t refs = 0) : std::numpunct_byname<char>(name, refs) {}
char do_thousands_sep() const override
{
unsigned char bs = base_type::do_thousands_sep();
@@ -209,7 +213,7 @@ namespace boost { namespace locale { namespace impl_std {
class utf8_moneypunct : public std::moneypunct_byname<char, Intl> {
public:
typedef std::moneypunct_byname<char, Intl> base_type;
- utf8_moneypunct(const char* name, size_t refs = 0) : std::moneypunct_byname<char, Intl>(name, refs) {}
+ utf8_moneypunct(const std::string& name, size_t refs = 0) : std::moneypunct_byname<char, Intl>(name, refs) {}
char do_thousands_sep() const override
{
unsigned char bs = base_type::do_thousands_sep();
@@ -233,20 +237,19 @@ namespace boost { namespace locale { namespace impl_std {
template<typename CharType>
std::locale create_basic_parsing(const std::locale& in, const std::string& locale_name)
{
- std::locale tmp = std::locale(in, new std::numpunct_byname<CharType>(locale_name.c_str()));
- tmp = std::locale(tmp, new std::moneypunct_byname<CharType, true>(locale_name.c_str()));
- tmp = std::locale(tmp, new std::moneypunct_byname<CharType, false>(locale_name.c_str()));
- tmp = std::locale(tmp, new std::ctype_byname<CharType>(locale_name.c_str()));
- return tmp;
+ std::locale tmp = std::locale(in, new std::numpunct_byname<CharType>(locale_name));
+ tmp = std::locale(tmp, new std::moneypunct_byname<CharType, true>(locale_name));
+ tmp = std::locale(tmp, new std::moneypunct_byname<CharType, false>(locale_name));
+ tmp = std::locale(tmp, new std::ctype_byname<CharType>(locale_name));
+ return std::locale(tmp, new util::base_num_parse<CharType>());
}
template<typename CharType>
std::locale create_basic_formatting(const std::locale& in, const std::string& locale_name)
{
std::locale tmp = create_basic_parsing<CharType>(in, locale_name);
- std::locale base(locale_name.c_str());
- tmp = std::locale(tmp, new time_put_from_base<CharType>(base));
- return tmp;
+ tmp = std::locale(tmp, new time_put_from_base<CharType>(std::locale(locale_name)));
+ return std::locale(tmp, new util::base_num_format<CharType>());
}
std::locale
@@ -254,59 +257,28 @@ namespace boost { namespace locale { namespace impl_std {
{
switch(type) {
case char_facet_t::nochar: break;
- case char_facet_t::char_f: {
- switch(utf) {
- case utf8_support::from_wide: {
- std::locale base = std::locale(locale_name.c_str());
-
- std::locale tmp = std::locale(in, new utf8_time_put_from_wide(base));
- tmp = std::locale(tmp, new utf8_numpunct_from_wide(base));
- tmp = std::locale(tmp, new utf8_moneypunct_from_wide<true>(base));
- tmp = std::locale(tmp, new utf8_moneypunct_from_wide<false>(base));
- return std::locale(tmp, new util::base_num_format<char>());
- }
- case utf8_support::native: {
- std::locale base = std::locale(locale_name.c_str());
-
- std::locale tmp = std::locale(in, new time_put_from_base<char>(base));
- tmp = std::locale(tmp, new utf8_numpunct(locale_name.c_str()));
- tmp = std::locale(tmp, new utf8_moneypunct<true>(locale_name.c_str()));
- tmp = std::locale(tmp, new utf8_moneypunct<false>(locale_name.c_str()));
- return std::locale(tmp, new util::base_num_format<char>());
- }
- case utf8_support::native_with_wide: {
- std::locale base = std::locale(locale_name.c_str());
-
- std::locale tmp = std::locale(in, new time_put_from_base<char>(base));
- tmp = std::locale(tmp, new utf8_numpunct_from_wide(base));
- tmp = std::locale(tmp, new utf8_moneypunct_from_wide<true>(base));
- tmp = std::locale(tmp, new utf8_moneypunct_from_wide<false>(base));
- return std::locale(tmp, new util::base_num_format<char>());
- }
- case utf8_support::none: break;
- }
- std::locale tmp = create_basic_formatting<char>(in, locale_name);
- tmp = std::locale(tmp, new util::base_num_format<char>());
- return tmp;
- }
- case char_facet_t::wchar_f: {
- std::locale tmp = create_basic_formatting<wchar_t>(in, locale_name);
- tmp = std::locale(tmp, new util::base_num_format<wchar_t>());
- return tmp;
- }
+ case char_facet_t::char_f:
+ if(utf != utf8_support::none) {
+ const std::locale base(locale_name);
+ std::time_put<char>* time_put;
+ if(utf == utf8_support::from_wide)
+ time_put = new utf8_time_put_from_wide(base);
+ else
+ time_put = new time_put_from_base<char>(base);
+ std::locale tmp(in, time_put);
+ // Fix possibly invalid UTF-8
+ tmp = std::locale(tmp, new utf8_numpunct_from_wide(base));
+ tmp = std::locale(tmp, new utf8_moneypunct_from_wide<true>(base));
+ tmp = std::locale(tmp, new utf8_moneypunct_from_wide<false>(base));
+ return std::locale(tmp, new util::base_num_format<char>());
+ } 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 BOOST_LOCALE_ENABLE_CHAR16_T
- case char_facet_t::char16_f: {
- std::locale tmp = create_basic_formatting<char16_t>(in, locale_name);
- tmp = std::locale(tmp, new util::base_num_format<char16_t>());
- return tmp;
- }
+ case char_facet_t::char16_f: return create_basic_formatting<char16_t>(in, locale_name);
#endif
#ifdef BOOST_LOCALE_ENABLE_CHAR32_T
- case char_facet_t::char32_f: {
- std::locale tmp = create_basic_formatting<char32_t>(in, locale_name);
- tmp = std::locale(tmp, new util::base_num_format<char32_t>());
- return tmp;
- }
+ case char_facet_t::char32_f: return create_basic_formatting<char32_t>(in, locale_name);
#endif
}
return in;
@@ -317,58 +289,22 @@ namespace boost { namespace locale { namespace impl_std {
{
switch(type) {
case char_facet_t::nochar: break;
- case char_facet_t::char_f: {
- switch(utf) {
- case utf8_support::from_wide: {
- std::locale base = std::locale::classic();
-
- base = std::locale(base, new std::numpunct_byname<wchar_t>(locale_name.c_str()));
- base = std::locale(base, new std::moneypunct_byname<wchar_t, true>(locale_name.c_str()));
- base = std::locale(base, new std::moneypunct_byname<wchar_t, false>(locale_name.c_str()));
-
- std::locale tmp = std::locale(in, new utf8_numpunct_from_wide(base));
- tmp = std::locale(tmp, new utf8_moneypunct_from_wide<true>(base));
- tmp = std::locale(tmp, new utf8_moneypunct_from_wide<false>(base));
- return std::locale(tmp, new util::base_num_parse<char>());
- }
- case utf8_support::native: {
- std::locale tmp = std::locale(in, new utf8_numpunct(locale_name.c_str()));
- tmp = std::locale(tmp, new utf8_moneypunct<true>(locale_name.c_str()));
- tmp = std::locale(tmp, new utf8_moneypunct<false>(locale_name.c_str()));
- return std::locale(tmp, new util::base_num_parse<char>());
- }
- case utf8_support::native_with_wide: {
- std::locale base = std::locale(locale_name.c_str());
-
- std::locale tmp = std::locale(in, new utf8_numpunct_from_wide(base));
- tmp = std::locale(tmp, new utf8_moneypunct_from_wide<true>(base));
- tmp = std::locale(tmp, new utf8_moneypunct_from_wide<false>(base));
- return std::locale(tmp, new util::base_num_parse<char>());
- }
- case utf8_support::none: break;
- }
- std::locale tmp = create_basic_parsing<char>(in, locale_name);
- tmp = std::locale(in, new util::base_num_parse<char>());
- return tmp;
- }
- case char_facet_t::wchar_f: {
- std::locale tmp = create_basic_parsing<wchar_t>(in, locale_name);
- tmp = std::locale(in, new util::base_num_parse<wchar_t>());
- return tmp;
- }
+ case char_facet_t::char_f:
+ if(utf != utf8_support::none) {
+ const std::locale base(locale_name);
+ // Fix possibly invalid UTF-8
+ std::locale tmp = std::locale(in, new utf8_numpunct_from_wide(base));
+ tmp = std::locale(tmp, new utf8_moneypunct_from_wide<true>(base));
+ tmp = std::locale(tmp, new utf8_moneypunct_from_wide<false>(base));
+ return std::locale(tmp, new util::base_num_parse<char>());
+ } 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 BOOST_LOCALE_ENABLE_CHAR16_T
- case char_facet_t::char16_f: {
- std::locale tmp = create_basic_parsing<char16_t>(in, locale_name);
- tmp = std::locale(in, new util::base_num_parse<char16_t>());
- return tmp;
- }
+ case char_facet_t::char16_f: return create_basic_parsing<char16_t>(in, locale_name);
#endif
#ifdef BOOST_LOCALE_ENABLE_CHAR32_T
- case char_facet_t::char32_f: {
- std::locale tmp = create_basic_parsing<char32_t>(in, locale_name);
- tmp = std::locale(in, new util::base_num_parse<char32_t>());
- return tmp;
- }
+ case char_facet_t::char32_f: return create_basic_parsing<char32_t>(in, locale_name);
#endif
}
return in;
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 05967eb4bc..7b70e8a9f8 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
@@ -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
@@ -9,21 +10,66 @@
#include <boost/locale/localization_backend.hpp>
#include <boost/locale/util.hpp>
#include <boost/locale/util/locale_data.hpp>
+#include <boost/assert.hpp>
+#include <boost/core/ignore_unused.hpp>
#include <algorithm>
#include <iterator>
#include <vector>
-#if defined(BOOST_WINDOWS)
+#if BOOST_LOCALE_USE_WIN32_API
# ifndef NOMINMAX
# define NOMINMAX
# endif
-# include "boost/locale/encoding/conv.hpp"
-# include "boost/locale/util/encoding.hpp"
# include "boost/locale/win32/lcid.hpp"
# include <windows.h>
#endif
#include "boost/locale/std/all_generator.hpp"
+#include "boost/locale/util/encoding.hpp"
#include "boost/locale/util/gregorian.hpp"
+#include "boost/locale/util/make_std_unique.hpp"
+#include "boost/locale/util/numeric.hpp"
+
+namespace {
+struct windows_name {
+ std::string name, codepage;
+ explicit operator bool() const { return !name.empty() && !codepage.empty(); }
+};
+
+windows_name to_windows_name(const std::string& l)
+{
+#if BOOST_LOCALE_USE_WIN32_API
+ windows_name res;
+ const unsigned lcid = boost::locale::impl_win::locale_to_lcid(l);
+ char win_lang[256]{};
+ if(lcid == 0 || GetLocaleInfoA(lcid, LOCALE_SENGLANGUAGE, win_lang, sizeof(win_lang)) == 0)
+ return res;
+ res.name = win_lang;
+ char win_country[256]{};
+ if(GetLocaleInfoA(lcid, LOCALE_SENGCOUNTRY, win_country, sizeof(win_country)) != 0) {
+ res.name += "_";
+ res.name += win_country;
+ }
+
+ char win_codepage[10]{};
+ if(GetLocaleInfoA(lcid, LOCALE_IDEFAULTANSICODEPAGE, win_codepage, sizeof(win_codepage)) != 0)
+ res.codepage = win_codepage;
+ return res;
+#else
+ boost::ignore_unused(l);
+ return {};
+#endif
+}
+
+bool loadable(const std::string& name)
+{
+ try {
+ std::locale l(name);
+ return true;
+ } catch(const std::exception&) {
+ return false;
+ }
+}
+} // namespace
namespace boost { namespace locale { namespace impl_std {
@@ -69,77 +115,54 @@ namespace boost { namespace locale { namespace impl_std {
}
in_use_id_ = lid;
data_.parse(lid);
- name_ = "C";
-#if defined(BOOST_WINDOWS)
- const std::pair<std::string, int> wl_inf = to_windows_name(lid);
- const std::string& win_name = wl_inf.first;
- const int win_codepage = wl_inf.second;
-#endif
+ const auto l_win = to_windows_name(lid);
if(!data_.is_utf8()) {
+ utf_mode_ = utf8_support::none;
if(loadable(lid))
name_ = lid;
-#if defined(BOOST_WINDOWS)
- else if(loadable(win_name) && win_codepage == util::encoding_to_windows_codepage(data_.encoding()))
- name_ = win_name;
-#endif
- utf_mode_ = utf8_support::none;
+ else if(l_win && loadable(l_win.name)) {
+ if(util::are_encodings_equal(l_win.codepage, data_.encoding()))
+ name_ = l_win.name;
+ else {
+ int codepage_int;
+ if(util::try_to_int(l_win.codepage, codepage_int)
+ && codepage_int == util::encoding_to_windows_codepage(data_.encoding()))
+ {
+ name_ = l_win.name;
+ } else
+ name_ = "C";
+ }
+ } else
+ name_ = "C";
} else {
if(loadable(lid)) {
name_ = lid;
- utf_mode_ = utf8_support::native_with_wide;
-#if defined(BOOST_WINDOWS)
- // This isn't fully correct:
- // It will treat the 2-Byte wchar_t as UTF-16 encoded while it may be UCS-2
- // std::basic_filebuf explicitely disallows using suche multi-byte codecvts
- // but it works in practice so far, so use it instead of failing for codepoints above U+FFFF
- utf_mode_ = utf8_support::from_wide;
-#endif
- }
-#if defined(BOOST_WINDOWS)
- else if(loadable(win_name))
- {
- name_ = win_name;
+ utf_mode_ = utf8_support::native;
+ } else {
+ std::vector<std::string> alt_names;
+ if(l_win)
+ alt_names.push_back(l_win.name);
+ // Try different spellings
+ alt_names.push_back(util::locale_data(data_).encoding("UTF-8").to_string());
+ alt_names.push_back(util::locale_data(data_).encoding("utf8", false).to_string());
+ // Without encoding, let from_wide classes handle it
+ alt_names.push_back(util::locale_data(data_).encoding("").to_string());
+ // Final try: Classic locale, but enable Unicode (if supported)
+ alt_names.push_back("C.UTF-8");
+ alt_names.push_back("C.utf8");
+ // If everything fails rely on the classic locale
+ alt_names.push_back("C");
+ for(const std::string& name : alt_names) {
+ if(loadable(name)) {
+ name_ = name;
+ break;
+ }
+ }
+ BOOST_ASSERT(!name_.empty());
utf_mode_ = utf8_support::from_wide;
}
-#endif
- else
- utf_mode_ = utf8_support::none;
- }
- }
-
-#if defined(BOOST_WINDOWS)
- std::pair<std::string, int> to_windows_name(const std::string& l)
- {
- std::pair<std::string, int> res("C", 0);
- unsigned lcid = impl_win::locale_to_lcid(l);
- char win_lang[256] = {0};
- char win_country[256] = {0};
- char win_codepage[10] = {0};
- if(GetLocaleInfoA(lcid, LOCALE_SENGLANGUAGE, win_lang, sizeof(win_lang)) == 0)
- return res;
- std::string lc_name = win_lang;
- if(GetLocaleInfoA(lcid, LOCALE_SENGCOUNTRY, win_country, sizeof(win_country)) != 0) {
- lc_name += "_";
- lc_name += win_country;
- }
-
- res.first = lc_name;
-
- if(GetLocaleInfoA(lcid, LOCALE_IDEFAULTANSICODEPAGE, win_codepage, sizeof(win_codepage)) != 0)
- res.second = atoi(win_codepage);
- return res;
- }
-#endif
-
- bool loadable(std::string name)
- {
- try {
- std::locale l(name.c_str());
- return true;
- } catch(const std::exception& /*e*/) {
- return false;
}
}
@@ -200,9 +223,9 @@ namespace boost { namespace locale { namespace impl_std {
bool use_ansi_encoding_;
};
- localization_backend* create_localization_backend()
+ std::unique_ptr<localization_backend> create_localization_backend()
{
- return new std_localization_backend();
+ return make_std_unique<std_localization_backend>();
}
}}} // namespace boost::locale::impl_std
diff --git a/contrib/restricted/boost/locale/src/boost/locale/std/std_backend.hpp b/contrib/restricted/boost/locale/src/boost/locale/std/std_backend.hpp
index 76ddc051d0..4ce6b271e3 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/std/std_backend.hpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/std/std_backend.hpp
@@ -6,10 +6,14 @@
#ifndef BOOST_LOCALE_IMPL_STD_LOCALIZATION_BACKEND_HPP
#define BOOST_LOCALE_IMPL_STD_LOCALIZATION_BACKEND_HPP
+
+#include <boost/locale/config.hpp>
+#include <memory>
+
namespace boost { namespace locale {
class localization_backend;
namespace impl_std {
- localization_backend* create_localization_backend();
+ std::unique_ptr<localization_backend> create_localization_backend();
} // namespace impl_std
}} // namespace boost::locale
#endif
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 40759882f2..7ad9846d23 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
@@ -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
@@ -8,12 +9,14 @@
#include <boost/locale/generator.hpp>
#include <boost/locale/utf8_codecvt.hpp>
#include <boost/locale/util.hpp>
+#include <boost/locale/util/string.hpp>
+#include <boost/assert.hpp>
#include <algorithm>
#include <cstddef>
#include <cstring>
-#include "boost/locale/encoding/conv.hpp"
#include "boost/locale/util/encoding.hpp"
+#include "boost/locale/util/make_std_unique.hpp"
#ifdef BOOST_MSVC
# pragma warning(disable : 4244) // loose data
@@ -31,11 +34,11 @@ namespace boost { namespace locale { namespace util {
bool is_thread_safe() const override { return true; }
- uint32_t to_unicode(const char*& begin, const char* end) override
+ utf::code_point to_unicode(const char*& begin, const char* end) override
{
const char* p = begin;
- utf::code_point c = utf::utf_traits<char>::decode(p, end);
+ const utf::code_point c = utf::utf_traits<char>::decode(p, end);
if(c == utf::illegal)
return illegal;
@@ -47,7 +50,7 @@ namespace boost { namespace locale { namespace util {
return c;
}
- uint32_t from_unicode(uint32_t u, char* begin, const char* end) override
+ utf::len_or_error from_unicode(utf::code_point u, char* begin, const char* end) override
{
if(!utf::is_valid_codepoint(u))
return illegal;
@@ -68,18 +71,18 @@ namespace boost { namespace locale { namespace util {
{
for(unsigned i = 0; i < 128; i++)
to_unicode_tbl_[i] = i;
+ const conv::utf_encoder<wchar_t> to_utf(encoding, conv::skip);
for(unsigned i = 128; i < 256; i++) {
- char buf[2] = {char(i), 0};
+ char buf[2] = {util::to_char(i), 0};
uint32_t uchar = utf::illegal;
try {
- std::wstring const tmp = conv::to_utf<wchar_t>(buf, buf + 1, encoding, conv::stop);
- if(tmp.size() == 1) {
+ std::wstring const tmp = to_utf.convert(buf, buf + 1);
+ if(tmp.size() == 1)
uchar = tmp[0];
- } else {
+ else
uchar = utf::illegal;
- }
- } catch(const conv::conversion_error& /*e*/) {
- uchar = utf::illegal;
+ } catch(const conv::conversion_error&) { // LCOV_EXCL_LINE
+ uchar = utf::illegal; // LCOV_EXCL_LINE
}
to_unicode_tbl_[i] = uchar;
}
@@ -95,14 +98,14 @@ namespace boost { namespace locale { namespace util {
}
}
- uint32_t to_unicode(const char*& begin, const char* end) const
+ utf::code_point to_unicode(const char*& begin, const char* end) const
{
if(begin == end)
return utf::incomplete;
unsigned char c = *begin++;
return to_unicode_tbl_[c];
}
- uint32_t from_unicode(uint32_t u, char* begin, const char* end) const
+ utf::len_or_error from_unicode(utf::code_point u, char* begin, const char* end) const
{
if(begin == end)
return utf::incomplete;
@@ -116,12 +119,12 @@ namespace boost { namespace locale { namespace util {
pos = (pos + 1) % hash_table_size;
if(c == 0)
return utf::illegal;
- *begin = c;
+ *begin = to_char(c);
return 1;
}
private:
- uint32_t to_unicode_tbl_[256];
+ utf::code_point to_unicode_tbl_[256];
unsigned char from_unicode_tbl_[hash_table_size];
};
@@ -134,8 +137,8 @@ namespace boost { namespace locale { namespace util {
bool is_thread_safe() const override { return true; }
base_converter* clone() const override { return new simple_converter(*this); }
- uint32_t to_unicode(const char*& begin, const char* end) override { return cvt_.to_unicode(begin, end); }
- uint32_t from_unicode(uint32_t u, char* begin, const char* end) override
+ utf::code_point to_unicode(const char*& begin, const char* end) override { return cvt_.to_unicode(begin, end); }
+ utf::len_or_error from_unicode(utf::code_point u, char* begin, const char* end) override
{
return cvt_.from_unicode(u, begin, end);
}
@@ -163,7 +166,7 @@ namespace boost { namespace locale { namespace util {
return cvt_.to_unicode(begin, end);
}
- utf::code_point from_unicode(state_type&, utf::code_point u, char* begin, const char* end) const
+ utf::len_or_error from_unicode(state_type&, utf::code_point u, char* begin, const char* end) const
{
return cvt_.from_unicode(u, begin, end);
}
@@ -186,71 +189,68 @@ namespace boost { namespace locale { namespace util {
}
} // namespace
- bool check_is_simple_encoding(const std::string& encoding)
+ std::vector<std::string> get_simple_encodings()
{
- std::string norm = util::normalize_encoding(encoding);
- return std::binary_search<const char**>(simple_encoding_table,
- simple_encoding_table
- + sizeof(simple_encoding_table) / sizeof(const char*),
- norm.c_str(),
- compare_strings);
+ return std::vector<std::string>(simple_encoding_table, std::end(simple_encoding_table));
}
- std::unique_ptr<base_converter> create_simple_converter(const std::string& encoding)
+ bool is_simple_encoding(const std::string& encoding)
{
- return std::unique_ptr<base_converter>(create_simple_converter_new_ptr(encoding));
+ std::string norm = util::normalize_encoding(encoding);
+ return std::binary_search(simple_encoding_table,
+ std::end(simple_encoding_table),
+ norm.c_str(),
+ compare_strings);
}
- base_converter* create_simple_converter_new_ptr(const std::string& encoding)
+
+ std::unique_ptr<base_converter> create_simple_converter(const std::string& encoding)
{
- if(check_is_simple_encoding(encoding))
- return new simple_converter(encoding);
- return 0;
+ if(is_simple_encoding(encoding))
+ return make_std_unique<simple_converter>(encoding);
+ return nullptr;
}
std::unique_ptr<base_converter> create_utf8_converter()
{
- return std::unique_ptr<base_converter>(create_utf8_converter_new_ptr());
+ return make_std_unique<utf8_converter>();
}
- base_converter* create_utf8_converter_new_ptr()
- {
- return new utf8_converter();
- }
+ // clang-format off
+ base_converter* create_simple_converter_new_ptr(const std::string& encoding){ return create_simple_converter(encoding).release(); } // LCOV_EXCL_LINE
+ base_converter* create_utf8_converter_new_ptr(){ return create_utf8_converter().release(); } // LCOV_EXCL_LINE
+ // clang-format on
- template<typename CharType>
- class code_converter : public generic_codecvt<CharType, code_converter<CharType>> {
+ template<typename CharType, bool ThreadSafe>
+ class code_converter : public generic_codecvt<CharType, code_converter<CharType, ThreadSafe>> {
public:
typedef std::unique_ptr<base_converter> base_converter_ptr;
typedef base_converter_ptr state_type;
code_converter(base_converter_ptr cvt, size_t refs = 0) :
- generic_codecvt<CharType, code_converter<CharType>>(refs), cvt_(std::move(cvt))
- {
- max_len_ = cvt_->max_len();
- thread_safe_ = cvt_->is_thread_safe();
- }
+ generic_codecvt<CharType, code_converter<CharType, ThreadSafe>>(refs), cvt_(std::move(cvt))
+ {}
- int max_encoding_length() const { return max_len_; }
+ int max_encoding_length() const { return cvt_->max_len(); }
base_converter_ptr initial_state(generic_codecvt_base::initial_convertion_state /* unused */) const
{
base_converter_ptr r;
- if(!thread_safe_)
+ if(!ThreadSafe)
r.reset(cvt_->clone());
return r;
}
utf::code_point to_unicode(base_converter_ptr& ptr, const char*& begin, const char* end) const
{
- if(thread_safe_)
+ if(ThreadSafe)
return cvt_->to_unicode(begin, end);
else
return ptr->to_unicode(begin, end);
}
- utf::code_point from_unicode(base_converter_ptr& ptr, utf::code_point u, char* begin, const char* end) const
+ utf::len_or_error from_unicode(base_converter_ptr& ptr, utf::code_point u, char* begin, const char* end) const
{
- if(thread_safe_)
+ if(ThreadSafe)
return cvt_->from_unicode(u, begin, end);
else
return ptr->from_unicode(u, begin, end);
@@ -258,23 +258,28 @@ namespace boost { namespace locale { namespace util {
private:
base_converter_ptr cvt_;
- int max_len_;
- bool thread_safe_;
};
+ template<typename CharType>
+ static std::locale do_create_codecvt(const std::locale& in, std::unique_ptr<base_converter> cvt)
+ {
+ return cvt->is_thread_safe() ? std::locale(in, new code_converter<CharType, true>(std::move(cvt))) :
+ std::locale(in, new code_converter<CharType, false>(std::move(cvt)));
+ }
+
std::locale create_codecvt(const std::locale& in, std::unique_ptr<base_converter> cvt, char_facet_t type)
{
if(!cvt)
cvt.reset(new base_converter());
switch(type) {
case char_facet_t::nochar: break;
- case char_facet_t::char_f: return std::locale(in, new code_converter<char>(std::move(cvt)));
- case char_facet_t::wchar_f: return std::locale(in, new code_converter<wchar_t>(std::move(cvt)));
+ 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 BOOST_LOCALE_ENABLE_CHAR16_T
- case char_facet_t::char16_f: return std::locale(in, new code_converter<char16_t>(std::move(cvt)));
+ case char_facet_t::char16_f: return do_create_codecvt<char16_t>(in, std::move(cvt));
#endif
#ifdef BOOST_LOCALE_ENABLE_CHAR32_T
- case char_facet_t::char32_f: return std::locale(in, new code_converter<char32_t>(std::move(cvt)));
+ case char_facet_t::char32_f: return do_create_codecvt<char32_t>(in, std::move(cvt));
#endif
}
return in;
@@ -298,14 +303,9 @@ namespace boost { namespace locale { namespace util {
return in;
}
- /// This function installs codecvt that can be used for conversion between single byte
- /// character encodings like ISO-8859-1, koi8-r, windows-1255 and Unicode code points,
- ///
- /// Throws invalid_charset_error if the character set is not supported or isn't single byte character
- /// set
std::locale create_simple_codecvt(const std::locale& in, const std::string& encoding, char_facet_t type)
{
- if(!check_is_simple_encoding(encoding))
+ if(!is_simple_encoding(encoding))
throw boost::locale::conv::invalid_charset_error("Invalid simple encoding " + encoding);
switch(type) {
diff --git a/contrib/restricted/boost/locale/src/boost/locale/util/default_locale.cpp b/contrib/restricted/boost/locale/src/boost/locale/util/default_locale.cpp
index d4ede78b1b..74cf7705dc 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/util/default_locale.cpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/util/default_locale.cpp
@@ -5,7 +5,8 @@
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/locale/util.hpp>
-#include <cstdlib>
+#include <boost/locale/util/string.hpp>
+#include <algorithm>
#if BOOST_LOCALE_USE_WIN32_API
# ifndef NOMINMAX
@@ -27,7 +28,7 @@ static bool get_user_default_locale_info(LCTYPE lcType, char (&buf)[N])
namespace boost { namespace locale { namespace util {
std::string get_system_locale(bool use_utf8_on_windows)
{
- const char* lang = 0;
+ const char* lang = nullptr;
if(!lang || !*lang)
lang = getenv("LC_ALL");
if(!lang || !*lang)
@@ -54,7 +55,7 @@ namespace boost { namespace locale { namespace util {
if(use_utf8_on_windows || !get_user_default_locale_info(LOCALE_IDEFAULTANSICODEPAGE, buf))
lc_name += ".UTF-8";
else {
- if(atoi(buf) == 0)
+ if(std::find_if_not(buf, str_end(buf), is_numeric_ascii) != str_end(buf))
lc_name += ".UTF-8";
else
lc_name.append(".windows-").append(buf);
diff --git a/contrib/restricted/boost/locale/src/boost/locale/util/encoding.cpp b/contrib/restricted/boost/locale/src/boost/locale/util/encoding.cpp
index 232fdaf245..8a6bf183be 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/util/encoding.cpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/util/encoding.cpp
@@ -7,7 +7,6 @@
#include "boost/locale/util/encoding.hpp"
#include "boost/locale/util/string.hpp"
-#include <boost/assert.hpp>
#if BOOST_LOCALE_USE_WIN32_API
# include "boost/locale/util/win_codepages.hpp"
# ifndef NOMINMAX
@@ -19,11 +18,11 @@
#include <cstring>
namespace boost { namespace locale { namespace util {
- static std::string do_normalize_encoding(const char* encoding, const size_t len)
+ std::string normalize_encoding(const string_view encoding)
{
std::string result;
- result.reserve(len);
- for(char c = *encoding; c != 0; c = *(++encoding)) {
+ result.reserve(encoding.length());
+ for(char c : encoding) {
if(is_lower_ascii(c) || is_numeric_ascii(c))
result += c;
else if(is_upper_ascii(c))
@@ -32,24 +31,12 @@ namespace boost { namespace locale { namespace util {
return result;
}
- std::string normalize_encoding(const std::string& encoding)
- {
- return do_normalize_encoding(encoding.c_str(), encoding.size());
- }
-
- std::string normalize_encoding(const char* encoding)
- {
- return do_normalize_encoding(encoding, std::strlen(encoding));
- }
-
#if BOOST_LOCALE_USE_WIN32_API
static int normalized_encoding_to_windows_codepage(const std::string& encoding)
{
- constexpr size_t n = sizeof(all_windows_encodings) / sizeof(all_windows_encodings[0]);
- windows_encoding* begin = all_windows_encodings;
- windows_encoding* end = all_windows_encodings + n;
+ windows_encoding* end = std::end(all_windows_encodings);
- windows_encoding* ptr = std::lower_bound(begin, end, encoding.c_str());
+ windows_encoding* ptr = std::lower_bound(all_windows_encodings, end, encoding.c_str());
while(ptr != end && ptr->name == encoding) {
if(ptr->was_tested)
return ptr->codepage;
@@ -64,12 +51,7 @@ namespace boost { namespace locale { namespace util {
return -1;
}
- int encoding_to_windows_codepage(const char* encoding)
- {
- return normalized_encoding_to_windows_codepage(normalize_encoding(encoding));
- }
-
- int encoding_to_windows_codepage(const std::string& encoding)
+ int encoding_to_windows_codepage(const string_view encoding)
{
return normalized_encoding_to_windows_codepage(normalize_encoding(encoding));
}
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 958233fb35..7f2f6a8cd8 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/util/encoding.hpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/util/encoding.hpp
@@ -9,8 +9,10 @@
#define BOOST_LOCALE_UTIL_ENCODING_HPP
#include <boost/locale/config.hpp>
+#include <boost/utility/string_view.hpp>
#include <cstdint>
#include <string>
+#include <vector>
namespace boost { namespace locale { namespace util {
@@ -37,17 +39,23 @@ namespace boost { namespace locale { namespace util {
}
/// Make encoding lowercase and remove all non-alphanumeric characters
- BOOST_LOCALE_DECL std::string normalize_encoding(const std::string& encoding);
- BOOST_LOCALE_DECL std::string normalize_encoding(const char* encoding);
+ BOOST_LOCALE_DECL std::string normalize_encoding(string_view encoding);
/// True if the normalized encodings are equal
inline bool are_encodings_equal(const std::string& l, const std::string& r)
{
return normalize_encoding(l) == normalize_encoding(r);
}
+ BOOST_LOCALE_DECL std::vector<std::string> get_simple_encodings();
+
#if BOOST_LOCALE_USE_WIN32_API
- int encoding_to_windows_codepage(const char* encoding);
- int encoding_to_windows_codepage(const std::string& encoding);
+ int encoding_to_windows_codepage(string_view encoding);
+#else
+ // Requires WinAPI -> Dummy returning invalid
+ inline int encoding_to_windows_codepage(string_view) // LCOV_EXCL_LINE
+ {
+ return -1; // LCOV_EXCL_LINE
+ }
#endif
}}} // namespace boost::locale::util
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
new file mode 100644
index 0000000000..df5857b9d9
--- /dev/null
+++ b/contrib/restricted/boost/locale/src/boost/locale/util/foreach_char.hpp
@@ -0,0 +1,29 @@
+//
+// Copyright (c) 2023-2023 Alexander Grund
+//
+// Distributed under the Boost Software License, Version 1.0.
+// https://www.boost.org/LICENSE_1_0.txt
+
+#ifndef BOOST_LOCALE_UTIL_FOREACH_CHAR_HPP
+#define BOOST_LOCALE_UTIL_FOREACH_CHAR_HPP
+
+#include <boost/locale/config.hpp>
+
+#ifdef BOOST_LOCALE_ENABLE_CHAR16_T
+# define BOOST_LOCALE_FOREACH_CHAR_I_CHAR16_T(F) F(char16_t)
+#else
+# define BOOST_LOCALE_FOREACH_CHAR_I_CHAR16_T(F)
+#endif
+#ifdef BOOST_LOCALE_ENABLE_CHAR32_T
+# define BOOST_LOCALE_FOREACH_CHAR_I_CHAR32_T(F) F(char32_t)
+#else
+# define BOOST_LOCALE_FOREACH_CHAR_I_CHAR32_T(F)
+#endif
+
+#define BOOST_LOCALE_FOREACH_CHAR(F) \
+ F(char) \
+ F(wchar_t) \
+ BOOST_LOCALE_FOREACH_CHAR_I_CHAR16_T(F) \
+ BOOST_LOCALE_FOREACH_CHAR_I_CHAR32_T(F)
+
+#endif
diff --git a/contrib/restricted/boost/locale/src/boost/locale/util/gregorian.cpp b/contrib/restricted/boost/locale/src/boost/locale/util/gregorian.cpp
index 5c74b54eee..b0bc6e8a29 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/util/gregorian.cpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/util/gregorian.cpp
@@ -19,18 +19,22 @@
#include <memory>
#include <string>
+#define BOOST_LOCALE_CASE_INVALID(action) \
+ BOOST_ASSERT_MSG(false, "Shouldn't use 'invalid' value."); \
+ action
+
namespace boost { namespace locale { namespace util {
namespace {
- int is_leap(int year)
+ bool is_leap(int year)
{
if(year % 400 == 0)
- return 1;
+ return true;
if(year % 100 == 0)
- return 0;
+ return false;
if(year % 4 == 0)
- return 1;
- return 0;
+ return true;
+ return false;
}
int days_in_month(int year, int month)
@@ -113,12 +117,9 @@ namespace boost { namespace locale { namespace util {
"PH", "PK", "SG", "TH", "TT", "TW", "UM", "US", "UZ", "VI", "ZW"};
if(strcmp(terr, "MV") == 0)
return 5; // fri
- if(std::binary_search<const char* const*>(sat, sat + sizeof(sat) / (sizeof(sat[0])), terr, comparator))
+ if(std::binary_search<const char* const*>(sat, std::end(sat), terr, comparator))
return 6; // sat
- if(std::binary_search<const char* const*>(sunday,
- sunday + sizeof(sunday) / (sizeof(sunday[0])),
- terr,
- comparator))
+ if(std::binary_search<const char* const*>(sunday, std::end(sunday), terr, comparator))
return 0; // sun
// default
return 1; // mon
@@ -130,7 +131,7 @@ namespace boost { namespace locale { namespace util {
gregorian_calendar(const std::string& terr)
{
first_day_of_week_ = first_day_of_week(terr.c_str());
- time_ = std::time(0);
+ time_ = std::time(nullptr);
is_local_ = true;
tzoff_ = 0;
from_time(time_);
@@ -190,8 +191,10 @@ namespace boost { namespace locale { namespace util {
int diff = 7 * (value - current_week);
tm_updated_.tm_mday += diff;
} break;
- case period::marks::first_day_of_week: ///< For example Sunday in US, Monday in France
- case invalid: return;
+ ///< For example Sunday in US, Monday in France
+ case period::marks::first_day_of_week: // LCOV_EXCL_LINE
+ throw std::invalid_argument("Can't change first day of week"); // LCOV_EXCL_LINE
+ case invalid: BOOST_LOCALE_CASE_INVALID(return ); // LCOV_EXCL_LINE
}
normalized_ = false;
}
@@ -209,19 +212,17 @@ namespace boost { namespace locale { namespace util {
#ifndef BOOST_WINDOWS
// windows does not handle negative time_t, under other plaforms
// it may be actually valid value in 1969-12-31 23:59:59
- // so we check that a filed was updated - does not happen in case of error
+ // so we check that a field was updated - does not happen in case of error
if(val.tm_wday == -1)
#endif
- {
- throw date_time_error("boost::locale::gregorian_calendar: invalid time");
- }
+ throw date_time_error("boost::locale::gregorian_calendar: invalid time"); // LCOV_EXCL_LINE
}
} else {
point = internal_timegm(&val);
#ifdef BOOST_WINDOWS
// Windows uses TLS, thread safe
- std::tm* revert_point = 0;
- if(point < 0 || (revert_point = gmtime(&point)) == 0)
+ std::tm* revert_point = nullptr;
+ if(point < 0 || (revert_point = gmtime(&point)) == nullptr)
throw date_time_error("boost::locale::gregorian_calendar time is out of range");
val = *revert_point;
#else
@@ -250,11 +251,10 @@ namespace boost { namespace locale { namespace util {
// adding something big dividable by 7
int start_of_period_in_weeks;
- if(first_week_day < days_in_full_week) {
+ if(first_week_day < days_in_full_week)
start_of_period_in_weeks = -first_week_day;
- } else {
+ else
start_of_period_in_weeks = 7 - first_week_day;
- }
int week_number_in_days = day - start_of_period_in_weeks;
if(week_number_in_days < 0)
return -1;
@@ -293,7 +293,7 @@ namespace boost { namespace locale { namespace util {
BOOST_LOCALE_END_CONST_CONDITION
case current: return tm_.tm_year + 1900;
};
- break;
+ throw std::invalid_argument("Invalid abstract_calendar::value_type"); // LCOV_EXCL_LINE
case month:
switch(v) {
case absolute_minimum:
@@ -304,7 +304,7 @@ namespace boost { namespace locale { namespace util {
case actual_maximum: return 11;
case current: return tm_.tm_mon;
};
- break;
+ throw std::invalid_argument("Invalid abstract_calendar::value_type"); // LCOV_EXCL_LINE
case day:
switch(v) {
case absolute_minimum:
@@ -315,7 +315,7 @@ namespace boost { namespace locale { namespace util {
case actual_maximum: return days_in_month(tm_.tm_year + 1900, tm_.tm_mon + 1);
case current: return tm_.tm_mday;
};
- break;
+ throw std::invalid_argument("Invalid abstract_calendar::value_type"); // LCOV_EXCL_LINE
case day_of_year: ///< The number of day in year, starting from 1
switch(v) {
case absolute_minimum:
@@ -326,7 +326,7 @@ namespace boost { namespace locale { namespace util {
case actual_maximum: return is_leap(tm_.tm_year + 1900) ? 366 : 365;
case current: return tm_.tm_yday + 1;
}
- break;
+ throw std::invalid_argument("Invalid abstract_calendar::value_type"); // LCOV_EXCL_LINE
case day_of_week: ///< Day of week, starting from Sunday, [1..7]
switch(v) {
case absolute_minimum:
@@ -337,7 +337,7 @@ namespace boost { namespace locale { namespace util {
case actual_maximum: return 7;
case current: return tm_.tm_wday + 1;
}
- break;
+ throw std::invalid_argument("Invalid abstract_calendar::value_type"); // LCOV_EXCL_LINE
case day_of_week_local: ///< Local day of week, for example in France Monday is 1, in US Sunday is 1,
///< [1..7]
switch(v) {
@@ -349,8 +349,8 @@ namespace boost { namespace locale { namespace util {
case actual_maximum: return 7;
case current: return (tm_.tm_wday - first_day_of_week_ + 7) % 7 + 1;
}
- break;
- case hour: ///< 24 clock hour [0..23]
+ throw std::invalid_argument("Invalid abstract_calendar::value_type"); // LCOV_EXCL_LINE
+ case hour: ///< 24 clock hour [0..23]
switch(v) {
case absolute_minimum:
case greatest_minimum:
@@ -360,8 +360,8 @@ namespace boost { namespace locale { namespace util {
case actual_maximum: return 23;
case current: return tm_.tm_hour;
}
- break;
- case hour_12: ///< 12 clock hour [0..11]
+ throw std::invalid_argument("Invalid abstract_calendar::value_type"); // LCOV_EXCL_LINE
+ case hour_12: ///< 12 clock hour [0..11]
switch(v) {
case absolute_minimum:
case greatest_minimum:
@@ -371,8 +371,8 @@ namespace boost { namespace locale { namespace util {
case actual_maximum: return 11;
case current: return tm_.tm_hour % 12;
}
- break;
- case am_pm: ///< am or pm marker, [0..1]
+ throw std::invalid_argument("Invalid abstract_calendar::value_type"); // LCOV_EXCL_LINE
+ case am_pm: ///< am or pm marker, [0..1]
switch(v) {
case absolute_minimum:
case greatest_minimum:
@@ -382,8 +382,8 @@ namespace boost { namespace locale { namespace util {
case actual_maximum: return 1;
case current: return tm_.tm_hour >= 12 ? 1 : 0;
}
- break;
- case minute: ///< minute [0..59]
+ throw std::invalid_argument("Invalid abstract_calendar::value_type"); // LCOV_EXCL_LINE
+ case minute: ///< minute [0..59]
switch(v) {
case absolute_minimum:
case greatest_minimum:
@@ -393,8 +393,8 @@ namespace boost { namespace locale { namespace util {
case actual_maximum: return 59;
case current: return tm_.tm_min;
}
- break;
- case second: ///< second [0..59]
+ throw std::invalid_argument("Invalid abstract_calendar::value_type"); // LCOV_EXCL_LINE
+ case second: ///< second [0..59]
switch(v) {
case absolute_minimum:
case greatest_minimum:
@@ -404,7 +404,7 @@ namespace boost { namespace locale { namespace util {
case actual_maximum: return 59;
case current: return tm_.tm_sec;
}
- break;
+ throw std::invalid_argument("Invalid abstract_calendar::value_type"); // LCOV_EXCL_LINE
case period::marks::first_day_of_week: ///< For example Sunday in US, Monday in France
return first_day_of_week_ + 1;
@@ -422,13 +422,11 @@ namespace boost { namespace locale { namespace util {
return get_week_number(end_of_year_days, dow_of_end_of_year);
}
case current: {
- int val = get_week_number(tm_.tm_yday, tm_.tm_wday);
- if(val < 0)
- return 53;
- return val;
+ const int val = get_week_number(tm_.tm_yday, tm_.tm_wday);
+ return (val < 0) ? 53 : val;
}
- }
- break;
+ } // LCOV_EXCL_LINE
+ throw std::invalid_argument("Invalid abstract_calendar::value_type"); // LCOV_EXCL_LINE
case week_of_month: ///< The week number within current month
switch(v) {
case absolute_minimum:
@@ -442,13 +440,11 @@ namespace boost { namespace locale { namespace util {
return get_week_number(end_of_month_days, dow_of_end_of_month);
}
case current: {
- int val = get_week_number(tm_.tm_mday, tm_.tm_wday);
- if(val < 0)
- return 5;
- return val;
+ const int val = get_week_number(tm_.tm_mday, tm_.tm_wday);
+ return (val < 0) ? 5 : val;
}
- }
- break;
+ } // LCOV_EXCL_LINE
+ throw std::invalid_argument("Invalid abstract_calendar::value_type"); // LCOV_EXCL_LINE
case day_of_week_in_month: ///< Original number of the day of the week in month.
switch(v) {
case absolute_minimum:
@@ -465,10 +461,10 @@ namespace boost { namespace locale { namespace util {
return 5;
case current: return (tm_.tm_mday - 1) / 7 + 1;
}
- break;
- case invalid: BOOST_ASSERT_MSG(false, "Shouldn't use 'invalid' value."); break;
+ throw std::invalid_argument("Invalid abstract_calendar::value_type"); // LCOV_EXCL_LINE
+ case invalid: BOOST_LOCALE_CASE_INVALID(break); // LCOV_EXCL_LINE
}
- return 0;
+ throw std::invalid_argument("Invalid period_mark"); // LCOV_EXCL_LINE
}
/// Set current time point
@@ -493,6 +489,7 @@ namespace boost { namespace locale { namespace util {
case is_gregorian: throw date_time_error("is_gregorian is not settable options for calendar");
case is_dst: throw date_time_error("is_dst is not settable options for calendar");
}
+ throw std::invalid_argument("Invalid option type"); // LCOV_EXCL_LINE
}
/// Get option for calendar, currently only check if it is Gregorian calendar
int get_option(calendar_option_type opt) const override
@@ -501,69 +498,66 @@ namespace boost { namespace locale { namespace util {
case is_gregorian: return 1;
case is_dst: return tm_.tm_isdst == 1;
}
- return 0;
+ throw std::invalid_argument("Invalid option type"); // LCOV_EXCL_LINE
}
/// Adjust period's \a p value by \a difference items using a update_type \a u.
/// Note: not all values are adjustable
void adjust_value(period::marks::period_mark m, update_type u, int difference) override
{
- switch(u) {
- case move: {
- using namespace period::marks;
- switch(m) {
- case year: ///< Year, it is calendar specific
- case extended_year: ///< Extended year for Gregorian/Julian calendars, where 1 BC == 0, 2 BC ==
- ///< -1.
- tm_updated_.tm_year += difference;
- break;
- case month: tm_updated_.tm_mon += difference; break;
- case day:
- case day_of_year:
- case day_of_week: ///< Day of week, starting from Sunday, [1..7]
- case day_of_week_local: ///< Local day of week, for example in France Monday is 1, in US Sunday
- ///< is 1, [1..7]
- tm_updated_.tm_mday += difference;
- break;
- case hour: ///< 24 clock hour [0..23]
- case hour_12: ///< 12 clock hour [0..11]
- tm_updated_.tm_hour += difference;
- break;
- case am_pm: ///< am or pm marker, [0..1]
- tm_updated_.tm_hour += 12 * difference;
- break;
- case minute: ///< minute [0..59]
- tm_updated_.tm_min += difference;
- break;
- case second: tm_updated_.tm_sec += difference; break;
- case week_of_year: ///< The week number in the year
- case week_of_month: ///< The week number within current month
- case day_of_week_in_month: ///< Original number of the day of the week in month.
- tm_updated_.tm_mday += difference * 7;
- break;
- case era:
- case period::marks::first_day_of_week:
- case invalid: break; // Not adjustable and ignored
- }
- normalized_ = false;
- normalize();
- } break;
- case roll: {
- const int cur_min = get_value(m, actual_minimum);
- const int cur_max = get_value(m, actual_maximum);
- BOOST_ASSERT(cur_max >= cur_min);
- const int range = cur_max - cur_min + 1;
- int value = get_value(m, current) - cur_min;
- BOOST_ASSERT(value >= 0 && value < range);
- BOOST_ASSERT_MSG(difference <= std::numeric_limits<int>::max(), "Input is to large");
- value = (value + difference) % range;
- // If the sum above was negative the result of the modulo operation "can" be negative too.
- if(value < 0)
- value += range;
- BOOST_ASSERT(value >= 0 && value < range);
- set_value(m, value + cur_min);
- normalize();
+ if(u == move) {
+ using namespace period::marks;
+ switch(m) {
+ case year: ///< Year, it is calendar specific
+ case extended_year: ///< Extended year for Gregorian/Julian calendars, where 1 BC == 0, 2 BC == -1
+ tm_updated_.tm_year += difference;
+ break;
+ case month: tm_updated_.tm_mon += difference; break;
+ case day:
+ case day_of_year:
+ case day_of_week: ///< starting from Sunday, [1..7]
+ case day_of_week_local: ///< Local DoW, e.g. in France Monday=1, in US Sunday=1, [1..7]
+ tm_updated_.tm_mday += difference;
+ break;
+ case hour: ///< 24 clock hour [0..23]
+ case hour_12: ///< 12 clock hour [0..11]
+ tm_updated_.tm_hour += difference;
+ break;
+ case am_pm: ///< am or pm marker, [0..1]
+ tm_updated_.tm_hour += 12 * difference;
+ break;
+ case minute: ///< minute [0..59]
+ tm_updated_.tm_min += difference;
+ break;
+ case second: tm_updated_.tm_sec += difference; break;
+ case week_of_year: ///< The week number in the year
+ case week_of_month: ///< The week number within current month
+ case day_of_week_in_month: ///< Original number of the day of the week in month.
+ tm_updated_.tm_mday += difference * 7;
+ break;
+ case era: throw std::invalid_argument("era not adjustable"); // LCOV_EXCL_LINE
+ case period::marks::first_day_of_week: // LCOV_EXCL_LINE
+ throw std::invalid_argument("Can't change first day of week"); // LCOV_EXCL_LINE
+ case invalid: BOOST_LOCALE_CASE_INVALID(return ); // LCOV_EXCL_LINE
}
+ normalized_ = false;
+ normalize();
+ } else {
+ BOOST_ASSERT(u == roll);
+ const int cur_min = get_value(m, actual_minimum);
+ const int cur_max = get_value(m, actual_maximum);
+ BOOST_ASSERT(cur_max >= cur_min);
+ const int range = cur_max - cur_min + 1;
+ int value = get_value(m, current) - cur_min;
+ BOOST_ASSERT(value >= 0 && value < range);
+ BOOST_ASSERT_MSG(difference <= std::numeric_limits<int>::max(), "Input is to large");
+ value = (value + difference) % range;
+ // If the sum above was negative the result of the modulo operation "can" be negative too.
+ if(value < 0)
+ value += range;
+ BOOST_ASSERT(value >= 0 && value < range);
+ set_value(m, value + cur_min);
+ normalize();
}
}
@@ -619,9 +613,8 @@ namespace boost { namespace locale { namespace util {
case day_of_week:
case day_of_week_local: {
int diff = other->tm_.tm_yday - tm_.tm_yday;
- if(other->tm_.tm_year != tm_.tm_year) {
+ if(other->tm_.tm_year != tm_.tm_year)
diff += days_from_0(other->tm_.tm_year + 1900) - days_from_0(tm_.tm_year + 1900);
- }
return get_diff(period::marks::day, diff, other) / factor;
}
case am_pm: return static_cast<int>((other->time_ - time_) / (3600 * 12));
@@ -629,10 +622,12 @@ namespace boost { namespace locale { namespace util {
case hour_12: return static_cast<int>((other->time_ - time_) / 3600);
case minute: return static_cast<int>((other->time_ - time_) / 60);
case second: return static_cast<int>(other->time_ - time_);
- case invalid:
- case period::marks::first_day_of_week: break; // Not adjustable
+ case invalid: // LCOV_EXCL_LINE
+ BOOST_LOCALE_CASE_INVALID(return 0); // LCOV_EXCL_LINE
+ // Not adjustable
+ case period::marks::first_day_of_week: return 0; // LCOV_EXCL_LINE
}
- return 0;
+ throw std::invalid_argument("Invalid period_mark"); // LCOV_EXCL_LINE
}
/// Set time zone, empty - use system
@@ -666,7 +661,7 @@ namespace boost { namespace locale { namespace util {
void from_time(std::time_t point)
{
std::time_t real_point = point + tzoff_;
- std::tm* t = 0;
+ std::tm* t;
#ifdef BOOST_WINDOWS
// Windows uses TLS, thread safe
t = is_local_ ? localtime(&real_point) : gmtime(&real_point);
@@ -674,9 +669,8 @@ namespace boost { namespace locale { namespace util {
std::tm tmp_tm;
t = is_local_ ? localtime_r(&real_point, &tmp_tm) : gmtime_r(&real_point, &tmp_tm);
#endif
- if(!t) {
+ if(!t)
throw date_time_error("boost::locale::gregorian_calendar: invalid time point");
- }
tm_ = *t;
tm_updated_ = *t;
normalized_ = true;
diff --git a/contrib/restricted/boost/locale/src/boost/locale/util/iconv.hpp b/contrib/restricted/boost/locale/src/boost/locale/util/iconv.hpp
index 25701f7eca..ed8157ba97 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/util/iconv.hpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/util/iconv.hpp
@@ -20,8 +20,12 @@ namespace boost { namespace locale {
}
public:
- iconv_handle(iconv_t h = iconv_t(-1)) : h_(h) {}
+ explicit iconv_handle(iconv_t h = iconv_t(-1)) : h_(h) {}
+
+ iconv_handle(const iconv_handle& rhs) = delete;
iconv_handle(iconv_handle&& rhs) noexcept : h_(exchange(rhs.h_, iconv_t(-1))) {}
+
+ iconv_handle& operator=(const iconv_handle& rhs) = delete;
iconv_handle& operator=(iconv_handle&& rhs) noexcept
{
h_ = exchange(rhs.h_, iconv_t(-1));
diff --git a/contrib/restricted/boost/locale/src/boost/locale/util/locale_data.cpp b/contrib/restricted/boost/locale/src/boost/locale/util/locale_data.cpp
index 113d27fffc..f95d28a580 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/util/locale_data.cpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/util/locale_data.cpp
@@ -6,7 +6,6 @@
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/locale/util/locale_data.hpp>
-#include "boost/locale/encoding/conv.hpp"
#include "boost/locale/util/encoding.hpp"
#include "boost/locale/util/string.hpp"
#include <boost/assert.hpp>
@@ -126,14 +125,7 @@ namespace boost { namespace locale { namespace util {
if(tmp.empty())
return false;
// No assumptions, but uppercase
- for(char& c : tmp) {
- if(util::is_lower_ascii(c))
- c += 'A' - 'a';
- }
- encoding_ = tmp;
-
- utf8_ = util::normalize_encoding(encoding_) == "utf8";
-
+ encoding(std::move(tmp));
if(end >= input.size())
return true;
else {
@@ -157,4 +149,17 @@ namespace boost { namespace locale { namespace util {
return true;
}
+ locale_data& locale_data::encoding(std::string new_encoding, const bool uppercase)
+ {
+ if(uppercase) {
+ for(char& c : new_encoding) {
+ if(util::is_lower_ascii(c))
+ c += 'A' - 'a';
+ }
+ }
+ encoding_ = std::move(new_encoding);
+ utf8_ = util::normalize_encoding(encoding_) == "utf8";
+ return *this;
+ }
+
}}} // namespace boost::locale::util
diff --git a/contrib/restricted/boost/locale/src/boost/locale/util/make_std_unique.hpp b/contrib/restricted/boost/locale/src/boost/locale/util/make_std_unique.hpp
new file mode 100644
index 0000000000..d7492adc03
--- /dev/null
+++ b/contrib/restricted/boost/locale/src/boost/locale/util/make_std_unique.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_MAKE_STD_UNIQUE_HPP
+#define BOOST_LOCALE_MAKE_STD_UNIQUE_HPP
+
+#include <boost/locale/config.hpp>
+#include <memory>
+#include <type_traits>
+#include <utility>
+
+namespace boost { namespace locale {
+ template<class T, class... Args>
+ std::unique_ptr<T> make_std_unique(Args&&... args)
+ {
+ static_assert(!std::is_array<T>::value, "Must not be an array");
+ return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
+ }
+}} // namespace boost::locale
+
+#endif
diff --git a/contrib/restricted/boost/locale/src/boost/locale/util/numeric.hpp b/contrib/restricted/boost/locale/src/boost/locale/util/numeric.hpp
index 5b4393d694..146309e357 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/util/numeric.hpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/util/numeric.hpp
@@ -9,18 +9,36 @@
#include <boost/locale/formatting.hpp>
#include <boost/locale/info.hpp>
#include <boost/predef/os.h>
+#include <algorithm>
+#include <cerrno>
#include <cstdlib>
#include <ctime>
#include <ios>
+#include <limits>
#include <locale>
#include <sstream>
#include <string>
#include <vector>
-#include "boost/locale/util/timezone.hpp"
+#include "timezone.hpp"
namespace boost { namespace locale { namespace util {
+ inline bool try_to_int(const std::string& s, int& res)
+ {
+ if(s.empty())
+ return false;
+ errno = 0;
+ char* end_char{};
+ const auto v = std::strtol(s.c_str(), &end_char, 10);
+ if(errno == ERANGE || end_char != s.c_str() + s.size())
+ return false;
+ if(v < std::numeric_limits<int>::min() || v > std::numeric_limits<int>::max())
+ return false;
+ res = v;
+ return true;
+ }
+
template<typename CharType>
struct formatting_size_traits {
static size_t size(const std::basic_string<CharType>& s, const std::locale& /*l*/) { return s.size(); }
@@ -35,16 +53,10 @@ namespace boost { namespace locale { namespace util {
if(!std::use_facet<info>(l).utf8())
return s.size();
// count code points, poor man's text size
- size_t res = 0;
- for(size_t i = 0; i < s.size(); i++) {
- unsigned char c = s[i];
- if(c <= 127)
- res++;
- else if((c & 0xC0) == 0xC0) { // first UTF-8 byte
- res++;
- }
- }
- return res;
+ return std::count_if(s.begin(), s.end(), [](const unsigned char c) {
+ return (c <= 127) // ASCII
+ || ((c & 0xC0) == 0xC0); // first UTF-8 byte
+ });
}
};
@@ -53,48 +65,47 @@ namespace boost { namespace locale { namespace util {
public:
typedef typename std::num_put<CharType>::iter_type iter_type;
typedef std::basic_string<CharType> string_type;
- typedef CharType char_type;
base_num_format(size_t refs = 0) : std::num_put<CharType>(refs) {}
protected:
- iter_type do_put(iter_type out, std::ios_base& ios, char_type fill, long val) const override
+ iter_type do_put(iter_type out, std::ios_base& ios, CharType fill, long val) const override
{
return do_real_put(out, ios, fill, val);
}
- iter_type do_put(iter_type out, std::ios_base& ios, char_type fill, unsigned long val) const override
+ iter_type do_put(iter_type out, std::ios_base& ios, CharType fill, unsigned long val) const override
{
return do_real_put(out, ios, fill, val);
}
- iter_type do_put(iter_type out, std::ios_base& ios, char_type fill, double val) const override
+ iter_type do_put(iter_type out, std::ios_base& ios, CharType fill, double val) const override
{
return do_real_put(out, ios, fill, val);
}
- iter_type do_put(iter_type out, std::ios_base& ios, char_type fill, long double val) const override
+ iter_type do_put(iter_type out, std::ios_base& ios, CharType fill, long double val) const override
{
return do_real_put(out, ios, fill, val);
}
- iter_type do_put(iter_type out, std::ios_base& ios, char_type fill, long long val) const override
+ iter_type do_put(iter_type out, std::ios_base& ios, CharType fill, long long val) const override
{
return do_real_put(out, ios, fill, val);
}
- iter_type do_put(iter_type out, std::ios_base& ios, char_type fill, unsigned long long val) const override
+ iter_type do_put(iter_type out, std::ios_base& ios, CharType fill, unsigned long long val) const override
{
return do_real_put(out, ios, fill, val);
}
private:
template<typename ValueType>
- iter_type do_real_put(iter_type out, std::ios_base& ios, char_type fill, ValueType val) const
+ iter_type do_real_put(iter_type out, std::ios_base& ios, CharType fill, ValueType val) const
{
- typedef std::num_put<char_type> super;
+ typedef std::num_put<CharType> super;
ios_info& info = ios_info::get(ios);
switch(info.display_flags()) {
case flags::posix: {
- typedef std::basic_ostringstream<char_type> sstream_type;
+ typedef std::basic_ostringstream<CharType> sstream_type;
sstream_type ss;
ss.imbue(std::locale::classic());
ss.flags(ios.flags());
@@ -112,7 +123,7 @@ namespace boost { namespace locale { namespace util {
ios,
fill,
static_cast<std::time_t>(val),
- info.date_time_pattern<char_type>());
+ info.date_time_pattern<CharType>());
case flags::currency: {
bool nat = info.currency_flags() == flags::currency_default
|| info.currency_flags() == flags::currency_national;
@@ -129,7 +140,7 @@ namespace boost { namespace locale { namespace util {
}
virtual iter_type
- do_format_currency(bool intl, iter_type out, std::ios_base& ios, char_type fill, long double val) const
+ do_format_currency(bool intl, iter_type out, std::ios_base& ios, CharType fill, long double val) const
{
if(intl)
return format_currency<true>(out, ios, fill, val);
@@ -138,34 +149,31 @@ namespace boost { namespace locale { namespace util {
}
template<bool intl>
- iter_type format_currency(iter_type out, std::ios_base& ios, char_type fill, long double val) const
+ iter_type format_currency(iter_type out, std::ios_base& ios, CharType fill, long double val) const
{
std::locale loc = ios.getloc();
- int digits = std::use_facet<std::moneypunct<char_type, intl>>(loc).frac_digits();
+ int digits = std::use_facet<std::moneypunct<CharType, intl>>(loc).frac_digits();
while(digits > 0) {
val *= 10;
digits--;
}
std::ios_base::fmtflags f = ios.flags();
ios.flags(f | std::ios_base::showbase);
- out = std::use_facet<std::money_put<char_type>>(loc).put(out, intl, ios, fill, val);
+ out = std::use_facet<std::money_put<CharType>>(loc).put(out, intl, ios, fill, val);
ios.flags(f);
return out;
}
- iter_type format_time(iter_type out, std::ios_base& ios, char_type fill, std::time_t time, char c) const
+ iter_type format_time(iter_type out, std::ios_base& ios, CharType fill, std::time_t time, char c) const
{
string_type fmt;
- fmt += char_type('%');
- fmt += char_type(c);
+ fmt += CharType('%');
+ fmt += CharType(c);
return format_time(out, ios, fill, time, fmt);
}
- iter_type format_time(iter_type out,
- std::ios_base& ios,
- char_type fill,
- std::time_t time,
- const string_type& format) const
+ iter_type
+ format_time(iter_type out, std::ios_base& ios, CharType fill, std::time_t time, const string_type& format) const
{
std::string tz = ios_info::get(ios).time_zone();
std::tm tm;
@@ -174,7 +182,7 @@ namespace boost { namespace locale { namespace util {
#endif
if(tz.empty()) {
#ifdef BOOST_WINDOWS
- /// Windows uses TLS
+ // Windows uses TLS
tm = *localtime(&time);
#else
localtime_r(&time, &tm);
@@ -183,7 +191,7 @@ namespace boost { namespace locale { namespace util {
int gmtoff = parse_tz(tz);
time += gmtoff;
#ifdef BOOST_WINDOWS
- /// Windows uses TLS
+ // Windows uses TLS
tm = *gmtime(&time);
#else
gmtime_r(&time, &tm);
@@ -193,17 +201,17 @@ namespace boost { namespace locale { namespace util {
// These have extra fields to specify timezone
if(gmtoff != 0) {
// bsd and apple want tm_zone be non-const
- tm.tm_zone = &tmp_buf.front();
+ tm.tm_zone = tmp_buf.data();
tm.tm_gmtoff = gmtoff;
}
#endif
}
- std::basic_ostringstream<char_type> tmp_out;
- std::use_facet<std::time_put<char_type>>(ios.getloc())
+ std::basic_ostringstream<CharType> tmp_out;
+ std::use_facet<std::time_put<CharType>>(ios.getloc())
.put(tmp_out, tmp_out, fill, &tm, format.c_str(), format.c_str() + format.size());
string_type str = tmp_out.str();
std::streamsize on_left = 0, on_right = 0;
- std::streamsize points = formatting_size_traits<char_type>::size(str, ios.getloc());
+ std::streamsize points = formatting_size_traits<CharType>::size(str, ios.getloc());
if(points < ios.width()) {
std::streamsize n = ios.width() - points;
@@ -228,7 +236,7 @@ namespace boost { namespace locale { namespace util {
return out;
}
- }; /// num_format
+ }; // num_format
template<typename CharType>
class base_num_parse : public std::num_get<CharType> {
@@ -238,7 +246,6 @@ namespace boost { namespace locale { namespace util {
protected:
typedef typename std::num_get<CharType>::iter_type iter_type;
typedef std::basic_string<CharType> string_type;
- typedef CharType char_type;
iter_type
do_get(iter_type in, iter_type end, std::ios_base& ios, std::ios_base::iostate& err, long& val) const override
@@ -317,7 +324,7 @@ namespace boost { namespace locale { namespace util {
iter_type
do_real_get(iter_type in, iter_type end, std::ios_base& ios, std::ios_base::iostate& err, ValueType& val) const
{
- typedef std::num_get<char_type> super;
+ typedef std::num_get<CharType> super;
ios_info& info = ios_info::get(ios);
@@ -364,9 +371,9 @@ namespace boost { namespace locale { namespace util {
long double& val) const
{
std::locale loc = ios.getloc();
- int digits = std::use_facet<std::moneypunct<char_type, intl>>(loc).frac_digits();
+ int digits = std::use_facet<std::moneypunct<CharType, intl>>(loc).frac_digits();
long double rval;
- in = std::use_facet<std::money_get<char_type>>(loc).get(in, end, intl, ios, err, rval);
+ in = std::use_facet<std::money_get<CharType>>(loc).get(in, end, intl, ios, err, rval);
if(!(err & std::ios::failbit)) {
while(digits > 0) {
rval /= 10;
diff --git a/contrib/restricted/boost/locale/src/boost/locale/util/timezone.hpp b/contrib/restricted/boost/locale/src/boost/locale/util/timezone.hpp
index 684379d87b..617f40a977 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/util/timezone.hpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/util/timezone.hpp
@@ -6,6 +6,7 @@
#ifndef BOOST_LOCALE_IMPL_UTIL_TIMEZONE_HPP
#define BOOST_LOCALE_IMPL_UTIL_TIMEZONE_HPP
+#include <boost/locale/util/string.hpp>
#include <cstdlib>
#include <cstring>
#include <string>
@@ -13,26 +14,23 @@
namespace boost { namespace locale { namespace util {
inline int parse_tz(const std::string& tz)
{
- int gmtoff = 0;
std::string ltz;
- for(unsigned i = 0; i < tz.size(); i++) {
- if('a' <= tz[i] && tz[i] <= 'z')
- ltz += tz[i] - 'a' + 'A';
- else if(tz[i] == ' ')
- ;
- else
- ltz += tz[i];
+ for(const char c : tz) {
+ if(is_lower_ascii(c))
+ ltz += c - 'a' + 'A';
+ else if(c != ' ')
+ ltz += c;
}
if(ltz.compare(0, 3, "GMT") != 0 && ltz.compare(0, 3, "UTC") != 0)
return 0;
if(ltz.size() <= 3)
return 0;
+ int gmtoff = 0;
const char* begin = ltz.c_str() + 3;
- char* end = 0;
+ char* end = const_cast<char*>(begin);
int hours = strtol(begin, &end, 10);
- if(end != begin) {
+ if(end != begin)
gmtoff += hours * 3600;
- }
if(*end == ':') {
begin = end + 1;
int minutes = strtol(begin, &end, 10);
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 a02d347779..aeda7ae602 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/win32/api.hpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/win32/api.hpp
@@ -95,18 +95,17 @@ namespace boost { namespace locale { namespace impl_win {
for(unsigned i = 0; gr[i]; i++) {
if(gr[i] == L';')
continue;
- if(L'1' <= gr[i] && gr[i] <= L'9') {
+ if(L'1' <= gr[i] && gr[i] <= L'9')
res.grouping += char(gr[i] - L'0');
- } else if(gr[i] == L'0')
+ else if(gr[i] == L'0')
inf_group = true;
}
if(!inf_group) {
BOOST_LOCALE_START_CONST_CONDITION
- if(std::numeric_limits<char>::is_signed) {
+ if(std::numeric_limits<char>::is_signed)
res.grouping += std::numeric_limits<char>::min();
- } else {
+ else
res.grouping += std::numeric_limits<char>::max();
- }
BOOST_LOCALE_END_CONST_CONDITION
}
return res;
@@ -124,8 +123,8 @@ namespace boost { namespace locale { namespace impl_win {
throw std::length_error("String to long for int type");
std::vector<wchar_t> buf(len + 1);
int l2 =
- LCMapStringW(l.lcid, flags, begin, static_cast<int>(end - begin), &buf.front(), static_cast<int>(buf.size()));
- res.assign(&buf.front(), l2);
+ LCMapStringW(l.lcid, flags, begin, static_cast<int>(end - begin), buf.data(), static_cast<int>(buf.size()));
+ res.assign(buf.data(), l2);
return res;
}
@@ -166,10 +165,10 @@ namespace boost { namespace locale { namespace impl_win {
ss << std::setprecision(std::numeric_limits<double>::digits10 + 1) << value;
std::wstring sval = ss.str();
- int len = GetCurrencyFormatW(l.lcid, 0, sval.c_str(), 0, 0, 0);
+ const auto len = GetCurrencyFormatW(l.lcid, 0, sval.c_str(), nullptr, nullptr, 0);
std::vector<wchar_t> buf(len + 1);
- GetCurrencyFormatW(l.lcid, 0, sval.c_str(), 0, &buf.front(), len);
- return &buf.front();
+ GetCurrencyFormatW(l.lcid, 0, sval.c_str(), nullptr, buf.data(), len);
+ return buf.data();
}
////////////////////////////////////////////////////////////////////////
@@ -180,18 +179,18 @@ namespace boost { namespace locale { namespace impl_win {
inline std::wstring wcs_format_date_l(const wchar_t* format, SYSTEMTIME const* tm, const winlocale& l)
{
- int len = GetDateFormatW(l.lcid, 0, tm, format, 0, 0);
+ const auto len = GetDateFormatW(l.lcid, 0, tm, format, nullptr, 0);
std::vector<wchar_t> buf(len + 1);
- GetDateFormatW(l.lcid, 0, tm, format, &buf.front(), len);
- return &buf.front();
+ GetDateFormatW(l.lcid, 0, tm, format, buf.data(), len);
+ return buf.data();
}
inline std::wstring wcs_format_time_l(const wchar_t* format, SYSTEMTIME const* tm, const winlocale& l)
{
- int len = GetTimeFormatW(l.lcid, 0, tm, format, 0, 0);
+ const auto len = GetTimeFormatW(l.lcid, 0, tm, format, nullptr, 0);
std::vector<wchar_t> buf(len + 1);
- GetTimeFormatW(l.lcid, 0, tm, format, &buf.front(), len);
- return &buf.front();
+ GetTimeFormatW(l.lcid, 0, tm, format, buf.data(), len);
+ return buf.data();
}
inline std::wstring wcsfold(const wchar_t* begin, const wchar_t* end)
@@ -221,8 +220,8 @@ namespace boost { namespace locale { namespace impl_win {
if(len == std::numeric_limits<int>::max())
throw std::length_error("String to long for int type");
std::vector<wchar_t> v(len + 1);
- len = FoldStringW(flags, begin, static_cast<int>(end - begin), &v.front(), len + 1);
- return std::wstring(&v.front(), len);
+ len = FoldStringW(flags, begin, static_cast<int>(end - begin), v.data(), len + 1);
+ return std::wstring(v.data(), len);
}
inline std::wstring wcsxfrm_l(collate_level level, 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 bd78c2116d..465676e437 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/win32/collate.cpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/win32/collate.cpp
@@ -20,32 +20,32 @@ namespace boost { namespace locale { namespace impl_win {
int
do_compare(collate_level level, const char* lb, const char* le, const char* rb, const char* re) const override
{
- std::wstring l = conv::to_utf<wchar_t>(lb, le, "UTF-8");
- std::wstring r = conv::to_utf<wchar_t>(rb, re, "UTF-8");
+ 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_);
}
long do_hash(collate_level level, const char* b, const char* e) const override
{
- std::string key = do_transform(level, b, e);
+ const std::string key = do_transform(level, b, e);
return gnu_gettext::pj_winberger_hash_function(key.c_str(), key.c_str() + key.size());
}
std::string do_transform(collate_level level, const char* b, const char* e) const override
{
- std::wstring tmp = conv::to_utf<wchar_t>(b, e, "UTF-8");
- std::wstring wkey = wcsxfrm_l(level, tmp.c_str(), tmp.c_str() + tmp.size(), lc_);
+ 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;
BOOST_LOCALE_START_CONST_CONDITION
if(sizeof(wchar_t) == 2)
key.reserve(wkey.size() * 2);
else
key.reserve(wkey.size() * 3);
- for(unsigned i = 0; i < wkey.size(); i++) {
+ for(const wchar_t c : wkey) {
if(sizeof(wchar_t) == 2) {
- uint16_t tv = static_cast<uint16_t>(wkey[i]);
+ const uint16_t tv = static_cast<uint16_t>(c);
key += char(tv >> 8);
key += char(tv & 0xFF);
} else { // 4
- uint32_t tv = static_cast<uint32_t>(wkey[i]);
+ const uint32_t tv = static_cast<uint32_t>(c);
// 21 bit
key += char((tv >> 16) & 0xFF);
key += char((tv >> 8) & 0xFF);
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 6911ab5996..ab0af493e4 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/win32/converter.cpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/win32/converter.cpp
@@ -43,7 +43,7 @@ namespace boost { namespace locale { namespace impl_win {
std::string
convert(converter_base::conversion_type how, const char* begin, const char* end, int flags = 0) const override
{
- std::wstring tmp = conv::to_utf<wchar_t>(begin, end, "UTF-8");
+ 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();
@@ -56,7 +56,7 @@ namespace boost { namespace locale { namespace impl_win {
case normalization: res = wcsnormalize(static_cast<norm_type>(flags), wb, we); break;
case title_case: break;
}
- return conv::from_utf(res, "UTF-8");
+ return conv::utf_to_utf<char>(res);
}
private:
diff --git a/contrib/restricted/boost/locale/src/boost/locale/win32/lcid.cpp b/contrib/restricted/boost/locale/src/boost/locale/win32/lcid.cpp
index f27cd099e5..1435455775 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/win32/lcid.cpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/win32/lcid.cpp
@@ -46,9 +46,8 @@ namespace boost { namespace locale { namespace impl_win {
unsigned lcid;
ss >> lcid;
- if(ss.fail() || !ss.eof()) {
+ if(ss.fail() || !ss.eof())
return FALSE;
- }
char iso_639_lang[16];
char iso_3166_country[16];
@@ -59,13 +58,12 @@ namespace boost { namespace locale { namespace impl_win {
lc_name += "_";
lc_name += iso_3166_country;
}
- table_type::iterator p = tbl.find(lc_name);
+ const auto p = tbl.find(lc_name);
if(p != tbl.end()) {
if(p->second > lcid)
p->second = lcid;
- } else {
+ } else
tbl[lc_name] = lcid;
- }
} catch(...) {
tbl.clear();
return FALSE;
@@ -89,27 +87,20 @@ namespace boost { namespace locale { namespace impl_win {
unsigned locale_to_lcid(const std::string& locale_name)
{
- if(locale_name.empty()) {
+ if(locale_name.empty())
return LOCALE_USER_DEFAULT;
- }
boost::locale::util::locale_data d;
d.parse(locale_name);
std::string id = d.language();
- if(!d.country().empty()) {
+ if(!d.country().empty())
id += "_" + d.country();
- }
- if(!d.variant().empty()) {
+ if(!d.variant().empty())
id += "@" + d.variant();
- }
const table_type& tbl = get_ready_lcid_table();
- table_type::const_iterator p = tbl.find(id);
-
- unsigned lcid = 0;
- if(p != tbl.end())
- lcid = p->second;
- return lcid;
+ const auto p = tbl.find(id);
+ return (p != tbl.end()) ? p->second : 0;
}
}}} // namespace boost::locale::impl_win
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 2654be7ed4..edbb663e78 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/win32/numeric.cpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/win32/numeric.cpp
@@ -10,6 +10,7 @@
#include <boost/locale/generator.hpp>
#include "boost/locale/win32/all_generator.hpp"
#include "boost/locale/win32/api.hpp"
+#include <algorithm>
#include <cctype>
#include <cstdlib>
#include <cstring>
@@ -22,20 +23,15 @@
namespace boost { namespace locale { namespace impl_win {
namespace {
-
std::ostreambuf_iterator<wchar_t> write_it(std::ostreambuf_iterator<wchar_t> out, const std::wstring& s)
{
- for(size_t i = 0; i < s.size(); i++)
- *out++ = s[i];
- return out;
+ return std::copy(s.begin(), s.end(), out);
}
std::ostreambuf_iterator<char> write_it(std::ostreambuf_iterator<char> out, const std::wstring& s)
{
- std::string tmp = conv::from_utf(s, "UTF-8");
- for(size_t i = 0; i < tmp.size(); i++)
- *out++ = tmp[i];
- return out;
+ const std::string tmp = conv::utf_to_utf<char>(s);
+ return std::copy(tmp.begin(), tmp.end(), out);
}
} // namespace
@@ -44,7 +40,6 @@ namespace boost { namespace locale { namespace impl_win {
public:
typedef typename std::num_put<CharType>::iter_type iter_type;
typedef std::basic_string<CharType> string_type;
- typedef CharType char_type;
num_format(const winlocale& lc, size_t refs = 0) : util::base_num_format<CharType>(refs), lc_(lc) {}
@@ -52,19 +47,19 @@ namespace boost { namespace locale { namespace impl_win {
iter_type do_format_currency(bool /*intl*/,
iter_type out,
std::ios_base& ios,
- char_type fill,
+ CharType fill,
long double val) const override
{
if(lc_.is_c()) {
std::locale loc = ios.getloc();
- int digits = std::use_facet<std::moneypunct<char_type>>(loc).frac_digits();
+ int digits = std::use_facet<std::moneypunct<CharType>>(loc).frac_digits();
while(digits > 0) {
val *= 10;
digits--;
}
std::ios_base::fmtflags f = ios.flags();
ios.flags(f | std::ios_base::showbase);
- out = std::use_facet<std::money_put<char_type>>(loc).put(out, false, ios, fill, val);
+ out = std::use_facet<std::money_put<CharType>>(loc).put(out, false, ios, fill, val);
ios.flags(f);
return out;
} else {
@@ -76,7 +71,7 @@ namespace boost { namespace locale { namespace impl_win {
private:
winlocale lc_;
- }; /// num_format
+ }; // num_format
template<typename CharType>
class time_put_win : public std::time_put<CharType> {
@@ -84,8 +79,7 @@ namespace boost { namespace locale { namespace impl_win {
time_put_win(const winlocale& lc, size_t refs = 0) : std::time_put<CharType>(refs), lc_(lc) {}
typedef typename std::time_put<CharType>::iter_type iter_type;
- typedef CharType char_type;
- typedef std::basic_string<char_type> string_type;
+ typedef std::basic_string<CharType> string_type;
iter_type do_put(iter_type out,
std::ios_base& /*ios*/,
@@ -125,7 +119,7 @@ namespace boost { namespace locale { namespace impl_win {
void to_str(std::wstring& s1, std::wstring& s2) { s2.swap(s1); }
- void to_str(std::wstring& s1, std::string& s2) { s2 = conv::from_utf(s1, "UTF-8"); }
+ void to_str(std::wstring& s1, std::string& s2) { s2 = conv::utf_to_utf<char>(s1); }
CharType do_decimal_point() const override { return *decimal_point_.c_str(); }
CharType do_thousands_sep() const override { return *thousands_sep_.c_str(); }
std::string do_grouping() const override { return grouping_; }
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 c1a8107423..aa694648d8 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
@@ -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
@@ -11,6 +12,7 @@
#include <boost/locale/util.hpp>
#include <boost/locale/util/locale_data.hpp>
#include "boost/locale/util/gregorian.hpp"
+#include "boost/locale/util/make_std_unique.hpp"
#include "boost/locale/win32/all_generator.hpp"
#include "boost/locale/win32/api.hpp"
#include <algorithm>
@@ -51,19 +53,16 @@ namespace boost { namespace locale { namespace impl_win {
if(!invalid_)
return;
invalid_ = false;
- if(locale_id_.empty()) {
+ if(locale_id_.empty())
real_id_ = util::get_system_locale(true); // always UTF-8
- lc_ = winlocale(real_id_);
- } else {
- lc_ = winlocale(locale_id_);
+ else
real_id_ = locale_id_;
- }
util::locale_data d;
d.parse(real_id_);
- if(!d.is_utf8()) {
- lc_ = winlocale();
- // Make it C as non-UTF8 locales are not supported
- }
+ if(!d.is_utf8())
+ lc_ = winlocale(); // Make it C as non-UTF8 locales are not supported
+ else
+ lc_ = winlocale(real_id_);
}
std::locale install(const std::locale& base, category_t category, char_facet_t type) override
@@ -126,9 +125,9 @@ namespace boost { namespace locale { namespace impl_win {
winlocale lc_;
};
- localization_backend* create_localization_backend()
+ std::unique_ptr<localization_backend> create_localization_backend()
{
- return new winapi_localization_backend();
+ return make_std_unique<winapi_localization_backend>();
}
}}} // namespace boost::locale::impl_win
diff --git a/contrib/restricted/boost/locale/src/boost/locale/win32/win_backend.hpp b/contrib/restricted/boost/locale/src/boost/locale/win32/win_backend.hpp
index 57fa5c2919..8980535e74 100644
--- a/contrib/restricted/boost/locale/src/boost/locale/win32/win_backend.hpp
+++ b/contrib/restricted/boost/locale/src/boost/locale/win32/win_backend.hpp
@@ -6,10 +6,14 @@
#ifndef BOOST_LOCALE_IMPL_WIN32_LOCALIZATION_BACKEND_HPP
#define BOOST_LOCALE_IMPL_WIN32_LOCALIZATION_BACKEND_HPP
+
+#include <boost/locale/config.hpp>
+#include <memory>
+
namespace boost { namespace locale {
class localization_backend;
namespace impl_win {
- localization_backend* create_localization_backend();
+ std::unique_ptr<localization_backend> create_localization_backend();
} // namespace impl_win
}} // namespace boost::locale
#endif
diff --git a/contrib/restricted/boost/locale/ya.make b/contrib/restricted/boost/locale/ya.make
index 1e440342d3..4243abc00d 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.82.0)
+VERSION(1.83.0)
-ORIGINAL_SOURCE(https://github.com/boostorg/locale/archive/boost-1.82.0.tar.gz)
+ORIGINAL_SOURCE(https://github.com/boostorg/locale/archive/boost-1.83.0.tar.gz)
PEERDIR(
contrib/libs/icu
@@ -18,6 +18,7 @@ PEERDIR(
contrib/restricted/boost/iterator
contrib/restricted/boost/predef
contrib/restricted/boost/thread
+ contrib/restricted/boost/utility
)
ADDINCL(
diff --git a/contrib/restricted/boost/utility/include/boost/utility/string_view.hpp b/contrib/restricted/boost/utility/include/boost/utility/string_view.hpp
new file mode 100644
index 0000000000..3d195b6e87
--- /dev/null
+++ b/contrib/restricted/boost/utility/include/boost/utility/string_view.hpp
@@ -0,0 +1,694 @@
+/*
+ Copyright (c) Marshall Clow 2012-2015.
+ Copyright (c) Beman Dawes 2015
+ Copyright (c) Glen Joseph Fernandes 2019 (glenjofe@gmail.com)
+
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+ For more information, see http://www.boost.org
+
+ Based on the StringRef implementation in LLVM (http://llvm.org) and
+ N3422 by Jeffrey Yasskin
+ http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html
+ Updated July 2015 to reflect the Library Fundamentals TS
+ http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4480.html
+*/
+
+#ifndef BOOST_STRING_VIEW_HPP
+#define BOOST_STRING_VIEW_HPP
+
+#include <boost/config.hpp>
+#include <boost/detail/workaround.hpp>
+#include <boost/io/ostream_put.hpp>
+#include <boost/utility/string_view_fwd.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/assert.hpp>
+
+#include <cstddef>
+#include <stdexcept>
+#include <algorithm>
+#include <iterator>
+#include <string>
+#include <cstring>
+#include <iosfwd>
+
+#if defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || (defined(BOOST_GCC) && ((BOOST_GCC+0) / 100) <= 406)
+// GCC 4.6 cannot handle a defaulted function with noexcept specifier
+#define BOOST_STRING_VIEW_NO_CXX11_DEFAULTED_NOEXCEPT_FUNCTIONS
+#endif
+
+namespace boost {
+
+ namespace detail {
+ // A helper functor because sometimes we don't have lambdas
+ template <typename charT, typename traits>
+ class string_view_traits_eq {
+ public:
+ string_view_traits_eq ( charT ch ) : ch_(ch) {}
+ bool operator()( charT val ) const { return traits::eq (ch_, val); }
+ charT ch_;
+ };
+ }
+
+ template<typename charT, typename traits> // traits defaulted in string_view_fwd.hpp
+ class basic_string_view {
+ public:
+ // types
+ typedef traits traits_type;
+ typedef charT value_type;
+ typedef charT* pointer;
+ typedef const charT* const_pointer;
+ typedef charT& reference;
+ typedef const charT& const_reference;
+ typedef const_pointer const_iterator; // impl-defined
+ typedef const_iterator iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef const_reverse_iterator reverse_iterator;
+ typedef std::size_t size_type;
+ typedef std::ptrdiff_t difference_type;
+ static BOOST_CONSTEXPR_OR_CONST size_type npos = size_type(-1);
+
+ // construct/copy
+ BOOST_CONSTEXPR basic_string_view() BOOST_NOEXCEPT
+ : ptr_(NULL), len_(0) {}
+
+ // by defaulting these functions, basic_string_ref becomes
+ // trivially copy/move constructible.
+ BOOST_CONSTEXPR basic_string_view(const basic_string_view &rhs) BOOST_NOEXCEPT
+#ifndef BOOST_STRING_VIEW_NO_CXX11_DEFAULTED_NOEXCEPT_FUNCTIONS
+ = default;
+#else
+ : ptr_(rhs.ptr_), len_(rhs.len_) {}
+#endif
+
+ basic_string_view& operator=(const basic_string_view &rhs) BOOST_NOEXCEPT
+#ifndef BOOST_STRING_VIEW_NO_CXX11_DEFAULTED_NOEXCEPT_FUNCTIONS
+ = default;
+#else
+ {
+ ptr_ = rhs.ptr_;
+ len_ = rhs.len_;
+ return *this;
+ }
+#endif
+
+ template<typename Allocator>
+ basic_string_view(const std::basic_string<charT, traits, Allocator>& str) BOOST_NOEXCEPT
+ : ptr_(str.data()), len_(str.length()) {}
+
+// #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
+// // Constructing a string_view from a temporary string is a bad idea
+// template<typename Allocator>
+// basic_string_view( std::basic_string<charT, traits, Allocator>&&)
+// = delete;
+// #endif
+
+ BOOST_CONSTEXPR basic_string_view(const charT* str)
+ : ptr_(str), len_(traits::length(str)) {}
+
+ BOOST_CONSTEXPR basic_string_view(const charT* str, size_type len)
+ : ptr_(str), len_(len) {}
+
+ // iterators
+ BOOST_CONSTEXPR const_iterator begin() const BOOST_NOEXCEPT { return ptr_; }
+ BOOST_CONSTEXPR const_iterator cbegin() const BOOST_NOEXCEPT { return ptr_; }
+ BOOST_CONSTEXPR const_iterator end() const BOOST_NOEXCEPT { return ptr_ + len_; }
+ BOOST_CONSTEXPR const_iterator cend() const BOOST_NOEXCEPT { return ptr_ + len_; }
+ const_reverse_iterator rbegin() const BOOST_NOEXCEPT { return const_reverse_iterator(end()); }
+ const_reverse_iterator crbegin() const BOOST_NOEXCEPT { return const_reverse_iterator(end()); }
+ const_reverse_iterator rend() const BOOST_NOEXCEPT { return const_reverse_iterator(begin()); }
+ const_reverse_iterator crend() const BOOST_NOEXCEPT { return const_reverse_iterator(begin()); }
+
+ // capacity
+ BOOST_CONSTEXPR size_type size() const BOOST_NOEXCEPT { return len_; }
+ BOOST_CONSTEXPR size_type length() const BOOST_NOEXCEPT { return len_; }
+ BOOST_CONSTEXPR size_type max_size() const BOOST_NOEXCEPT { return ~static_cast<size_type>(0) / (sizeof(value_type) * 2u); }
+ BOOST_CONSTEXPR bool empty() const BOOST_NOEXCEPT { return len_ == 0; }
+
+ // element access
+ BOOST_CONSTEXPR const_reference operator[](size_type pos) const BOOST_NOEXCEPT { return ptr_[pos]; }
+
+ BOOST_CONSTEXPR const_reference at(size_type pos) const {
+ return pos >= len_ ? BOOST_THROW_EXCEPTION(std::out_of_range("boost::string_view::at")), ptr_[0] : ptr_[pos];
+ }
+
+ BOOST_CONSTEXPR const_reference front() const { return ptr_[0]; }
+ BOOST_CONSTEXPR const_reference back() const { return ptr_[len_-1]; }
+ BOOST_CONSTEXPR const_pointer data() const BOOST_NOEXCEPT { return ptr_; }
+
+ // modifiers
+ void clear() BOOST_NOEXCEPT { len_ = 0; } // Boost extension
+
+ BOOST_CXX14_CONSTEXPR void remove_prefix(size_type n) {
+ BOOST_ASSERT(n <= size());
+ // This check is deprecated and is left for backward compatibility. It will be removed in the future.
+ if ( n > len_ )
+ n = len_;
+ ptr_ += n;
+ len_ -= n;
+ }
+
+ BOOST_CXX14_CONSTEXPR void remove_suffix(size_type n) {
+ BOOST_ASSERT(n <= size());
+ // This check is deprecated and is left for backward compatibility. It will be removed in the future.
+ if ( n > len_ )
+ n = len_;
+ len_ -= n;
+ }
+
+ BOOST_CXX14_CONSTEXPR void swap(basic_string_view& s) BOOST_NOEXCEPT {
+ std::swap(ptr_, s.ptr_);
+ std::swap(len_, s.len_);
+ }
+
+ // basic_string_view string operations
+#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
+ template<typename Allocator>
+ explicit operator std::basic_string<charT, traits, Allocator>() const {
+ return std::basic_string<charT, traits, Allocator>(begin(), end());
+ }
+#endif
+
+#ifndef BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS
+ template<typename Allocator = std::allocator<charT> >
+ std::basic_string<charT, traits, Allocator> to_string(const Allocator& a = Allocator()) const {
+ return std::basic_string<charT, traits, Allocator>(begin(), end(), a);
+ }
+#else
+ std::basic_string<charT, traits> to_string() const {
+ return std::basic_string<charT, traits>(begin(), end());
+ }
+
+ template<typename Allocator>
+ std::basic_string<charT, traits, Allocator> to_string(const Allocator& a) const {
+ return std::basic_string<charT, traits, Allocator>(begin(), end(), a);
+ }
+#endif
+
+ size_type copy(charT* s, size_type n, size_type pos=0) const {
+ if (pos > size())
+ BOOST_THROW_EXCEPTION(std::out_of_range("string_view::copy" ));
+ size_type rlen = (std::min)(n, len_ - pos);
+ traits_type::copy(s, data() + pos, rlen);
+ return rlen;
+ }
+
+ BOOST_CXX14_CONSTEXPR basic_string_view substr() const {
+ return basic_string_view(data(), size());
+ }
+
+ BOOST_CXX14_CONSTEXPR basic_string_view substr(size_type pos, size_type n=npos) const {
+ if ( pos > size())
+ BOOST_THROW_EXCEPTION( std::out_of_range ( "string_view::substr" ) );
+ return basic_string_view(data() + pos, (std::min)(size() - pos, n));
+ }
+
+ BOOST_CXX14_CONSTEXPR int compare(basic_string_view x) const BOOST_NOEXCEPT {
+ const int cmp = traits::compare(ptr_, x.ptr_, (std::min)(len_, x.len_));
+ return cmp != 0 ? cmp : (len_ == x.len_ ? 0 : len_ < x.len_ ? -1 : 1);
+ }
+
+ BOOST_CXX14_CONSTEXPR int compare(size_type pos1, size_type n1, basic_string_view x)
+ const {
+ return substr(pos1, n1).compare(x);
+ }
+
+ BOOST_CXX14_CONSTEXPR int compare(size_type pos1, size_type n1,
+ basic_string_view x, size_type pos2, size_type n2) const {
+ return substr(pos1, n1).compare(x.substr(pos2, n2));
+ }
+
+ BOOST_CXX14_CONSTEXPR int compare(const charT* x) const {
+ return compare(basic_string_view(x));
+ }
+
+ BOOST_CXX14_CONSTEXPR int compare(size_type pos1, size_type n1, const charT* x) const {
+ return substr(pos1, n1).compare(basic_string_view(x));
+ }
+
+ BOOST_CXX14_CONSTEXPR int compare(size_type pos1, size_type n1,
+ const charT* x, size_type n2) const {
+ return substr(pos1, n1).compare(basic_string_view(x, n2));
+ }
+
+ // Searches
+ BOOST_CONSTEXPR bool starts_with(charT c) const BOOST_NOEXCEPT { // Boost extension
+ return !empty() && traits::eq(c, front());
+ }
+
+ BOOST_CONSTEXPR bool starts_with(basic_string_view x) const BOOST_NOEXCEPT { // Boost extension
+ return len_ >= x.len_ && traits::compare(ptr_, x.ptr_, x.len_) == 0;
+ }
+
+ BOOST_CONSTEXPR bool ends_with(charT c) const BOOST_NOEXCEPT { // Boost extension
+ return !empty() && traits::eq(c, back());
+ }
+
+ BOOST_CONSTEXPR bool ends_with(basic_string_view x) const BOOST_NOEXCEPT { // Boost extension
+ return len_ >= x.len_ &&
+ traits::compare(ptr_ + len_ - x.len_, x.ptr_, x.len_) == 0;
+ }
+
+ BOOST_CXX14_CONSTEXPR bool contains(basic_string_view s) const BOOST_NOEXCEPT {
+ return find(s) != npos;
+ }
+
+ BOOST_CXX14_CONSTEXPR bool contains(charT c) const BOOST_NOEXCEPT {
+ return find(c) != npos;
+ }
+
+ BOOST_CXX14_CONSTEXPR bool contains(const charT* s) const BOOST_NOEXCEPT {
+ return find(s) != npos;
+ }
+
+ // find
+ BOOST_CXX14_CONSTEXPR size_type find(basic_string_view s, size_type pos = 0) const BOOST_NOEXCEPT {
+ if (pos > size())
+ return npos;
+ if (s.empty())
+ return pos;
+ if (s.size() > size() - pos)
+ return npos;
+ const charT* cur = ptr_ + pos;
+ const charT* last = cend() - s.size() + 1;
+ for (; cur != last ; ++cur) {
+ cur = traits::find(cur, last - cur, s[0]);
+ if (!cur)
+ return npos;
+ if (traits::compare(cur, s.cbegin(), s.size()) == 0)
+ return cur - ptr_;
+ }
+ return npos;
+ }
+ BOOST_CXX14_CONSTEXPR size_type find(charT c, size_type pos = 0) const BOOST_NOEXCEPT {
+ if (pos > size())
+ return npos;
+ const charT* ret_ptr = traits::find(ptr_ + pos, len_ - pos, c);
+ if (ret_ptr)
+ return ret_ptr - ptr_;
+ return npos;
+ }
+ BOOST_CXX14_CONSTEXPR size_type find(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT
+ { return find(basic_string_view(s, n), pos); }
+ BOOST_CXX14_CONSTEXPR size_type find(const charT* s, size_type pos = 0) const BOOST_NOEXCEPT
+ { return find(basic_string_view(s), pos); }
+
+ // rfind
+ BOOST_CXX14_CONSTEXPR size_type rfind(basic_string_view s, size_type pos = npos) const BOOST_NOEXCEPT {
+ if (len_ < s.len_)
+ return npos;
+ if (pos > len_ - s.len_)
+ pos = len_ - s.len_;
+ if (s.len_ == 0u) // an empty string is always found
+ return pos;
+ for (const charT* cur = ptr_ + pos; ; --cur) {
+ if (traits::compare(cur, s.ptr_, s.len_) == 0)
+ return cur - ptr_;
+ if (cur == ptr_)
+ return npos;
+ };
+ }
+ BOOST_CXX14_CONSTEXPR size_type rfind(charT c, size_type pos = npos) const BOOST_NOEXCEPT
+ { return rfind(basic_string_view(&c, 1), pos); }
+ BOOST_CXX14_CONSTEXPR size_type rfind(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT
+ { return rfind(basic_string_view(s, n), pos); }
+ BOOST_CXX14_CONSTEXPR size_type rfind(const charT* s, size_type pos = npos) const BOOST_NOEXCEPT
+ { return rfind(basic_string_view(s), pos); }
+
+ // find_first_of
+ BOOST_CXX14_CONSTEXPR size_type find_first_of(basic_string_view s, size_type pos = 0) const BOOST_NOEXCEPT {
+ if (pos >= len_ || s.len_ == 0)
+ return npos;
+ const_iterator iter = std::find_first_of
+ (this->cbegin () + pos, this->cend (), s.cbegin (), s.cend (), traits::eq);
+ return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter );
+ }
+ BOOST_CXX14_CONSTEXPR size_type find_first_of(charT c, size_type pos = 0) const BOOST_NOEXCEPT
+ { return find(c, pos); }
+ BOOST_CXX14_CONSTEXPR size_type find_first_of(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT
+ { return find_first_of(basic_string_view(s, n), pos); }
+ BOOST_CXX14_CONSTEXPR size_type find_first_of(const charT* s, size_type pos = 0) const BOOST_NOEXCEPT
+ { return find_first_of(basic_string_view(s), pos); }
+
+ // find_last_of
+ BOOST_CXX14_CONSTEXPR size_type find_last_of(basic_string_view s, size_type pos = npos) const BOOST_NOEXCEPT {
+ if (s.len_ == 0u)
+ return npos;
+ if (pos >= len_)
+ pos = 0;
+ else
+ pos = len_ - (pos+1);
+ const_reverse_iterator iter = std::find_first_of
+ ( this->crbegin () + pos, this->crend (), s.cbegin (), s.cend (), traits::eq );
+ return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter);
+ }
+ BOOST_CXX14_CONSTEXPR size_type find_last_of(charT c, size_type pos = npos) const BOOST_NOEXCEPT
+ { return find_last_of(basic_string_view(&c, 1), pos); }
+ BOOST_CXX14_CONSTEXPR size_type find_last_of(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT
+ { return find_last_of(basic_string_view(s, n), pos); }
+ BOOST_CXX14_CONSTEXPR size_type find_last_of(const charT* s, size_type pos = npos) const BOOST_NOEXCEPT
+ { return find_last_of(basic_string_view(s), pos); }
+
+ // find_first_not_of
+ BOOST_CXX14_CONSTEXPR size_type find_first_not_of(basic_string_view s, size_type pos = 0) const BOOST_NOEXCEPT {
+ if (pos >= len_)
+ return npos;
+ if (s.len_ == 0)
+ return pos;
+ const_iterator iter = find_not_of ( this->cbegin () + pos, this->cend (), s );
+ return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter );
+ }
+ BOOST_CXX14_CONSTEXPR size_type find_first_not_of(charT c, size_type pos = 0) const BOOST_NOEXCEPT
+ { return find_first_not_of(basic_string_view(&c, 1), pos); }
+ BOOST_CXX14_CONSTEXPR size_type find_first_not_of(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT
+ { return find_first_not_of(basic_string_view(s, n), pos); }
+ BOOST_CXX14_CONSTEXPR size_type find_first_not_of(const charT* s, size_type pos = 0) const BOOST_NOEXCEPT
+ { return find_first_not_of(basic_string_view(s), pos); }
+
+ // find_last_not_of
+ BOOST_CXX14_CONSTEXPR size_type find_last_not_of(basic_string_view s, size_type pos = npos) const BOOST_NOEXCEPT {
+ if (pos >= len_)
+ pos = len_ - 1;
+ if (s.len_ == 0u)
+ return pos;
+ pos = len_ - (pos+1);
+ const_reverse_iterator iter = find_not_of ( this->crbegin () + pos, this->crend (), s );
+ return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter );
+ }
+ BOOST_CXX14_CONSTEXPR size_type find_last_not_of(charT c, size_type pos = npos) const BOOST_NOEXCEPT
+ { return find_last_not_of(basic_string_view(&c, 1), pos); }
+ BOOST_CXX14_CONSTEXPR size_type find_last_not_of(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT
+ { return find_last_not_of(basic_string_view(s, n), pos); }
+ BOOST_CXX14_CONSTEXPR size_type find_last_not_of(const charT* s, size_type pos = npos) const BOOST_NOEXCEPT
+ { return find_last_not_of(basic_string_view(s), pos); }
+
+ private:
+ template <typename r_iter>
+ size_type reverse_distance(r_iter first, r_iter last) const BOOST_NOEXCEPT {
+ // Portability note here: std::distance is not NOEXCEPT, but calling it with a string_view::reverse_iterator will not throw.
+ return len_ - 1 - std::distance ( first, last );
+ }
+
+ template <typename Iterator>
+ Iterator find_not_of(Iterator first, Iterator last, basic_string_view s) const BOOST_NOEXCEPT {
+ for (; first != last ; ++first)
+ if ( 0 == traits::find(s.ptr_, s.len_, *first))
+ return first;
+ return last;
+ }
+
+ const charT *ptr_;
+ std::size_t len_;
+ };
+
+
+// Comparison operators
+// Equality
+ template<typename charT, typename traits>
+ inline BOOST_CXX14_CONSTEXPR bool operator==(basic_string_view<charT, traits> x,
+ basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
+ if (x.size () != y.size ()) return false;
+ return x.compare(y) == 0;
+ }
+
+// Inequality
+ template<typename charT, typename traits>
+ inline BOOST_CXX14_CONSTEXPR bool operator!=(basic_string_view<charT, traits> x,
+ basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
+ if ( x.size () != y.size ()) return true;
+ return x.compare(y) != 0;
+ }
+
+// Less than
+ template<typename charT, typename traits>
+ inline BOOST_CXX14_CONSTEXPR bool operator<(basic_string_view<charT, traits> x,
+ basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
+ return x.compare(y) < 0;
+ }
+
+// Greater than
+ template<typename charT, typename traits>
+ inline BOOST_CXX14_CONSTEXPR bool operator>(basic_string_view<charT, traits> x,
+ basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
+ return x.compare(y) > 0;
+ }
+
+// Less than or equal to
+ template<typename charT, typename traits>
+ inline BOOST_CXX14_CONSTEXPR bool operator<=(basic_string_view<charT, traits> x,
+ basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
+ return x.compare(y) <= 0;
+ }
+
+// Greater than or equal to
+ template<typename charT, typename traits>
+ inline BOOST_CXX14_CONSTEXPR bool operator>=(basic_string_view<charT, traits> x,
+ basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
+ return x.compare(y) >= 0;
+ }
+
+// "sufficient additional overloads of comparison functions"
+ template<typename charT, typename traits, typename Allocator>
+ inline BOOST_CXX14_CONSTEXPR bool operator==(basic_string_view<charT, traits> x,
+ const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {
+ return x == basic_string_view<charT, traits>(y);
+ }
+
+ template<typename charT, typename traits, typename Allocator>
+ inline BOOST_CXX14_CONSTEXPR bool operator==(const std::basic_string<charT, traits, Allocator> & x,
+ basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
+ return basic_string_view<charT, traits>(x) == y;
+ }
+
+ template<typename charT, typename traits>
+ inline BOOST_CXX14_CONSTEXPR bool operator==(basic_string_view<charT, traits> x,
+ const charT * y) BOOST_NOEXCEPT {
+ return x == basic_string_view<charT, traits>(y);
+ }
+
+ template<typename charT, typename traits>
+ inline BOOST_CXX14_CONSTEXPR bool operator==(const charT * x,
+ basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
+ return basic_string_view<charT, traits>(x) == y;
+ }
+
+ template<typename charT, typename traits, typename Allocator>
+ inline BOOST_CXX14_CONSTEXPR bool operator!=(basic_string_view<charT, traits> x,
+ const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {
+ return x != basic_string_view<charT, traits>(y);
+ }
+
+ template<typename charT, typename traits, typename Allocator>
+ inline BOOST_CXX14_CONSTEXPR bool operator!=(const std::basic_string<charT, traits, Allocator> & x,
+ basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
+ return basic_string_view<charT, traits>(x) != y;
+ }
+
+ template<typename charT, typename traits>
+ inline BOOST_CXX14_CONSTEXPR bool operator!=(basic_string_view<charT, traits> x,
+ const charT * y) BOOST_NOEXCEPT {
+ return x != basic_string_view<charT, traits>(y);
+ }
+
+ template<typename charT, typename traits>
+ inline BOOST_CXX14_CONSTEXPR bool operator!=(const charT * x,
+ basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
+ return basic_string_view<charT, traits>(x) != y;
+ }
+
+ template<typename charT, typename traits, typename Allocator>
+ inline BOOST_CXX14_CONSTEXPR bool operator<(basic_string_view<charT, traits> x,
+ const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {
+ return x < basic_string_view<charT, traits>(y);
+ }
+
+ template<typename charT, typename traits, typename Allocator>
+ inline BOOST_CXX14_CONSTEXPR bool operator<(const std::basic_string<charT, traits, Allocator> & x,
+ basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
+ return basic_string_view<charT, traits>(x) < y;
+ }
+
+ template<typename charT, typename traits>
+ inline BOOST_CXX14_CONSTEXPR bool operator<(basic_string_view<charT, traits> x,
+ const charT * y) BOOST_NOEXCEPT {
+ return x < basic_string_view<charT, traits>(y);
+ }
+
+ template<typename charT, typename traits>
+ inline BOOST_CXX14_CONSTEXPR bool operator<(const charT * x,
+ basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
+ return basic_string_view<charT, traits>(x) < y;
+ }
+
+ template<typename charT, typename traits, typename Allocator>
+ inline BOOST_CXX14_CONSTEXPR bool operator>(basic_string_view<charT, traits> x,
+ const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {
+ return x > basic_string_view<charT, traits>(y);
+ }
+
+ template<typename charT, typename traits, typename Allocator>
+ inline BOOST_CXX14_CONSTEXPR bool operator>(const std::basic_string<charT, traits, Allocator> & x,
+ basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
+ return basic_string_view<charT, traits>(x) > y;
+ }
+
+ template<typename charT, typename traits>
+ inline BOOST_CXX14_CONSTEXPR bool operator>(basic_string_view<charT, traits> x,
+ const charT * y) BOOST_NOEXCEPT {
+ return x > basic_string_view<charT, traits>(y);
+ }
+
+ template<typename charT, typename traits>
+ inline BOOST_CXX14_CONSTEXPR bool operator>(const charT * x,
+ basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
+ return basic_string_view<charT, traits>(x) > y;
+ }
+
+ template<typename charT, typename traits, typename Allocator>
+ inline BOOST_CXX14_CONSTEXPR bool operator<=(basic_string_view<charT, traits> x,
+ const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {
+ return x <= basic_string_view<charT, traits>(y);
+ }
+
+ template<typename charT, typename traits, typename Allocator>
+ inline BOOST_CXX14_CONSTEXPR bool operator<=(const std::basic_string<charT, traits, Allocator> & x,
+ basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
+ return basic_string_view<charT, traits>(x) <= y;
+ }
+
+ template<typename charT, typename traits>
+ inline BOOST_CXX14_CONSTEXPR bool operator<=(basic_string_view<charT, traits> x,
+ const charT * y) BOOST_NOEXCEPT {
+ return x <= basic_string_view<charT, traits>(y);
+ }
+
+ template<typename charT, typename traits>
+ inline BOOST_CXX14_CONSTEXPR bool operator<=(const charT * x,
+ basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
+ return basic_string_view<charT, traits>(x) <= y;
+ }
+
+ template<typename charT, typename traits, typename Allocator>
+ inline BOOST_CXX14_CONSTEXPR bool operator>=(basic_string_view<charT, traits> x,
+ const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {
+ return x >= basic_string_view<charT, traits>(y);
+ }
+
+ template<typename charT, typename traits, typename Allocator>
+ inline BOOST_CXX14_CONSTEXPR bool operator>=(const std::basic_string<charT, traits, Allocator> & x,
+ basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
+ return basic_string_view<charT, traits>(x) >= y;
+ }
+
+ template<typename charT, typename traits>
+ inline BOOST_CXX14_CONSTEXPR bool operator>=(basic_string_view<charT, traits> x,
+ const charT * y) BOOST_NOEXCEPT {
+ return x >= basic_string_view<charT, traits>(y);
+ }
+
+ template<typename charT, typename traits>
+ inline BOOST_CXX14_CONSTEXPR bool operator>=(const charT * x,
+ basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
+ return basic_string_view<charT, traits>(x) >= y;
+ }
+
+ // Inserter
+ template<class charT, class traits>
+ inline std::basic_ostream<charT, traits>&
+ operator<<(std::basic_ostream<charT, traits>& os,
+ const basic_string_view<charT,traits>& str) {
+ return boost::io::ostream_put(os, str.data(), str.size());
+ }
+
+#if 0
+ // numeric conversions
+ //
+ // These are short-term implementations.
+ // In a production environment, I would rather avoid the copying.
+ //
+ inline int stoi (string_view str, size_t* idx=0, int base=10) {
+ return std::stoi ( std::string(str), idx, base );
+ }
+
+ inline long stol (string_view str, size_t* idx=0, int base=10) {
+ return std::stol ( std::string(str), idx, base );
+ }
+
+ inline unsigned long stoul (string_view str, size_t* idx=0, int base=10) {
+ return std::stoul ( std::string(str), idx, base );
+ }
+
+ inline long long stoll (string_view str, size_t* idx=0, int base=10) {
+ return std::stoll ( std::string(str), idx, base );
+ }
+
+ inline unsigned long long stoull (string_view str, size_t* idx=0, int base=10) {
+ return std::stoull ( std::string(str), idx, base );
+ }
+
+ inline float stof (string_view str, size_t* idx=0) {
+ return std::stof ( std::string(str), idx );
+ }
+
+ inline double stod (string_view str, size_t* idx=0) {
+ return std::stod ( std::string(str), idx );
+ }
+
+ inline long double stold (string_view str, size_t* idx=0) {
+ return std::stold ( std::string(str), idx );
+ }
+
+ inline int stoi (wstring_view str, size_t* idx=0, int base=10) {
+ return std::stoi ( std::wstring(str), idx, base );
+ }
+
+ inline long stol (wstring_view str, size_t* idx=0, int base=10) {
+ return std::stol ( std::wstring(str), idx, base );
+ }
+
+ inline unsigned long stoul (wstring_view str, size_t* idx=0, int base=10) {
+ return std::stoul ( std::wstring(str), idx, base );
+ }
+
+ inline long long stoll (wstring_view str, size_t* idx=0, int base=10) {
+ return std::stoll ( std::wstring(str), idx, base );
+ }
+
+ inline unsigned long long stoull (wstring_view str, size_t* idx=0, int base=10) {
+ return std::stoull ( std::wstring(str), idx, base );
+ }
+
+ inline float stof (wstring_view str, size_t* idx=0) {
+ return std::stof ( std::wstring(str), idx );
+ }
+
+ inline double stod (wstring_view str, size_t* idx=0) {
+ return std::stod ( std::wstring(str), idx );
+ }
+
+ inline long double stold (wstring_view str, size_t* idx=0) {
+ return std::stold ( std::wstring(str), idx );
+ }
+#endif
+
+ // Forward declaration of Boost.ContainerHash function
+ template <class It> std::size_t hash_range(It, It);
+
+ template <class charT, class traits>
+ std::size_t hash_value(basic_string_view<charT, traits> s) {
+ return boost::hash_range(s.begin(), s.end());
+ }
+}
+
+#if 0
+namespace std {
+ // Hashing
+ template<> struct hash<boost::string_view>;
+ template<> struct hash<boost::u16string_view>;
+ template<> struct hash<boost::u32string_view>;
+ template<> struct hash<boost::wstring_view>;
+}
+#endif
+
+#endif
diff --git a/contrib/restricted/boost/utility/include/boost/utility/string_view_fwd.hpp b/contrib/restricted/boost/utility/include/boost/utility/string_view_fwd.hpp
new file mode 100644
index 0000000000..dbda0de46a
--- /dev/null
+++ b/contrib/restricted/boost/utility/include/boost/utility/string_view_fwd.hpp
@@ -0,0 +1,39 @@
+/*
+ Copyright (c) Marshall Clow 2012-2012.
+
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+ For more information, see http://www.boost.org
+
+ Based on the StringRef implementation in LLVM (http://llvm.org) and
+ N3422 by Jeffrey Yasskin
+ http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html
+ Updated July 2015 to reflect the Library Fundamentals TS
+ http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4480.html
+
+*/
+
+#ifndef BOOST_STRING_VIEW_FWD_HPP
+#define BOOST_STRING_VIEW_FWD_HPP
+
+#include <boost/config.hpp>
+#include <string>
+
+namespace boost {
+
+ template<typename charT, typename traits = std::char_traits<charT> > class basic_string_view;
+ typedef basic_string_view<char, std::char_traits<char> > string_view;
+ typedef basic_string_view<wchar_t, std::char_traits<wchar_t> > wstring_view;
+
+#ifndef BOOST_NO_CXX11_CHAR16_T
+ typedef basic_string_view<char16_t, std::char_traits<char16_t> > u16string_view;
+#endif
+
+#ifndef BOOST_NO_CXX11_CHAR32_T
+ typedef basic_string_view<char32_t, std::char_traits<char32_t> > u32string_view;
+#endif
+
+}
+
+#endif