diff options
author | thegeorg <thegeorg@yandex-team.com> | 2022-12-31 12:45:45 +0300 |
---|---|---|
committer | thegeorg <thegeorg@yandex-team.com> | 2022-12-31 12:45:45 +0300 |
commit | ec49685b324b479946bb811edb1920e158508f74 (patch) | |
tree | 9390a5c86b450ef1aa0a61908e7fa8d63d73b293 /contrib/restricted/boost | |
parent | 8fd51d45ec75d85ab82699a4ecf4f2fa94c773b4 (diff) | |
download | ydb-ec49685b324b479946bb811edb1920e158508f74.tar.gz |
Update contrib/restricted/boost/locale to 1.81.0
Diffstat (limited to 'contrib/restricted/boost')
102 files changed, 13585 insertions, 16843 deletions
diff --git a/contrib/restricted/boost/locale/CMakeLists.darwin.txt b/contrib/restricted/boost/locale/CMakeLists.darwin.txt index 6923f40331..f9069bfa97 100644 --- a/contrib/restricted/boost/locale/CMakeLists.darwin.txt +++ b/contrib/restricted/boost/locale/CMakeLists.darwin.txt @@ -24,14 +24,10 @@ target_link_libraries(restricted-boost-locale PUBLIC contrib-libs-icu restricted-boost-assert restricted-boost-config - restricted-boost-function + restricted-boost-core restricted-boost-iterator restricted-boost-predef - restricted-boost-smart_ptr - restricted-boost-static_assert restricted-boost-thread - restricted-boost-type_traits - restricted-boost-unordered ) target_sources(restricted-boost-locale PRIVATE ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/locale/src/boost/locale/posix/codecvt.cpp @@ -46,6 +42,7 @@ target_sources(restricted-boost-locale PRIVATE ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/locale/src/boost/locale/icu/conversion.cpp ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/locale/src/boost/locale/icu/date_time.cpp ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/locale/src/boost/locale/icu/formatter.cpp + ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/locale/src/boost/locale/icu/formatters_cache.cpp ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/locale/src/boost/locale/icu/icu_backend.cpp ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/locale/src/boost/locale/icu/numeric.cpp ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/locale/src/boost/locale/icu/time_zone.cpp diff --git a/contrib/restricted/boost/locale/CMakeLists.linux-aarch64.txt b/contrib/restricted/boost/locale/CMakeLists.linux-aarch64.txt index 9a19a44900..afec940393 100644 --- a/contrib/restricted/boost/locale/CMakeLists.linux-aarch64.txt +++ b/contrib/restricted/boost/locale/CMakeLists.linux-aarch64.txt @@ -25,14 +25,10 @@ target_link_libraries(restricted-boost-locale PUBLIC contrib-libs-icu restricted-boost-assert restricted-boost-config - restricted-boost-function + restricted-boost-core restricted-boost-iterator restricted-boost-predef - restricted-boost-smart_ptr - restricted-boost-static_assert restricted-boost-thread - restricted-boost-type_traits - restricted-boost-unordered ) target_sources(restricted-boost-locale PRIVATE ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/locale/src/boost/locale/posix/codecvt.cpp @@ -47,6 +43,7 @@ target_sources(restricted-boost-locale PRIVATE ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/locale/src/boost/locale/icu/conversion.cpp ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/locale/src/boost/locale/icu/date_time.cpp ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/locale/src/boost/locale/icu/formatter.cpp + ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/locale/src/boost/locale/icu/formatters_cache.cpp ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/locale/src/boost/locale/icu/icu_backend.cpp ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/locale/src/boost/locale/icu/numeric.cpp ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/locale/src/boost/locale/icu/time_zone.cpp diff --git a/contrib/restricted/boost/locale/CMakeLists.linux.txt b/contrib/restricted/boost/locale/CMakeLists.linux.txt index 9a19a44900..afec940393 100644 --- a/contrib/restricted/boost/locale/CMakeLists.linux.txt +++ b/contrib/restricted/boost/locale/CMakeLists.linux.txt @@ -25,14 +25,10 @@ target_link_libraries(restricted-boost-locale PUBLIC contrib-libs-icu restricted-boost-assert restricted-boost-config - restricted-boost-function + restricted-boost-core restricted-boost-iterator restricted-boost-predef - restricted-boost-smart_ptr - restricted-boost-static_assert restricted-boost-thread - restricted-boost-type_traits - restricted-boost-unordered ) target_sources(restricted-boost-locale PRIVATE ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/locale/src/boost/locale/posix/codecvt.cpp @@ -47,6 +43,7 @@ target_sources(restricted-boost-locale PRIVATE ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/locale/src/boost/locale/icu/conversion.cpp ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/locale/src/boost/locale/icu/date_time.cpp ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/locale/src/boost/locale/icu/formatter.cpp + ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/locale/src/boost/locale/icu/formatters_cache.cpp ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/locale/src/boost/locale/icu/icu_backend.cpp ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/locale/src/boost/locale/icu/numeric.cpp ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/locale/src/boost/locale/icu/time_zone.cpp diff --git a/contrib/restricted/boost/locale/README.md b/contrib/restricted/boost/locale/README.md index b73b3dd82a..a8e73bc55a 100644 --- a/contrib/restricted/boost/locale/README.md +++ b/contrib/restricted/boost/locale/README.md @@ -1,4 +1,4 @@ -# Boost.CI +# Boost.Locale Part of the [Boost C++ Libraries](http://github.com/boostorg). @@ -19,7 +19,7 @@ Provided Features: - Character set conversion. - Transparent support for 8-bit character sets like Latin1 - Support for `char` and `wchar_t` -- Experimental support for C++0x `char16_t` and `char32_t` strings and streams. +- 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. @@ -37,7 +37,8 @@ Distributed under the [Boost Software License, Version 1.0](https://www.boost.or ### Properties -* C++03 +* C++11 +* Formatted with clang-format, see [`tools/format_source.sh`](https://github.com/boostorg/locale/blob/develop/tools/format_source.sh) ### Build Status diff --git a/contrib/restricted/boost/locale/include/boost/locale/boundary.hpp b/contrib/restricted/boost/locale/include/boost/locale/boundary.hpp index d767d173d4..34e20374b5 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/boundary.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/boundary.hpp @@ -7,10 +7,10 @@ #ifndef BOOST_LOCALE_BOUNDARY_HPP_INCLUDED #define BOOST_LOCALE_BOUNDARY_HPP_INCLUDED -#include <boost/locale/boundary/types.hpp> -#include <boost/locale/boundary/facets.hpp> -#include <boost/locale/boundary/segment.hpp> #include <boost/locale/boundary/boundary_point.hpp> +#include <boost/locale/boundary/facets.hpp> #include <boost/locale/boundary/index.hpp> +#include <boost/locale/boundary/segment.hpp> +#include <boost/locale/boundary/types.hpp> #endif diff --git a/contrib/restricted/boost/locale/include/boost/locale/boundary/boundary_point.hpp b/contrib/restricted/boost/locale/include/boost/locale/boundary/boundary_point.hpp index 306a8f6e3b..494352a081 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/boundary/boundary_point.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/boundary/boundary_point.hpp @@ -8,33 +8,30 @@ #define BOOST_LOCALE_BOUNDARY_BOUNDARY_POINT_HPP_INCLUDED #include <boost/locale/boundary/types.hpp> +#include <string> -namespace boost { -namespace locale { -namespace boundary { +namespace boost { namespace locale { namespace boundary { - /// /// \addtogroup boundary /// @{ - /// /// \brief This class represents a boundary point in the text. /// /// It represents a pair - an iterator and a rule that defines this /// point. /// - /// This type of object is dereference by the iterators of boundary_point_index. Using a rule() + /// This type of object is dereferenced by the iterators of boundary_point_index. Using a rule() /// member function you can get the reason why this specific boundary point was selected. /// - /// For example, When you use a sentence boundary analysis, the (rule() & \ref sentence_term) != 0 means + /// For example, when you use sentence boundary analysis, the (rule() & \ref sentence_term) != 0 means /// that this boundary point was selected because a sentence terminator (like .?!) was spotted /// and the (rule() & \ref sentence_sep)!=0 means that a separator like line feed or carriage /// return was observed. /// /// \note /// - /// - The beginning of analyzed range is always considered a boundary point and its rule is always 0. - /// - when using a word boundary analysis the returned rule relates to a chunk of text preceding + /// - The beginning of the analyzed range is always considered a boundary point and its rule is always 0. + /// - When using word boundary analysis, the returned rule relates to a chunk of text preceding /// this point. /// /// \see @@ -44,138 +41,81 @@ namespace boundary { /// - \ref segment_index /// template<typename IteratorType> - class boundary_point { + class boundary_point { public: - /// /// The type of the base iterator that iterates the original text - /// typedef IteratorType iterator_type; - /// /// Empty default constructor - /// boundary_point() : rule_(0) {} - /// /// Create a new boundary_point using iterator \p and a rule \a r - /// - boundary_point(iterator_type p,rule_type r) : - iterator_(p), - rule_(r) - { - } - /// + boundary_point(iterator_type p, rule_type r) : iterator_(p), rule_(r) {} + /// Set an new iterator value \a i - /// - void iterator(iterator_type i) - { - iterator_ = i; - } - /// - /// Set an new rule value \a r - /// - void rule(rule_type r) - { - rule_ = r; - } - /// + void iterator(iterator_type i) { iterator_ = i; } /// Fetch an iterator - /// - iterator_type iterator() const - { - return iterator_; - } - /// + iterator_type iterator() const { return iterator_; } + + /// Set an new rule value \a r + void rule(rule_type r) { rule_ = r; } /// Fetch a rule - /// - rule_type rule() const - { - return rule_; - } - /// + rule_type rule() const { return rule_; } + /// Check if two boundary points are the same - /// - bool operator==(boundary_point const &other) const + bool operator==(const boundary_point& other) const { return iterator_ == other.iterator_ && rule_ = other.rule_; } - /// /// Check if two boundary points are different - /// - bool operator!=(boundary_point const &other) const - { - return !(*this==other); - } - /// + bool operator!=(const boundary_point& other) const { return !(*this == other); } + /// Check if the boundary point points to same location as an iterator \a other - /// - bool operator==(iterator_type const &other) const - { - return iterator_ == other; - } - /// + bool operator==(const iterator_type& other) const { return iterator_ == other; } /// Check if the boundary point points to different location from an iterator \a other - /// - bool operator!=(iterator_type const &other) const - { - return iterator_ != other; - } + bool operator!=(const iterator_type& other) const { return iterator_ != other; } - /// /// Automatic cast to the iterator it represents - /// - operator iterator_type ()const - { - return iterator_; - } + operator iterator_type() const { return iterator_; } private: iterator_type iterator_; rule_type rule_; - }; - /// + /// Check if the boundary point \a r points to same location as an iterator \a l - /// template<typename BaseIterator> - bool operator==(BaseIterator const &l,boundary_point<BaseIterator> const &r) + bool operator==(const BaseIterator& l, const boundary_point<BaseIterator>& r) { - return r==l; + return r == l; } - /// /// Check if the boundary point \a r points to different location from an iterator \a l - /// template<typename BaseIterator> - bool operator!=(BaseIterator const &l,boundary_point<BaseIterator> const &r) + bool operator!=(const BaseIterator& l, const boundary_point<BaseIterator>& r) { - return r!=l; + return r != l; } /// @} - typedef boundary_point<std::string::const_iterator> sboundary_point; ///< convenience typedef - typedef boundary_point<std::wstring::const_iterator> wsboundary_point; ///< convenience typedef - #ifdef BOOST_LOCALE_ENABLE_CHAR16_T - typedef boundary_point<std::u16string::const_iterator> u16sboundary_point;///< convenience typedef - #endif - #ifdef BOOST_LOCALE_ENABLE_CHAR32_T - typedef boundary_point<std::u32string::const_iterator> u32sboundary_point;///< convenience typedef - #endif - - typedef boundary_point<char const *> cboundary_point; ///< convenience typedef - typedef boundary_point<wchar_t const *> wcboundary_point; ///< convenience typedef - #ifdef BOOST_LOCALE_ENABLE_CHAR16_T - typedef boundary_point<char16_t const *> u16cboundary_point; ///< convenience typedef - #endif - #ifdef BOOST_LOCALE_ENABLE_CHAR32_T - typedef boundary_point<char32_t const *> u32cboundary_point; ///< convenience typedef - #endif - + typedef boundary_point<std::string::const_iterator> sboundary_point; ///< convenience typedef + typedef boundary_point<std::wstring::const_iterator> wsboundary_point; ///< convenience typedef +#ifdef BOOST_LOCALE_ENABLE_CHAR16_T + typedef boundary_point<std::u16string::const_iterator> u16sboundary_point; ///< convenience typedef +#endif +#ifdef BOOST_LOCALE_ENABLE_CHAR32_T + typedef boundary_point<std::u32string::const_iterator> u32sboundary_point; ///< convenience typedef +#endif -} // boundary -} // locale -} // boost + typedef boundary_point<const char*> cboundary_point; ///< convenience typedef + typedef boundary_point<const wchar_t*> wcboundary_point; ///< convenience typedef +#ifdef BOOST_LOCALE_ENABLE_CHAR16_T + typedef boundary_point<const char16_t*> u16cboundary_point; ///< convenience typedef +#endif +#ifdef BOOST_LOCALE_ENABLE_CHAR32_T + typedef boundary_point<const char32_t*> u32cboundary_point; ///< convenience typedef +#endif +}}} // namespace boost::locale::boundary #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 1c9c891276..4d443c9aa8 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/boundary/facets.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/boundary/facets.hpp @@ -12,191 +12,120 @@ #include <vector> #ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4275 4251 4231 4660) +# pragma warning(push) +# pragma warning(disable : 4275 4251 4231 4660) #endif -namespace boost { - - namespace locale { +namespace boost { namespace locale { + /// \brief This namespace contains all operations required for boundary analysis of text + namespace boundary { + /// \addtogroup boundary /// - /// \brief This namespace contains all operations required for boundary analysis of text + /// @{ + + /// \brief This structure is used for representing boundary points + /// that follow the offset. + struct break_info { + /// Create empty break point at beginning + break_info() : offset(0), rule(0) {} + + /// Create an empty break point at offset v. + /// it is useful for order comparison with other points. + break_info(size_t v) : offset(v), rule(0) {} + + /// Offset from the beginning of the text where a break occurs. + size_t offset; + /// The identification of this break point according to + /// various break types + rule_type rule; + + /// Compare two break points' offset. Allows to search with + /// standard algorithms over the index. + bool operator<(const break_info& other) const { return offset < other.offset; } + }; + + /// This type holds the analysis of the text - all its break points + /// 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. /// - namespace boundary { - /// - /// \addtogroup boundary - /// - /// @{ - /// - - + /// It is specialized for 4 types of characters \c char_t, \c wchar_t, \c char16_t and \c char32_t + template<typename Char> + class BOOST_LOCALE_DECL boundary_indexing : public std::locale::facet { + public: + /// Default constructor typical for facets + boundary_indexing(size_t refs = 0) : std::locale::facet(refs) {} + + /// Create index for boundary type \a t for text in range [begin,end) /// - /// \brief This structure is used for representing boundary point - /// that follows the offset. - /// - struct break_info { - - /// - /// Create empty break point at beginning - /// - break_info() : - offset(0), - rule(0) - { - } - /// - /// Create empty break point at offset v. - /// it is useful for order comparison with other points. - /// - break_info(size_t v) : - offset(v), - rule(0) - { - } - - /// - /// Offset from the beginning of the text where a break occurs. - /// - size_t offset; - /// - /// The identification of this break point according to - /// various break types - /// - rule_type rule; - - /// - /// Compare two break points' offset. Allows to search with - /// standard algorithms over the index. - /// - bool operator<(break_info const &other) const - { - return offset < other.offset; - } - }; - - /// - /// This type holds the analysis of the text - all its break points - /// with marks - /// - typedef std::vector<break_info> index_type; - + /// The returned value is an index of type \ref index_type. Note that this + /// 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 - template<typename CharType> - class boundary_indexing; - - #ifdef BOOST_LOCALE_DOXYGEN - /// - /// \brief This facet generates an index for boundary analysis - /// for a given text. - /// - /// It is specialized for 4 types of characters \c char_t, \c wchar_t, \c char16_t and \c char32_t - /// - template<typename Char> - class BOOST_LOCALE_DECL boundary_indexing : public std::locale::facet { - public: - /// - /// Default constructor typical for facets - /// - boundary_indexing(size_t refs=0) : std::locale::facet(refs) - { - } - /// - /// Create index for boundary type \a t for text in range [begin,end) - /// - /// The returned value is an index of type \ref index_type. Note that this - /// 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,Char const *begin,Char const *end) const = 0; - /// - /// Identification of this facet - /// - static std::locale::id id; - - #if defined (__SUNPRO_CC) && defined (_RWSTD_VER) - std::locale::id& __get_id (void) const { return id; } - #endif - }; - - #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,char const *begin,char const *end) const = 0; - static std::locale::id id; - #if defined (__SUNPRO_CC) && defined (_RWSTD_VER) - std::locale::id& __get_id (void) const { return id; } - #endif - }; - - 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,wchar_t const *begin,wchar_t const *end) const = 0; - - static std::locale::id id; - #if defined (__SUNPRO_CC) && defined (_RWSTD_VER) - std::locale::id& __get_id (void) const { return id; } - #endif - }; - - #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,char16_t const *begin,char16_t const *end) const = 0; - static std::locale::id id; - #if defined (__SUNPRO_CC) && defined (_RWSTD_VER) - std::locale::id& __get_id (void) const { return id; } - #endif - }; - #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,char32_t const *begin,char32_t const *end) const = 0; - static std::locale::id id; - #if defined (__SUNPRO_CC) && defined (_RWSTD_VER) - std::locale::id& __get_id (void) const { return id; } - #endif - }; - #endif - - #endif - - /// - /// @} - /// - - - } // boundary +#endif - } // locale -} // boost + /// @} + } // namespace boundary +}} // namespace boost::locale #ifdef BOOST_MSVC -#pragma warning(pop) +# pragma warning(pop) #endif #endif diff --git a/contrib/restricted/boost/locale/include/boost/locale/boundary/index.hpp b/contrib/restricted/boost/locale/include/boost/locale/boundary/index.hpp index dab4673d57..7d2eb66071 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/boundary/index.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/boundary/index.hpp @@ -7,1073 +7,899 @@ #ifndef BOOST_LOCALE_BOUNDARY_INDEX_HPP_INCLUDED #define BOOST_LOCALE_BOUNDARY_INDEX_HPP_INCLUDED -#include <boost/locale/boundary/types.hpp> +#include <boost/locale/boundary/boundary_point.hpp> #include <boost/locale/boundary/facets.hpp> #include <boost/locale/boundary/segment.hpp> -#include <boost/locale/boundary/boundary_point.hpp> -#include <boost/assert.hpp> +#include <boost/locale/boundary/types.hpp> #include <boost/cstdint.hpp> #include <boost/iterator/iterator_facade.hpp> -#include <boost/shared_ptr.hpp> -#include <boost/type_traits/is_same.hpp> #include <algorithm> -#include <iostream> #include <iterator> #include <locale> +#include <memory> #include <stdexcept> #include <string> +#include <type_traits> #include <vector> #ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4275 4251 4231 4660) +# pragma warning(push) +# pragma warning(disable : 4275 4251 4231 4660) #endif -namespace boost { - - namespace locale { - - namespace boundary { - /// - /// \defgroup boundary Boundary Analysis - /// - /// This module contains all operations required for %boundary analysis of text: character, word, like and sentence boundaries - /// - /// @{ - /// - - /// \cond INTERNAL - - namespace details { - - template<typename IteratorType,typename CategoryType = typename std::iterator_traits<IteratorType>::iterator_category> - struct mapping_traits { - typedef typename std::iterator_traits<IteratorType>::value_type char_type; - static index_type map(boundary_type t,IteratorType b,IteratorType e,std::locale const &l) - { - std::basic_string<char_type> str(b,e); - return std::use_facet<boundary_indexing<char_type> >(l).map(t,str.c_str(),str.c_str()+str.size()); - } - }; - - template<typename CharType,typename SomeIteratorType> - struct linear_iterator_traits { - static const bool is_linear = - is_same<SomeIteratorType,CharType*>::value - || is_same<SomeIteratorType,CharType const*>::value - || is_same<SomeIteratorType,typename std::basic_string<CharType>::iterator>::value - || is_same<SomeIteratorType,typename std::basic_string<CharType>::const_iterator>::value - || is_same<SomeIteratorType,typename std::vector<CharType>::iterator>::value - || is_same<SomeIteratorType,typename std::vector<CharType>::const_iterator>::value - ; - }; - - - - template<typename IteratorType> - struct mapping_traits<IteratorType,std::random_access_iterator_tag> { - - typedef typename std::iterator_traits<IteratorType>::value_type char_type; - - - - static index_type map(boundary_type t,IteratorType b,IteratorType e,std::locale const &l) - { - index_type result; - - // - // Optimize for most common cases - // - // C++0x requires that string is continious in memory and all known - // string implementations - // do this because of c_str() support. - // - - if(linear_iterator_traits<char_type,IteratorType>::is_linear && b!=e) - { - char_type const *begin = &*b; - char_type const *end = begin + (e-b); - index_type tmp=std::use_facet<boundary_indexing<char_type> >(l).map(t,begin,end); - result.swap(tmp); - } - else { - std::basic_string<char_type> str(b,e); - index_type tmp = std::use_facet<boundary_indexing<char_type> >(l).map(t,str.c_str(),str.c_str()+str.size()); - result.swap(tmp); - } - return result; - } - }; - - template<typename BaseIterator> - class mapping { - public: - typedef BaseIterator base_iterator; - typedef typename std::iterator_traits<base_iterator>::value_type char_type; - - - mapping(boundary_type type, - base_iterator begin, - base_iterator end, - std::locale const &loc) - : - index_(new index_type()), - begin_(begin), - end_(end) - { - index_type idx=details::mapping_traits<base_iterator>::map(type,begin,end,loc); - index_->swap(idx); - } - - mapping() - { - } - - index_type const &index() const - { - return *index_; - } - - base_iterator begin() const - { - return begin_; - } - - base_iterator end() const - { - return end_; - } - - private: - boost::shared_ptr<index_type> index_; - base_iterator begin_,end_; - }; - - template<typename BaseIterator> - class segment_index_iterator : - public boost::iterator_facade< - segment_index_iterator<BaseIterator>, - segment<BaseIterator>, - boost::bidirectional_traversal_tag, - segment<BaseIterator> const & - > - { - public: - typedef BaseIterator base_iterator; - typedef mapping<base_iterator> mapping_type; - typedef segment<base_iterator> segment_type; - - segment_index_iterator() : current_(0,0),map_(0) - { - } - - segment_index_iterator(base_iterator p,mapping_type const *map,rule_type mask,bool full_select) : - map_(map), - mask_(mask), - full_select_(full_select) - { - set(p); - } - segment_index_iterator(bool is_begin,mapping_type const *map,rule_type mask,bool full_select) : - map_(map), - mask_(mask), - full_select_(full_select) - { - if(is_begin) - set_begin(); - else - set_end(); - } - - segment_type const &dereference() const - { - return value_; - } - - bool equal(segment_index_iterator const &other) const - { - return map_ == other.map_ && current_.second == other.current_.second; - } - - void increment() - { - std::pair<size_t,size_t> next = current_; - if(full_select_) { - next.first = next.second; - while(next.second < size()) { - next.second++; - if(valid_offset(next.second)) - break; - } - if(next.second == size()) - next.first = next.second - 1; - } - else { - while(next.second < size()) { - next.first = next.second; - next.second++; - if(valid_offset(next.second)) - break; - } - } - update_current(next); - } - - void decrement() - { - std::pair<size_t,size_t> next = current_; - if(full_select_) { - while(next.second >1) { - next.second--; - if(valid_offset(next.second)) - break; - } - next.first = next.second; - while(next.first >0) { - next.first--; - if(valid_offset(next.first)) - break; - } - } - else { - while(next.second >1) { - next.second--; - if(valid_offset(next.second)) - break; - } - next.first = next.second - 1; - } - update_current(next); - } - - private: - - void set_end() - { - current_.first = size() - 1; - current_.second = size(); - value_ = segment_type(map_->end(),map_->end(),0); - } - void set_begin() - { - current_.first = current_.second = 0; - value_ = segment_type(map_->begin(),map_->begin(),0); - increment(); - } - - 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)); - while(boundary_point != e && (boundary_point->rule & mask_)==0) - boundary_point++; - - current_.first = current_.second = boundary_point - b; - - if(full_select_) { - while(current_.first > 0) { - current_.first --; - if(valid_offset(current_.first)) - break; - } - } - else { - if(current_.first > 0) - current_.first --; - } - value_.first = map_->begin(); - std::advance(value_.first,get_offset(current_.first)); - value_.second = value_.first; - std::advance(value_.second,get_offset(current_.second) - get_offset(current_.first)); - - update_rule(); - } - - void update_current(std::pair<size_t,size_t> pos) - { - std::ptrdiff_t first_diff = get_offset(pos.first) - get_offset(current_.first); - std::ptrdiff_t second_diff = get_offset(pos.second) - get_offset(current_.second); - std::advance(value_.first,first_diff); - std::advance(value_.second,second_diff); - current_ = pos; - update_rule(); - } - - void update_rule() - { - if(current_.second != size()) { - value_.rule(index()[current_.second].rule); - } - } - size_t get_offset(size_t ind) const - { - if(ind == size()) - return index().back().offset; - return index()[ind].offset; - } - - bool valid_offset(size_t offset) const - { - return offset == 0 - || offset == size() // make sure we not acess index[size] - || (index()[offset].rule & mask_)!=0; - } - - size_t size() const - { - return index().size(); - } - - index_type const &index() const - { - return map_->index(); - } - +namespace boost { namespace locale { namespace boundary { + /// + /// \defgroup boundary Boundary Analysis + /// + /// This module contains all operations required for %boundary analysis of text: character, word, line and sentence + /// boundaries + /// + /// @{ + /// + + /// \cond INTERNAL + + namespace detail { + + template<typename IteratorType, + typename CategoryType = typename std::iterator_traits<IteratorType>::iterator_category> + struct mapping_traits { + typedef typename std::iterator_traits<IteratorType>::value_type char_type; + static index_type map(boundary_type t, IteratorType b, IteratorType e, const std::locale& l) + { + std::basic_string<char_type> str(b, e); + return std::use_facet<boundary_indexing<char_type>>(l).map(t, str.c_str(), str.c_str() + str.size()); + } + }; + + template<typename CharType, typename SomeIteratorType> + struct linear_iterator_traits { + static constexpr bool is_linear = + std::is_same<SomeIteratorType, CharType*>::value || std::is_same<SomeIteratorType, const CharType*>::value + || std::is_same<SomeIteratorType, typename std::basic_string<CharType>::iterator>::value + || std::is_same<SomeIteratorType, typename std::basic_string<CharType>::const_iterator>::value + || std::is_same<SomeIteratorType, typename std::vector<CharType>::iterator>::value + || std::is_same<SomeIteratorType, typename std::vector<CharType>::const_iterator>::value; + }; + + template<typename IteratorType> + struct mapping_traits<IteratorType, std::random_access_iterator_tag> { + typedef typename std::iterator_traits<IteratorType>::value_type char_type; + + static index_type map(boundary_type t, IteratorType b, IteratorType e, const std::locale& l) + { + index_type result; + + // Optimize for most common cases + // + // C++11 requires that string is continuous in memory and all known + // string implementations do this because of c_str() support. + + if(linear_iterator_traits<char_type, IteratorType>::is_linear && b != e) { + const char_type* begin = &*b; + const char_type* end = begin + (e - b); + index_type tmp = std::use_facet<boundary_indexing<char_type>>(l).map(t, begin, end); + result.swap(tmp); + } else { + std::basic_string<char_type> str(b, e); + index_type tmp = + std::use_facet<boundary_indexing<char_type>>(l).map(t, str.c_str(), str.c_str() + str.size()); + result.swap(tmp); + } + return result; + } + }; - segment_type value_; - std::pair<size_t,size_t> current_; - mapping_type const *map_; - rule_type mask_; - bool full_select_; - }; - - template<typename BaseIterator> - class boundary_point_index_iterator : - public boost::iterator_facade< - boundary_point_index_iterator<BaseIterator>, - boundary_point<BaseIterator>, - boost::bidirectional_traversal_tag, - boundary_point<BaseIterator> const & - > - { - public: - typedef BaseIterator base_iterator; - typedef mapping<base_iterator> mapping_type; - typedef boundary_point<base_iterator> boundary_point_type; - - boundary_point_index_iterator() : current_(0),map_(0) - { - } + template<typename BaseIterator> + class mapping { + public: + typedef BaseIterator base_iterator; + typedef typename std::iterator_traits<base_iterator>::value_type char_type; - boundary_point_index_iterator(bool is_begin,mapping_type const *map,rule_type mask) : - map_(map), - mask_(mask) - { - if(is_begin) - set_begin(); - else - set_end(); - } - boundary_point_index_iterator(base_iterator p,mapping_type const *map,rule_type mask) : - map_(map), - mask_(mask) - { - set(p); - } + mapping(boundary_type type, base_iterator begin, base_iterator end, const std::locale& loc) : + index_(new index_type()), begin_(begin), end_(end) + { + index_type idx = detail::mapping_traits<base_iterator>::map(type, begin, end, loc); + index_->swap(idx); + } - boundary_point_type const &dereference() const - { - return value_; - } + mapping() {} - bool equal(boundary_point_index_iterator const &other) const - { - return map_ == other.map_ && current_ == other.current_; - } + const index_type& index() const { return *index_; } - void increment() - { - size_t next = current_; - while(next < size()) { - next++; - if(valid_offset(next)) - break; - } - update_current(next); - } + base_iterator begin() const { return begin_; } - void decrement() - { - size_t next = current_; - while(next>0) { - next--; - if(valid_offset(next)) - break; - } - update_current(next); - } + base_iterator end() const { return end_; } - private: - void set_end() - { - current_ = size(); - value_ = boundary_point_type(map_->end(),0); - } - void set_begin() - { - current_ = 0; - value_ = boundary_point_type(map_->begin(),0); - } + private: + std::shared_ptr<index_type> index_; + base_iterator begin_, end_; + }; - void set(base_iterator p) - { - size_t dist = std::distance(map_->begin(),p); + template<typename BaseIterator> + class segment_index_iterator : public boost::iterator_facade<segment_index_iterator<BaseIterator>, + segment<BaseIterator>, + boost::bidirectional_traversal_tag, + const segment<BaseIterator>&> { + public: + typedef BaseIterator base_iterator; + typedef mapping<base_iterator> mapping_type; + typedef segment<base_iterator> segment_type; - 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)); + segment_index_iterator() : current_(0, 0), map_(0), mask_(0), full_select_(false) {} - if(ptr==index().end()) - current_=size()-1; - else - current_=ptr - index().begin(); + segment_index_iterator(base_iterator p, const mapping_type* map, rule_type mask, bool full_select) : + map_(map), mask_(mask), full_select_(full_select) + { + set(p); + } + segment_index_iterator(bool is_begin, const mapping_type* map, rule_type mask, bool full_select) : + map_(map), mask_(mask), full_select_(full_select) + { + if(is_begin) + set_begin(); + else + set_end(); + } - while(!valid_offset(current_)) - current_ ++; + const segment_type& dereference() const { return value_; } - std::ptrdiff_t diff = get_offset(current_) - dist; - std::advance(p,diff); - value_.iterator(p); - update_rule(); - } + bool equal(const segment_index_iterator& other) const + { + return map_ == other.map_ && current_.second == other.current_.second; + } - void update_current(size_t pos) - { - std::ptrdiff_t diff = get_offset(pos) - get_offset(current_); - base_iterator i=value_.iterator(); - std::advance(i,diff); - current_ = pos; - value_.iterator(i); - update_rule(); + void increment() + { + std::pair<size_t, size_t> next = current_; + if(full_select_) { + next.first = next.second; + while(next.second < size()) { + next.second++; + if(valid_offset(next.second)) + break; + } + if(next.second == size()) + next.first = next.second - 1; + } else { + while(next.second < size()) { + next.first = next.second; + next.second++; + if(valid_offset(next.second)) + break; } + } + update_current(next); + } - void update_rule() - { - if(current_ != size()) { - value_.rule(index()[current_].rule); - } - } - size_t get_offset(size_t ind) const - { - if(ind == size()) - return index().back().offset; - return index()[ind].offset; - } + void decrement() + { + std::pair<size_t, size_t> next = current_; + if(full_select_) { + while(next.second > 1) { + next.second--; + if(valid_offset(next.second)) + break; + } + next.first = next.second; + while(next.first > 0) { + next.first--; + if(valid_offset(next.first)) + break; + } + } else { + while(next.second > 1) { + next.second--; + if(valid_offset(next.second)) + break; + } + next.first = next.second - 1; + } + update_current(next); + } - bool valid_offset(size_t offset) const - { - return offset == 0 - || offset + 1 >= size() // last and first are always valid regardless of mark - || (index()[offset].rule & mask_)!=0; - } + private: + void set_end() + { + current_.first = size() - 1; + current_.second = size(); + value_ = segment_type(map_->end(), map_->end(), 0); + } + void set_begin() + { + current_.first = current_.second = 0; + value_ = segment_type(map_->begin(), map_->begin(), 0); + increment(); + } - size_t size() const - { - return index().size(); - } + 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)); + while(boundary_point != e && (boundary_point->rule & mask_) == 0) + boundary_point++; + + current_.first = current_.second = boundary_point - b; + + if(full_select_) { + while(current_.first > 0) { + current_.first--; + if(valid_offset(current_.first)) + break; + } + } else { + if(current_.first > 0) + current_.first--; + } + value_.first = map_->begin(); + std::advance(value_.first, get_offset(current_.first)); + value_.second = value_.first; + std::advance(value_.second, get_offset(current_.second) - get_offset(current_.first)); - index_type const &index() const - { - return map_->index(); - } + update_rule(); + } + void update_current(std::pair<size_t, size_t> pos) + { + std::ptrdiff_t first_diff = get_offset(pos.first) - get_offset(current_.first); + std::ptrdiff_t second_diff = get_offset(pos.second) - get_offset(current_.second); + std::advance(value_.first, first_diff); + std::advance(value_.second, second_diff); + current_ = pos; + update_rule(); + } - boundary_point_type value_; - size_t current_; - mapping_type const *map_; - rule_type mask_; - }; - - - } // details - - /// \endcond - - template<typename BaseIterator> - class segment_index; - - template<typename BaseIterator> - class boundary_point_index; - - - /// - /// \brief This class holds an index of segments in the text range and allows to iterate over them - /// - /// This class is provides \ref begin() and \ref end() member functions that return bidirectional iterators - /// to the \ref segment objects. - /// - /// It provides two options on way of selecting segments: - /// - /// - \ref rule(rule_type mask) - a mask that allows to select only specific types of segments according to - /// various masks %as \ref word_any. - /// \n - /// The default is to select any types of boundaries. - /// \n - /// For example: using word %boundary analysis, when the provided mask is \ref word_kana then the iterators - /// would iterate only over the words containing Kana letters and \ref word_any would select all types of - /// words excluding ranges that consist of white space and punctuation marks. So iterating over the text - /// "to be or not to be?" with \ref word_any rule would return segments "to", "be", "or", "not", "to", "be", instead - /// of default "to", " ", "be", " ", "or", " ", "not", " ", "to", " ", "be", "?". - /// - \ref full_select(bool how) - a flag that defines the way a range is selected if the rule of the previous - /// %boundary point does not fit the selected rule. - /// \n - /// For example: We want to fetch all sentences from the following text: "Hello! How\nare you?". - /// \n - /// This text contains three %boundary points separating it to sentences by different rules: - /// - The exclamation mark "!" ends the sentence "Hello!" - /// - The line feed that splits the sentence "How\nare you?" into two parts. - /// - The question mark that ends the second sentence. - /// \n - /// If you would only change the \ref rule() to \ref sentence_term then the segment_index would - /// provide two sentences "Hello!" and "are you?" %as only them actually terminated with required - /// terminator "!" or "?". But changing \ref full_select() to true, the selected segment would include - /// all the text up to previous valid %boundary point and would return two expected sentences: - /// "Hello!" and "How\nare you?". - /// - /// This class allows to find a segment according to the given iterator in range using \ref find() member - /// function. - /// - /// \note - /// - /// - Changing any of the options - \ref rule() or \ref full_select() and of course re-indexing the text - /// invalidates existing iterators and they can't be used any more. - /// - segment_index can be created from boundary_point_index or other segment_index that was created with - /// same \ref boundary_type. This is very fast operation %as they shared same index - /// and it does not require its regeneration. - /// - /// \see - /// - /// - \ref boundary_point_index - /// - \ref segment - /// - \ref boundary_point - /// - - template<typename BaseIterator> - class segment_index { - public: - - /// - /// The type of the iterator used to iterate over the original text - /// - typedef BaseIterator base_iterator; - #ifdef BOOST_LOCALE_DOXYGEN - /// - /// The bidirectional iterator that iterates over \ref value_type objects. - /// - /// - The iterators may be invalidated by use of any non-const member function - /// including but not limited to \ref rule(rule_type) and \ref full_select(bool). - /// - The returned value_type object is valid %as long %as iterator points to it. - /// So this following code is wrong %as t used after p was updated: - /// \code - /// segment_index<some_iterator>::iterator p=index.begin(); - /// segment<some_iterator> &t = *p; - /// ++p; - /// std::cout << t.str() << std::endl; - /// \endcode - /// - typedef unspecified_iterator_type iterator; - /// - /// \copydoc iterator - /// - typedef unspecified_iterator_type const_iterator; - #else - typedef details::segment_index_iterator<base_iterator> iterator; - typedef details::segment_index_iterator<base_iterator> const_iterator; - #endif - /// - /// The type dereferenced by the \ref iterator and \ref const_iterator. It is - /// an object that represents selected segment. - /// - typedef segment<base_iterator> value_type; - - /// - /// Default constructor. - /// - /// \note - /// - /// When this object is constructed by default it does not include a valid index, thus - /// calling \ref begin(), \ref end() or \ref find() member functions would lead to undefined - /// behavior - /// - segment_index() : mask_(0xFFFFFFFFu),full_select_(false) - { - } - /// - /// Create a segment_index for %boundary analysis \ref boundary_type "type" of the text - /// in range [begin,end) using a rule \a mask for locale \a loc. - /// - segment_index(boundary_type type, - base_iterator begin, - base_iterator end, - rule_type mask, - std::locale const &loc=std::locale()) - : - map_(type,begin,end,loc), - mask_(mask), - full_select_(false) - { - } - /// - /// Create a segment_index for %boundary analysis \ref boundary_type "type" of the text - /// in range [begin,end) selecting all possible segments (full mask) for locale \a loc. - /// - segment_index(boundary_type type, - base_iterator begin, - base_iterator end, - std::locale const &loc=std::locale()) - : - map_(type,begin,end,loc), - mask_(0xFFFFFFFFu), - full_select_(false) - { + void update_rule() + { + if(current_.second != size()) { + value_.rule(index()[current_.second].rule); } + } + size_t get_offset(size_t ind) const + { + if(ind == size()) + return index().back().offset; + return index()[ind].offset; + } - /// - /// Create a segment_index from a \ref boundary_point_index. It copies all indexing information - /// and used default rule (all possible segments) - /// - /// This operation is very cheap, so if you use boundary_point_index and segment_index on same text - /// range it is much better to create one from another rather then indexing the same - /// range twice. - /// - /// \note \ref rule() flags are not copied - /// - segment_index(boundary_point_index<base_iterator> const &); - /// - /// Copy an index from a \ref boundary_point_index. It copies all indexing information - /// and uses the default rule (all possible segments) - /// - /// This operation is very cheap, so if you use boundary_point_index and segment_index on same text - /// range it is much better to create one from another rather then indexing the same - /// range twice. - /// - /// \note \ref rule() flags are not copied - /// - segment_index const &operator = (boundary_point_index<base_iterator> const &); - - - /// - /// Create a new index for %boundary analysis \ref boundary_type "type" of the text - /// in range [begin,end) for locale \a loc. - /// - /// \note \ref rule() and \ref full_select() remain unchanged. - /// - void map(boundary_type type,base_iterator begin,base_iterator end,std::locale const &loc=std::locale()) - { - map_ = mapping_type(type,begin,end,loc); - } + bool valid_offset(size_t offset) const + { + return offset == 0 || offset == size() // make sure we not acess index[size] + || (index()[offset].rule & mask_) != 0; + } - /// - /// Get the \ref iterator on the beginning of the segments range. - /// - /// Preconditions: the segment_index should have a mapping - /// - /// \note - /// - /// The returned iterator is invalidated by access to any non-const member functions of this object - /// - iterator begin() const - { - return iterator(true,&map_,mask_,full_select_); - } + size_t size() const { return index().size(); } - /// - /// Get the \ref iterator on the ending of the segments range. - /// - /// Preconditions: the segment_index should have a mapping - /// - /// The returned iterator is invalidated by access to any non-const member functions of this object - /// - iterator end() const - { - return iterator(false,&map_,mask_,full_select_); - } + const index_type& index() const { return map_->index(); } - /// - /// Find a first valid segment following a position \a p. - /// - /// If \a p is inside a valid segment this segment is selected: - /// - /// For example: For \ref word %boundary analysis with \ref word_any rule(): - /// - /// - "to| be or ", would point to "be", - /// - "t|o be or ", would point to "to", - /// - "to be or| ", would point to end. - /// - /// - /// Preconditions: the segment_index should have a mapping and \a p should be valid iterator - /// to the text in the mapped range. - /// - /// The returned iterator is invalidated by access to any non-const member functions of this object - /// - iterator find(base_iterator p) const - { - return iterator(p,&map_,mask_,full_select_); - } + segment_type value_; + std::pair<size_t, size_t> current_; + const mapping_type* map_; + rule_type mask_; + bool full_select_; + }; - /// - /// Get the mask of rules that are used - /// - rule_type rule() const - { - return mask_; - } - /// - /// Set the mask of rules that are used - /// - void rule(rule_type v) - { - mask_ = v; - } + template<typename BaseIterator> + class boundary_point_index_iterator : public boost::iterator_facade<boundary_point_index_iterator<BaseIterator>, + boundary_point<BaseIterator>, + boost::bidirectional_traversal_tag, + const boundary_point<BaseIterator>&> { + public: + typedef BaseIterator base_iterator; + typedef mapping<base_iterator> mapping_type; + typedef boundary_point<base_iterator> boundary_point_type; - /// - /// Get the full_select property value - should segment include in the range - /// values that not belong to specific \ref rule() or not. - /// - /// The default value is false. - /// - /// For example for \ref sentence %boundary with rule \ref sentence_term the segments - /// of text "Hello! How\nare you?" are "Hello!\", "are you?" when full_select() is false - /// because "How\n" is selected %as sentence by a rule spits the text by line feed. If full_select() - /// is true the returned segments are "Hello! ", "How\nare you?" where "How\n" is joined with the - /// following part "are you?" - /// - - bool full_select() const - { - return full_select_; - } + boundary_point_index_iterator() : current_(0), map_(0), mask_(0) {} - /// - /// Set the full_select property value - should segment include in the range - /// values that not belong to specific \ref rule() or not. - /// - /// The default value is false. - /// - /// For example for \ref sentence %boundary with rule \ref sentence_term the segments - /// of text "Hello! How\nare you?" are "Hello!\", "are you?" when full_select() is false - /// because "How\n" is selected %as sentence by a rule spits the text by line feed. If full_select() - /// is true the returned segments are "Hello! ", "How\nare you?" where "How\n" is joined with the - /// following part "are you?" - /// - - void full_select(bool v) - { - full_select_ = v; - } + boundary_point_index_iterator(bool is_begin, const mapping_type* map, rule_type mask) : + map_(map), mask_(mask) + { + if(is_begin) + set_begin(); + else + set_end(); + } + boundary_point_index_iterator(base_iterator p, const mapping_type* map, rule_type mask) : + map_(map), mask_(mask) + { + set(p); + } - private: - friend class boundary_point_index<base_iterator>; - typedef details::mapping<base_iterator> mapping_type; - mapping_type map_; - rule_type mask_; - bool full_select_; - }; - - /// - /// \brief This class holds an index of \ref boundary_point "boundary points" and allows iterating - /// over them. - /// - /// This class is provides \ref begin() and \ref end() member functions that return bidirectional iterators - /// to the \ref boundary_point objects. - /// - /// It provides an option that affects selecting %boundary points according to different rules: - /// using \ref rule(rule_type mask) member function. It allows to set a mask that select only specific - /// types of %boundary points like \ref sentence_term. - /// - /// For example for a sentence %boundary analysis of a text "Hello! How\nare you?" when the default - /// rule is used the %boundary points would be: - /// - /// - "|Hello! How\nare you?" - /// - "Hello! |How\nare you?" - /// - "Hello! How\n|are you?" - /// - "Hello! How\nare you?|" - /// - /// However if \ref rule() is set to \ref sentence_term then the selected %boundary points would be: - /// - /// - "|Hello! How\nare you?" - /// - "Hello! |How\nare you?" - /// - "Hello! How\nare you?|" - /// - /// Such that a %boundary point defined by a line feed character would be ignored. - /// - /// This class allows to find a boundary_point according to the given iterator in range using \ref find() member - /// function. - /// - /// \note - /// - Even an empty text range [x,x) considered to have a one %boundary point x. - /// - \a a and \a b points of the range [a,b) are always considered %boundary points - /// regardless the rules used. - /// - Changing any of the option \ref rule() or course re-indexing the text - /// invalidates existing iterators and they can't be used any more. - /// - boundary_point_index can be created from segment_index or other boundary_point_index that was created with - /// same \ref boundary_type. This is very fast operation %as they shared same index - /// and it does not require its regeneration. - /// - /// \see - /// - /// - \ref segment_index - /// - \ref boundary_point - /// - \ref segment - /// - - - template<typename BaseIterator> - class boundary_point_index { - public: - /// - /// The type of the iterator used to iterate over the original text - /// - typedef BaseIterator base_iterator; - #ifdef BOOST_LOCALE_DOXYGEN - /// - /// The bidirectional iterator that iterates over \ref value_type objects. - /// - /// - The iterators may be invalidated by use of any non-const member function - /// including but not limited to \ref rule(rule_type) member function. - /// - The returned value_type object is valid %as long %as iterator points to it. - /// So this following code is wrong %as t used after p was updated: - /// \code - /// boundary_point_index<some_iterator>::iterator p=index.begin(); - /// boundary_point<some_iterator> &t = *p; - /// ++p; - /// rule_type r = t->rule(); - /// \endcode - /// - typedef unspecified_iterator_type iterator; - /// - /// \copydoc iterator - /// - typedef unspecified_iterator_type const_iterator; - #else - typedef details::boundary_point_index_iterator<base_iterator> iterator; - typedef details::boundary_point_index_iterator<base_iterator> const_iterator; - #endif - /// - /// The type dereferenced by the \ref iterator and \ref const_iterator. It is - /// an object that represents the selected \ref boundary_point "boundary point". - /// - typedef boundary_point<base_iterator> value_type; - - /// - /// Default constructor. - /// - /// \note - /// - /// When this object is constructed by default it does not include a valid index, thus - /// calling \ref begin(), \ref end() or \ref find() member functions would lead to undefined - /// behavior - /// - boundary_point_index() : mask_(0xFFFFFFFFu) - { - } + const boundary_point_type& dereference() const { return value_; } - /// - /// Create a segment_index for %boundary analysis \ref boundary_type "type" of the text - /// in range [begin,end) using a rule \a mask for locale \a loc. - /// - boundary_point_index(boundary_type type, - base_iterator begin, - base_iterator end, - rule_type mask, - std::locale const &loc=std::locale()) - : - map_(type,begin,end,loc), - mask_(mask) - { - } - /// - /// Create a segment_index for %boundary analysis \ref boundary_type "type" of the text - /// in range [begin,end) selecting all possible %boundary points (full mask) for locale \a loc. - /// - boundary_point_index(boundary_type type, - base_iterator begin, - base_iterator end, - std::locale const &loc=std::locale()) - : - map_(type,begin,end,loc), - mask_(0xFFFFFFFFu) - { - } + bool equal(const boundary_point_index_iterator& other) const + { + return map_ == other.map_ && current_ == other.current_; + } - /// - /// Create a boundary_point_index from a \ref segment_index. It copies all indexing information - /// and uses the default rule (all possible %boundary points) - /// - /// This operation is very cheap, so if you use boundary_point_index and segment_index on same text - /// range it is much better to create one from another rather then indexing the same - /// range twice. - /// - /// \note \ref rule() flags are not copied - /// - boundary_point_index(segment_index<base_iterator> const &other); - /// - /// Copy a boundary_point_index from a \ref segment_index. It copies all indexing information - /// and keeps the current \ref rule() unchanged - /// - /// This operation is very cheap, so if you use boundary_point_index and segment_index on same text - /// range it is much better to create one from another rather then indexing the same - /// range twice. - /// - /// \note \ref rule() flags are not copied - /// - boundary_point_index const &operator=(segment_index<base_iterator> const &other); - - /// - /// Create a new index for %boundary analysis \ref boundary_type "type" of the text - /// in range [begin,end) for locale \a loc. - /// - /// \note \ref rule() remains unchanged. - /// - void map(boundary_type type,base_iterator begin,base_iterator end,std::locale const &loc=std::locale()) - { - map_ = mapping_type(type,begin,end,loc); + void increment() + { + size_t next = current_; + while(next < size()) { + next++; + if(valid_offset(next)) + break; } + update_current(next); + } - /// - /// Get the \ref iterator on the beginning of the %boundary points range. - /// - /// Preconditions: this boundary_point_index should have a mapping - /// - /// \note - /// - /// The returned iterator is invalidated by access to any non-const member functions of this object - /// - iterator begin() const - { - return iterator(true,&map_,mask_); + void decrement() + { + size_t next = current_; + while(next > 0) { + next--; + if(valid_offset(next)) + break; } + update_current(next); + } - /// - /// Get the \ref iterator on the ending of the %boundary points range. - /// - /// Preconditions: this boundary_point_index should have a mapping - /// - /// \note - /// - /// The returned iterator is invalidated by access to any non-const member functions of this object - /// - iterator end() const - { - return iterator(false,&map_,mask_); - } + private: + void set_end() + { + current_ = size(); + value_ = boundary_point_type(map_->end(), 0); + } + void set_begin() + { + current_ = 0; + value_ = boundary_point_type(map_->begin(), 0); + } - /// - /// Find a first valid %boundary point on a position \a p or following it. - /// - /// For example: For \ref word %boundary analysis of the text "to be or" - /// - /// - "|to be", would return %boundary point at "|to be", - /// - "t|o be", would point to "to| be" - /// - /// Preconditions: the boundary_point_index should have a mapping and \a p should be valid iterator - /// to the text in the mapped range. - /// - /// The returned iterator is invalidated by access to any non-const member functions of this object - /// - iterator find(base_iterator p) const - { - return iterator(p,&map_,mask_); - } + void set(base_iterator p) + { + size_t dist = std::distance(map_->begin(), p); - /// - /// Get the mask of rules that are used - /// - rule_type rule() const - { - return mask_; - } - /// - /// Set the mask of rules that are used - /// - void rule(rule_type v) - { - mask_ = v; - } + 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)); - private: + if(ptr == index().end()) + current_ = size() - 1; + else + current_ = ptr - index().begin(); - friend class segment_index<base_iterator>; - typedef details::mapping<base_iterator> mapping_type; - mapping_type map_; - rule_type mask_; - }; + while(!valid_offset(current_)) + current_++; - /// \cond INTERNAL - template<typename BaseIterator> - segment_index<BaseIterator>::segment_index(boundary_point_index<BaseIterator> const &other) : - map_(other.map_), - mask_(0xFFFFFFFFu), - full_select_(false) - { + std::ptrdiff_t diff = get_offset(current_) - dist; + std::advance(p, diff); + value_.iterator(p); + update_rule(); } - template<typename BaseIterator> - boundary_point_index<BaseIterator>::boundary_point_index(segment_index<BaseIterator> const &other) : - map_(other.map_), - mask_(0xFFFFFFFFu) + void update_current(size_t pos) { + std::ptrdiff_t diff = get_offset(pos) - get_offset(current_); + base_iterator i = value_.iterator(); + std::advance(i, diff); + current_ = pos; + value_.iterator(i); + update_rule(); } - template<typename BaseIterator> - segment_index<BaseIterator> const &segment_index<BaseIterator>::operator=(boundary_point_index<BaseIterator> const &other) + void update_rule() { - map_ = other.map_; - return *this; + if(current_ != size()) { + value_.rule(index()[current_].rule); + } + } + size_t get_offset(size_t ind) const + { + if(ind == size()) + return index().back().offset; + return index()[ind].offset; } - template<typename BaseIterator> - boundary_point_index<BaseIterator> const &boundary_point_index<BaseIterator>::operator=(segment_index<BaseIterator> const &other) + bool valid_offset(size_t offset) const { - map_ = other.map_; - return *this; + return offset == 0 || offset + 1 >= size() // last and first are always valid regardless of mark + || (index()[offset].rule & mask_) != 0; } - /// \endcond - - typedef segment_index<std::string::const_iterator> ssegment_index; ///< convenience typedef - typedef segment_index<std::wstring::const_iterator> wssegment_index; ///< convenience typedef - #ifdef BOOST_LOCALE_ENABLE_CHAR16_T - typedef segment_index<std::u16string::const_iterator> u16ssegment_index;///< convenience typedef - #endif - #ifdef BOOST_LOCALE_ENABLE_CHAR32_T - typedef segment_index<std::u32string::const_iterator> u32ssegment_index;///< convenience typedef - #endif - - typedef segment_index<char const *> csegment_index; ///< convenience typedef - typedef segment_index<wchar_t const *> wcsegment_index; ///< convenience typedef - #ifdef BOOST_LOCALE_ENABLE_CHAR16_T - typedef segment_index<char16_t const *> u16csegment_index; ///< convenience typedef - #endif - #ifdef BOOST_LOCALE_ENABLE_CHAR32_T - typedef segment_index<char32_t const *> u32csegment_index; ///< convenience typedef - #endif - - typedef boundary_point_index<std::string::const_iterator> sboundary_point_index;///< convenience typedef - typedef boundary_point_index<std::wstring::const_iterator> wsboundary_point_index;///< convenience typedef - #ifdef BOOST_LOCALE_ENABLE_CHAR16_T - typedef boundary_point_index<std::u16string::const_iterator> u16sboundary_point_index;///< convenience typedef - #endif - #ifdef BOOST_LOCALE_ENABLE_CHAR32_T - typedef boundary_point_index<std::u32string::const_iterator> u32sboundary_point_index;///< convenience typedef - #endif - - typedef boundary_point_index<char const *> cboundary_point_index; ///< convenience typedef - typedef boundary_point_index<wchar_t const *> wcboundary_point_index; ///< convenience typedef - #ifdef BOOST_LOCALE_ENABLE_CHAR16_T - typedef boundary_point_index<char16_t const *> u16cboundary_point_index;///< convenience typedef - #endif - #ifdef BOOST_LOCALE_ENABLE_CHAR32_T - typedef boundary_point_index<char32_t const *> u32cboundary_point_index;///< convenience typedef - #endif - - - - } // boundary - - } // locale -} // boost + + size_t size() const { return index().size(); } + + const index_type& index() const { return map_->index(); } + + boundary_point_type value_; + size_t current_; + const mapping_type* map_; + rule_type mask_; + }; + + } // namespace detail + + /// \endcond + + template<typename BaseIterator> + class segment_index; + + template<typename BaseIterator> + class boundary_point_index; + + /// \brief This class holds an index of segments in the text range and allows to iterate over them + /// + /// This class is provides \ref begin() and \ref end() member functions that return bidirectional iterators + /// to the \ref segment objects. + /// + /// It provides two options on way of selecting segments: + /// + /// - \ref rule(rule_type mask) - a mask that allows to select only specific types of segments according to + /// various masks %as \ref word_any. + /// \n + /// The default is to select any types of boundaries. + /// \n + /// For example: using word %boundary analysis, when the provided mask is \ref word_kana then the iterators + /// would iterate only over the words containing Kana letters and \ref word_any would select all types of + /// words excluding ranges that consist of white space and punctuation marks. So iterating over the text + /// "to be or not to be?" with \ref word_any rule would return segments "to", "be", "or", "not", "to", "be", + /// instead of default "to", " ", "be", " ", "or", " ", "not", " ", "to", " ", "be", "?". + /// - \ref full_select(bool how) - a flag that defines the way a range is selected if the rule of the previous + /// %boundary point does not fit the selected rule. + /// \n + /// For example: We want to fetch all sentences from the following text: "Hello! How\nare you?". + /// \n + /// This text contains three %boundary points separating it to sentences by different rules: + /// - The exclamation mark "!" ends the sentence "Hello!" + /// - The line feed that splits the sentence "How\nare you?" into two parts. + /// - The question mark that ends the second sentence. + /// \n + /// If you would only change the \ref rule() to \ref sentence_term then the segment_index would + /// provide two sentences "Hello!" and "are you?" %as only them actually terminated with required + /// terminator "!" or "?". But changing \ref full_select() to true, the selected segment would include + /// all the text up to previous valid %boundary point and would return two expected sentences: + /// "Hello!" and "How\nare you?". + /// + /// This class allows to find a segment according to the given iterator in range using \ref find() member + /// function. + /// + /// \note + /// + /// - Changing any of the options - \ref rule() or \ref full_select() and of course re-indexing the text + /// invalidates existing iterators and they can't be used any more. + /// - segment_index can be created from boundary_point_index or other segment_index that was created with + /// same \ref boundary_type. This is very fast operation %as they shared same index + /// and it does not require its regeneration. + /// + /// \see + /// + /// - \ref boundary_point_index + /// - \ref segment + /// - \ref boundary_point + + template<typename BaseIterator> + class segment_index { + public: + /// The type of the iterator used to iterate over the original text + typedef BaseIterator base_iterator; + +#ifdef BOOST_LOCALE_DOXYGEN + /// The bidirectional iterator that iterates over \ref value_type objects. + /// + /// - The iterators may be invalidated by use of any non-const member function + /// including but not limited to \ref rule(rule_type) and \ref full_select(bool). + /// - The returned value_type object is valid %as long %as iterator points to it. + /// So this following code is wrong %as t used after p was updated: + /// \code + /// segment_index<some_iterator>::iterator p=index.begin(); + /// segment<some_iterator> &t = *p; + /// ++p; + /// std::cout << t.str() << std::endl; + /// \endcode + typedef unspecified_iterator_type iterator; + /// \copydoc iterator + typedef unspecified_iterator_type const_iterator; +#else + typedef detail::segment_index_iterator<base_iterator> iterator; + typedef detail::segment_index_iterator<base_iterator> const_iterator; +#endif + /// The type dereferenced by the \ref iterator and \ref const_iterator. It is + /// an object that represents selected segment. + typedef segment<base_iterator> value_type; + + /// Default constructor. + /// + /// \note + /// + /// When this object is constructed by default it does not include a valid index, thus + /// calling \ref begin(), \ref end() or \ref find() member functions would lead to undefined + /// behavior + segment_index() : mask_(0xFFFFFFFFu), full_select_(false) {} + /// Create a segment_index for %boundary analysis \ref boundary_type "type" of the text + /// in range [begin,end) using a rule \a mask for locale \a loc. + segment_index(boundary_type type, + base_iterator begin, + base_iterator end, + rule_type mask, + const std::locale& loc = std::locale()) : + map_(type, begin, end, loc), + mask_(mask), full_select_(false) + {} + /// Create a segment_index for %boundary analysis \ref boundary_type "type" of the text + /// in range [begin,end) selecting all possible segments (full mask) for locale \a loc. + segment_index(boundary_type type, + base_iterator begin, + base_iterator end, + const std::locale& loc = std::locale()) : + map_(type, begin, end, loc), + mask_(0xFFFFFFFFu), full_select_(false) + {} + + /// Create a segment_index from a \ref boundary_point_index. It copies all indexing information + /// and used default rule (all possible segments) + /// + /// This operation is very cheap, so if you use boundary_point_index and segment_index on same text + /// range it is much better to create one from another rather then indexing the same + /// range twice. + /// + /// \note \ref rule() flags are not copied + segment_index(const boundary_point_index<base_iterator>&); + + /// Copy an index from a \ref boundary_point_index. It copies all indexing information + /// and uses the default rule (all possible segments) + /// + /// This operation is very cheap, so if you use boundary_point_index and segment_index on same text + /// range it is much better to create one from another rather then indexing the same + /// range twice. + /// + /// \note \ref rule() flags are not copied + segment_index& operator=(const boundary_point_index<base_iterator>&); + + /// Create a new index for %boundary analysis \ref boundary_type "type" of the text + /// in range [begin,end) for locale \a loc. + /// + /// \note \ref rule() and \ref full_select() remain unchanged. + void map(boundary_type type, base_iterator begin, base_iterator end, const std::locale& loc = std::locale()) + { + map_ = mapping_type(type, begin, end, loc); + } + + /// Get the \ref iterator on the beginning of the segments range. + /// + /// Preconditions: the segment_index should have a mapping + /// + /// \note + /// + /// The returned iterator is invalidated by access to any non-const member functions of this object + iterator begin() const + { + return iterator(true, &map_, mask_, full_select_); + } + + /// Get the \ref iterator on the ending of the segments range. + /// + /// Preconditions: the segment_index should have a mapping + /// + /// The returned iterator is invalidated by access to any non-const member functions of this object + iterator end() const + { + return iterator(false, &map_, mask_, full_select_); + } + + /// Find a first valid segment following a position \a p. + /// + /// If \a p is inside a valid segment this segment is selected: + /// + /// For example: For \ref word %boundary analysis with \ref word_any rule(): + /// + /// - "to| be or ", would point to "be", + /// - "t|o be or ", would point to "to", + /// - "to be or| ", would point to end. + /// + /// + /// Preconditions: the segment_index should have a mapping and \a p should be valid iterator + /// to the text in the mapped range. + /// + /// The returned iterator is invalidated by access to any non-const member functions of this object + iterator find(base_iterator p) const + { + return iterator(p, &map_, mask_, full_select_); + } + + /// Get the mask of rules that are used + rule_type rule() const + { + return mask_; + } + /// Set the mask of rules that are used + void rule(rule_type v) + { + mask_ = v; + } + + /// Get the full_select property value - should segment include in the range + /// values that not belong to specific \ref rule() or not. + /// + /// The default value is false. + /// + /// For example for \ref sentence %boundary with rule \ref sentence_term the segments + /// of text "Hello! How\nare you?" are "Hello!\", "are you?" when full_select() is false + /// because "How\n" is selected %as sentence by a rule spits the text by line feed. If full_select() + /// is true the returned segments are "Hello! ", "How\nare you?" where "How\n" is joined with the + /// following part "are you?" + bool full_select() const + { + return full_select_; + } + + /// Set the full_select property value - should segment include in the range + /// values that not belong to specific \ref rule() or not. + /// + /// The default value is false. + /// + /// For example for \ref sentence %boundary with rule \ref sentence_term the segments + /// of text "Hello! How\nare you?" are "Hello!\", "are you?" when full_select() is false + /// because "How\n" is selected %as sentence by a rule spits the text by line feed. If full_select() + /// is true the returned segments are "Hello! ", "How\nare you?" where "How\n" is joined with the + /// following part "are you?" + void full_select(bool v) + { + full_select_ = v; + } + + private: + friend class boundary_point_index<base_iterator>; + typedef detail::mapping<base_iterator> mapping_type; + mapping_type map_; + rule_type mask_; + bool full_select_; + }; + + /// \brief This class holds an index of \ref boundary_point "boundary points" and allows iterating + /// over them. + /// + /// This class is provides \ref begin() and \ref end() member functions that return bidirectional iterators + /// to the \ref boundary_point objects. + /// + /// It provides an option that affects selecting %boundary points according to different rules: + /// using \ref rule(rule_type mask) member function. It allows to set a mask that select only specific + /// types of %boundary points like \ref sentence_term. + /// + /// For example for a sentence %boundary analysis of a text "Hello! How\nare you?" when the default + /// rule is used the %boundary points would be: + /// + /// - "|Hello! How\nare you?" + /// - "Hello! |How\nare you?" + /// - "Hello! How\n|are you?" + /// - "Hello! How\nare you?|" + /// + /// However if \ref rule() is set to \ref sentence_term then the selected %boundary points would be: + /// + /// - "|Hello! How\nare you?" + /// - "Hello! |How\nare you?" + /// - "Hello! How\nare you?|" + /// + /// Such that a %boundary point defined by a line feed character would be ignored. + /// + /// This class allows to find a boundary_point according to the given iterator in range using \ref find() member + /// function. + /// + /// \note + /// - Even an empty text range [x,x) considered to have a one %boundary point x. + /// - \a a and \a b points of the range [a,b) are always considered %boundary points + /// regardless the rules used. + /// - Changing any of the option \ref rule() or course re-indexing the text + /// invalidates existing iterators and they can't be used any more. + /// - boundary_point_index can be created from segment_index or other boundary_point_index that was created with + /// same \ref boundary_type. This is very fast operation %as they shared same index + /// and it does not require its regeneration. + /// + /// \see + /// + /// - \ref segment_index + /// - \ref boundary_point + /// - \ref segment + template<typename BaseIterator> + class boundary_point_index { + public: + /// The type of the iterator used to iterate over the original text + typedef BaseIterator base_iterator; + +#ifdef BOOST_LOCALE_DOXYGEN + /// The bidirectional iterator that iterates over \ref value_type objects. + /// + /// - The iterators may be invalidated by use of any non-const member function + /// including but not limited to \ref rule(rule_type) member function. + /// - The returned value_type object is valid %as long %as iterator points to it. + /// So this following code is wrong %as t used after p was updated: + /// \code + /// boundary_point_index<some_iterator>::iterator p=index.begin(); + /// boundary_point<some_iterator> &t = *p; + /// ++p; + /// rule_type r = t->rule(); + /// \endcode + /// + typedef unspecified_iterator_type iterator; + /// \copydoc iterator + typedef unspecified_iterator_type const_iterator; +#else + typedef detail::boundary_point_index_iterator<base_iterator> iterator; + typedef detail::boundary_point_index_iterator<base_iterator> const_iterator; +#endif + /// The type dereferenced by the \ref iterator and \ref const_iterator. It is + /// an object that represents the selected \ref boundary_point "boundary point". + typedef boundary_point<base_iterator> value_type; + + /// Default constructor. + /// + /// \note + /// + /// When this object is constructed by default it does not include a valid index, thus + /// calling \ref begin(), \ref end() or \ref find() member functions would lead to undefined + /// behavior + boundary_point_index() : mask_(0xFFFFFFFFu) {} + + /// Create a segment_index for %boundary analysis \ref boundary_type "type" of the text + /// in range [begin,end) using a rule \a mask for locale \a loc. + boundary_point_index(boundary_type type, + base_iterator begin, + base_iterator end, + rule_type mask, + const std::locale& loc = std::locale()) : + map_(type, begin, end, loc), + mask_(mask) + {} + /// Create a segment_index for %boundary analysis \ref boundary_type "type" of the text + /// in range [begin,end) selecting all possible %boundary points (full mask) for locale \a loc. + boundary_point_index(boundary_type type, + base_iterator begin, + base_iterator end, + const std::locale& loc = std::locale()) : + map_(type, begin, end, loc), + mask_(0xFFFFFFFFu) + {} + + /// Create a boundary_point_index from a \ref segment_index. It copies all indexing information + /// and uses the default rule (all possible %boundary points) + /// + /// This operation is very cheap, so if you use boundary_point_index and segment_index on the same text + /// range it is much better to create one from another rather then indexing the same + /// range twice. + /// + /// \note \ref rule() flags are not copied + boundary_point_index(const segment_index<base_iterator>& other); + /// Copy a boundary_point_index from a \ref segment_index. It copies all indexing information + /// and keeps the current \ref rule() unchanged + /// + /// This operation is very cheap, so if you use boundary_point_index and segment_index on the same text + /// range it is much better to create one from another rather then indexing the same + /// range twice. + /// + /// \note \ref rule() flags are not copied + boundary_point_index& operator=(const segment_index<base_iterator>& other); + + /// Create a new index for %boundary analysis \ref boundary_type "type" of the text + /// in range [begin,end) for locale \a loc. + /// + /// \note \ref rule() remains unchanged. + void map(boundary_type type, base_iterator begin, base_iterator end, const std::locale& loc = std::locale()) + { + map_ = mapping_type(type, begin, end, loc); + } + + /// Get the \ref iterator on the beginning of the %boundary points range. + /// + /// Preconditions: this boundary_point_index should have a mapping + /// + /// \note + /// + /// The returned iterator is invalidated by access to any non-const member functions of this object + iterator begin() const + { + return iterator(true, &map_, mask_); + } + + /// Get the \ref iterator on the ending of the %boundary points range. + /// + /// Preconditions: this boundary_point_index should have a mapping + /// + /// \note + /// + /// The returned iterator is invalidated by access to any non-const member functions of this object + iterator end() const + { + return iterator(false, &map_, mask_); + } + + /// Find a first valid %boundary point on a position \a p or following it. + /// + /// For example: For \ref word %boundary analysis of the text "to be or" + /// + /// - "|to be", would return %boundary point at "|to be", + /// - "t|o be", would point to "to| be" + /// + /// Preconditions: the boundary_point_index should have a mapping and \a p should be valid iterator + /// to the text in the mapped range. + /// + /// The returned iterator is invalidated by access to any non-const member functions of this object + iterator find(base_iterator p) const + { + return iterator(p, &map_, mask_); + } + + /// Get the mask of rules that are used + rule_type rule() const + { + return mask_; + } + /// Set the mask of rules that are used + void rule(rule_type v) + { + mask_ = v; + } + + private: + friend class segment_index<base_iterator>; + typedef detail::mapping<base_iterator> mapping_type; + mapping_type map_; + rule_type mask_; + }; + + /// \cond INTERNAL + template<typename BaseIterator> + segment_index<BaseIterator>::segment_index(const boundary_point_index<BaseIterator>& other) : + map_(other.map_), mask_(0xFFFFFFFFu), full_select_(false) + {} + + template<typename BaseIterator> + boundary_point_index<BaseIterator>::boundary_point_index(const segment_index<BaseIterator>& other) : + map_(other.map_), mask_(0xFFFFFFFFu) + {} + + template<typename BaseIterator> + segment_index<BaseIterator>& segment_index<BaseIterator>::operator=(const boundary_point_index<BaseIterator>& other) + { + map_ = other.map_; + return *this; + } + + template<typename BaseIterator> + boundary_point_index<BaseIterator>& + boundary_point_index<BaseIterator>::operator=(const segment_index<BaseIterator>& other) + { + map_ = other.map_; + return *this; + } + /// \endcond + + typedef segment_index<std::string::const_iterator> ssegment_index; ///< convenience typedef + typedef segment_index<std::wstring::const_iterator> wssegment_index; ///< convenience typedef +#ifdef BOOST_LOCALE_ENABLE_CHAR16_T + typedef segment_index<std::u16string::const_iterator> u16ssegment_index; ///< convenience typedef +#endif +#ifdef BOOST_LOCALE_ENABLE_CHAR32_T + typedef segment_index<std::u32string::const_iterator> u32ssegment_index; ///< convenience typedef +#endif + + typedef segment_index<const char*> csegment_index; ///< convenience typedef + typedef segment_index<const wchar_t*> wcsegment_index; ///< convenience typedef +#ifdef BOOST_LOCALE_ENABLE_CHAR16_T + typedef segment_index<const char16_t*> u16csegment_index; ///< convenience typedef +#endif +#ifdef BOOST_LOCALE_ENABLE_CHAR32_T + typedef segment_index<const char32_t*> u32csegment_index; ///< convenience typedef +#endif + + typedef boundary_point_index<std::string::const_iterator> sboundary_point_index; ///< convenience typedef + typedef boundary_point_index<std::wstring::const_iterator> wsboundary_point_index; ///< convenience typedef +#ifdef BOOST_LOCALE_ENABLE_CHAR16_T + typedef boundary_point_index<std::u16string::const_iterator> u16sboundary_point_index; ///< convenience typedef +#endif +#ifdef BOOST_LOCALE_ENABLE_CHAR32_T + typedef boundary_point_index<std::u32string::const_iterator> u32sboundary_point_index; ///< convenience typedef +#endif + + typedef boundary_point_index<const char*> cboundary_point_index; ///< convenience typedef + typedef boundary_point_index<const wchar_t*> wcboundary_point_index; ///< convenience typedef +#ifdef BOOST_LOCALE_ENABLE_CHAR16_T + typedef boundary_point_index<const char16_t*> u16cboundary_point_index; ///< convenience typedef +#endif +#ifdef BOOST_LOCALE_ENABLE_CHAR32_T + typedef boundary_point_index<const char32_t*> u32cboundary_point_index; ///< convenience typedef +#endif + +}}} // namespace boost::locale::boundary /// /// \example boundary.cpp @@ -1083,7 +909,7 @@ namespace boost { /// #ifdef BOOST_MSVC -#pragma warning(pop) +# pragma warning(pop) #endif #endif diff --git a/contrib/restricted/boost/locale/include/boost/locale/boundary/segment.hpp b/contrib/restricted/boost/locale/include/boost/locale/boundary/segment.hpp index 6260f59faa..68146b3df9 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/boundary/segment.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/boundary/segment.hpp @@ -8,86 +8,76 @@ #define BOOST_LOCALE_BOUNDARY_SEGMENT_HPP_INCLUDED #include <boost/locale/config.hpp> +#include <boost/locale/util/string.hpp> #include <iosfwd> #include <iterator> #include <locale> #include <string> #ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4275 4251 4231 4660) +# pragma warning(push) +# pragma warning(disable : 4275 4251 4231 4660) #endif -namespace boost { -namespace locale { -namespace boundary { +namespace boost { namespace locale { namespace boundary { /// \cond INTERNAL - namespace details { - template<typename LeftIterator,typename RightIterator> - int compare_text(LeftIterator l_begin,LeftIterator l_end,RightIterator r_begin,RightIterator r_end) + namespace detail { + template<typename LeftIterator, typename RightIterator> + int compare_text(LeftIterator l_begin, LeftIterator l_end, RightIterator r_begin, RightIterator r_end) { typedef LeftIterator left_iterator; typedef typename std::iterator_traits<left_iterator>::value_type char_type; typedef std::char_traits<char_type> traits; - while(l_begin!=l_end && r_begin!=r_end) { + while(l_begin != l_end && r_begin != r_end) { char_type lchar = *l_begin++; char_type rchar = *r_begin++; - if(traits::eq(lchar,rchar)) + if(traits::eq(lchar, rchar)) continue; - if(traits::lt(lchar,rchar)) + if(traits::lt(lchar, rchar)) return -1; else return 1; } - if(l_begin==l_end && r_begin==r_end) + if(l_begin == l_end && r_begin == r_end) return 0; - if(l_begin==l_end) + if(l_begin == l_end) return -1; else return 1; } - - template<typename Left,typename Right> - int compare_text(Left const &l,Right const &r) + template<typename Left, typename Right> + int compare_text(const Left& l, const Right& r) { - return compare_text(l.begin(),l.end(),r.begin(),r.end()); + return compare_text(l.begin(), l.end(), r.begin(), r.end()); } - template<typename Left,typename Char> - int compare_string(Left const &l,Char const *begin) + template<typename Left, typename Char> + int compare_string(const Left& l, const Char* begin) { - Char const *end = begin; - while(*end!=0) - end++; - return compare_text(l.begin(),l.end(),begin,end); + return compare_text(l.begin(), l.end(), begin, util::str_end(begin)); } - template<typename Right,typename Char> - int compare_string(Char const *begin,Right const &r) + template<typename Right, typename Char> + int compare_string(const Char* begin, const Right& r) { - Char const *end = begin; - while(*end!=0) - end++; - return compare_text(begin,end,r.begin(),r.end()); + return compare_text(begin, util::str_end(begin), r.begin(), r.end()); } - } + } // namespace detail /// \endcond - /// /// \addtogroup boundary /// @{ - /// /// \brief a segment object that represents a pair of two iterators that define the range where /// this segment exits and a rule that defines it. /// /// This type of object is dereferenced by the iterators of segment_index. Using a rule() member function /// you can get a specific rule this segment was selected with. For example, when you use - /// word boundary analysis, you can check if the specific word contains Kana letters by checking (rule() & \ref word_kana)!=0 - /// For a sentence analysis you can check if the sentence is selected because a sentence terminator is found (\ref sentence_term) or - /// there is a line break (\ref sentence_sep). + /// word boundary analysis, you can check if the specific word contains Kana letters by checking (rule() & \ref + /// word_kana)!=0 For a sentence analysis you can check if the sentence is selected because a sentence terminator is + /// found (\ref sentence_term) or there is a line break (\ref sentence_sep). /// /// This object can be automatically converted to std::basic_string with the same type of character. It is also /// valid range that has begin() and end() member functions returning iterators on the location of the segment. @@ -97,386 +87,292 @@ namespace boundary { /// - \ref segment_index /// - \ref boundary_point /// - \ref boundary_point_index - /// template<typename IteratorType> - class segment : public std::pair<IteratorType,IteratorType> { + class segment : public std::pair<IteratorType, IteratorType> { public: - /// /// The type of the underlying character - /// typedef typename std::iterator_traits<IteratorType>::value_type char_type; - /// /// The type of the string it is converted to - /// typedef std::basic_string<char_type> string_type; - /// /// The value that iterators return - the character itself - /// typedef char_type value_type; - /// /// The iterator that allows to iterate the range - /// typedef IteratorType iterator; - /// /// The iterator that allows to iterate the range - /// typedef IteratorType const_iterator; - /// /// The type that represent a difference between two iterators - /// typedef typename std::iterator_traits<IteratorType>::difference_type difference_type; - /// /// Default constructor - /// - segment() {} - /// + segment() : rule_(0) {} /// Create a segment using two iterators and a rule that represents this point - /// - segment(iterator b,iterator e,rule_type r) : - std::pair<IteratorType,IteratorType>(b,e), - rule_(r) - { - } - /// + segment(iterator b, iterator e, rule_type r) : std::pair<IteratorType, IteratorType>(b, e), rule_(r) {} /// Set the start of the range - /// - void begin(iterator const &v) - { - this->first = v; - } - /// + void begin(const iterator& v) { this->first = v; } /// Set the end of the range - /// - void end(iterator const &v) - { - this->second = v; - } + void end(const iterator& v) { this->second = v; } - /// /// Get the start of the range - /// - IteratorType begin() const - { - return this->first; - } - /// + IteratorType begin() const { return this->first; } /// Set the end of the range - /// - IteratorType end() const - { - return this->second; - } + IteratorType end() const { return this->second; } - /// /// Convert the range to a string automatically - /// - template <class T, class A> - operator std::basic_string<char_type, T, A> ()const + template<class T, class A> + operator std::basic_string<char_type, T, A>() const { return std::basic_string<char_type, T, A>(this->first, this->second); } - /// /// Create a string from the range explicitly - /// - string_type str() const - { - return string_type(begin(),end()); - } + string_type str() const { return string_type(begin(), end()); } - /// /// Get the length of the text chunk - /// - - size_t length() const - { - return std::distance(begin(),end()); - } + size_t length() const { return std::distance(begin(), end()); } - /// /// Check if the segment is empty - /// - bool empty() const - { - return begin() == end(); - } + bool empty() const { return begin() == end(); } - /// /// Get the rule that is used for selection of this segment. - /// - rule_type rule() const - { - return rule_; - } - /// + rule_type rule() const { return rule_; } /// Set a rule that is used for segment selection - /// - void rule(rule_type r) - { - rule_ = r; - } + void rule(rule_type r) { rule_ = r; } // make sure we override std::pair's operator== /// Compare two segments - bool operator==(segment const &other) const - { - return details::compare_text(*this,other) == 0; - } - + bool operator==(const segment& other) const { return detail::compare_text(*this, other) == 0; } /// Compare two segments - bool operator!=(segment const &other) const - { - return details::compare_text(*this,other) != 0; - } + bool operator!=(const segment& other) const { return detail::compare_text(*this, other) != 0; } private: rule_type rule_; - }; - /// Compare two segments - template<typename IteratorL,typename IteratorR> - bool operator==(segment<IteratorL> const &l,segment<IteratorR> const &r) + template<typename IteratorL, typename IteratorR> + bool operator==(const segment<IteratorL>& l, const segment<IteratorR>& r) { - return details::compare_text(l,r) == 0; + return detail::compare_text(l, r) == 0; } /// Compare two segments - template<typename IteratorL,typename IteratorR> - bool operator!=(segment<IteratorL> const &l,segment<IteratorR> const &r) + template<typename IteratorL, typename IteratorR> + bool operator!=(const segment<IteratorL>& l, const segment<IteratorR>& r) { - return details::compare_text(l,r) != 0; + return detail::compare_text(l, r) != 0; } /// Compare two segments - template<typename IteratorL,typename IteratorR> - bool operator<(segment<IteratorL> const &l,segment<IteratorR> const &r) + template<typename IteratorL, typename IteratorR> + bool operator<(const segment<IteratorL>& l, const segment<IteratorR>& r) { - return details::compare_text(l,r) < 0; + return detail::compare_text(l, r) < 0; } /// Compare two segments - template<typename IteratorL,typename IteratorR> - bool operator<=(segment<IteratorL> const &l,segment<IteratorR> const &r) + template<typename IteratorL, typename IteratorR> + bool operator<=(const segment<IteratorL>& l, const segment<IteratorR>& r) { - return details::compare_text(l,r) <= 0; + return detail::compare_text(l, r) <= 0; } /// Compare two segments - template<typename IteratorL,typename IteratorR> - bool operator>(segment<IteratorL> const &l,segment<IteratorR> const &r) + template<typename IteratorL, typename IteratorR> + bool operator>(const segment<IteratorL>& l, const segment<IteratorR>& r) { - return details::compare_text(l,r) > 0; + return detail::compare_text(l, r) > 0; } /// Compare two segments - template<typename IteratorL,typename IteratorR> - bool operator>=(segment<IteratorL> const &l,segment<IteratorR> const &r) + template<typename IteratorL, typename IteratorR> + bool operator>=(const segment<IteratorL>& l, const segment<IteratorR>& r) { - return details::compare_text(l,r) >= 0; + return detail::compare_text(l, r) >= 0; } /// Compare string and segment - template<typename CharType,typename Traits,typename Alloc,typename IteratorR> - bool operator==(std::basic_string<CharType,Traits,Alloc> const &l,segment<IteratorR> const &r) + template<typename CharType, typename Traits, typename Alloc, typename IteratorR> + bool operator==(const std::basic_string<CharType, Traits, Alloc>& l, const segment<IteratorR>& r) { - return details::compare_text(l,r) == 0; + return detail::compare_text(l, r) == 0; } /// Compare string and segment - template<typename CharType,typename Traits,typename Alloc,typename IteratorR> - bool operator!=(std::basic_string<CharType,Traits,Alloc> const &l,segment<IteratorR> const &r) + template<typename CharType, typename Traits, typename Alloc, typename IteratorR> + bool operator!=(const std::basic_string<CharType, Traits, Alloc>& l, const segment<IteratorR>& r) { - return details::compare_text(l,r) != 0; + return detail::compare_text(l, r) != 0; } /// Compare string and segment - template<typename CharType,typename Traits,typename Alloc,typename IteratorR> - bool operator<(std::basic_string<CharType,Traits,Alloc> const &l,segment<IteratorR> const &r) + template<typename CharType, typename Traits, typename Alloc, typename IteratorR> + bool operator<(const std::basic_string<CharType, Traits, Alloc>& l, const segment<IteratorR>& r) { - return details::compare_text(l,r) < 0; + return detail::compare_text(l, r) < 0; } /// Compare string and segment - template<typename CharType,typename Traits,typename Alloc,typename IteratorR> - bool operator<=(std::basic_string<CharType,Traits,Alloc> const &l,segment<IteratorR> const &r) + template<typename CharType, typename Traits, typename Alloc, typename IteratorR> + bool operator<=(const std::basic_string<CharType, Traits, Alloc>& l, const segment<IteratorR>& r) { - return details::compare_text(l,r) <= 0; + return detail::compare_text(l, r) <= 0; } /// Compare string and segment - template<typename CharType,typename Traits,typename Alloc,typename IteratorR> - bool operator>(std::basic_string<CharType,Traits,Alloc> const &l,segment<IteratorR> const &r) + template<typename CharType, typename Traits, typename Alloc, typename IteratorR> + bool operator>(const std::basic_string<CharType, Traits, Alloc>& l, const segment<IteratorR>& r) { - return details::compare_text(l,r) > 0; + return detail::compare_text(l, r) > 0; } /// Compare string and segment - template<typename CharType,typename Traits,typename Alloc,typename IteratorR> - bool operator>=(std::basic_string<CharType,Traits,Alloc> const &l,segment<IteratorR> const &r) + template<typename CharType, typename Traits, typename Alloc, typename IteratorR> + bool operator>=(const std::basic_string<CharType, Traits, Alloc>& l, const segment<IteratorR>& r) { - return details::compare_text(l,r) >= 0; + return detail::compare_text(l, r) >= 0; } /// Compare string and segment - template<typename Iterator,typename CharType,typename Traits,typename Alloc> - bool operator==(segment<Iterator> const &l,std::basic_string<CharType,Traits,Alloc> const &r) + template<typename Iterator, typename CharType, typename Traits, typename Alloc> + bool operator==(const segment<Iterator>& l, const std::basic_string<CharType, Traits, Alloc>& r) { - return details::compare_text(l,r) == 0; + return detail::compare_text(l, r) == 0; } /// Compare string and segment - template<typename Iterator,typename CharType,typename Traits,typename Alloc> - bool operator!=(segment<Iterator> const &l,std::basic_string<CharType,Traits,Alloc> const &r) + template<typename Iterator, typename CharType, typename Traits, typename Alloc> + bool operator!=(const segment<Iterator>& l, const std::basic_string<CharType, Traits, Alloc>& r) { - return details::compare_text(l,r) != 0; + return detail::compare_text(l, r) != 0; } /// Compare string and segment - template<typename Iterator,typename CharType,typename Traits,typename Alloc> - bool operator<(segment<Iterator> const &l,std::basic_string<CharType,Traits,Alloc> const &r) + template<typename Iterator, typename CharType, typename Traits, typename Alloc> + bool operator<(const segment<Iterator>& l, const std::basic_string<CharType, Traits, Alloc>& r) { - return details::compare_text(l,r) < 0; + return detail::compare_text(l, r) < 0; } /// Compare string and segment - template<typename Iterator,typename CharType,typename Traits,typename Alloc> - bool operator<=(segment<Iterator> const &l,std::basic_string<CharType,Traits,Alloc> const &r) + template<typename Iterator, typename CharType, typename Traits, typename Alloc> + bool operator<=(const segment<Iterator>& l, const std::basic_string<CharType, Traits, Alloc>& r) { - return details::compare_text(l,r) <= 0; + return detail::compare_text(l, r) <= 0; } /// Compare string and segment - template<typename Iterator,typename CharType,typename Traits,typename Alloc> - bool operator>(segment<Iterator> const &l,std::basic_string<CharType,Traits,Alloc> const &r) + template<typename Iterator, typename CharType, typename Traits, typename Alloc> + bool operator>(const segment<Iterator>& l, const std::basic_string<CharType, Traits, Alloc>& r) { - return details::compare_text(l,r) > 0; + return detail::compare_text(l, r) > 0; } /// Compare string and segment - template<typename Iterator,typename CharType,typename Traits,typename Alloc> - bool operator>=(segment<Iterator> const &l,std::basic_string<CharType,Traits,Alloc> const &r) + template<typename Iterator, typename CharType, typename Traits, typename Alloc> + bool operator>=(const segment<Iterator>& l, const std::basic_string<CharType, Traits, Alloc>& r) { - return details::compare_text(l,r) >= 0; + return detail::compare_text(l, r) >= 0; } - /// Compare C string and segment - template<typename CharType,typename IteratorR> - bool operator==(CharType const *l,segment<IteratorR> const &r) + template<typename CharType, typename IteratorR> + bool operator==(const CharType* l, const segment<IteratorR>& r) { - return details::compare_string(l,r) == 0; + return detail::compare_string(l, r) == 0; } /// Compare C string and segment - template<typename CharType,typename IteratorR> - bool operator!=(CharType const *l,segment<IteratorR> const &r) + template<typename CharType, typename IteratorR> + bool operator!=(const CharType* l, const segment<IteratorR>& r) { - return details::compare_string(l,r) != 0; + return detail::compare_string(l, r) != 0; } /// Compare C string and segment - template<typename CharType,typename IteratorR> - bool operator<(CharType const *l,segment<IteratorR> const &r) + template<typename CharType, typename IteratorR> + bool operator<(const CharType* l, const segment<IteratorR>& r) { - return details::compare_string(l,r) < 0; + return detail::compare_string(l, r) < 0; } /// Compare C string and segment - template<typename CharType,typename IteratorR> - bool operator<=(CharType const *l,segment<IteratorR> const &r) + template<typename CharType, typename IteratorR> + bool operator<=(const CharType* l, const segment<IteratorR>& r) { - return details::compare_string(l,r) <= 0; + return detail::compare_string(l, r) <= 0; } /// Compare C string and segment - template<typename CharType,typename IteratorR> - bool operator>(CharType const *l,segment<IteratorR> const &r) + template<typename CharType, typename IteratorR> + bool operator>(const CharType* l, const segment<IteratorR>& r) { - return details::compare_string(l,r) > 0; + return detail::compare_string(l, r) > 0; } /// Compare C string and segment - template<typename CharType,typename IteratorR> - bool operator>=(CharType const *l,segment<IteratorR> const &r) + template<typename CharType, typename IteratorR> + bool operator>=(const CharType* l, const segment<IteratorR>& r) { - return details::compare_string(l,r) >= 0; + return detail::compare_string(l, r) >= 0; } /// Compare C string and segment - template<typename Iterator,typename CharType> - bool operator==(segment<Iterator> const &l,CharType const *r) + template<typename Iterator, typename CharType> + bool operator==(const segment<Iterator>& l, const CharType* r) { - return details::compare_string(l,r) == 0; + return detail::compare_string(l, r) == 0; } /// Compare C string and segment - template<typename Iterator,typename CharType> - bool operator!=(segment<Iterator> const &l,CharType const *r) + template<typename Iterator, typename CharType> + bool operator!=(const segment<Iterator>& l, const CharType* r) { - return details::compare_string(l,r) != 0; + return detail::compare_string(l, r) != 0; } /// Compare C string and segment - template<typename Iterator,typename CharType> - bool operator<(segment<Iterator> const &l,CharType const *r) + template<typename Iterator, typename CharType> + bool operator<(const segment<Iterator>& l, const CharType* r) { - return details::compare_string(l,r) < 0; + return detail::compare_string(l, r) < 0; } /// Compare C string and segment - template<typename Iterator,typename CharType> - bool operator<=(segment<Iterator> const &l,CharType const *r) + template<typename Iterator, typename CharType> + bool operator<=(const segment<Iterator>& l, const CharType* r) { - return details::compare_string(l,r) <= 0; + return detail::compare_string(l, r) <= 0; } /// Compare C string and segment - template<typename Iterator,typename CharType> - bool operator>(segment<Iterator> const &l,CharType const *r) + template<typename Iterator, typename CharType> + bool operator>(const segment<Iterator>& l, const CharType* r) { - return details::compare_string(l,r) > 0; + return detail::compare_string(l, r) > 0; } /// Compare C string and segment - template<typename Iterator,typename CharType> - bool operator>=(segment<Iterator> const &l,CharType const *r) + template<typename Iterator, typename CharType> + bool operator>=(const segment<Iterator>& l, const CharType* r) { - return details::compare_string(l,r) >= 0; + return detail::compare_string(l, r) >= 0; } + typedef segment<std::string::const_iterator> ssegment; ///< convenience typedef + typedef segment<std::wstring::const_iterator> wssegment; ///< convenience typedef +#ifdef BOOST_LOCALE_ENABLE_CHAR16_T + typedef segment<std::u16string::const_iterator> u16ssegment; ///< convenience typedef +#endif +#ifdef BOOST_LOCALE_ENABLE_CHAR32_T + typedef segment<std::u32string::const_iterator> u32ssegment; ///< convenience typedef +#endif + typedef segment<const char*> csegment; ///< convenience typedef + typedef segment<const wchar_t*> wcsegment; ///< convenience typedef +#ifdef BOOST_LOCALE_ENABLE_CHAR16_T + typedef segment<const char16_t*> u16csegment; ///< convenience typedef +#endif +#ifdef BOOST_LOCALE_ENABLE_CHAR32_T + typedef segment<const char32_t*> u32csegment; ///< convenience typedef +#endif - - - - typedef segment<std::string::const_iterator> ssegment; ///< convenience typedef - typedef segment<std::wstring::const_iterator> wssegment; ///< convenience typedef - #ifdef BOOST_LOCALE_ENABLE_CHAR16_T - typedef segment<std::u16string::const_iterator> u16ssegment;///< convenience typedef - #endif - #ifdef BOOST_LOCALE_ENABLE_CHAR32_T - typedef segment<std::u32string::const_iterator> u32ssegment;///< convenience typedef - #endif - - typedef segment<char const *> csegment; ///< convenience typedef - typedef segment<wchar_t const *> wcsegment; ///< convenience typedef - #ifdef BOOST_LOCALE_ENABLE_CHAR16_T - typedef segment<char16_t const *> u16csegment; ///< convenience typedef - #endif - #ifdef BOOST_LOCALE_ENABLE_CHAR32_T - typedef segment<char32_t const *> u32csegment; ///< convenience typedef - #endif - - - - - - /// /// 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, - segment<Iterator> const &tok) + template<typename CharType, typename TraitsType, typename Iterator> + std::basic_ostream<CharType, TraitsType>& operator<<(std::basic_ostream<CharType, TraitsType>& out, + const segment<Iterator>& tok) { - for(Iterator p=tok.begin(),e=tok.end();p!=e;++p) + for(Iterator p = tok.begin(), e = tok.end(); p != e; ++p) out << *p; return out; } /// @} -} // boundary -} // locale -} // boost +}}} // namespace boost::locale::boundary #ifdef BOOST_MSVC -#pragma warning(pop) +# pragma warning(pop) #endif #endif - 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 8eeb254769..9fac23b172 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/boundary/types.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/boundary/types.hpp @@ -8,127 +8,103 @@ #define BOOST_LOCALE_BOUNDARY_TYPES_HPP_INCLUDED #include <boost/locale/config.hpp> -#include <boost/assert.hpp> #include <boost/cstdint.hpp> #ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4275 4251 4231 4660) +# pragma warning(push) +# pragma warning(disable : 4275 4251 4231 4660) #endif -namespace boost { +namespace boost { namespace locale { - namespace locale { + /// \brief This namespace contains all operations required for boundary analysis of text + namespace boundary { + /// \defgroup boundary Boundary Analysis + /// + /// This module contains all operations required for boundary analysis of text: character, word, like and + /// sentence boundaries + /// + /// @{ + + /// This type describes a possible boundary analysis alternatives. + enum boundary_type { + character, ///< Analyse the text for character boundaries + word, ///< Analyse the text for word boundaries + sentence, ///< Analyse the text for Find sentence boundaries + line ///< Analyse the text for positions suitable for line breaks + }; + /// \brief Flags used with word boundary analysis -- the type of the word, line or sentence boundary found. /// - /// \brief This namespase contains all operations required for boundary analysis of text + /// It is a bit-mask that represents various combinations of rules used to select this specific boundary. + typedef uint32_t rule_type; + + /// \anchor bl_boundary_word_rules + /// \name Flags that describe a type of word selected + /// @{ + constexpr rule_type word_none = 0x0000F, ///< Not a word, like white space or punctuation mark + word_number = 0x000F0, ///< Word that appear to be a number + word_letter = 0x00F00, ///< Word that contains letters, excluding kana and ideographic characters + word_kana = 0x0F000, ///< Word that contains kana characters + word_ideo = 0xF0000, ///< Word that contains ideographic characters + word_any = 0xFFFF0, ///< Any word including numbers, 0 is special flag, equivalent to 15 + word_letters = 0xFFF00, ///< Any word, excluding numbers but including letters, kana and ideograms. + word_kana_ideo = 0xFF000, ///< Word that includes kana or ideographic characters + word_mask = 0xFFFFF; ///< Full word mask - select all possible variants + /// @} + + /// \anchor bl_boundary_line_rules + /// \name Flags that describe a type of line break + /// @{ + constexpr rule_type line_soft = 0x0F, ///< Soft line break: optional but not required + line_hard = 0xF0, ///< Hard line break: like break is required (as per CR/LF) + line_any = 0xFF, ///< Soft or Hard line break + line_mask = 0xFF; ///< Select all types of line breaks + + /// @} + + /// \anchor bl_boundary_sentence_rules + /// \name Flags that describe a type of sentence break /// - namespace boundary { - /// - /// \defgroup boundary Boundary Analysis - /// - /// This module contains all operations required for boundary analysis of text: character, word, like and sentence boundaries - /// - /// @{ - /// - - /// - /// This type describes a possible boundary analysis alternatives. - /// - enum boundary_type { - character, ///< Analyse the text for character boundaries - word, ///< Analyse the text for word boundaries - sentence, ///< Analyse the text for Find sentence boundaries - line ///< Analyse the text for positions suitable for line breaks - }; - - /// - /// \brief Flags used with word boundary analysis -- the type of the word, line or sentence boundary found. - /// - /// It is a bit-mask that represents various combinations of rules used to select this specific boundary. - /// - typedef uint32_t rule_type; - - /// - /// \anchor bl_boundary_word_rules - /// \name Flags that describe a type of word selected - /// @{ - static const rule_type - word_none = 0x0000F, ///< Not a word, like white space or punctuation mark - word_number = 0x000F0, ///< Word that appear to be a number - word_letter = 0x00F00, ///< Word that contains letters, excluding kana and ideographic characters - word_kana = 0x0F000, ///< Word that contains kana characters - word_ideo = 0xF0000, ///< Word that contains ideographic characters - word_any = 0xFFFF0, ///< Any word including numbers, 0 is special flag, equivalent to 15 - word_letters = 0xFFF00, ///< Any word, excluding numbers but including letters, kana and ideograms. - word_kana_ideo = 0xFF000, ///< Word that includes kana or ideographic characters - word_mask = 0xFFFFF; ///< Full word mask - select all possible variants - /// @} - - /// - /// \anchor bl_boundary_line_rules - /// \name Flags that describe a type of line break - /// @{ - static const rule_type - line_soft = 0x0F, ///< Soft line break: optional but not required - line_hard = 0xF0, ///< Hard line break: like break is required (as per CR/LF) - line_any = 0xFF, ///< Soft or Hard line break - line_mask = 0xFF; ///< Select all types of line breaks - - /// @} - - /// - /// \anchor bl_boundary_sentence_rules - /// \name Flags that describe a type of sentence break - /// - /// @{ - static const rule_type - sentence_term = 0x0F, ///< \brief The sentence was terminated with a sentence terminator - /// like ".", "!" possible followed by hard separator like CR, LF, PS - sentence_sep = 0xF0, ///< \brief The sentence does not contain terminator like ".", "!" but ended with hard separator - /// like CR, LF, PS or end of input. - sentence_any = 0xFF, ///< Either first or second sentence break type;. - sentence_mask = 0xFF; ///< Select all sentence breaking points - - ///@} - - /// - /// \name Flags that describe a type of character break. - /// - /// At this point break iterator does not distinguish different - /// kinds of characters so it is used for consistency. - ///@{ - static const rule_type - character_any = 0xF, ///< Not in use, just for consistency - character_mask = 0xF; ///< Select all character breaking points - - ///@} - - /// - /// This function returns the mask that covers all variants for specific boundary type - /// - inline rule_type boundary_rule(boundary_type t) - { - switch(t) { + /// @{ + constexpr rule_type sentence_term = 0x0F, ///< \brief The sentence was terminated with a sentence terminator + /// like ".", "!" possible followed by hard separator like CR, LF, PS + sentence_sep = + 0xF0, ///< \brief The sentence does not contain terminator like ".", "!" but ended with hard separator + /// like CR, LF, PS or end of input. + sentence_any = 0xFF, ///< Either first or second sentence break type;. + sentence_mask = 0xFF; ///< Select all sentence breaking points + + ///@} + + /// \name Flags that describe a type of character break. + /// + /// At this point break iterator does not distinguish different + /// kinds of characters so it is used for consistency. + ///@{ + constexpr rule_type character_any = 0xF, ///< Not in use, just for consistency + character_mask = 0xF; ///< Select all character breaking points + + ///@} + + /// This function returns the mask that covers all variants for specific boundary type + inline rule_type boundary_rule(boundary_type t) + { + switch(t) { case character: return character_mask; - case word: return word_mask; - case sentence: return sentence_mask; - case line: return line_mask; - default: return 0; - } + case word: return word_mask; + case sentence: return sentence_mask; + case line: return line_mask; } + return 0; + } - /// - ///@} - /// - - } // boundary - } // locale -} // boost - + ///@} + } // namespace boundary +}} // namespace boost::locale #ifdef BOOST_MSVC -#pragma warning(pop) +# pragma warning(pop) #endif #endif diff --git a/contrib/restricted/boost/locale/include/boost/locale/collator.hpp b/contrib/restricted/boost/locale/include/boost/locale/collator.hpp index 67e6da8c29..dfef535d23 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/collator.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/collator.hpp @@ -11,75 +11,63 @@ #include <locale> #ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4275 4251 4231 4660) +# pragma warning(push) +# pragma warning(disable : 4275 4251 4231 4660) #endif -namespace boost { -namespace locale { +namespace boost { namespace locale { class info; - /// /// \defgroup collation Collation /// /// This module introduces collation related classes - /// /// @{ - /// - /// \brief a base class that includes collation level flags - /// + /// Unicode collation level types + enum class collate_level { + primary = 0, ///< 1st collation level: base letters + secondary = 1, ///< 2nd collation level: letters and accents + tertiary = 2, ///< 3rd collation level: letters, accents and case + quaternary = 3, ///< 4th collation level: letters, accents, case and punctuation + identical = 4 ///< identical collation level: include code-point comparison + }; - class collator_base { + class BOOST_DEPRECATED("Use collate_level") collator_base { public: - /// - /// Unicode collation level types - /// - typedef enum { - primary = 0, ///< 1st collation level: base letters - secondary = 1, ///< 2nd collation level: letters and accents - tertiary = 2, ///< 3rd collation level: letters, accents and case - quaternary = 3, ///< 4th collation level: letters, accents, case and punctuation - identical = 4 ///< identical collation level: include code-point comparison - } level_type; + using level_type = collate_level; + static constexpr auto primary = collate_level::primary; + static constexpr auto secondary = collate_level::secondary; + static constexpr auto tertiary = collate_level::tertiary; + static constexpr auto quaternary = collate_level::quaternary; + static constexpr auto identical = collate_level::identical; }; - /// /// \brief Collation facet. /// /// It reimplements standard C++ std::collate, /// allowing usage of std::locale for direct string comparison - /// template<typename CharType> - class collator : - public std::collate<CharType>, - public collator_base - { + class collator : public std::collate<CharType> { public: - /// /// Type of the underlying character - /// typedef CharType char_type; - /// /// Type of string used with this facet - /// typedef std::basic_string<CharType> string_type; - - /// /// Compare two strings in rage [b1,e1), [b2,e2) according using a collation level \a level. Calls do_compare /// /// Returns -1 if the first of the two strings sorts before the seconds, returns 1 if sorts after and 0 if /// they considered equal. - /// - int compare(level_type level, - char_type const *b1,char_type const *e1, - char_type const *b2,char_type const *e2) const + int compare(collate_level level, + const char_type* b1, + const char_type* e1, + const char_type* b2, + const char_type* e2) const { - return do_compare(level,b1,e1,b2,e2); + return do_compare(level, b1, e1, b2, e2); } - /// + /// Create a binary string that can be compared to other in order to get collation order. The string is created /// for text in range [b,e). It is useful for collation of multiple strings for text. /// @@ -89,47 +77,35 @@ namespace locale { /// \endcode /// /// Calls do_transform - /// - string_type transform(level_type level,char_type const *b,char_type const *e) const + string_type transform(collate_level level, const char_type* b, const char_type* e) const { - return do_transform(level,b,e); + return do_transform(level, b, e); } - /// /// Calculate a hash of a text in range [b,e). The value can be used for collation sensitive string comparison. /// /// If compare(level,b1,e1,b2,e2) == 0 then hash(level,b1,e1) == hash(level,b2,e2) /// /// Calls do_hash - /// - long hash(level_type level,char_type const *b,char_type const *e) const - { - return do_hash(level,b,e); - } + long hash(collate_level level, const char_type* b, const char_type* e) const { return do_hash(level, b, e); } - /// /// Compare two strings \a l and \a r using collation level \a level /// /// Returns -1 if the first of the two strings sorts before the seconds, returns 1 if sorts after and 0 if /// they considered equal. - /// - /// - int compare(level_type level,string_type const &l,string_type const &r) const + int compare(collate_level level, const string_type& l, const string_type& r) const { - return do_compare(level,l.data(),l.data()+l.size(),r.data(),r.data()+r.size()); + return do_compare(level, l.data(), l.data() + l.size(), r.data(), r.data() + r.size()); } - /// /// Calculate a hash that can be used for collation sensitive string comparison of a string \a s /// /// If compare(level,s1,s2) == 0 then hash(level,s1) == hash(level,s2) - /// - - long hash(level_type level,string_type const &s) const + long hash(collate_level level, const string_type& s) const { - return do_hash(level,s.data(),s.data()+s.size()); + return do_hash(level, s.data(), s.data() + s.size()); } - /// + /// Create a binary string from string \a s, that can be compared to other, useful for collation of multiple /// strings. /// @@ -137,119 +113,92 @@ namespace locale { /// \code /// compare(level,s1,s2) == sign( transform(level,s1).compare(transform(level,s2)) ); /// \endcode - /// - string_type transform(level_type level,string_type const &s) const + string_type transform(collate_level level, const string_type& s) const { - return do_transform(level,s.data(),s.data()+s.size()); + return do_transform(level, s.data(), s.data() + s.size()); } protected: - - /// /// constructor of the collator object - /// - collator(size_t refs = 0) : std::collate<CharType>(refs) - { - } + collator(size_t refs = 0) : std::collate<CharType>(refs) {} - /// /// This function is used to override default collation function that does not take in account collation level. /// Uses primary level - /// - int do_compare( char_type const *b1,char_type const *e1, - char_type const *b2,char_type const *e2) const BOOST_OVERRIDE + int + do_compare(const char_type* b1, const char_type* e1, const char_type* b2, const char_type* e2) const override { - return do_compare(identical,b1,e1,b2,e2); + return do_compare(collate_level::identical, b1, e1, b2, e2); } - /// + /// This function is used to override default collation function that does not take in account collation level. /// Uses primary level - /// - string_type do_transform(char_type const *b,char_type const *e) const BOOST_OVERRIDE + string_type do_transform(const char_type* b, const char_type* e) const override { - return do_transform(identical,b,e); + return do_transform(collate_level::identical, b, e); } - /// + /// This function is used to override default collation function that does not take in account collation level. /// Uses primary level - /// - long do_hash(char_type const *b,char_type const *e) const BOOST_OVERRIDE + long do_hash(const char_type* b, const char_type* e) const override { - return do_hash(identical,b,e); + return do_hash(collate_level::identical, b, e); } - /// - /// Actual function that performs comparison between the strings. For details see compare member function. Can be overridden. - /// - virtual int do_compare( level_type level, - char_type const *b1,char_type const *e1, - char_type const *b2,char_type const *e2) const = 0; - /// + /// Actual function that performs comparison between the strings. For details see compare member function. Can + /// be overridden. + virtual int do_compare(collate_level level, + const char_type* b1, + const char_type* e1, + const char_type* b2, + const char_type* e2) const = 0; + /// Actual function that performs transformation. For details see transform member function. Can be overridden. - /// - virtual string_type do_transform(level_type level,char_type const *b,char_type const *e) const = 0; - /// + virtual string_type do_transform(collate_level level, const char_type* b, const char_type* e) const = 0; /// Actual function that calculates hash. For details see hash member function. Can be overridden. - /// - virtual long do_hash(level_type level,char_type const *b,char_type const *e) const = 0; - - + virtual long do_hash(collate_level level, const char_type* b, const char_type* e) const = 0; }; - /// /// \brief This class can be used in STL algorithms and containers for comparison of strings /// with a level other than primary /// /// For example: /// /// \code - /// std::map<std::string,std::string,comparator<char,collator_base::secondary> > data; + /// std::map<std::string,std::string,comparator<char,collate_level::secondary> > data; /// \endcode /// /// Would create a map the keys of which are sorted using secondary collation level - /// - template<typename CharType,collator_base::level_type default_level = collator_base::identical> - struct comparator - { + template<typename CharType, collate_level default_level = collate_level::identical> + struct comparator { public: - /// /// Create a comparator class for locale \a l and with collation leval \a level /// /// \note throws std::bad_cast if l does not have \ref collator facet installed - /// - comparator(std::locale const &l=std::locale(),collator_base::level_type level=default_level) : - locale_(l), - level_(level) - { - } + comparator(const std::locale& l = std::locale(), collate_level level = default_level) : + locale_(l), level_(level) + {} - /// /// Compare two strings -- equivalent to return left < right according to collation rules - /// - bool operator()(std::basic_string<CharType> const &left,std::basic_string<CharType> const &right) const + bool operator()(const std::basic_string<CharType>& left, const std::basic_string<CharType>& right) const { - return std::use_facet<collator<CharType> >(locale_).compare(level_,left,right) < 0; + return std::use_facet<collator<CharType>>(locale_).compare(level_, left, right) < 0; } + private: std::locale locale_; - collator_base::level_type level_; + collate_level level_; }; - - /// ///@} - /// - - } // locale -} // boost +}} // namespace boost::locale #ifdef BOOST_MSVC -#pragma warning(pop) +# pragma warning(pop) #endif - -#endif /// /// \example collate.cpp /// Example of using collation functions /// + +#endif diff --git a/contrib/restricted/boost/locale/include/boost/locale/config.hpp b/contrib/restricted/boost/locale/include/boost/locale/config.hpp index 518b601c84..f75a4801f9 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/config.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/config.hpp @@ -10,13 +10,13 @@ #include <boost/config.hpp> #if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_LOCALE_DYN_LINK) -# ifdef BOOST_LOCALE_SOURCE -# define BOOST_LOCALE_DECL BOOST_SYMBOL_EXPORT -# else -# define BOOST_LOCALE_DECL BOOST_SYMBOL_IMPORT -# endif // BOOST_LOCALE_SOURCE +# ifdef BOOST_LOCALE_SOURCE +# define BOOST_LOCALE_DECL BOOST_SYMBOL_EXPORT +# else +# define BOOST_LOCALE_DECL BOOST_SYMBOL_IMPORT +# endif // BOOST_LOCALE_SOURCE #else -# define BOOST_LOCALE_DECL +# define BOOST_LOCALE_DECL #endif // BOOST_LOCALE_DYN_LINK // @@ -27,54 +27,42 @@ // Set the name of our library, this will get undef'ed by auto_link.hpp // once it's done with it: // -#define BOOST_LIB_NAME boost_locale +# define BOOST_LIB_NAME boost_locale // // If we're importing code from a dll, then tell auto_link.hpp about it: // -#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_LOCALE_DYN_LINK) -# define BOOST_DYN_LINK -#endif +# if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_LOCALE_DYN_LINK) +# define BOOST_DYN_LINK +# endif // // And include the header that does the work: // -#include <boost/config/auto_link.hpp> -#endif // auto-linking disabled - -#if defined(BOOST_LOCALE_HIDE_AUTO_PTR) || defined(BOOST_NO_AUTO_PTR) -#define BOOST_LOCALE_USE_AUTO_PTR 0 -#else -#define BOOST_LOCALE_USE_AUTO_PTR 1 -#endif +# include <boost/config/auto_link.hpp> +#endif // auto-linking disabled -// Check for C++11 features that will be used in Boost 1.81 -// If you are using Boost.Locale and REALLY require it to keep -// supporting C++03/C++98 please comment with a detailed description -// of your use case and reasoning why using C++11 is not possible in -// https://github.com/boostorg/locale/issues/90 -#if !defined(BOOST_LOCALE_DISABLE_DEPRECATED_03_WARNING) && ( \ - defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || \ - defined(BOOST_NO_CXX11_DEFAULTED_MOVES) || \ - defined(BOOST_NO_CXX11_HDR_FUNCTIONAL) || \ - defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) || \ - defined(BOOST_NO_CXX11_NOEXCEPT) || \ - defined(BOOST_NO_CXX11_OVERRIDE) || \ - defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || \ - defined(BOOST_NO_CXX11_SMART_PTR) || \ - defined(BOOST_NO_CXX11_STATIC_ASSERT) \ - ) - #include <boost/config/pragma_message.hpp> - BOOST_PRAGMA_MESSAGE("CAUTION: Boost.Locale support for C++03 is deprecated. C++11 will be required from Boost 1.81 onwards.") - BOOST_PRAGMA_MESSAGE("CAUTION: Define BOOST_LOCALE_DISABLE_DEPRECATED_03_WARNING to suppress this message.") +// Check for some C++11 features to provide easier checks for what is missing +// shortly after the requirement of C++11 in Boost 1.81 +// clang-format off +#if defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || \ + defined(BOOST_NO_CXX11_DEFAULTED_MOVES) || \ + defined(BOOST_NO_CXX11_HDR_FUNCTIONAL) || \ + defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) || \ + defined(BOOST_NO_CXX11_NOEXCEPT) || \ + defined(BOOST_NO_CXX11_OVERRIDE) || \ + defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || \ + defined(BOOST_NO_CXX11_SMART_PTR) || \ + defined(BOOST_NO_CXX11_STATIC_ASSERT) +// clang-format on +# error "Boost.Locale requires C++11 since Boost 1.81." #endif #ifdef _MSC_VER // Denote a constant condition, e.g. for if(sizeof(... -#define BOOST_LOCALE_START_CONST_CONDITION __pragma(warning(push)) __pragma(warning(disable : 4127)) -#define BOOST_LOCALE_END_CONST_CONDITION __pragma(warning(pop)) +# define BOOST_LOCALE_START_CONST_CONDITION __pragma(warning(push)) __pragma(warning(disable : 4127)) +# define BOOST_LOCALE_END_CONST_CONDITION __pragma(warning(pop)) #else -#define BOOST_LOCALE_START_CONST_CONDITION -#define BOOST_LOCALE_END_CONST_CONDITION +# define BOOST_LOCALE_START_CONST_CONDITION +# define BOOST_LOCALE_END_CONST_CONDITION #endif #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 ef5c6e6766..5917e05d79 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/conversion.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/conversion.hpp @@ -8,368 +8,287 @@ #define BOOST_LOCALE_CONVERTER_HPP_INCLUDED #include <boost/locale/config.hpp> +#include <boost/locale/util/string.hpp> #include <locale> #ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4275 4251 4231 4660) +# pragma warning(push) +# pragma warning(disable : 4275 4251 4231 4660) #endif -namespace boost { - namespace locale { - - /// - /// \defgroup convert Text Conversions - /// - /// This module provides various function for string manipulation like Unicode normalization, case conversion etc. - /// @{ - /// - - - /// - /// \brief This class provides base flags for text manipulation. It is used as base for converter facet. - /// - class converter_base { - public: - /// - /// The flag used for facet - the type of operation to perform - /// - typedef enum { - normalization, ///< Apply Unicode normalization on the text - upper_case, ///< Convert text to upper case - lower_case, ///< Convert text to lower case - case_folding, ///< Fold case in the text - title_case ///< Convert text to title case - } conversion_type; +namespace boost { namespace locale { + + /// \defgroup convert Text Conversions + /// + /// This module provides various function for string manipulation like Unicode normalization, case conversion etc. + /// @{ + + /// \brief This class provides base flags for text manipulation. It is used as base for converter facet. + class converter_base { + public: + /// The flag used for facet - the type of operation to perform + enum conversion_type { + normalization, ///< Apply Unicode normalization on the text + upper_case, ///< Convert text to upper case + lower_case, ///< Convert text to lower case + case_folding, ///< Fold case in the text + title_case ///< Convert text to title case }; + }; + + 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 + template<typename Char> + class BOOST_LOCALE_DECL converter : public converter_base, public std::locale::facet { + public: + /// Locale identification + static std::locale::id id; + + /// 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 - 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 conversion_type. It is specialized - /// for four types of characters \c char, \c wchar_t, \c char16_t, \c char32_t - /// - template<typename Char> - class BOOST_LOCALE_DECL converter: public converter_base, public std::locale::facet { - public: - /// Locale identification - static std::locale::id id; - - /// 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,Char const *begin,Char const *end,int flags = 0) const = 0; -#if defined (__SUNPRO_CC) && defined (_RWSTD_VER) - std::locale::id& __get_id (void) const { return id; } #endif - }; - #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,char const *begin,char const *end,int flags = 0) const = 0; -#if defined (__SUNPRO_CC) && defined (_RWSTD_VER) - std::locale::id& __get_id (void) const { return id; } -#endif - }; - 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,wchar_t const *begin,wchar_t const *end,int flags = 0) const = 0; -#if defined (__SUNPRO_CC) && defined (_RWSTD_VER) - std::locale::id& __get_id (void) const { return id; } -#endif - }; - - #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,char16_t const *begin,char16_t const *end,int flags = 0) const = 0; -#if defined (__SUNPRO_CC) && defined (_RWSTD_VER) - std::locale::id& __get_id (void) const { return id; } -#endif - }; - #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,char32_t const *begin,char32_t const *end,int flags = 0) const = 0; -#if defined (__SUNPRO_CC) && defined (_RWSTD_VER) - std::locale::id& __get_id (void) const { return id; } -#endif - }; - #endif - - #endif - - /// - /// The type that defined <a href="http://unicode.org/reports/tr15/#Norm_Forms">normalization form</a> - /// - - typedef enum { - norm_nfd, ///< Canonical decomposition - norm_nfc, ///< Canonical decomposition followed by canonical composition - norm_nfkd, ///< Compatibility decomposition - norm_nfkc, ///< Compatibility decomposition followed by canonical composition. - norm_default = norm_nfc, ///< Default normalization - canonical decomposition followed by canonical composition - } norm_type; - - /// - /// Normalize Unicode string \a str according to \ref norm_type "normalization form" \a n - /// - /// Note: This function receives only Unicode strings, i.e.: UTF-8, UTF-16 or UTF-32. It does not take - /// 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 - /// - template<typename CharType> - std::basic_string<CharType> normalize(std::basic_string<CharType> const &str,norm_type n=norm_default,std::locale const &loc=std::locale()) - { - return std::use_facet<converter<CharType> >(loc).convert(converter_base::normalization,str.data(),str.data() + str.size(),n); - } - - /// - /// Normalize NUL terminated Unicode string \a str according to \ref norm_type "normalization form" \a n - /// - /// Note: This function receives only Unicode strings, i.e.: UTF-8, UTF-16 or UTF-32. It does not take - /// 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 - /// - template<typename CharType> - std::basic_string<CharType> normalize(CharType const *str,norm_type n=norm_default,std::locale const &loc=std::locale()) - { - CharType const *end=str; - while(*end) - end++; - return std::use_facet<converter<CharType> >(loc).convert(converter_base::normalization,str,end,n); - } - - /// - /// Normalize Unicode string in range [begin,end) according to \ref norm_type "normalization form" \a n - /// - /// Note: This function receives only Unicode strings, i.e.: UTF-8, UTF-16 or UTF-32. It does not take - /// 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 - /// - template<typename CharType> - std::basic_string<CharType> normalize( CharType const *begin, - CharType const *end, - norm_type n=norm_default, - std::locale const &loc=std::locale()) - { - return std::use_facet<converter<CharType> >(loc).convert(converter_base::normalization,begin,end,n); - } - - /////////////////////////////////////////////////// - - /// - /// 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 - /// - - template<typename CharType> - std::basic_string<CharType> to_upper(std::basic_string<CharType> const &str,std::locale const &loc=std::locale()) - { - return std::use_facet<converter<CharType> >(loc).convert(converter_base::upper_case,str.data(),str.data()+str.size()); - } - - /// - /// Convert a NUL 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 - /// - template<typename CharType> - std::basic_string<CharType> to_upper(CharType const *str,std::locale const &loc=std::locale()) - { - CharType const *end=str; - while(*end) - end++; - return std::use_facet<converter<CharType> >(loc).convert(converter_base::upper_case,str,end); - } - - /// - /// 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 - /// - template<typename CharType> - std::basic_string<CharType> to_upper(CharType const *begin,CharType const *end,std::locale const &loc=std::locale()) - { - return std::use_facet<converter<CharType> >(loc).convert(converter_base::upper_case,begin,end); - } - - /////////////////////////////////////////////////// - - /// - /// 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 - /// - - template<typename CharType> - std::basic_string<CharType> to_lower(std::basic_string<CharType> const &str,std::locale const &loc=std::locale()) - { - return std::use_facet<converter<CharType> >(loc).convert(converter_base::lower_case,str.data(),str.data()+str.size()); - } - - /// - /// Convert a NUL 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 - /// - template<typename CharType> - std::basic_string<CharType> to_lower(CharType const *str,std::locale const &loc=std::locale()) - { - CharType const *end=str; - while(*end) - end++; - return std::use_facet<converter<CharType> >(loc).convert(converter_base::lower_case,str,end); - } - - /// - /// 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 - /// - template<typename CharType> - std::basic_string<CharType> to_lower(CharType const *begin,CharType const *end,std::locale const &loc=std::locale()) - { - return std::use_facet<converter<CharType> >(loc).convert(converter_base::lower_case,begin,end); - } - /////////////////////////////////////////////////// - - /// - /// 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 - /// - - template<typename CharType> - std::basic_string<CharType> to_title(std::basic_string<CharType> const &str,std::locale const &loc=std::locale()) - { - return std::use_facet<converter<CharType> >(loc).convert(converter_base::title_case,str.data(),str.data()+str.size()); - } - - /// - /// Convert a NUL 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 - /// - template<typename CharType> - std::basic_string<CharType> to_title(CharType const *str,std::locale const &loc=std::locale()) - { - CharType const *end=str; - while(*end) - end++; - return std::use_facet<converter<CharType> >(loc).convert(converter_base::title_case,str,end); - } - - /// - /// 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 - /// - template<typename CharType> - std::basic_string<CharType> to_title(CharType const *begin,CharType const *end,std::locale const &loc=std::locale()) - { - return std::use_facet<converter<CharType> >(loc).convert(converter_base::title_case,begin,end); - } - - /////////////////////////////////////////////////// - - /// - /// 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 - /// - - template<typename CharType> - std::basic_string<CharType> fold_case(std::basic_string<CharType> const &str,std::locale const &loc=std::locale()) - { - return std::use_facet<converter<CharType> >(loc).convert(converter_base::case_folding,str.data(),str.data()+str.size()); - } - - /// - /// Fold case of a NUL terminated string \a str according to locale \a loc - /// - /// \note throws std::bad_cast if loc does not have \ref converter facet installed - /// - template<typename CharType> - std::basic_string<CharType> fold_case(CharType const *str,std::locale const &loc=std::locale()) - { - CharType const *end=str; - while(*end) - end++; - return std::use_facet<converter<CharType> >(loc).convert(converter_base::case_folding,str,end); - } - - /// - /// 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 - /// - template<typename CharType> - std::basic_string<CharType> fold_case(CharType const *begin,CharType const *end,std::locale const &loc=std::locale()) - { - return std::use_facet<converter<CharType> >(loc).convert(converter_base::case_folding,begin,end); - } - - /// - ///@} - /// - } // locale - -} // boost + /// The type that defined <a href="http://unicode.org/reports/tr15/#Norm_Forms">normalization form</a> + enum norm_type { + norm_nfd, ///< Canonical decomposition + norm_nfc, ///< Canonical decomposition followed by canonical composition + norm_nfkd, ///< Compatibility decomposition + norm_nfkc, ///< Compatibility decomposition followed by canonical composition. + norm_default = norm_nfc, ///< Default normalization - canonical decomposition followed by canonical composition + }; + + /// Normalize Unicode string in range [begin,end) according to \ref norm_type "normalization form" \a n + /// + /// Note: This function receives only Unicode strings, i.e.: UTF-8, UTF-16 or UTF-32. It does not take + /// 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 + template<typename CharType> + std::basic_string<CharType> normalize(const CharType* begin, + const CharType* end, + norm_type n = norm_default, + const std::locale& loc = std::locale()) + { + return std::use_facet<converter<CharType>>(loc).convert(converter_base::normalization, begin, end, n); + } + + /// Normalize Unicode string \a str according to \ref norm_type "normalization form" \a n + /// + /// Note: This function receives only Unicode strings, i.e.: UTF-8, UTF-16 or UTF-32. It does not take + /// 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 + template<typename CharType> + std::basic_string<CharType> normalize(const std::basic_string<CharType>& str, + norm_type n = norm_default, + const std::locale& loc = std::locale()) + { + return normalize(str.data(), str.data() + str.size(), n, loc); + } + + /// Normalize NULL terminated Unicode string \a str according to \ref norm_type "normalization form" \a n + /// + /// Note: This function receives only Unicode strings, i.e.: UTF-8, UTF-16 or UTF-32. It does not take + /// 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 + template<typename CharType> + std::basic_string<CharType> + normalize(const CharType* str, norm_type n = norm_default, const std::locale& loc = std::locale()) + { + return normalize(str, util::str_end(str), n, loc); + } + + /////////////////////////////////////////////////// + + /// 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 + template<typename CharType> + std::basic_string<CharType> + to_upper(const CharType* begin, const CharType* end, const std::locale& loc = std::locale()) + { + return std::use_facet<converter<CharType>>(loc).convert(converter_base::upper_case, begin, end); + } + + /// 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 + template<typename CharType> + std::basic_string<CharType> to_upper(const std::basic_string<CharType>& str, const std::locale& loc = std::locale()) + { + return to_upper(str.data(), str.data() + str.size(), loc); + } + + /// 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 + template<typename CharType> + std::basic_string<CharType> to_upper(const CharType* str, const std::locale& loc = std::locale()) + { + return to_upper(str, util::str_end(str), loc); + } + + /////////////////////////////////////////////////// + + /// 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 + template<typename CharType> + std::basic_string<CharType> + to_lower(const CharType* begin, const CharType* end, const std::locale& loc = std::locale()) + { + return std::use_facet<converter<CharType>>(loc).convert(converter_base::lower_case, begin, end); + } + + /// 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 + template<typename CharType> + std::basic_string<CharType> to_lower(const std::basic_string<CharType>& str, const std::locale& loc = std::locale()) + { + return to_lower(str.data(), str.data() + str.size(), loc); + } + + /// 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 + template<typename CharType> + std::basic_string<CharType> to_lower(const CharType* str, const std::locale& loc = std::locale()) + { + return to_lower(str, util::str_end(str), loc); + } + + /////////////////////////////////////////////////// + + /// 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 + template<typename CharType> + std::basic_string<CharType> + to_title(const CharType* begin, const CharType* end, const std::locale& loc = std::locale()) + { + return std::use_facet<converter<CharType>>(loc).convert(converter_base::title_case, begin, end); + } + + /// 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 + template<typename CharType> + std::basic_string<CharType> to_title(const std::basic_string<CharType>& str, const std::locale& loc = std::locale()) + { + return to_title(str.data(), str.data() + str.size(), loc); + } + + /// 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 + template<typename CharType> + std::basic_string<CharType> to_title(const CharType* str, const std::locale& loc = std::locale()) + { + return to_title(str, util::str_end(str), loc); + } + + /////////////////////////////////////////////////// + + /// 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 + template<typename CharType> + std::basic_string<CharType> + fold_case(const CharType* begin, const CharType* end, const std::locale& loc = std::locale()) + { + return std::use_facet<converter<CharType>>(loc).convert(converter_base::case_folding, begin, end); + } + + /// 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 + template<typename CharType> + std::basic_string<CharType> fold_case(const std::basic_string<CharType>& str, + const std::locale& loc = std::locale()) + { + return fold_case(str.data(), str.data() + str.size(), loc); + } + + /// 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 + template<typename CharType> + std::basic_string<CharType> fold_case(const CharType* str, const std::locale& loc = std::locale()) + { + return fold_case(str, util::str_end(str), loc); + } + + ///@} +}} // namespace boost::locale #ifdef BOOST_MSVC -#pragma warning(pop) -#endif - - +# pragma warning(pop) #endif -/// /// \example conversions.cpp /// /// Example of using various text conversion functions. @@ -377,6 +296,5 @@ namespace boost { /// \example wconversions.cpp /// /// Example of using various text conversion functions with wide strings. -/// - +#endif 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 0ce2e55d2f..8895628163 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/date_time.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/date_time.hpp @@ -16,1138 +16,987 @@ #include <vector> #ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4275 4251 4231 4660) +# pragma warning(push) +# pragma warning(disable : 4275 4251 4231 4660) #endif -namespace boost { - namespace locale { - /// - /// \defgroup date_time Date, Time, Timezone and Calendar manipulations - /// - /// This module provides various calendar, timezone and date time services +namespace boost { namespace locale { + /// \defgroup date_time Date, Time, Timezone and Calendar manipulations + /// + /// This module provides various calendar, timezone and date time services + /// @{ + + /// \brief This error is thrown in case of invalid state that occurred + class BOOST_SYMBOL_VISIBLE date_time_error : public std::runtime_error { + public: + /// Constructor of date_time_error class + date_time_error(const std::string& e) : std::runtime_error(e) {} + }; + + /// \brief This class represents a pair of period_type and the integer + /// values that describes its amount. For example 3 days or 4 years. + /// + /// Usually obtained as product of period_type and integer or + /// my calling a representative functions + /// For example day()*3 == date_time_period(day(),3) == day(3) + struct date_time_period { + period::period_type type; ///< The type of period, i.e. era, year, day etc. + int value; ///< The value the actual number of \a periods + /// Operator + returns copy of itself + date_time_period operator+() const { return *this; } + /// Operator -, switches the sign of period + date_time_period operator-() const { return date_time_period(type, -value); } + + /// Constructor that creates date_time_period from period_type \a f and a value \a v -- default 1. + date_time_period(period::period_type f = period::period_type(), int v = 1) : type(f), value(v) {} + }; + + namespace period { + /// Get period_type for: special invalid value, should not be used directly + inline period_type invalid() + { + return period_type(marks::invalid); + } + /// Get period_type for: Era i.e. AC, BC in Gregorian and Julian calendar, range [0,1] + inline period_type era() + { + return period_type(marks::era); + } + /// Get period_type for: Year, it is calendar specific, for example 2011 in Gregorian calendar. + inline period_type year() + { + return period_type(marks::year); + } + /// Get period_type for: Extended year for Gregorian/Julian calendars, where 1 BC == 0, 2 BC == -1. + inline period_type extended_year() + { + return period_type(marks::extended_year); + } + /// Get period_type for: The month of year, calendar specific, in Gregorian [0..11] + inline period_type month() + { + return period_type(marks::month); + } + /// Get period_type for: The day of month, calendar specific, in Gregorian [1..31] + inline period_type day() + { + return period_type(marks::day); + } + /// Get period_type for: The number of day in year, starting from 1, in Gregorian [1..366] + inline period_type day_of_year() + { + return period_type(marks::day_of_year); + } + /// Get period_type for: Day of week, Sunday=1, Monday=2,..., Saturday=7. /// - /// @{ - + /// Note that updating this value respects local day of week, so for example, + /// If first day of week is Monday and the current day is Tuesday then setting + /// the value to Sunday (1) would forward the date by 5 days forward and not backward + /// by two days as it could be expected if the numbers were taken as is. + inline period_type day_of_week() + { + return period_type(marks::day_of_week); + } + /// Get period_type for: Original number of the day of the week in month. For example 1st Sunday, + /// 2nd Sunday, etc. in Gregorian [1..5] + inline period_type day_of_week_in_month() + { + return period_type(marks::day_of_week_in_month); + } + /// Get period_type for: Local day of week, for example in France Monday is 1, in US Sunday is 1, [1..7] + inline period_type day_of_week_local() + { + return period_type(marks::day_of_week_local); + } + /// Get period_type for: 24 clock hour [0..23] + inline period_type hour() + { + return period_type(marks::hour); + } + /// Get period_type for: 12 clock hour [0..11] + inline period_type hour_12() + { + return period_type(marks::hour_12); + } + /// Get period_type for: am or pm marker [0..1] + inline period_type am_pm() + { + return period_type(marks::am_pm); + } + /// Get period_type for: minute [0..59] + inline period_type minute() + { + return period_type(marks::minute); + } + /// Get period_type for: second [0..59] + inline period_type second() + { + return period_type(marks::second); + } + /// Get period_type for: The week number in the year + inline period_type week_of_year() + { + return period_type(marks::week_of_year); + } + /// Get period_type for: The week number within current month + inline period_type week_of_month() + { + return period_type(marks::week_of_month); + } + /// Get period_type for: First day of week, constant, for example Sunday in US = 1, Monday in France = 2 + inline period_type first_day_of_week() + { + return period_type(marks::first_day_of_week); + } + /// Get date_time_period for: Era i.e. AC, BC in Gregorian and Julian calendar, range [0,1] + inline date_time_period era(int v) + { + return date_time_period(era(), v); + } + /// Get date_time_period for: Year, it is calendar specific, for example 2011 in Gregorian calendar. + inline date_time_period year(int v) + { + return date_time_period(year(), v); + } + /// Get date_time_period for: Extended year for Gregorian/Julian calendars, where 1 BC == 0, 2 BC == -1. + inline date_time_period extended_year(int v) + { + return date_time_period(extended_year(), v); + } + /// Get date_time_period for: The month of year, calendar specific, in Gregorian [0..11] + inline date_time_period month(int v) + { + return date_time_period(month(), v); + } + /// Get date_time_period for: The day of month, calendar specific, in Gregorian [1..31] + inline date_time_period day(int v) + { + return date_time_period(day(), v); + } + /// Get date_time_period for: The number of day in year, starting from 1, in Gregorian [1..366] + inline date_time_period day_of_year(int v) + { + return date_time_period(day_of_year(), v); + } + /// Get date_time_period for: Day of week, Sunday=1, Monday=2,..., Saturday=7. /// - /// \brief This error is thrown in case of invalid state that occurred - /// - class BOOST_SYMBOL_VISIBLE date_time_error : public std::runtime_error { - public: - /// - /// Constructor of date_time_error class - /// - date_time_error(std::string const &e) : std::runtime_error(e) {} - }; - + /// Note that updating this value respects local day of week, so for example, + /// If first day of week is Monday and the current day is Tuesday then setting + /// the value to Sunday (1) would forward the date by 5 days forward and not backward + /// by two days as it could be expected if the numbers were taken as is. + inline date_time_period day_of_week(int v) + { + return date_time_period(day_of_week(), v); + } + /// Get date_time_period for: Original number of the day of the week in month. For example 1st Sunday, + /// 2nd Sunday, etc. in Gregorian [1..5] + inline date_time_period day_of_week_in_month(int v) + { + return date_time_period(day_of_week_in_month(), v); + } + /// Get date_time_period for: Local day of week, for example in France Monday is 1, in US Sunday is 1, [1..7] + inline date_time_period day_of_week_local(int v) + { + return date_time_period(day_of_week_local(), v); + } + /// Get date_time_period for: 24 clock hour [0..23] + inline date_time_period hour(int v) + { + return date_time_period(hour(), v); + } + /// Get date_time_period for: 12 clock hour [0..11] + inline date_time_period hour_12(int v) + { + return date_time_period(hour_12(), v); + } + /// Get date_time_period for: am or pm marker [0..1] + inline date_time_period am_pm(int v) + { + return date_time_period(am_pm(), v); + } + /// Get date_time_period for: minute [0..59] + inline date_time_period minute(int v) + { + return date_time_period(minute(), v); + } + /// Get date_time_period for: second [0..59] + inline date_time_period second(int v) + { + return date_time_period(second(), v); + } + /// Get date_time_period for: The week number in the year + inline date_time_period week_of_year(int v) + { + return date_time_period(week_of_year(), v); + } + /// Get date_time_period for: The week number within current month + inline date_time_period week_of_month(int v) + { + return date_time_period(week_of_month(), v); + } + /// Get date_time_period for: First day of week, constant, for example Sunday in US = 1, Monday in France = 2 + inline date_time_period first_day_of_week(int v) + { + return date_time_period(first_day_of_week(), v); + } - /// - /// \brief This class represents a pair of period_type and the integer - /// values that describes its amount. For example 3 days or 4 years. - /// - /// Usually obtained as product of period_type and integer or - /// my calling a representative functions - /// For example day()*3 == date_time_period(day(),3) == day(3) - /// - struct date_time_period - { - period::period_type type; ///< The type of period, i.e. era, year, day etc. - int value; ///< The value the actual number of \a periods - /// - /// Operator + returns copy of itself - /// - date_time_period operator+() const { return *this; } - /// - /// Operator -, switches the sign of period - /// - date_time_period operator-() const { return date_time_period(type,-value); } - - /// - /// Constructor that creates date_time_period from period_type \a f and a value \a v -- default 1. - /// - date_time_period(period::period_type f=period::period_type(),int v=1) : type(f), value(v) {} - }; - - namespace period { - /// - /// Get period_type for: special invalid value, should not be used directly - /// - inline period_type invalid(){ return period_type(marks::invalid); } - /// - /// Get period_type for: Era i.e. AC, BC in Gregorian and Julian calendar, range [0,1] - /// - inline period_type era(){ return period_type(marks::era); } - /// - /// Get period_type for: Year, it is calendar specific, for example 2011 in Gregorian calendar. - /// - inline period_type year(){ return period_type(marks::year); } - /// - /// Get period_type for: Extended year for Gregorian/Julian calendars, where 1 BC == 0, 2 BC == -1. - /// - inline period_type extended_year(){ return period_type(marks::extended_year); } - /// - /// Get period_type for: The month of year, calendar specific, in Gregorian [0..11] - /// - inline period_type month(){ return period_type(marks::month); } - /// - /// Get period_type for: The day of month, calendar specific, in Gregorian [1..31] - /// - inline period_type day(){ return period_type(marks::day); } - /// - /// Get period_type for: The number of day in year, starting from 1, in Gregorian [1..366] - /// - inline period_type day_of_year(){ return period_type(marks::day_of_year); } - /// - /// Get period_type for: Day of week, Sunday=1, Monday=2,..., Saturday=7. - /// - /// Note that updating this value respects local day of week, so for example, - /// If first day of week is Monday and the current day is Tuesday then setting - /// the value to Sunday (1) would forward the date by 5 days forward and not backward - /// by two days as it could be expected if the numbers were taken as is. - /// - inline period_type day_of_week(){ return period_type(marks::day_of_week); } - /// - /// Get period_type for: Original number of the day of the week in month. For example 1st Sunday, - /// 2nd Sunday, etc. in Gregorian [1..5] - /// - inline period_type day_of_week_in_month(){ return period_type(marks::day_of_week_in_month); } - /// - /// Get period_type for: Local day of week, for example in France Monday is 1, in US Sunday is 1, [1..7] - /// - inline period_type day_of_week_local(){ return period_type(marks::day_of_week_local); } - /// - /// Get period_type for: 24 clock hour [0..23] - /// - inline period_type hour(){ return period_type(marks::hour); } - /// - /// Get period_type for: 12 clock hour [0..11] - /// - inline period_type hour_12(){ return period_type(marks::hour_12); } - /// - /// Get period_type for: am or pm marker [0..1] - /// - inline period_type am_pm(){ return period_type(marks::am_pm); } - /// - /// Get period_type for: minute [0..59] - /// - inline period_type minute(){ return period_type(marks::minute); } - /// - /// Get period_type for: second [0..59] - /// - inline period_type second(){ return period_type(marks::second); } - /// - /// Get period_type for: The week number in the year - /// - inline period_type week_of_year(){ return period_type(marks::week_of_year); } - /// - /// Get period_type for: The week number within current month - /// - inline period_type week_of_month(){ return period_type(marks::week_of_month); } - /// - /// Get period_type for: First day of week, constant, for example Sunday in US = 1, Monday in France = 2 - /// - inline period_type first_day_of_week(){ return period_type(marks::first_day_of_week); } - - /// - /// Get date_time_period for: Era i.e. AC, BC in Gregorian and Julian calendar, range [0,1] - /// - inline date_time_period era(int v) { return date_time_period(era(),v); } - /// - /// Get date_time_period for: Year, it is calendar specific, for example 2011 in Gregorian calendar. - /// - inline date_time_period year(int v) { return date_time_period(year(),v); } - /// - /// Get date_time_period for: Extended year for Gregorian/Julian calendars, where 1 BC == 0, 2 BC == -1. - /// - inline date_time_period extended_year(int v) { return date_time_period(extended_year(),v); } - /// - /// Get date_time_period for: The month of year, calendar specific, in Gregorian [0..11] - /// - inline date_time_period month(int v) { return date_time_period(month(),v); } - /// - /// Get date_time_period for: The day of month, calendar specific, in Gregorian [1..31] - /// - inline date_time_period day(int v) { return date_time_period(day(),v); } - /// - /// Get date_time_period for: The number of day in year, starting from 1, in Gregorian [1..366] - /// - inline date_time_period day_of_year(int v) { return date_time_period(day_of_year(),v); } - /// - /// Get date_time_period for: Day of week, Sunday=1, Monday=2,..., Saturday=7. - /// - /// Note that updating this value respects local day of week, so for example, - /// If first day of week is Monday and the current day is Tuesday then setting - /// the value to Sunday (1) would forward the date by 5 days forward and not backward - /// by two days as it could be expected if the numbers were taken as is. - /// - inline date_time_period day_of_week(int v) { return date_time_period(day_of_week(),v); } - /// - /// Get date_time_period for: Original number of the day of the week in month. For example 1st Sunday, - /// 2nd Sunday, etc. in Gregorian [1..5] - /// - inline date_time_period day_of_week_in_month(int v) { return date_time_period(day_of_week_in_month(),v); } - /// - /// Get date_time_period for: Local day of week, for example in France Monday is 1, in US Sunday is 1, [1..7] - /// - inline date_time_period day_of_week_local(int v) { return date_time_period(day_of_week_local(),v); } - /// - /// Get date_time_period for: 24 clock hour [0..23] - /// - inline date_time_period hour(int v) { return date_time_period(hour(),v); } - /// - /// Get date_time_period for: 12 clock hour [0..11] - /// - inline date_time_period hour_12(int v) { return date_time_period(hour_12(),v); } - /// - /// Get date_time_period for: am or pm marker [0..1] - /// - inline date_time_period am_pm(int v) { return date_time_period(am_pm(),v); } - /// - /// Get date_time_period for: minute [0..59] - /// - inline date_time_period minute(int v) { return date_time_period(minute(),v); } - /// - /// Get date_time_period for: second [0..59] - /// - inline date_time_period second(int v) { return date_time_period(second(),v); } - /// - /// Get date_time_period for: The week number in the year - /// - inline date_time_period week_of_year(int v) { return date_time_period(week_of_year(),v); } - /// - /// Get date_time_period for: The week number within current month - /// - inline date_time_period week_of_month(int v) { return date_time_period(week_of_month(),v); } - /// - /// Get date_time_period for: First day of week, constant, for example Sunday in US = 1, Monday in France = 2 - /// - inline date_time_period first_day_of_week(int v) { return date_time_period(first_day_of_week(),v); } - - /// - /// Get predefined constant for January - /// - inline date_time_period january() { return date_time_period(month(),0); } - /// - /// Get predefined constant for February - /// - inline date_time_period february() { return date_time_period(month(),1); } - /// - /// Get predefined constant for March - /// - inline date_time_period march() { return date_time_period(month(),2); } - /// - /// Get predefined constant for April - /// - inline date_time_period april() { return date_time_period(month(),3); } - /// - /// Get predefined constant for May - /// - inline date_time_period may() { return date_time_period(month(),4); } - /// - /// Get predefined constant for June - /// - inline date_time_period june() { return date_time_period(month(),5); } - /// - /// Get predefined constant for July - /// - inline date_time_period july() { return date_time_period(month(),6); } - /// - /// Get predefined constant for August - /// - inline date_time_period august() { return date_time_period(month(),7); } - /// - /// Get predefined constant for September - /// - inline date_time_period september() { return date_time_period(month(),8); } - /// - /// Get predefined constant for October - /// - inline date_time_period october() { return date_time_period(month(),9); } - /// - /// Get predefined constant for November - /// - inline date_time_period november() { return date_time_period(month(),10); } - /// - /// Get predefined constant for December - /// - inline date_time_period december() { return date_time_period(month(),11); } - - /// - /// Get predefined constant for Sunday - /// - inline date_time_period sunday() { return date_time_period(day_of_week(),1); } - /// - /// Get predefined constant for Monday - /// - inline date_time_period monday() { return date_time_period(day_of_week(),2); } - /// - /// Get predefined constant for Tuesday - /// - inline date_time_period tuesday() { return date_time_period(day_of_week(),3); } - /// - /// Get predefined constant for Wednesday - /// - inline date_time_period wednesday() { return date_time_period(day_of_week(),4); } - /// - /// Get predefined constant for Thursday - /// - inline date_time_period thursday() { return date_time_period(day_of_week(),5); } - /// - /// Get predefined constant for Friday - /// - inline date_time_period friday() { return date_time_period(day_of_week(),6); } - /// - /// Get predefined constant for Saturday - /// - inline date_time_period saturday() { return date_time_period(day_of_week(),7); } - /// - /// Get predefined constant for AM (Ante Meridiem) - /// - inline date_time_period am() { return date_time_period(am_pm(),0); } - /// - /// Get predefined constant for PM (Post Meridiem) - /// - inline date_time_period pm() { return date_time_period(am_pm(),1); } - - /// - /// convert period_type to date_time_period(f,1) - /// - inline date_time_period operator+(period::period_type f) - { - return date_time_period(f); - } - /// - /// convert period_type to date_time_period(f,-1) - /// - inline date_time_period operator-(period::period_type f) - { - return date_time_period(f,-1); - } - - /// - /// Create date_time_period of type \a f with value \a v. - /// - template<typename T> - date_time_period operator*(period::period_type f,T v) - { - return date_time_period(f,v); - } - - /// - /// Create date_time_period of type \a f with value \a v. - /// - template<typename T> - date_time_period operator*(T v,period::period_type f) - { - return date_time_period(f,v); - } - /// - /// Create date_time_period of type \a f with value \a v. - /// - template<typename T> - date_time_period operator*(T v,date_time_period f) - { - return date_time_period(f.type,f.value*v); - } - - /// - /// Create date_time_period of type \a f with value \a v. - /// - template<typename T> - date_time_period operator*(date_time_period f,T v) - { - return date_time_period(f.type,f.value*v); - } - - - } // period + /// Get predefined constant for January + inline date_time_period january() + { + return date_time_period(month(), 0); + } + /// Get predefined constant for February + inline date_time_period february() + { + return date_time_period(month(), 1); + } + /// Get predefined constant for March + inline date_time_period march() + { + return date_time_period(month(), 2); + } + /// Get predefined constant for April + inline date_time_period april() + { + return date_time_period(month(), 3); + } + /// Get predefined constant for May + inline date_time_period may() + { + return date_time_period(month(), 4); + } + /// Get predefined constant for June + inline date_time_period june() + { + return date_time_period(month(), 5); + } + /// Get predefined constant for July + inline date_time_period july() + { + return date_time_period(month(), 6); + } + /// Get predefined constant for August + inline date_time_period august() + { + return date_time_period(month(), 7); + } + /// Get predefined constant for September + inline date_time_period september() + { + return date_time_period(month(), 8); + } + /// Get predefined constant for October + inline date_time_period october() + { + return date_time_period(month(), 9); + } + /// Get predefined constant for November + inline date_time_period november() + { + return date_time_period(month(), 10); + } + /// Get predefined constant for December + inline date_time_period december() + { + return date_time_period(month(), 11); + } + /// Get predefined constant for Sunday + inline date_time_period sunday() + { + return date_time_period(day_of_week(), 1); + } + /// Get predefined constant for Monday + inline date_time_period monday() + { + return date_time_period(day_of_week(), 2); + } + /// Get predefined constant for Tuesday + inline date_time_period tuesday() + { + return date_time_period(day_of_week(), 3); + } + /// Get predefined constant for Wednesday + inline date_time_period wednesday() + { + return date_time_period(day_of_week(), 4); + } + /// Get predefined constant for Thursday + inline date_time_period thursday() + { + return date_time_period(day_of_week(), 5); + } + /// Get predefined constant for Friday + inline date_time_period friday() + { + return date_time_period(day_of_week(), 6); + } + /// Get predefined constant for Saturday + inline date_time_period saturday() + { + return date_time_period(day_of_week(), 7); + } + /// Get predefined constant for AM (Ante Meridiem) + inline date_time_period am() + { + return date_time_period(am_pm(), 0); + } + /// Get predefined constant for PM (Post Meridiem) + inline date_time_period pm() + { + return date_time_period(am_pm(), 1); + } - /// - /// \brief this class that represents a set of periods, - /// - /// It is generally created by operations on periods: - /// 1995*year + 3*month + 1*day. Note: operations are not commutative. - /// - class date_time_period_set { - public: - - /// - /// Default constructor - empty set - /// - date_time_period_set() - { - } - /// - /// Create a set of single period with value 1 - /// - date_time_period_set(period::period_type f) - { - basic_[0]=date_time_period(f); - } - /// - /// Create a set of single period \a fl - /// - date_time_period_set(date_time_period const &fl) - { - basic_[0]=fl; - } - /// - /// Append date_time_period \a f to the set - /// - void add(date_time_period f) - { - size_t n=size(); - if(n < 4) - basic_[n]=f; - else - periods_.push_back(f); - } - /// - /// Get number if items in list - /// - size_t size() const - { - if(basic_[0].type == period::period_type()) - return 0; - if(basic_[1].type == period::period_type()) - return 1; - if(basic_[2].type == period::period_type()) - return 2; - if(basic_[3].type == period::period_type()) - return 3; - return 4+periods_.size(); - } - /// - /// Get item at position \a n the set, n should be in range [0,size) - /// - date_time_period const &operator[](size_t n) const - { - if(n >= size()) - throw std::out_of_range("Invalid index to date_time_period"); - if(n < 4) - return basic_[n]; - else - return periods_[n-4]; - } - private: - date_time_period basic_[4]; - std::vector<date_time_period> periods_; - }; + /// convert period_type to date_time_period(f,1) + inline date_time_period operator+(period::period_type f) + { + return date_time_period(f); + } + /// convert period_type to date_time_period(f,-1) + inline date_time_period operator-(period::period_type f) + { + return date_time_period(f, -1); + } + /// Create date_time_period of type \a f with value \a v. + template<typename T> + date_time_period operator*(period::period_type f, T v) + { + return date_time_period(f, v); + } - /// - /// Append two periods sets. Note this operator is not commutative - /// - inline date_time_period_set operator+(date_time_period_set const &a,date_time_period_set const &b) + /// Create date_time_period of type \a f with value \a v. + template<typename T> + date_time_period operator*(T v, period::period_type f) { - date_time_period_set s(a); - for(unsigned i=0;i<b.size();i++) - s.add(b[i]); - return s; + return date_time_period(f, v); + } + /// Create date_time_period of type \a f with value \a v. + template<typename T> + date_time_period operator*(T v, date_time_period f) + { + return date_time_period(f.type, f.value * v); } - /// - /// Append two period sets when all periods of set \b change their sign - /// - inline date_time_period_set operator-(date_time_period_set const &a,date_time_period_set const &b) + /// Create date_time_period of type \a f with value \a v. + template<typename T> + date_time_period operator*(date_time_period f, T v) { - date_time_period_set s(a); - for(unsigned i=0;i<b.size();i++) - s.add(-b[i]); - return s; + return date_time_period(f.type, f.value * v); } + } // namespace period - /// - /// \brief this class provides an access to general calendar information. - /// - /// This information is not connected to specific date but generic to locale, and timezone. - /// It is used in obtaining general information about calendar and is essential for creation of - /// date_time objects. - /// - class BOOST_LOCALE_DECL calendar { - 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 - /// 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 - /// - calendar(std::locale const &l,std::string const &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 - /// - calendar(std::locale const &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 - /// - calendar(std::string const &zone); - /// - /// Create calendar with default locale and timezone - /// - /// \note throws std::bad_cast if global locale does not have \ref calendar_facet facet installed - /// - calendar(); - ~calendar(); - - /// - /// copy calendar - /// - calendar(calendar const &other); - /// - /// assign calendar - /// - calendar const &operator=(calendar const &other); - - /// - /// Get minimum value for period f, For example for period::day it is 1. - /// - int minimum(period::period_type f) const; - /// - /// Get greatest possible minimum value for period f, For example for period::day it is 1, but may be different for other calendars. - /// - int greatest_minimum(period::period_type f) const; - /// - /// Get maximum value for period f, For example for Gregorian calendar's maximum period::day it is 31. - /// - int maximum(period::period_type f) const; - /// - /// Get least maximum value for period f, For example for Gregorian calendar's maximum period::day it is 28. - /// - int least_maximum(period::period_type f) const; - - /// - /// Get first day of week for specific calendar, for example for US it is 1 - Sunday for France it is 2 - Monday - int first_day_of_week() const; - - /// - /// get calendar's locale - /// - std::locale get_locale() const; - /// - /// get calendar's time zone - /// - std::string get_time_zone() const; - - /// - /// Check if the calendar is Gregorian - /// - bool is_gregorian() const; - - /// - /// Compare calendars for equivalence: i.e. calendar types, time zones etc. - /// - bool operator==(calendar const &other) const; - /// - /// Opposite of == - /// - bool operator!=(calendar const &other) const; - - private: - friend class date_time; - std::locale locale_; - std::string tz_; - hold_ptr<abstract_calendar> impl_; - }; + /// \brief this class that represents a set of periods, + /// + /// It is generally created by operations on periods: + /// 1995*year + 3*month + 1*day. Note: operations are not commutative. + class date_time_period_set { + public: + /// Default constructor - empty set + date_time_period_set() {} - /// - /// \brief this class represents a date time and allows to perform various operation according to the - /// locale settings. - /// - /// This class allows to manipulate various aspects of dates and times easily using arithmetic operations with - /// periods. - /// - /// General arithmetic functions: - /// - /// - date_time + date_time_period_set = date_time: move time point forward by specific periods like date_time + month; - /// - date_time - date_time_period_set = date_time: move time point backward by specific periods like date_time - month; - /// - date_time << date_time_period_set = date_time: roll time point forward by specific periods with rolling to begin if overflows: like "2010-01-31" << 2* day == "2010-01-02" instead of "2010-02-02" - /// - date_time >> date_time_period_set = date_time: roll time point backward by specific periods with rolling to end if overflows: like "2010-01-02" >> 2* day == "2010-01-31" instead of "2009-12-30" - /// - date_time / period_type = int - current period value: like "2010-12-21" / month == 12. "2010-12-21" / year = 2010 - /// - (date_time - date_time) / period_type = int: distance between dates in period_type. Like ("2010-12-01" - "2008-12-01") / month = 24. - /// - /// You can also assign specific periods using assignment operator like: - /// some_time = year * 1995 that sets the year to 1995. - /// - /// + /// Create a set of single period with value 1 + date_time_period_set(period::period_type f) { basic_[0] = date_time_period(f); } - class BOOST_LOCALE_DECL date_time { - public: - - /// - /// Dafault 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 - /// - date_time(); - /// - /// copy date_time - /// - date_time(date_time const &other); - /// - /// copy date_time and change some fields according to the \a set - /// - date_time(date_time const &other,date_time_period_set const &set); - /// - /// assign the date_time - /// - date_time const &operator=(date_time const &other); - ~date_time(); - - /// - /// 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 - /// - date_time(double time); - /// - /// Create a date_time object using POSIX time \a time and calendar \a cal - /// - date_time(double time,calendar const &cal); - /// - /// Create a date_time object using calendar \a cal and initializes it to current time. - /// - date_time(calendar const &cal); - - /// - /// 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 - /// - date_time(date_time_period_set const &set); - /// - /// Create a date_time object using calendar \a cal and define values given in \a set - /// - date_time(date_time_period_set const &set,calendar const &cal); - - - /// - /// assign values to various periods in set \a f - /// - date_time const &operator=(date_time_period_set const &f); - - /// - /// set specific period \a f value to \a v - /// - void set(period::period_type f,int v); - /// - /// get specific period \a f value - /// - int get(period::period_type f) const; - - /// - /// syntactic sugar for get(f) - /// - int operator/(period::period_type f) const - { - return get(f); - } - - /// - /// add single period f to the current date_time - /// - date_time operator+(period::period_type f) const - { - return *this+date_time_period(f); - } - - /// - /// subtract single period f from the current date_time - /// - date_time operator-(period::period_type f) const - { - return *this-date_time_period(f); - } - - /// - /// add single period f to the current date_time - /// - date_time const &operator+=(period::period_type f) - { - return *this+=date_time_period(f); - } - /// - /// subtract single period f from the current date_time - /// - date_time const &operator-=(period::period_type f) - { - return *this-=date_time_period(f); - } - - /// - /// roll forward a date by single period f. - /// - date_time operator<<(period::period_type f) const - { - return *this << date_time_period(f); - } - - /// - /// roll backward a date by single period f. - /// - date_time operator>>(period::period_type f) const - { - return *this>>date_time_period(f); - } - - /// - /// roll forward a date by single period f. - /// - date_time const &operator<<=(period::period_type f) - { - return *this <<= date_time_period(f); - } - /// - /// roll backward a date by single period f. - /// - date_time const &operator>>=(period::period_type f) - { - return *this >>= date_time_period(f); - } - - /// - /// add date_time_period to the current date_time - /// - date_time operator+(date_time_period const &v) const; - /// - /// subtract date_time_period from the current date_time - /// - date_time operator-(date_time_period const &v) const; - /// - /// add date_time_period to the current date_time - /// - date_time const &operator+=(date_time_period const &v); - /// - /// subtract date_time_period from the current date_time - /// - date_time const &operator-=(date_time_period const &v); - - /// - /// roll current date_time forward by date_time_period v - /// - date_time operator<<(date_time_period const &v) const; - /// - /// roll current date_time backward by date_time_period v - /// - date_time operator>>(date_time_period const &v) const ; - /// - /// roll current date_time forward by date_time_period v - /// - date_time const &operator<<=(date_time_period const &v); - /// - /// roll current date_time backward by date_time_period v - /// - date_time const &operator>>=(date_time_period const &v); - - /// - /// add date_time_period_set v to the current date_time - /// - date_time operator+(date_time_period_set const &v) const; - /// - /// subtract date_time_period_set v from the current date_time - /// - date_time operator-(date_time_period_set const &v) const; - /// - /// add date_time_period_set v to the current date_time - /// - date_time const &operator+=(date_time_period_set const &v); - /// - /// subtract date_time_period_set v from the current date_time - /// - date_time const &operator-=(date_time_period_set const &v); - - /// - /// roll current date_time forward by date_time_period_set v - /// - date_time operator<<(date_time_period_set const &v) const; - /// - /// roll current date_time backward by date_time_period_set v - /// - date_time operator>>(date_time_period_set const &v) const ; - /// - /// roll current date_time forward by date_time_period_set v - /// - date_time const &operator<<=(date_time_period_set const &v); - /// - /// roll current date_time backward by date_time_period_set v - /// - date_time const &operator>>=(date_time_period_set const &v); - - /// - /// Get POSIX time - /// - /// The POSIX time is number of seconds since January 1st, 1970 00:00 UTC, ignoring leap seconds. - /// - double time() const; - /// - /// set POSIX time - /// - /// The POSIX time is number of seconds since January 1st, 1970 00:00 UTC, ignoring leap seconds. - /// This time can be fetched from Operating system clock using C function time, gettimeofday and others. - /// - void time(double v); - - /// - /// compare date_time in the timeline (ignores difference in calendar, timezone etc) - /// - bool operator==(date_time const &other) const; - /// - /// compare date_time in the timeline (ignores difference in calendar, timezone etc) - /// - bool operator!=(date_time const &other) const; - /// - /// compare date_time in the timeline (ignores difference in calendar, timezone etc) - /// - bool operator<(date_time const &other) const; - /// - /// compare date_time in the timeline (ignores difference in calendar, timezone etc) - /// - bool operator>(date_time const &other) const; - /// - /// compare date_time in the timeline (ignores difference in calendar, timezone etc) - /// - bool operator<=(date_time const &other) const; - /// - /// compare date_time in the timeline (ignores difference in calendar, timezone etc) - /// - bool operator>=(date_time const &other) const; - - /// - /// swaps two dates - efficient, does not throw - /// - void swap(date_time &other); - - /// - /// calculate the distance from this date_time to \a other in terms of perios \a f - /// - int difference(date_time const &other,period::period_type f) const; - - /// - /// Get minimal possible value for *this time point for a period \a f. - /// - int minimum(period::period_type f) const; - /// - /// Get minimal possible value for *this time point for a period \a f. For example - /// in February maximum(day) may be 28 or 29, in January maximum(day)==31 - /// - int maximum(period::period_type f) const; - - /// - /// Check if *this time point is in daylight saving time - /// - bool is_in_daylight_saving_time() const; - - private: - hold_ptr<abstract_calendar> impl_; - }; + /// Create a set of single period \a fl + date_time_period_set(const date_time_period& fl) { basic_[0] = fl; } - /// - /// Writes date_time \a t to output stream \a out. - /// - /// This function uses locale, calendar and time zone of the target stream \a in. - /// - /// For example: - /// \code - /// date_time now(time(0),hebrew_calendar) - /// std::cout << "Year: " << period::year(now) << " Full Date:" << now; - /// \endcode - /// - /// The output may be Year:5770 Full Date:Jan 1, 2010 - /// - template<typename CharType> - std::basic_ostream<CharType> &operator<<(std::basic_ostream<CharType> &out,date_time const &t) - { - double time_point = t.time(); - uint64_t display_flags = ios_info::get(out).display_flags(); - if ( - display_flags == flags::date - || display_flags == flags::time - || display_flags == flags::datetime - || display_flags == flags::strftime - ) - { - out << time_point; - } - else { - ios_info::get(out).display_flags(flags::datetime); - out << time_point; - ios_info::get(out).display_flags(display_flags); - } - return out; + /// Append date_time_period \a f to the set + void add(date_time_period f) + { + size_t n = size(); + if(n < 4) + basic_[n] = f; + else + periods_.push_back(f); } - /// - /// Reads date_time \a t from output stream \a in - /// - /// This function uses locale, calendar and time zone of the source stream \a in. - /// - template<typename CharType> - std::basic_istream<CharType> &operator>>(std::basic_istream<CharType> &in,date_time &t) - { - double v; - uint64_t display_flags = ios_info::get(in).display_flags(); - if ( - display_flags == flags::date - || display_flags == flags::time - || display_flags == flags::datetime - || display_flags == flags::strftime - ) - { - in >> v; - } - else { - ios_info::get(in).display_flags(flags::datetime); - in >> v; - ios_info::get(in).display_flags(display_flags); - } - if(!in.fail()) - t.time(v); - return in; + /// Get number if items in list + size_t size() const + { + if(basic_[0].type == period::period_type()) + return 0; + if(basic_[1].type == period::period_type()) + return 1; + if(basic_[2].type == period::period_type()) + return 2; + if(basic_[3].type == period::period_type()) + return 3; + return 4 + periods_.size(); + } + + /// Get item at position \a n the set, n should be in range [0,size) + const date_time_period& operator[](size_t n) const + { + if(n >= size()) + throw std::out_of_range("Invalid index to date_time_period"); + if(n < 4) + return basic_[n]; + else + return periods_[n - 4]; } + private: + date_time_period basic_[4]; + std::vector<date_time_period> periods_; + }; + + /// Append two periods sets. Note this operator is not commutative + inline date_time_period_set operator+(const date_time_period_set& a, const date_time_period_set& b) + { + date_time_period_set s(a); + for(unsigned i = 0; i < b.size(); i++) + s.add(b[i]); + return s; + } + + /// Append two period sets when all periods of set \b change their sign + inline date_time_period_set operator-(const date_time_period_set& a, const date_time_period_set& b) + { + date_time_period_set s(a); + for(unsigned i = 0; i < b.size(); i++) + s.add(-b[i]); + return s; + } + + /// \brief this class provides an access to general calendar information. + /// + /// This information is not connected to specific date but generic to locale, and timezone. + /// It is used in obtaining general information about calendar and is essential for creation of + /// date_time objects. + class BOOST_LOCALE_DECL calendar { + 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 + /// 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 + 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 + 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 + + 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 + calendar(); + ~calendar(); + + /// copy calendar + calendar(const calendar& other); + /// assign calendar + calendar& operator=(const calendar& other); + + /// Get minimum value for period f, For example for period::day it is 1. + int minimum(period::period_type f) const; + /// Get greatest possible minimum value for period f, For example for period::day it is 1, but may be different + /// for other calendars. + int greatest_minimum(period::period_type f) const; + /// Get maximum value for period f, For example for Gregorian calendar's maximum period::day it is 31. + int maximum(period::period_type f) const; + /// Get least maximum value for period f, For example for Gregorian calendar's maximum period::day it is 28. + int least_maximum(period::period_type f) const; + + /// Get first day of week for specific calendar, for example for US it is 1 - Sunday for France it is 2 - Monday + int first_day_of_week() const; + + /// get calendar's locale + std::locale get_locale() const; + /// get calendar's time zone + std::string get_time_zone() const; + + /// Check if the calendar is Gregorian + bool is_gregorian() const; + + /// Compare calendars for equivalence: i.e. calendar types, time zones etc. + bool operator==(const calendar& other) const; + /// Opposite of == + bool operator!=(const calendar& other) const; + + private: + friend class date_time; + std::locale locale_; + std::string tz_; + hold_ptr<abstract_calendar> impl_; + }; + + /// \brief this class represents a date time and allows to perform various operation according to the + /// locale settings. + /// + /// This class allows to manipulate various aspects of dates and times easily using arithmetic operations with + /// periods. + /// + /// General arithmetic functions: + /// + /// - date_time + date_time_period_set = date_time: move time point forward by specific periods like date_time + + /// month; + /// - date_time - date_time_period_set = date_time: move time point backward by specific periods like date_time - + /// month; + /// - date_time << date_time_period_set = date_time: roll time point forward by specific periods with rolling to + /// begin if overflows: like "2010-01-31" << 2* day == "2010-01-02" instead of "2010-02-02" + /// - date_time >> date_time_period_set = date_time: roll time point backward by specific periods with rolling to + /// end if overflows: like "2010-01-02" >> 2* day == "2010-01-31" instead of "2009-12-30" + /// - date_time / period_type = int - current period value: like "2010-12-21" / month == 12. "2010-12-21" / year = + /// 2010 + /// - (date_time - date_time) / period_type = int: distance between dates in period_type. Like ("2010-12-01" - + /// "2008-12-01") / month = 24. + /// + /// You can also assign specific periods using assignment operator like: + /// some_time = year * 1995 that sets the year to 1995. + + class BOOST_LOCALE_DECL date_time { + 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 + date_time(); + + /// Copy a date_time + date_time(const date_time& other); + // Move construct a new date_time + date_time(date_time&& other) = 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); + + /// assign the date_time + date_time& operator=(const date_time& other); + // Move assign a date_time + date_time& operator=(date_time&& other) = 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 + date_time(double time); + + /// Create a date_time object using POSIX time \a time and calendar \a cal + date_time(double time, const calendar& cal); + + /// Create a date_time object using calendar \a cal and initializes it to current time. + date_time(const calendar& cal); + + /// 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 + date_time(const date_time_period_set& set); + + /// Create a date_time object using calendar \a cal and define values given in \a set + date_time(const date_time_period_set& set, const calendar& cal); + + /// assign values to various periods in set \a f + date_time& operator=(const date_time_period_set& f); + + /// set specific period \a f value to \a v + void set(period::period_type f, int v); + + /// get specific period \a f value + int get(period::period_type f) const; + /// syntactic sugar for get(f) + int operator/(period::period_type f) const { return get(f); } + + /// add single period f to the current date_time + date_time operator+(period::period_type f) const { return *this + date_time_period(f); } + /// subtract single period f from the current date_time + date_time operator-(period::period_type f) const { return *this - date_time_period(f); } + /// add single period f to the current date_time + date_time& operator+=(period::period_type f) { return *this += date_time_period(f); } + /// subtract single period f from the current date_time + date_time& operator-=(period::period_type f) { return *this -= date_time_period(f); } + + /// roll forward a date by single period f. + date_time operator<<(period::period_type f) const { return *this << date_time_period(f); } + /// roll backward a date by single period f. + date_time operator>>(period::period_type f) const { return *this >> date_time_period(f); } + /// roll forward a date by single period f. + date_time& operator<<=(period::period_type f) { return *this <<= date_time_period(f); } + /// roll backward a date by single period f. + date_time& operator>>=(period::period_type f) { return *this >>= date_time_period(f); } + + /// add date_time_period to the current date_time + date_time operator+(const date_time_period& v) const; + /// subtract date_time_period from the current date_time + date_time operator-(const date_time_period& v) const; + /// add date_time_period to the current date_time + date_time& operator+=(const date_time_period& v); + /// subtract date_time_period from the current date_time + date_time& operator-=(const date_time_period& v); + + /// roll current date_time forward by date_time_period v + date_time operator<<(const date_time_period& v) const; + /// roll current date_time backward by date_time_period v + date_time operator>>(const date_time_period& v) const; + /// roll current date_time forward by date_time_period v + date_time& operator<<=(const date_time_period& v); + /// roll current date_time backward by date_time_period v + date_time& operator>>=(const date_time_period& v); + + /// add date_time_period_set v to the current date_time + date_time operator+(const date_time_period_set& v) const; + /// subtract date_time_period_set v from the current date_time + date_time operator-(const date_time_period_set& v) const; + /// add date_time_period_set v to the current date_time + date_time& operator+=(const date_time_period_set& v); + /// subtract date_time_period_set v from the current date_time + date_time& operator-=(const date_time_period_set& v); + + /// roll current date_time forward by date_time_period_set v + date_time operator<<(const date_time_period_set& v) const; + /// roll current date_time backward by date_time_period_set v + date_time operator>>(const date_time_period_set& v) const; + /// roll current date_time forward by date_time_period_set v + date_time& operator<<=(const date_time_period_set& v); + /// roll current date_time backward by date_time_period_set v + date_time& operator>>=(const date_time_period_set& v); + + /// Get POSIX time + /// + /// The POSIX time is number of seconds since January 1st, 1970 00:00 UTC, ignoring leap seconds. + double time() const; + /// Set POSIX time + /// + /// The POSIX time is number of seconds since January 1st, 1970 00:00 UTC, ignoring leap seconds. + /// This time can be fetched from Operating system clock using C function time, gettimeofday and others. + void time(double v); + + /// 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) + bool operator!=(const date_time& other) 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) + bool operator>(const date_time& other) 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) + bool operator>=(const date_time& other) const; + + /// swaps two dates - efficient, does not throw + void swap(date_time& other); + + /// 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; + + /// Get minimal possible value for *this time point for a period \a f. + int minimum(period::period_type f) const; + /// Get minimal possible value for *this time point for a period \a f. For example + /// in February maximum(day) may be 28 or 29, in January maximum(day)==31 + int maximum(period::period_type f) const; + + /// Check if *this time point is in daylight saving time + bool is_in_daylight_saving_time() const; + + private: + hold_ptr<abstract_calendar> impl_; + }; + + /// Writes date_time \a t to output stream \a out. + /// + /// This function uses locale, calendar and time zone of the target stream \a in. + /// + /// For example: + /// \code + /// date_time now(time(0),hebrew_calendar) + /// std::cout << "Year: " << period::year(now) << " Full Date:" << now; + /// \endcode + /// + /// The output may be Year:5770 Full Date:Jan 1, 2010 + template<typename CharType> + std::basic_ostream<CharType>& operator<<(std::basic_ostream<CharType>& out, const date_time& t) + { + double time_point = t.time(); + uint64_t display_flags = ios_info::get(out).display_flags(); + if(display_flags == flags::date || display_flags == flags::time || display_flags == flags::datetime + || display_flags == flags::strftime) + { + out << time_point; + } else { + ios_info::get(out).display_flags(flags::datetime); + out << time_point; + ios_info::get(out).display_flags(display_flags); + } + return out; + } + + /// Reads date_time \a t from output stream \a in + /// + /// This function uses locale, calendar and time zone of the source stream \a in. + template<typename CharType> + std::basic_istream<CharType>& operator>>(std::basic_istream<CharType>& in, date_time& t) + { + double v; + uint64_t display_flags = ios_info::get(in).display_flags(); + if(display_flags == flags::date || display_flags == flags::time || display_flags == flags::datetime + || display_flags == flags::strftime) + { + in >> v; + } else { + ios_info::get(in).display_flags(flags::datetime); + in >> v; + ios_info::get(in).display_flags(display_flags); + } + if(!in.fail()) + t.time(v); + return in; + } + #ifdef BOOST_MSVC -#pragma warning(push) -#pragma warning(disable:4512) //assignment operator could not be generated +# pragma warning(push) +# pragma warning(disable : 4512) // assignment operator could not be generated #endif - /// - /// \brief This class represents a period: a pair of two date_time objects. - /// - /// It is generally used as syntactic sugar to calculate difference between two dates. - /// - /// Note: it stores references to the original objects, so it is not recommended to be used - /// outside of the equation you calculate the difference in. - /// - class date_time_duration { - public: - - /// - /// Create an object were \a first represents earlier point on time line and \a second is later - /// point. - /// - date_time_duration(date_time const &first,date_time const &second) : - s_(first), - e_(second) - { - } - - /// - /// find a difference in terms of period_type \a f - /// - int get(period::period_type f) const - { - return start().difference(end(),f); - } - - /// - /// Syntactic sugar for get(f) - /// - int operator / (period::period_type f) const - { - return start().difference(end(),f); - } - - /// - /// Get starting point - /// - date_time const &start() const { return s_; } - /// - /// Get ending point - /// - date_time const &end() const { return e_; } - private: - date_time const &s_; - date_time const &e_; - }; + + /// \brief This class represents a period: a pair of two date_time objects. + /// + /// It is generally used as syntactic sugar to calculate difference between two dates. + /// + /// Note: it stores references to the original objects, so it is not recommended to be used + /// outside of the equation you calculate the difference in. + class date_time_duration { + public: + /// Create an object were \a first represents earlier point on time line and \a second is later + /// point. + date_time_duration(const date_time& first, const date_time& second) : s_(first), e_(second) {} + + /// find a difference in terms of period_type \a f + int get(period::period_type f) const { return start().difference(end(), f); } + /// Syntactic sugar for get(f) + int operator/(period::period_type f) const { return start().difference(end(), f); } + + /// Get starting point + const date_time& start() const { return s_; } + /// Get ending point + const date_time& end() const { return e_; } + + private: + const date_time& s_; + const date_time& e_; + }; #ifdef BOOST_MSVC -#pragma warning(pop) +# pragma warning(pop) #endif + /// Calculates the difference between two dates, the left operand is a later point on time line. + /// Returns date_time_duration object. + inline date_time_duration operator-(const date_time& later, const date_time& earlier) + { + return date_time_duration(earlier, later); + } + + namespace period { + /// Extract from date_time numerical value of Era i.e. AC, BC in Gregorian and Julian calendar, range [0,1] + inline int era(const date_time& dt) + { + return dt.get(era()); + } + /// Extract from date_time numerical value of Year, it is calendar specific, for example 2011 in Gregorian + /// calendar. + inline int year(const date_time& dt) + { + return dt.get(year()); + } + /// Extract from date_time numerical value of Extended year for Gregorian/Julian calendars, where 1 BC == 0, 2 + /// BC == -1. + inline int extended_year(const date_time& dt) + { + return dt.get(extended_year()); + } + /// Extract from date_time numerical value of The month of year, calendar specific, in Gregorian [0..11] + inline int month(const date_time& dt) + { + return dt.get(month()); + } + /// Extract from date_time numerical value of The day of month, calendar specific, in Gregorian [1..31] + inline int day(const date_time& dt) + { + return dt.get(day()); + } + /// Extract from date_time numerical value of The number of day in year, starting from 1, in Gregorian [1..366] + inline int day_of_year(const date_time& dt) + { + return dt.get(day_of_year()); + } + /// Extract from date_time numerical value of Day of week, Sunday=1, Monday=2,..., Saturday=7. /// - /// Calculates the difference between two dates, the left operand is a later point on time line. - /// Returns date_time_duration object. - /// - inline date_time_duration operator-(date_time const &later,date_time const &earlier) - { - return date_time_duration(earlier,later); - } - - - namespace period { - /// - /// Extract from date_time numerical value of Era i.e. AC, BC in Gregorian and Julian calendar, range [0,1] - /// - inline int era(date_time const &dt) { return dt.get(era()); } - /// - /// Extract from date_time numerical value of Year, it is calendar specific, for example 2011 in Gregorian calendar. - /// - inline int year(date_time const &dt) { return dt.get(year()); } - /// - /// Extract from date_time numerical value of Extended year for Gregorian/Julian calendars, where 1 BC == 0, 2 BC == -1. - /// - inline int extended_year(date_time const &dt) { return dt.get(extended_year()); } - /// - /// Extract from date_time numerical value of The month of year, calendar specific, in Gregorian [0..11] - /// - inline int month(date_time const &dt) { return dt.get(month()); } - /// - /// Extract from date_time numerical value of The day of month, calendar specific, in Gregorian [1..31] - /// - inline int day(date_time const &dt) { return dt.get(day()); } - /// - /// Extract from date_time numerical value of The number of day in year, starting from 1, in Gregorian [1..366] - /// - inline int day_of_year(date_time const &dt) { return dt.get(day_of_year()); } - /// - /// Extract from date_time numerical value of Day of week, Sunday=1, Monday=2,..., Saturday=7. - /// - /// Note that updating this value respects local day of week, so for example, - /// If first day of week is Monday and the current day is Tuesday then setting - /// the value to Sunday (1) would forward the date by 5 days forward and not backward - /// by two days as it could be expected if the numbers were taken as is. - /// - inline int day_of_week(date_time const &dt) { return dt.get(day_of_week()); } - /// - /// Extract from date_time numerical value of Original number of the day of the week in month. For example 1st Sunday, - /// 2nd Sunday, etc. in Gregorian [1..5] - /// - inline int day_of_week_in_month(date_time const &dt) { return dt.get(day_of_week_in_month()); } - /// - /// Extract from date_time numerical value of Local day of week, for example in France Monday is 1, in US Sunday is 1, [1..7] - /// - inline int day_of_week_local(date_time const &dt) { return dt.get(day_of_week_local()); } - /// - /// Extract from date_time numerical value of 24 clock hour [0..23] - /// - inline int hour(date_time const &dt) { return dt.get(hour()); } - /// - /// Extract from date_time numerical value of 12 clock hour [0..11] - /// - inline int hour_12(date_time const &dt) { return dt.get(hour_12()); } - /// - /// Extract from date_time numerical value of am or pm marker [0..1] - /// - inline int am_pm(date_time const &dt) { return dt.get(am_pm()); } - /// - /// Extract from date_time numerical value of minute [0..59] - /// - inline int minute(date_time const &dt) { return dt.get(minute()); } - /// - /// Extract from date_time numerical value of second [0..59] - /// - inline int second(date_time const &dt) { return dt.get(second()); } - /// - /// Extract from date_time numerical value of The week number in the year - /// - inline int week_of_year(date_time const &dt) { return dt.get(week_of_year()); } - /// - /// Extract from date_time numerical value of The week number within current month - /// - inline int week_of_month(date_time const &dt) { return dt.get(week_of_month()); } - /// - /// Extract from date_time numerical value of First day of week, constant, for example Sunday in US = 1, Monday in France = 2 - /// - inline int first_day_of_week(date_time const &dt) { return dt.get(first_day_of_week()); } - - /// - /// Extract from date_time_duration numerical value of duration in Era i.e. AC, BC in Gregorian and Julian calendar, range [0,1] - /// - inline int era(date_time_duration const &dt) { return dt.get(era()); } - /// - /// Extract from date_time_duration numerical value of duration in years - /// - inline int year(date_time_duration const &dt) { return dt.get(year()); } - /// - /// Extract from date_time_duration numerical value of duration in extended years (for Gregorian/Julian calendars, where 1 BC == 0, 2 BC == -1). - /// - inline int extended_year(date_time_duration const &dt) { return dt.get(extended_year()); } - /// - /// Extract from date_time_duration numerical value of duration in months - /// - inline int month(date_time_duration const &dt) { return dt.get(month()); } - /// - /// Extract from date_time_duration numerical value of duration in days of month - /// - inline int day(date_time_duration const &dt) { return dt.get(day()); } - /// - /// Extract from date_time_duration numerical value of duration in days of year - /// - inline int day_of_year(date_time_duration const &dt) { return dt.get(day_of_year()); } - /// - /// Extract from date_time_duration numerical value of duration in days of week - /// - inline int day_of_week(date_time_duration const &dt) { return dt.get(day_of_week()); } - /// - /// Extract from date_time_duration numerical value of duration in original number of the day of the week in month - /// - inline int day_of_week_in_month(date_time_duration const &dt) { return dt.get(day_of_week_in_month()); } - /// - /// Extract from date_time_duration numerical value of duration in local day of week - /// - inline int day_of_week_local(date_time_duration const &dt) { return dt.get(day_of_week_local()); } - /// - /// Extract from date_time_duration numerical value of duration in hours - /// - inline int hour(date_time_duration const &dt) { return dt.get(hour()); } - /// - /// Extract from date_time_duration numerical value of duration in 12 clock hours - /// - inline int hour_12(date_time_duration const &dt) { return dt.get(hour_12()); } - /// - /// Extract from date_time_duration numerical value of duration in am or pm markers - /// - inline int am_pm(date_time_duration const &dt) { return dt.get(am_pm()); } - /// - /// Extract from date_time_duration numerical value of duration in minutes - /// - inline int minute(date_time_duration const &dt) { return dt.get(minute()); } - /// - /// Extract from date_time_duration numerical value of duration in seconds - /// - inline int second(date_time_duration const &dt) { return dt.get(second()); } - /// - /// Extract from date_time_duration numerical value of duration in the week number in the year - /// - inline int week_of_year(date_time_duration const &dt) { return dt.get(week_of_year()); } - /// - /// Extract from date_time_duration numerical value of duration in The week number within current month - /// - inline int week_of_month(date_time_duration const &dt) { return dt.get(week_of_month()); } - /// - /// Extract from date_time_duration numerical value of duration in the first day of week - /// - inline int first_day_of_week(date_time_duration const &dt) { return dt.get(first_day_of_week()); } - - - } - - /// @} - - - } // locale -} // boost + /// Note that updating this value respects local day of week, so for example, + /// If first day of week is Monday and the current day is Tuesday then setting + /// the value to Sunday (1) would forward the date by 5 days forward and not backward + /// by two days as it could be expected if the numbers were taken as is. + inline int day_of_week(const date_time& dt) + { + return dt.get(day_of_week()); + } + /// Extract from date_time numerical value of Original number of the day of the week in month. For example 1st + /// Sunday, + /// 2nd Sunday, etc. in Gregorian [1..5] + inline int day_of_week_in_month(const date_time& dt) + { + return dt.get(day_of_week_in_month()); + } + /// Extract from date_time numerical value of Local day of week, for example in France Monday is 1, in US + /// Sunday is 1, [1..7] + inline int day_of_week_local(const date_time& dt) + { + return dt.get(day_of_week_local()); + } + /// Extract from date_time numerical value of 24 clock hour [0..23] + inline int hour(const date_time& dt) + { + return dt.get(hour()); + } + /// Extract from date_time numerical value of 12 clock hour [0..11] + inline int hour_12(const date_time& dt) + { + return dt.get(hour_12()); + } + /// Extract from date_time numerical value of am or pm marker [0..1] + inline int am_pm(const date_time& dt) + { + return dt.get(am_pm()); + } + /// Extract from date_time numerical value of minute [0..59] + inline int minute(const date_time& dt) + { + return dt.get(minute()); + } + /// Extract from date_time numerical value of second [0..59] + inline int second(const date_time& dt) + { + return dt.get(second()); + } + /// Extract from date_time numerical value of The week number in the year + inline int week_of_year(const date_time& dt) + { + return dt.get(week_of_year()); + } + /// Extract from date_time numerical value of The week number within current month + inline int week_of_month(const date_time& dt) + { + return dt.get(week_of_month()); + } + /// Extract from date_time numerical value of First day of week, constant, for example Sunday in US = 1, Monday + /// in France = 2 + inline int first_day_of_week(const date_time& dt) + { + return dt.get(first_day_of_week()); + } -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif + /// Extract from date_time_duration numerical value of duration in Era i.e. AC, BC in Gregorian and Julian + /// calendar, range [0,1] + inline int era(const date_time_duration& dt) + { + return dt.get(era()); + } + /// Extract from date_time_duration numerical value of duration in years + inline int year(const date_time_duration& dt) + { + return dt.get(year()); + } + /// Extract from date_time_duration numerical value of duration in extended years (for Gregorian/Julian + /// calendars, where 1 BC == 0, 2 BC == -1). + inline int extended_year(const date_time_duration& dt) + { + return dt.get(extended_year()); + } + /// Extract from date_time_duration numerical value of duration in months + inline int month(const date_time_duration& dt) + { + return dt.get(month()); + } + /// Extract from date_time_duration numerical value of duration in days of month + inline int day(const date_time_duration& dt) + { + return dt.get(day()); + } + /// Extract from date_time_duration numerical value of duration in days of year + inline int day_of_year(const date_time_duration& dt) + { + return dt.get(day_of_year()); + } + /// Extract from date_time_duration numerical value of duration in days of week + inline int day_of_week(const date_time_duration& dt) + { + return dt.get(day_of_week()); + } + /// Extract from date_time_duration numerical value of duration in original number of the day of the week in + /// month + inline int day_of_week_in_month(const date_time_duration& dt) + { + return dt.get(day_of_week_in_month()); + } + /// Extract from date_time_duration numerical value of duration in local day of week + inline int day_of_week_local(const date_time_duration& dt) + { + return dt.get(day_of_week_local()); + } + /// Extract from date_time_duration numerical value of duration in hours + inline int hour(const date_time_duration& dt) + { + return dt.get(hour()); + } + /// Extract from date_time_duration numerical value of duration in 12 clock hours + inline int hour_12(const date_time_duration& dt) + { + return dt.get(hour_12()); + } + /// Extract from date_time_duration numerical value of duration in am or pm markers + inline int am_pm(const date_time_duration& dt) + { + return dt.get(am_pm()); + } + /// Extract from date_time_duration numerical value of duration in minutes + inline int minute(const date_time_duration& dt) + { + return dt.get(minute()); + } + /// Extract from date_time_duration numerical value of duration in seconds + inline int second(const date_time_duration& dt) + { + return dt.get(second()); + } + /// Extract from date_time_duration numerical value of duration in the week number in the year + inline int week_of_year(const date_time_duration& dt) + { + return dt.get(week_of_year()); + } + /// Extract from date_time_duration numerical value of duration in The week number within current month + inline int week_of_month(const date_time_duration& dt) + { + return dt.get(week_of_month()); + } + /// Extract from date_time_duration numerical value of duration in the first day of week + inline int first_day_of_week(const date_time_duration& dt) + { + return dt.get(first_day_of_week()); + } + + } // namespace period + + /// @} +}} // namespace boost::locale +#ifdef BOOST_MSVC +# pragma warning(pop) #endif + /// /// \example calendar.cpp /// /// Example of using date_time functions for generating calendar for current year. /// +#endif 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 ef0ff3ca72..c67efc7c2c 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 @@ -12,247 +12,177 @@ #include <locale> #ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4275 4251 4231 4660) +# pragma warning(push) +# pragma warning(disable : 4275 4251 4231 4660) #endif -namespace boost { - namespace locale { - /// - /// \brief Namespace that contains various types for manipulation with dates - /// - namespace period { - /// - /// \brief This namespace holds a enum of various period types like era, year, month, etc.. - /// - namespace marks { - /// \brief the type that defines a flag that holds a period identifier - enum period_mark { - invalid, ///< Special invalid value, should not be used directly - era, ///< Era i.e. AC, BC in Gregorian and Julian calendar, range [0,1] - year, ///< Year, it is calendar specific, for example 2011 in Gregorian calendar. - extended_year, ///< Extended year for Gregorian/Julian calendars, where 1 BC == 0, 2 BC == -1. - month, ///< The month of year, calendar specific, in Gregorian [0..11] - day, ///< The day of month, calendar specific, in Gregorian [1..31] - day_of_year, ///< The number of day in year, starting from 1, in Gregorian [1..366] - day_of_week, ///< Day of week, Sunday=1, Monday=2,..., Saturday=7. - ///< Note that updating this value respects local day of week, so for example, - ///< If first day of week is Monday and the current day is Tuesday then setting - ///< the value to Sunday (1) would forward the date by 5 days forward and not backward - ///< by two days as it could be expected if the numbers were taken as is. - day_of_week_in_month, ///< Original number of the day of the week in month. For example 1st Sunday, - ///< 2nd Sunday, etc. in Gregorian [1..5] - day_of_week_local, ///< Local day of week, for example in France Monday is 1, in US Sunday is 1, [1..7] - hour, ///< 24 clock hour [0..23] - hour_12, ///< 12 clock hour [0..11] - am_pm, ///< am or pm marker [0..1] - minute, ///< minute [0..59] - second, ///< second [0..59] - week_of_year, ///< The week number in the year - week_of_month, ///< The week number within current month - first_day_of_week, ///< First day of week, constant, for example Sunday in US = 1, Monday in France = 2 - }; - - } // marks - - /// - /// \brief This class holds a type that represents certain period of time like - /// year, hour, second and so on. - /// - /// It can be created from either marks::period_mark type or by using shortcuts in period - /// namespace - calling functions like period::year(), period::hour() and so on. - /// - /// Basically it represents the same object as enum marks::period_mark but allows to - /// provide save operator overloading that would not collide with casing of enum to - /// numeric values. - /// - class period_type { - public: - /// - /// Create a period of specific type, default is invalid. - /// - period_type(marks::period_mark m = marks::invalid) : mark_(m) - { - } - - /// - /// Get the value of marks::period_mark it was created with. - /// - marks::period_mark mark() const - { - return mark_; - } - - /// - /// Check if two periods are the same - /// - bool operator==(period_type const &other) const - { - return mark()==other.mark(); - } - /// - /// Check if two periods are different - /// - bool operator!=(period_type const &other) const - { - return mark()!=other.mark(); - } - private: - marks::period_mark mark_; +namespace boost { namespace locale { + + /// \brief Namespace that contains various types for manipulation with dates + namespace period { + + /// \brief This namespace holds a enum of various period types like era, year, month, etc.. + namespace marks { + + /// \brief the type that defines a flag that holds a period identifier + enum period_mark { + invalid, ///< Special invalid value, should not be used directly + era, ///< Era i.e. AC, BC in Gregorian and Julian calendar, range [0,1] + year, ///< Year, it is calendar specific, for example 2011 in Gregorian calendar. + extended_year, ///< Extended year for Gregorian/Julian calendars, where 1 BC == 0, 2 BC == -1. + month, ///< The month of year, calendar specific, in Gregorian [0..11] + day, ///< The day of month, calendar specific, in Gregorian [1..31] + day_of_year, ///< The number of day in year, starting from 1, in Gregorian [1..366] + day_of_week, ///< Day of week, Sunday=1, Monday=2,..., Saturday=7. + ///< Note that updating this value respects local day of week, so for example, + ///< If first day of week is Monday and the current day is Tuesday then setting + ///< the value to Sunday (1) would forward the date by 5 days forward and not backward + ///< by two days as it could be expected if the numbers were taken as is. + day_of_week_in_month, ///< Original number of the day of the week in month. For example 1st Sunday, + ///< 2nd Sunday, etc. in Gregorian [1..5] + day_of_week_local, ///< Local day of week, for example in France Monday is 1, in US Sunday is 1, [1..7] + hour, ///< 24 clock hour [0..23] + hour_12, ///< 12 clock hour [0..11] + am_pm, ///< am or pm marker [0..1] + minute, ///< minute [0..59] + second, ///< second [0..59] + week_of_year, ///< The week number in the year + week_of_month, ///< The week number within current month + first_day_of_week, ///< First day of week, constant, for example Sunday in US = 1, Monday in France = 2 }; - } // namespace period + } // namespace marks + /// \brief This class holds a type that represents certain period of time like + /// year, hour, second and so on. /// - /// Structure that define POSIX time, seconds and milliseconds - /// since Jan 1, 1970, 00:00 not including leap seconds. + /// It can be created from either marks::period_mark type or by using shortcuts in period + /// namespace - calling functions like period::year(), period::hour() and so on. /// - struct posix_time { - int64_t seconds; ///< Seconds since epoch - uint32_t nanoseconds; ///< Nanoseconds resolution + /// Basically it represents the same object as enum marks::period_mark but allows to + /// provide save operator overloading that would not collide with casing of enum to + /// numeric values. + class period_type { + public: + /// Create a period of specific type, default is invalid. + period_type(marks::period_mark m = marks::invalid) : mark_(m) {} + + /// Get the value of marks::period_mark it was created with. + marks::period_mark mark() const { return mark_; } + + /// Check if two periods are the same + bool operator==(const period_type& other) const { return mark() == other.mark(); } + /// Check if two periods are different + bool operator!=(const period_type& other) const { return mark() != other.mark(); } + + private: + marks::period_mark mark_; }; - /// - /// 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 - /// + } // namespace period + + /// Structure that define POSIX time, seconds and milliseconds + /// since Jan 1, 1970, 00:00 not including leap seconds. + struct posix_time { + int64_t seconds; ///< Seconds since epoch + uint32_t nanoseconds; ///< Nanoseconds resolution + }; + + /// 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 { + public: + /// Type that defines how to fetch the value + enum value_type { + absolute_minimum, ///< Absolute possible minimum for the value, for example for day is 1 + actual_minimum, ///< Actual minimal value for this period. + greatest_minimum, ///< Maximal minimum value that can be for this period + current, ///< Current value of this period + least_maximum, ///< The last maximal value for this period, For example for Gregorian calendar + ///< day it is 28 + actual_maximum, ///< Actual maximum, for it can be 28, 29, 30, 31 for day according to current month + absolute_maximum, ///< Maximal value, for Gregorian day it would be 31. + }; - class abstract_calendar { - public: + /// A way to update the value + enum update_type { + move, ///< Change the value up or down effecting others for example 1990-12-31 + 1 day = 1991-01-01 + roll, ///< Change the value up or down not effecting others for example 1990-12-31 + 1 day = 1990-12-01 + }; - /// - /// Type that defines how to fetch the value - /// - typedef enum { - absolute_minimum, ///< Absolute possible minimum for the value, for example for day is 1 - actual_minimum, ///< Actual minimal value for this period. - greatest_minimum, ///< Maximal minimum value that can be for this period - current, ///< Current value of this period - least_maximum, ///< The last maximal value for this period, For example for Gregorian calendar - ///< day it is 28 - actual_maximum, ///< Actual maximum, for it can be 28, 29, 30, 31 for day according to current month - absolute_maximum, ///< Maximal value, for Gregorian day it would be 31. - } value_type; - - /// - /// A way to update the value - /// - typedef enum { - move, ///< Change the value up or down effecting others for example 1990-12-31 + 1 day = 1991-01-01 - roll, ///< Change the value up or down not effecting others for example 1990-12-31 + 1 day = 1990-12-01 - } update_type; - - /// - /// Information about calendar - /// - typedef enum { - is_gregorian, ///< Check if the calendar is Gregorian - is_dst ///< Check if the current time is in daylight time savings - } calendar_option_type; - - /// - /// Make a polymorphic copy of the calendar - /// - virtual abstract_calendar *clone() const = 0; - - /// - /// Set specific \a value for period \a p, note not all values are settable. - /// - /// After call of set_value you may want to call normalize() function to make sure - /// vall periods are updated, if you set sereral fields that are part of single - /// date/time representation you should call set_value several times and then - /// call normalize(). - /// - /// If normalize() is not called after set_value, the behavior is undefined - /// - virtual void set_value(period::marks::period_mark m,int value) = 0; - - /// - /// Recalculate all periods after setting them, should be called after use of set_value() function. - /// - virtual void normalize() = 0; - - /// - /// Get specific value for period \a p according to a value_type \a v - /// - virtual int get_value(period::marks::period_mark m,value_type v) const = 0; - - /// - /// Set current time point - /// - virtual void set_time(posix_time const &p) = 0; - /// - /// Get current time point - /// - virtual posix_time get_time() const = 0; - - /// - /// Set option for calendar, for future use - /// - virtual void set_option(calendar_option_type opt,int v) = 0; - /// - /// Get option for calendar, currently only check if it is Gregorian calendar - /// - virtual int get_option(calendar_option_type opt) const = 0; - - /// - /// Adjust period's \a p value by \a difference items using a update_type \a u. - /// Note: not all values are adjustable - /// - virtual void adjust_value(period::marks::period_mark m,update_type u,int difference) = 0; - - /// - /// Calculate the difference between this calendar and \a other in \a p units - /// - virtual int difference(abstract_calendar const *other,period::marks::period_mark m) const = 0; - - /// - /// Set time zone, empty - use system - /// - virtual void set_timezone(std::string const &tz) = 0; - /// - /// Get current time zone, empty - system one - /// - virtual std::string get_timezone() const = 0; - - /// - /// Check of two calendars have same rules - /// - virtual bool same(abstract_calendar const *other) const = 0; - - virtual ~abstract_calendar() {} + /// Information about calendar + enum calendar_option_type { + is_gregorian, ///< Check if the calendar is Gregorian + is_dst ///< Check if the current time is in daylight time savings }; + /// Make a polymorphic copy of the calendar + virtual abstract_calendar* clone() const = 0; + + /// Set specific \a value for period \a p, note not all values are settable. /// - /// \brief the facet that generates calendar for specific locale + /// After calling set_value you may want to call normalize() function to make sure + /// all periods are updated, if you set several fields that are part of a single + /// date/time representation you should call set_value several times and then + /// call normalize(). /// - class BOOST_LOCALE_DECL calendar_facet : public std::locale::facet { - public: - /// - /// Basic constructor - /// - calendar_facet(size_t refs = 0) : std::locale::facet(refs) - { - } - /// - /// 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; - }; + /// If normalize() is not called after set_value, the behavior is undefined + virtual void set_value(period::marks::period_mark m, int value) = 0; - } // locale -} // boost + /// Recalculate all periods after setting them, should be called after use of set_value() function. + virtual void normalize() = 0; -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif + /// Get specific value for period \a p according to a value_type \a v + virtual int get_value(period::marks::period_mark m, value_type v) const = 0; + + /// Set current time point + virtual void set_time(const posix_time& p) = 0; + /// Get current time point + virtual posix_time get_time() const = 0; + /// Get current time since epoch in milliseconds + virtual double get_time_ms() const = 0; + + /// Set option for calendar, for future use + virtual void set_option(calendar_option_type opt, int v) = 0; + /// Get option for calendar, currently only check if it is Gregorian calendar + virtual int get_option(calendar_option_type opt) const = 0; + + /// Adjust period's \a p value by \a difference items using a update_type \a u. + /// Note: not all values are adjustable + virtual void adjust_value(period::marks::period_mark m, update_type u, int difference) = 0; + + /// Calculate the difference between this calendar and \a other in \a p units + virtual int difference(const abstract_calendar& other, period::marks::period_mark m) const = 0; + + /// Set time zone, empty - use system + virtual void set_timezone(const std::string& tz) = 0; + /// Get current time zone, empty - system one + virtual std::string get_timezone() const = 0; + /// Check of two calendars have same rules + virtual bool same(const abstract_calendar* other) const = 0; + virtual ~abstract_calendar(); + }; + + /// \brief the facet that generates calendar for specific locale + class BOOST_LOCALE_DECL calendar_facet : public std::locale::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 + +#ifdef BOOST_MSVC +# pragma warning(pop) #endif +#endif diff --git a/contrib/restricted/boost/locale/include/boost/locale/encoding.hpp b/contrib/restricted/boost/locale/include/boost/locale/encoding.hpp index 8ecec46f09..0947028cdf 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/encoding.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/encoding.hpp @@ -8,238 +8,205 @@ #define BOOST_LOCALE_ENCODING_HPP_INCLUDED #include <boost/locale/config.hpp> -#include <boost/locale/info.hpp> #include <boost/locale/encoding_errors.hpp> #include <boost/locale/encoding_utf.hpp> +#include <boost/locale/info.hpp> +#include <boost/locale/util/string.hpp> #ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4275 4251 4231 4660) +# pragma warning(push) +# pragma warning(disable : 4275 4251 4231 4660) #endif -namespace boost { - namespace locale { +namespace boost { namespace locale { + /// \brief Namespace that contains all functions related to character set conversion + namespace conv { + /// \defgroup codepage Character conversion functions /// - /// \brief Namespace that contains all functions related to character set conversion + /// @{ + + /// convert text in range [begin,end) encoded with \a charset to UTF string according to policy \a how + template<typename CharType> + 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 + template<typename CharType> + 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 /// - namespace conv { - /// - /// \defgroup codepage Character conversion functions - /// - /// @{ - - /// - /// convert string to UTF string from text in range [begin,end) encoded with \a charset according to policy \a how - /// - template<typename CharType> - std::basic_string<CharType> to_utf(char const *begin,char const *end,std::string const &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 - /// - template<typename CharType> - std::string from_utf(CharType const *begin,CharType const *end,std::string const &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 - /// - /// \note throws std::bad_cast if the loc does not have \ref info facet installed - /// - template<typename CharType> - std::basic_string<CharType> to_utf(char const *begin,char const *end,std::locale const &loc,method_type how=default_method) - { - return to_utf<CharType>(begin,end,std::use_facet<info>(loc).encoding(),how); - } - - /// - /// convert UTF text in range [begin,end) to a text encoded according to locale \a loc according to policy \a how - /// - /// \note throws std::bad_cast if the loc does not have \ref info facet installed - /// - template<typename CharType> - std::string from_utf(CharType const *begin,CharType const *end,std::locale const &loc,method_type how=default_method) - { - return from_utf(begin,end,std::use_facet<info>(loc).encoding(),how); - } - - /// - /// convert a string \a text encoded with \a charset to UTF string - /// - - template<typename CharType> - std::basic_string<CharType> to_utf(std::string const &text,std::string const &charset,method_type how=default_method) - { - return to_utf<CharType>(text.c_str(),text.c_str()+text.size(),charset,how); - } - - /// - /// Convert a \a text from \a charset to UTF string - /// - template<typename CharType> - std::string from_utf(std::basic_string<CharType> const &text,std::string const &charset,method_type how=default_method) - { - return from_utf(text.c_str(),text.c_str()+text.size(),charset,how); - } - - /// - /// Convert a \a text from \a charset to UTF string - /// - template<typename CharType> - std::basic_string<CharType> to_utf(char const *text,std::string const &charset,method_type how=default_method) - { - char const *text_end = text; - while(*text_end) - text_end++; - return to_utf<CharType>(text,text_end,charset,how); - } - - /// - /// Convert a \a text from UTF to \a charset - /// - template<typename CharType> - std::string from_utf(CharType const *text,std::string const &charset,method_type how=default_method) - { - CharType const *text_end = text; - while(*text_end) - text_end++; - return from_utf(text,text_end,charset,how); - } - - /// - /// Convert a \a text in locale encoding given by \a loc to UTF - /// - /// \note throws std::bad_cast if the loc does not have \ref info facet installed - /// - template<typename CharType> - std::basic_string<CharType> to_utf(std::string const &text,std::locale const &loc,method_type how=default_method) - { - return to_utf<CharType>(text.c_str(),text.c_str()+text.size(),loc,how); - } - - /// - /// Convert a \a text in UTF to locale encoding given by \a loc - /// - /// \note throws std::bad_cast if the loc does not have \ref info facet installed - /// - template<typename CharType> - std::string from_utf(std::basic_string<CharType> const &text,std::locale const &loc,method_type how=default_method) - { - return from_utf(text.c_str(),text.c_str()+text.size(),loc,how); - } - - /// - /// Convert a \a text in locale encoding given by \a loc to UTF - /// - /// \note throws std::bad_cast if the loc does not have \ref info facet installed - /// - template<typename CharType> - std::basic_string<CharType> to_utf(char const *text,std::locale const &loc,method_type how=default_method) - { - char const *text_end = text; - while(*text_end) - text_end++; - return to_utf<CharType>(text,text_end,loc,how); - } - - /// - /// Convert a \a text in UTF to locale encoding given by \a loc - /// - /// \note throws std::bad_cast if the loc does not have \ref info facet installed - /// - template<typename CharType> - std::string from_utf(CharType const *text,std::locale const &loc,method_type how=default_method) - { - CharType const *text_end = text; - while(*text_end) - text_end++; - return from_utf(text,text_end,loc,how); - } - - - /// - /// Convert a text in range [begin,end) to \a to_encoding from \a from_encoding - /// - - BOOST_LOCALE_DECL - std::string between(char const *begin, - char const *end, - std::string const &to_encoding, - std::string const &from_encoding, - method_type how=default_method); - - /// - /// Convert a \a text to \a to_encoding from \a from_encoding - /// - - inline - std::string between(char const *text, - std::string const &to_encoding, - std::string const &from_encoding, - method_type how=default_method) - { - char const *end=text; - while(*end) - end++; - return boost::locale::conv::between(text,end,to_encoding,from_encoding,how); - } - - /// - /// Convert a \a text to \a to_encoding from \a from_encoding - /// - inline - std::string between(std::string const &text, - std::string const &to_encoding, - std::string const &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); - } - - /// \cond INTERNAL - - template<> - BOOST_LOCALE_DECL std::basic_string<char> to_utf(char const *begin,char const *end,std::string const &charset,method_type how); - - template<> - BOOST_LOCALE_DECL std::string from_utf(char const *begin,char const *end,std::string const &charset,method_type how); - - template<> - BOOST_LOCALE_DECL std::basic_string<wchar_t> to_utf(char const *begin,char const *end,std::string const &charset,method_type how); - - template<> - BOOST_LOCALE_DECL std::string from_utf(wchar_t const *begin,wchar_t const *end,std::string const &charset,method_type how); - - #ifdef BOOST_LOCALE_ENABLE_CHAR16_T - template<> - BOOST_LOCALE_DECL std::basic_string<char16_t> to_utf(char const *begin,char const *end,std::string const &charset,method_type how); - - template<> - BOOST_LOCALE_DECL std::string from_utf(char16_t const *begin,char16_t const *end,std::string const &charset,method_type how); - #endif - - #ifdef BOOST_LOCALE_ENABLE_CHAR32_T - template<> - BOOST_LOCALE_DECL std::basic_string<char32_t> to_utf(char const *begin,char const *end,std::string const &charset,method_type how); - - template<> - BOOST_LOCALE_DECL std::string from_utf(char32_t const *begin,char32_t const *end,std::string const &charset,method_type how); - #endif - - - /// \endcond - - /// @} - - } // conv - - } // locale -} // boost - -#ifdef BOOST_MSVC -#pragma warning(pop) + /// \note throws std::bad_cast if the loc does not have \ref info facet installed + template<typename CharType> + std::basic_string<CharType> + to_utf(const char* begin, const char* end, const std::locale& loc, method_type how = default_method) + { + return to_utf<CharType>(begin, end, std::use_facet<info>(loc).encoding(), how); + } + + /// convert UTF text in range [begin,end) to a text encoded according to locale \a loc according to policy \a + /// how + /// + /// \note throws std::bad_cast if the loc does not have \ref info facet installed + template<typename CharType> + std::string + from_utf(const CharType* begin, const CharType* end, const std::locale& loc, method_type how = default_method) + { + return from_utf(begin, end, std::use_facet<info>(loc).encoding(), how); + } + + /// convert a string \a text encoded with \a charset to UTF string + template<typename CharType> + std::basic_string<CharType> + to_utf(const std::string& text, const std::string& charset, method_type how = default_method) + { + return to_utf<CharType>(text.c_str(), text.c_str() + text.size(), charset, how); + } + + /// Convert a \a text from \a charset to UTF string + template<typename CharType> + std::string + from_utf(const std::basic_string<CharType>& text, const std::string& charset, method_type how = default_method) + { + return from_utf(text.c_str(), text.c_str() + text.size(), charset, how); + } + + /// Convert a \a text from \a charset to UTF string + template<typename CharType> + std::basic_string<CharType> + to_utf(const char* text, const std::string& charset, method_type how = default_method) + { + return to_utf<CharType>(text, util::str_end(text), charset, how); + } + + /// Convert a \a text from UTF to \a charset + template<typename CharType> + std::string from_utf(const CharType* text, const std::string& charset, method_type how = default_method) + { + return from_utf(text, util::str_end(text), charset, how); + } + + /// Convert a \a text in locale encoding given by \a loc to UTF + /// + /// \note throws std::bad_cast if the loc does not have \ref info facet installed + template<typename CharType> + std::basic_string<CharType> + to_utf(const std::string& text, const std::locale& loc, method_type how = default_method) + { + return to_utf<CharType>(text.c_str(), text.c_str() + text.size(), loc, how); + } + + /// Convert a \a text in UTF to locale encoding given by \a loc + /// + /// \note throws std::bad_cast if the loc does not have \ref info facet installed + template<typename CharType> + std::string + from_utf(const std::basic_string<CharType>& text, const std::locale& loc, method_type how = default_method) + { + return from_utf(text.c_str(), text.c_str() + text.size(), loc, how); + } + + /// Convert a \a text in locale encoding given by \a loc to UTF + /// + /// \note throws std::bad_cast if the loc does not have \ref info facet installed + template<typename CharType> + 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), loc, how); + } + + /// Convert a \a text in UTF to locale encoding given by \a loc + /// + /// \note throws std::bad_cast if the loc does not have \ref info facet installed + 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); + } + + /// Convert a text in range [begin,end) to \a to_encoding from \a from_encoding + BOOST_LOCALE_DECL + std::string between(const char* begin, + const char* end, + const std::string& to_encoding, + const std::string& from_encoding, + method_type how = default_method); + + /// Convert a \a text to \a to_encoding from \a from_encoding + 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); + } + + /// Convert a \a text to \a to_encoding from \a from_encoding + 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); + } + + /// \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 + + /// @} + + } // namespace conv + +}} // namespace boost::locale +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + +#endif 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 27964121de..6643a6394e 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/encoding_errors.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/encoding_errors.hpp @@ -9,64 +9,47 @@ #include <boost/locale/config.hpp> #include <stdexcept> +#include <string> #ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4275 4251 4231 4660) +# pragma warning(push) +# pragma warning(disable : 4275 4251 4231 4660) #endif -namespace boost { - namespace locale { - namespace conv { - /// - /// \addtogroup codepage - /// - /// @{ - - /// - /// \brief The excepton that is thrown in case of conversion error - /// - class BOOST_SYMBOL_VISIBLE conversion_error : public std::runtime_error { - public: - conversion_error() : std::runtime_error("Conversion failed") {} - }; - - /// - /// \brief This exception is thrown in case of use of unsupported - /// or invalid character set - /// - class BOOST_SYMBOL_VISIBLE invalid_charset_error : public std::runtime_error { - public: - - /// Create an error for charset \a charset - invalid_charset_error(std::string charset) : - std::runtime_error("Invalid or unsupported charset:" + charset) - { - } - }; - - - /// - /// enum that defines conversion policy - /// - typedef enum { - skip = 0, ///< Skip illegal/unconvertable characters - stop = 1, ///< Stop conversion and throw conversion_error - default_method = skip ///< Default method - skip - } method_type; - - - /// @} - - } // conv - - } // locale -} // boost +namespace boost { namespace locale { namespace conv { + /// \addtogroup codepage + /// + /// @{ + + /// \brief The exception that is thrown in case of conversion error + class BOOST_SYMBOL_VISIBLE conversion_error : public std::runtime_error { + public: + conversion_error() : std::runtime_error("Conversion failed") {} + }; + + /// \brief This exception is thrown in case of use of unsupported + /// or invalid character set + class BOOST_SYMBOL_VISIBLE invalid_charset_error : public std::runtime_error { + public: + /// Create an error for charset \a charset + invalid_charset_error(const std::string& charset) : + std::runtime_error("Invalid or unsupported charset:" + charset) + {} + }; + + /// enum that defines conversion policy + enum method_type { + skip = 0, ///< Skip illegal/unconvertible characters + stop = 1, ///< Stop conversion and throw conversion_error + default_method = skip ///< Default method - skip + }; + + /// @} + +}}} // namespace boost::locale::conv #ifdef BOOST_MSVC -#pragma warning(pop) +# pragma warning(pop) #endif #endif - - diff --git a/contrib/restricted/boost/locale/include/boost/locale/encoding_utf.hpp b/contrib/restricted/boost/locale/include/boost/locale/encoding_utf.hpp index 558e7248cc..ed1e5db3c4 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/encoding_utf.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/encoding_utf.hpp @@ -7,84 +7,62 @@ #ifndef BOOST_LOCALE_ENCODING_UTF_HPP_INCLUDED #define BOOST_LOCALE_ENCODING_UTF_HPP_INCLUDED -#include <boost/locale/utf.hpp> #include <boost/locale/encoding_errors.hpp> +#include <boost/locale/utf.hpp> +#include <boost/locale/util/string.hpp> #include <iterator> #ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4275 4251 4231 4660) +# pragma warning(push) +# pragma warning(disable : 4275 4251 4231 4660) #endif -namespace boost { - namespace locale { - namespace conv { - /// - /// \addtogroup codepage - /// - /// @{ - - /// - /// Convert a Unicode text in range [begin,end) to other Unicode encoding - /// - template<typename CharOut,typename CharIn> - std::basic_string<CharOut> - utf_to_utf(CharIn const *begin,CharIn const *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; - while(begin!=end) { - c=utf::utf_traits<CharIn>::template decode<CharIn const *>(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); - } - } - return result; - } - - /// - /// Convert a Unicode NUL terminated string \a str other Unicode encoding - /// - template<typename CharOut,typename CharIn> - std::basic_string<CharOut> - utf_to_utf(CharIn const *str,method_type how = default_method) - { - CharIn const *end = str; - while(*end) - end++; - return utf_to_utf<CharOut,CharIn>(str,end,how); +namespace boost { namespace locale { namespace conv { + /// \addtogroup codepage + /// + /// @{ + + /// Convert a Unicode text in range [begin,end) to other Unicode encoding + 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; + while(begin != end) { + c = utf::utf_traits<CharIn>::template decode<const CharIn*>(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); } + } + return result; + } + /// Convert a Unicode NULL terminated string \a str other Unicode encoding + template<typename CharOut, typename CharIn> + std::basic_string<CharOut> utf_to_utf(const CharIn* str, method_type how = default_method) + { + return utf_to_utf<CharOut, CharIn>(str, util::str_end(str), how); + } - /// - /// Convert a Unicode string \a str other Unicode encoding - /// - template<typename CharOut,typename CharIn> - std::basic_string<CharOut> - utf_to_utf(std::basic_string<CharIn> const &str,method_type how = default_method) - { - return utf_to_utf<CharOut,CharIn>(str.c_str(),str.c_str()+str.size(),how); - } - - - /// @} + /// Convert a Unicode string \a str other Unicode encoding + template<typename CharOut, typename CharIn> + std::basic_string<CharOut> utf_to_utf(const std::basic_string<CharIn>& str, method_type how = default_method) + { + return utf_to_utf<CharOut, CharIn>(str.c_str(), str.c_str() + str.size(), how); + } - } // conv + /// @} - } // locale -} // boost +}}} // namespace boost::locale::conv #ifdef BOOST_MSVC -#pragma warning(pop) +# pragma warning(pop) #endif #endif - - diff --git a/contrib/restricted/boost/locale/include/boost/locale/format.hpp b/contrib/restricted/boost/locale/include/boost/locale/format.hpp index cffbc94664..12f9d6bd30 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/format.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/format.hpp @@ -12,495 +12,440 @@ #include <boost/locale/hold_ptr.hpp> #include <boost/locale/message.hpp> #include <sstream> +#include <stdexcept> #include <vector> #ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4275 4251 4231 4660) +# pragma warning(push) +# pragma warning(disable : 4275 4251 4231 4660) #endif -namespace boost { - namespace locale { +namespace boost { namespace locale { - /// - /// \defgroup format Format - /// - /// This module provides printf like functionality integrated into iostreams and suitable for localization - /// - /// @{ - /// - - /// \cond INTERNAL - namespace details { + /// \defgroup format Format + /// + /// This module provides printf like functionality integrated into iostreams and suitable for localization + /// + /// @{ - template<typename CharType> - struct formattible { - typedef std::basic_ostream<CharType> stream_type; - typedef void (*writer_type)(stream_type &output,void const *ptr); - - formattible() : - pointer_(0), - writer_(&formattible::void_write) - { - } + /// \cond INTERNAL + namespace detail { - formattible(formattible const &other) : - pointer_(other.pointer_), - writer_(other.writer_) - { - } + template<typename CharType> + struct formattible { + typedef std::basic_ostream<CharType> stream_type; + typedef void (*writer_type)(stream_type& output, const void* ptr); - formattible const &operator=(formattible const &other) - { - if(this != &other) { - pointer_=other.pointer_; - writer_=other.writer_; - } - return *this; - } + formattible() : pointer_(0), writer_(&formattible::void_write) {} - template<typename Type> - formattible(Type const &value) - { - pointer_ = static_cast<void const *>(&value); - writer_ = &write<Type>; - } + formattible(const formattible& other) = default; + formattible(formattible&& other) = default; + formattible& operator=(const formattible& other) = default; + formattible& operator=(formattible&& other) = default; - template<typename Type> - formattible const &operator=(Type const &other) - { - *this = formattible(other); - return *this; - } + template<typename Type> + explicit formattible(const Type& value) + { + pointer_ = static_cast<const void*>(&value); + writer_ = &write<Type>; + } - friend stream_type &operator<<(stream_type &out,formattible const &fmt) - { - fmt.writer_(out,fmt.pointer_); - return out; - } + friend stream_type& operator<<(stream_type& out, const formattible& fmt) + { + fmt.writer_(out, fmt.pointer_); + return out; + } - private: - static void void_write(stream_type &output,void const * /*ptr*/) - { - CharType empty_string[1]={0}; - output << empty_string; - } + private: + static void void_write(stream_type& output, const void* /*ptr*/) + { + CharType empty_string[1] = {0}; + output << empty_string; + } - template<typename Type> - static void write(stream_type &output,void const *ptr) - { - output << *static_cast<Type const *>(ptr); - } + template<typename Type> + static void write(stream_type& output, const void* ptr) + { + output << *static_cast<const Type*>(ptr); + } - void const *pointer_; - writer_type writer_; - }; // formattible + const void* pointer_; + writer_type writer_; + }; // formattible - class BOOST_LOCALE_DECL format_parser { - public: - format_parser(std::ios_base &ios,void *,void (*imbuer)(void *,std::locale const &)); - ~format_parser(); + class BOOST_LOCALE_DECL format_parser { + public: + format_parser(std::ios_base& ios, void*, void (*imbuer)(void*, const std::locale&)); + ~format_parser(); + format_parser(const format_parser&) = delete; + format_parser& operator=(const format_parser&) = delete; - unsigned get_position(); + unsigned get_position(); - void set_one_flag(std::string const &key,std::string const &value); + void set_one_flag(const std::string& key, const std::string& value); - template<typename CharType> - void set_flag_with_str(std::string const &key,std::basic_string<CharType> const &value) - { - if(key=="ftime" || key=="strftime") { - as::strftime(ios_); - ios_info::get(ios_).date_time_pattern(value); - } + template<typename CharType> + void set_flag_with_str(const std::string& key, const std::basic_string<CharType>& value) + { + if(key == "ftime" || key == "strftime") { + as::strftime(ios_); + ios_info::get(ios_).date_time_pattern(value); } - void restore(); - private: - void imbue(std::locale const &); - format_parser(format_parser const &); - void operator=(format_parser const &); + } + void restore(); - std::ios_base &ios_; - struct data; - hold_ptr<data> d; - }; + private: + void imbue(const std::locale&); - } + std::ios_base& ios_; + struct data; + hold_ptr<data> d; + }; + } // namespace detail + + /// \endcond + + /// \brief a printf like class that allows type-safe and locale aware message formatting + /// + /// This class creates a formatted message similar to printf or boost::format and receives + /// formatted entries via operator %. + /// + /// For example + /// \code + /// std::cout << format("Hello {1}, you are {2} years old") % name % age << std::endl; + /// \endcode + /// + /// Formatting is enclosed between curly brackets \c { \c } and defined by a comma separated list of flags in the + /// format key[=value] value may also be text included between single quotes \c ' that is used for special purposes + /// where inclusion of non-ASCII text is allowed + /// + /// Including of literal \c { and \c } is possible by specifying double brackets \c {{ and \c }} accordingly. + /// + /// + /// For example: + /// + /// \code + /// std::cout << format("The height of water at {1,time} is {2,num=fixed,precision=3}") % time % height; + /// \endcode + /// + /// The special key -- a number without a value defines the position of an input parameter. + /// List of keys: + /// - \c [0-9]+ -- digits, the index of a formatted parameter -- mandatory key. + /// - \c num or \c number -- format a number. Optional values are: + /// - \c hex -- display hexadecimal number + /// - \c oct -- display in octal format + /// - \c sci or \c scientific -- display in scientific format + /// - \c fix or \c fixed -- display in fixed format + /// . + /// For example \c number=sci + /// - \c cur or \c currency -- format currency. Optional values are: + /// + /// - \c iso -- display using ISO currency symbol. + /// - \c nat or \c national -- display using national currency symbol. + /// . + /// - \c per or \c percent -- format percent value. + /// - \c date, \c time , \c datetime or \c dt -- format date, time or date and time. Optional values are: + /// - \c s or \c short -- display in short format + /// - \c m or \c medium -- display in medium format. + /// - \c l or \c long -- display in long format. + /// - \c f or \c full -- display in full format. + /// . + /// - \c ftime with string (quoted) parameter -- display as with \c strftime see, \c as::ftime manipulator + /// - \c spell or \c spellout -- spell the number. + /// - \c ord or \c ordinal -- format ordinal number (1st, 2nd... etc) + /// - \c left or \c < -- align to left. + /// - \c right or \c > -- align to right. + /// - \c width or \c w -- set field width (requires parameter). + /// - \c precision or \c p -- set precision (requires parameter). + /// - \c locale -- with parameter -- switch locale for current operation. This command generates locale + /// with formatting facets giving more fine grained control of formatting. For example: + /// \code + /// std::cout << format("Today {1,date} ({1,date,locale=he_IL.UTF-8@calendar=hebrew,date} Hebrew Date)") % date; + /// \endcode + /// - \c timezone or \c tz -- the name of the timezone to display the time in. For example:\n + /// \code + /// std::cout << format("Time is: Local {1,time}, ({1,time,tz=EET} Eastern European Time)") % date; + /// \endcode + /// - \c local - display the time in local time + /// - \c gmt - display the time in UTC time scale + /// \code + /// std::cout << format("Local time is: {1,time,local}, universal time is {1,time,gmt}") % time; + /// \endcode + /// + /// + /// Invalid formatting strings are slightly ignored. This would prevent from translator + /// to crash the program in unexpected location. + template<typename CharType> + class basic_format { + public: + typedef CharType char_type; ///< Underlying character type + typedef basic_message<char_type> message_type; ///< The translation message type + /// \cond INTERNAL + typedef detail::formattible<CharType> formattible_type; /// \endcond + typedef std::basic_string<CharType> string_type; ///< string type for this type of character + typedef std::basic_ostream<CharType> stream_type; ///< output stream type for this type of character + + /// Create a format class for \a format_string + basic_format(const string_type& format_string) : format_(format_string), translate_(false), parameters_count_(0) + {} + /// Create a format class using message \a trans. The message if translated first according + /// to the rules of the target locale and then interpreted as a format string + basic_format(const message_type& trans) : message_(trans), translate_(true), parameters_count_(0) {} + + /// Non-copyable + basic_format(const basic_format& other) = delete; + 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"); + } + basic_format& operator=(basic_format&& other) + { + if(other.parameters_count_) + throw std::invalid_argument("Can't move a basic_format with bound parameters"); + message_ = std::move(other.message_); + format_ = std::move(other.format_); + translate_ = other.translate_; + parameters_count_ = 0; + ext_params_.clear(); + return *this; + } + + /// Add new parameter to the format list. The object should be a type + /// with defined expression out << object where \c out is \c std::basic_ostream. /// - /// \brief a printf like class that allows type-safe and locale aware message formatting - /// - /// This class creates a formatted message similar to printf or boost::format and receives - /// formatted entries via operator %. - /// - /// For example - /// \code - /// std::cout << format("Hello {1}, you are {2} years old") % name % age << std::endl; - /// \endcode - /// - /// Formatting is enclosed between curly brackets \c { \c } and defined by a comma separated list of flags in the format key[=value] - /// value may also be text included between single quotes \c ' that is used for special purposes where inclusion of non-ASCII - /// text is allowed - /// - /// Including of literal \c { and \c } is possible by specifying double brackets \c {{ and \c }} accordingly. - /// - /// - /// For example: - /// + /// A reference to the object is stored, so do not store the format object longer + /// than the lifetime of the parameter. + /// It is advisable to directly print the result: /// \code - /// std::cout << format("The height of water at {1,time} is {2,num=fixed,precision=3}") % time % height; + /// basic_format<char> fmt("{0}"); + /// fmt % (5 + 2); // INVALID: Dangling reference + /// int i = 42; + /// return fmt % i; // INVALID: Dangling reference + /// std::cout << fmt % (5 + 2); // OK, print immediately + /// return (fmt % (5 + 2)).str(); // OK, convert immediately to string /// \endcode - /// - /// The special key -- a number without a value defines the position of an input parameter. - /// List of keys: - /// - \c [0-9]+ -- digits, the index of a formatted parameter -- mandatory key. - /// - \c num or \c number -- format a number. Optional values are: - /// - \c hex -- display hexadecimal number - /// - \c oct -- display in octal format - /// - \c sci or \c scientific -- display in scientific format - /// - \c fix or \c fixed -- display in fixed format - /// . - /// For example \c number=sci - /// - \c cur or \c currency -- format currency. Optional values are: - /// - /// - \c iso -- display using ISO currency symbol. - /// - \c nat or \c national -- display using national currency symbol. - /// . - /// - \c per or \c percent -- format percent value. - /// - \c date, \c time , \c datetime or \c dt -- format date, time or date and time. Optional values are: - /// - \c s or \c short -- display in short format - /// - \c m or \c medium -- display in medium format. - /// - \c l or \c long -- display in long format. - /// - \c f or \c full -- display in full format. - /// . - /// - \c ftime with string (quoted) parameter -- display as with \c strftime see, \c as::ftime manipulator - /// - \c spell or \c spellout -- spell the number. - /// - \c ord or \c ordinal -- format ordinal number (1st, 2nd... etc) - /// - \c left or \c < -- align to left. - /// - \c right or \c > -- align to right. - /// - \c width or \c w -- set field width (requires parameter). - /// - \c precision or \c p -- set precision (requires parameter). - /// - \c locale -- with parameter -- switch locale for current operation. This command generates locale - /// with formatting facets giving more fine grained control of formatting. For example: - /// \code - /// std::cout << format("Today {1,date} ({1,date,locale=he_IL.UTF-8@calendar=hebrew,date} Hebrew Date)") % date; - /// \endcode - /// - \c timezone or \c tz -- the name of the timezone to display the time in. For example:\n - /// \code - /// std::cout << format("Time is: Local {1,time}, ({1,time,tz=EET} Eastern European Time)") % date; - /// \endcode - /// - \c local - display the time in local time - /// - \c gmt - display the time in UTC time scale - /// \code - /// std::cout << format("Local time is: {1,time,local}, universal time is {1,time,gmt}") % time; - /// \endcode - /// - /// - /// Invalid formatting strings are slightly ignored. This would prevent from translator - /// to crash the program in unexpected location. - /// - template<typename CharType> - class basic_format { - public: - typedef CharType char_type; ///< Underlying character type - typedef basic_message<char_type> message_type; ///< The translation message type - /// \cond INTERNAL - typedef details::formattible<CharType> formattible_type; - /// \endcond - - typedef std::basic_string<CharType> string_type; ///< string type for this type of character - typedef std::basic_ostream<CharType> stream_type; ///< output stream type for this type of character - - - /// - /// Create a format class for \a format_string - /// - basic_format(string_type format_string) : - format_(format_string), - translate_(false), - parameters_count_(0) - { - } - /// - /// Create a format class using message \a trans. The message if translated first according - /// to the rules of target locale and then interpreted as format string - /// - basic_format(message_type const &trans) : - message_(trans), - translate_(true), - parameters_count_(0) - { - } + template<typename Formattible> + basic_format& operator%(const Formattible& object) + { + add(formattible_type(object)); + return *this; + } - /// - /// Add new parameter to format list. The object should be a type - /// with defined expression out << object where \c out is \c std::basic_ostream. - /// - template<typename Formattible> - basic_format &operator % (Formattible const &object) - { - add(formattible_type(object)); - return *this; - } + /// Format a string using a locale \a loc + string_type str(const std::locale& loc = std::locale()) const + { + std::basic_ostringstream<CharType> buffer; + buffer.imbue(loc); + write(buffer); + return buffer.str(); + } + + /// write a formatted string to output stream \a out using out's locale + void write(stream_type& out) const + { + string_type format; + if(translate_) + format = message_.str(out.getloc(), ios_info::get(out).domain_id()); + else + format = format_; + + format_output(out, format); + } - /// - /// Format a string using a locale \a loc - /// - string_type str(std::locale const &loc = std::locale()) const + private: + class format_guard { + public: + format_guard(detail::format_parser& fmt) : fmt_(&fmt), restored_(false) {} + void restore() { - std::basic_ostringstream<CharType> buffer; - buffer.imbue(loc); - write(buffer); - return buffer.str(); + if(restored_) + return; + fmt_->restore(); + restored_ = true; } - - /// - /// write a formatted string to output stream \a out using out's locale - /// - void write(stream_type &out) const + ~format_guard() { - string_type format; - if(translate_) - format = message_.str(out.getloc(),ios_info::get(out).domain_id()); - else - format = format_; - - format_output(out,format); - + try { + restore(); + } catch(...) { + } } - private: + detail::format_parser* fmt_; + bool restored_; + }; - class format_guard { - public: - format_guard(details::format_parser &fmt) : - fmt_(&fmt), - restored_(false) - { - } - void restore() - { - if(restored_) - return; - fmt_->restore(); - restored_ = true; - } - ~format_guard() - { - try { - restore(); - } - catch(...) { + 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(); + const CharType* format = sformat.c_str(); + while(format[pos] != 0) { + if(format[pos] != obrk) { + if(format[pos] == cbrk && format[pos + 1] == cbrk) { + out << cbrk; + pos += 2; + } else { + out << format[pos]; + pos++; } + continue; } - private: - details::format_parser *fmt_; - bool restored_; - }; - void format_output(stream_type &out,string_type const &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(); - CharType const *format=sformat.c_str(); - while(format[pos]!=0) { - if(format[pos] != obrk) { - if(format[pos]==cbrk && format[pos+1]==cbrk) { - out << cbrk; - pos+=2; - } + if(pos + 1 < size && format[pos + 1] == obrk) { + out << obrk; + pos += 2; + continue; + } + pos++; + + detail::format_parser fmt(out, static_cast<void*>(&out), &basic_format::imbue_locale); + + format_guard guard(fmt); + + while(pos < size) { + std::string key; + 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 { - out << format[pos]; - pos++; + key += static_cast<char>(c); } - continue; } - if(pos+1 < size && format[pos+1]==obrk) { - out << obrk; - pos+=2; - continue; - } - pos++; - - details::format_parser fmt(out,static_cast<void *>(&out),&basic_format::imbue_locale); - - format_guard guard(fmt); - - while(pos < size) { - std::string key; - 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); - } - } - - if(format[pos]==eq) { + if(format[pos] == eq) { + pos++; + if(format[pos] == quote) { pos++; - if(format[pos]==quote) { - pos++; - use_svalue = false; - while(format[pos]) { - if(format[pos]==quote) { - if(format[pos+1]==quote) { - value+=quote; - pos+=2; - } - else { - pos++; - break; - } - } - else { - value+=format[pos]; + use_svalue = false; + while(format[pos]) { + if(format[pos] == quote) { + if(format[pos + 1] == quote) { + value += quote; + pos += 2; + } else { pos++; + break; } - } - } - else { - char_type c; - while((c=format[pos])!=0 && c!=comma && c!=cbrk) { - svalue+=static_cast<char>(c); + } else { + value += format[pos]; pos++; } } + } else { + char_type c; + while((c = format[pos]) != 0 && c != comma && c != cbrk) { + svalue += static_cast<char>(c); + pos++; + } } + } - if(use_svalue) { - fmt.set_one_flag(key,svalue); - } - else - fmt.set_flag_with_str(key,value); + if(use_svalue) { + fmt.set_one_flag(key, svalue); + } 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(); - pos++; - break; - } - else { - guard.restore(); - break; - } + if(format[pos] == comma) { + pos++; + continue; + } else if(format[pos] == cbrk) { + unsigned position = fmt.get_position(); + out << get(position); + guard.restore(); + pos++; + break; + } else { + guard.restore(); + break; } } } + } + void add(const formattible_type& param) + { + if(parameters_count_ >= base_params_) + ext_params_.push_back(param); + else + parameters_[parameters_count_] = param; + parameters_count_++; + } - // - // Non-copyable - // - basic_format(basic_format const &other); - void operator=(basic_format const &other); - - void add(formattible_type const ¶m) - { - if(parameters_count_ >= base_params_) - ext_params_.push_back(param); - else - parameters_[parameters_count_] = param; - parameters_count_++; - } - - formattible_type get(unsigned id) const - { - if(id >= parameters_count_) - return formattible_type(); - else if(id >= base_params_) - return ext_params_[id - base_params_]; - else - return parameters_[id]; - } - - static void imbue_locale(void *ptr,std::locale const &l) - { - reinterpret_cast<stream_type *>(ptr)->imbue(l); - } - - - - static unsigned const base_params_ = 8; - - message_type message_; - string_type format_; - bool translate_; - - - formattible_type parameters_[base_params_]; - unsigned parameters_count_; - std::vector<formattible_type> ext_params_; - }; - - /// - /// Write formatted message to stream. - /// - /// This operator actually causes actual text formatting. It uses the locale of \a out stream - /// - template<typename CharType> - std::basic_ostream<CharType> &operator<<(std::basic_ostream<CharType> &out,basic_format<CharType> const &fmt) + formattible_type get(unsigned id) const { - fmt.write(out); - return out; + if(id >= parameters_count_) + return formattible_type(); + else if(id >= base_params_) + return ext_params_[id - base_params_]; + else + return parameters_[id]; } + static void imbue_locale(void* ptr, const std::locale& l) { reinterpret_cast<stream_type*>(ptr)->imbue(l); } - /// - /// Definition of char based format - /// - typedef basic_format<char> format; + static constexpr unsigned base_params_ = 8; - /// - /// Definition of wchar_t based format - /// - typedef basic_format<wchar_t> wformat; + message_type message_; + string_type format_; + bool translate_; - #ifdef BOOST_LOCALE_ENABLE_CHAR16_T - /// - /// Definition of char16_t based format - /// - typedef basic_format<char16_t> u16format; - #endif + formattible_type parameters_[base_params_]; + unsigned parameters_count_; + std::vector<formattible_type> ext_params_; + }; - #ifdef BOOST_LOCALE_ENABLE_CHAR32_T - /// - /// Definition of char32_t based format - /// - typedef basic_format<char32_t> u32format; - #endif + /// Write formatted message to stream. + /// + /// This operator actually causes actual text formatting. It uses the locale of \a out stream + template<typename CharType> + std::basic_ostream<CharType>& operator<<(std::basic_ostream<CharType>& out, const basic_format<CharType>& fmt) + { + fmt.write(out); + return out; + } - /// - /// @} - /// + /// Definition of char based format + typedef basic_format<char> format; + /// Definition of wchar_t based format + typedef basic_format<wchar_t> wformat; - } -} +#ifdef BOOST_LOCALE_ENABLE_CHAR16_T + /// Definition of char16_t based format + typedef basic_format<char16_t> u16format; +#endif -#ifdef BOOST_MSVC -#pragma warning(pop) +#ifdef BOOST_LOCALE_ENABLE_CHAR32_T + /// Definition of char32_t based format + typedef basic_format<char32_t> u32format; #endif + /// @} +}} // namespace boost::locale + +#ifdef BOOST_MSVC +# pragma warning(pop) #endif -/// /// \example hello.cpp /// /// Basic example of using various functions provided by this library @@ -508,7 +453,5 @@ namespace boost { /// \example whello.cpp /// /// Basic example of using various functions with wide strings provided by this library -/// -/// - +#endif diff --git a/contrib/restricted/boost/locale/include/boost/locale/formatting.hpp b/contrib/restricted/boost/locale/include/boost/locale/formatting.hpp index d7111ebbb6..8348f7f826 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/formatting.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/formatting.hpp @@ -9,6 +9,8 @@ #include <boost/locale/config.hpp> #include <boost/locale/time_zone.hpp> +#include <boost/locale/util/string.hpp> +#include <boost/assert.hpp> #include <boost/cstdint.hpp> #include <cstring> #include <istream> @@ -17,656 +19,511 @@ #include <typeinfo> #ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4275 4251 4231 4660) +# pragma warning(push) +# pragma warning(disable : 4275 4251 4231 4660) #endif -namespace boost { - namespace locale { - /// - /// \brief This namespace holds additional formatting - /// flags that can be set using ios_info. - /// - namespace flags { - /// - /// Formatting flags, each one of them has corresponding manipulation - /// in namespace \a as - /// - typedef enum { - posix = 0, - number = 1, - currency = 2, - percent = 3, - date = 4, - time = 5, - datetime = 6, - strftime = 7, - spellout = 8, - ordinal = 9, - - display_flags_mask = 31, - - currency_default = 0 << 5, - currency_iso = 1 << 5, - currency_national = 2 << 5, - - currency_flags_mask = 3 << 5, - - time_default = 0 << 7, - time_short = 1 << 7, - time_medium = 2 << 7, - time_long = 3 << 7, - time_full = 4 << 7, - time_flags_mask = 7 << 7, - - date_default = 0 << 10, - date_short = 1 << 10, - date_medium = 2 << 10, - date_long = 3 << 10, - date_full = 4 << 10, - date_flags_mask = 7 << 10, - - datetime_flags_mask = date_flags_mask | time_flags_mask - - } display_flags_type; - - /// - /// Special string patters that can be used - /// for text formatting - /// - typedef enum { - datetime_pattern, ///< strftime like formatting - time_zone_id ///< time zone name - } pattern_type; - - /// - /// Special integer values that can be used for formatting - /// - typedef enum { - domain_id ///< Domain code - for message formatting - } value_type; - - - } // flags - - /// - /// \brief This class holds an external data - beyond existing fmtflags that std::ios_base holds - /// - /// You should almost never create this object directly. Instead, you should access it via ios_info::get(stream_object) - /// static member function. It automatically creates default formatting data for that stream - /// - class BOOST_LOCALE_DECL ios_info { - public: - - /// \cond INTERNAL - - ios_info(); - ios_info(ios_info const &); - ios_info const &operator=(ios_info const &); - ~ios_info(); - - /// \endcond - - /// - /// Get ios_info instance for specific stream object - /// - static ios_info &get(std::ios_base &ios); - - /// - /// Set a flags that define a way for format data like number, spell, currency etc. - /// - void display_flags(uint64_t flags); - - /// - /// Set a flags that define how to format currency - /// - void currency_flags(uint64_t flags); - - /// - /// Set a flags that define how to format date - /// - void date_flags(uint64_t flags); - - /// - /// Set a flags that define how to format time - /// - void time_flags(uint64_t flags); - - /// - /// Set a flags that define how to format both date and time - /// - void datetime_flags(uint64_t flags); - - /// - /// Set special message domain identification - /// - void domain_id(int); +namespace boost { namespace locale { + + /// \brief This namespace holds additional formatting + /// flags that can be set using ios_info. + namespace flags { + + /// Formatting flags, each one of them has corresponding manipulation + /// in namespace \a as + enum display_flags_type { + posix = 0, + number = 1, + currency = 2, + percent = 3, + date = 4, + time = 5, + datetime = 6, + strftime = 7, + spellout = 8, + ordinal = 9, + + display_flags_mask = 31, + + currency_default = 0 << 5, + currency_iso = 1 << 5, + currency_national = 2 << 5, + + currency_flags_mask = 3 << 5, + + time_default = 0 << 7, + time_short = 1 << 7, + time_medium = 2 << 7, + time_long = 3 << 7, + time_full = 4 << 7, + time_flags_mask = 7 << 7, + + date_default = 0 << 10, + date_short = 1 << 10, + date_medium = 2 << 10, + date_long = 3 << 10, + date_full = 4 << 10, + date_flags_mask = 7 << 10, + }; - /// - /// Set time zone for formatting dates and time - /// - void time_zone(std::string const &); + /// Special string patterns that can be used for text formatting + enum pattern_type { + datetime_pattern, ///< strftime like formatting + time_zone_id ///< time zone name + }; + /// Special integer values that can be used for formatting + enum value_type { + domain_id ///< Domain code - for message formatting + }; - /// - /// Set date/time pattern (strftime like) - /// - template<typename CharType> - void date_time_pattern(std::basic_string<CharType> const &str) + } // namespace flags + + /// \brief This class holds external data beyond existing fmtflags that std::ios_base holds + /// + /// You should almost never create this object directly. Instead, you should access it via + /// ios_info::get(stream_object) static member function. It automatically creates default formatting data for that + /// stream + class BOOST_LOCALE_DECL ios_info { + public: + /// \cond INTERNAL + ios_info(); + ios_info(const ios_info&); + ios_info& operator=(const ios_info&); + ~ios_info(); + /// \endcond + + /// Get ios_info instance for specific stream object + static ios_info& get(std::ios_base& ios); + + /// Set flags that define how to format data, e.g. number, spell, currency etc. + void display_flags(uint64_t flags); + /// Get flags that define how to format data, e.g. number, spell, currency etc. + uint64_t display_flags() const; + + /// Set flags that define how to format currency + void currency_flags(uint64_t flags); + /// Get flags that define how to format currency + uint64_t currency_flags() const; + + /// Set flags that define how to format date + void date_flags(uint64_t flags); + /// Get flags that define how to format date + uint64_t date_flags() const; + + /// Set flags that define how to format time + void time_flags(uint64_t flags); + /// Get flags that define how to format time + uint64_t time_flags() const; + + /// Set special message domain identification + void domain_id(int); + /// Get special message domain identification + int domain_id() const; + + /// Set time zone for formatting dates and time + void time_zone(const std::string&); + /// Get time zone for formatting dates and time + std::string time_zone() const; + + /// Set date/time pattern (strftime like) + 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()); + } + /// 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>(); + } + + /// \cond INTERNAL + void on_imbue(); + /// \endcond + + private: + class string_set; + + const string_set& date_time_pattern_set() const; + string_set& date_time_pattern_set(); + + class BOOST_LOCALE_DECL string_set { + public: + string_set(); + ~string_set(); + string_set(const string_set& other); + string_set& operator=(string_set other); + void swap(string_set& other); + + template<typename Char> + void set(const Char* s) { - string_set &s = date_time_pattern_set(); - s.set<CharType>(str.c_str()); + BOOST_ASSERT(s); + delete[] ptr; + ptr = nullptr; + type = &typeid(Char); + size = sizeof(Char) * (util::str_end(s) - s + 1); + ptr = new char[size]; + memcpy(ptr, s, size); } - - /// - /// Get a flags that define a way for format data like number, spell, currency etc. - /// - uint64_t display_flags() const; - - /// - /// Get a flags that define how to format currency - /// - uint64_t currency_flags() const; - - - /// - /// Get a flags that define how to format date - /// - uint64_t date_flags() const; - - /// - /// Get a flags that define how to format time - /// - uint64_t time_flags() const; - - /// - /// Get a flags that define how to format both date and time - /// - uint64_t datetime_flags() const; - - /// - /// Get special message domain identification - /// - int domain_id() const; - - /// - /// Get time zone for formatting dates and time - /// - std::string time_zone() const; - - /// - /// Get date/time pattern (strftime like) - /// - template<typename CharType> - std::basic_string<CharType> date_time_pattern() const + template<typename Char> + std::basic_string<Char> get() const { - string_set const &s = date_time_pattern_set(); - return s.get<CharType>(); + if(type == 0 || *type != typeid(Char)) + throw std::bad_cast(); + std::basic_string<Char> result = reinterpret_cast<const Char*>(ptr); + return result; } - /// \cond INTERNAL - void on_imbue(); - /// \endcond - private: - - class string_set; - - string_set const &date_time_pattern_set() const; - string_set &date_time_pattern_set(); - - class BOOST_LOCALE_DECL string_set { - public: - string_set(); - ~string_set(); - string_set(string_set const &other); - string_set const &operator=(string_set const &other); - void swap(string_set &other); - - template<typename Char> - void set(Char const *s) - { - delete [] ptr; - ptr = 0; - type=&typeid(Char); - Char const *end = s; - while(*end!=0) end++; - // if ptr = 0 it does not matter what is value of size - size = sizeof(Char)*(end - s+1); - ptr = new char[size]; - memcpy(ptr,s,size); - } - - template<typename Char> - std::basic_string<Char> get() const - { - if(type==0 || *type!=typeid(Char)) - throw std::bad_cast(); - std::basic_string<Char> result = reinterpret_cast<Char const *>(ptr); - return result; - } - - private: - std::type_info const *type; - size_t size; - char *ptr; - }; - - uint64_t flags_; - int domain_id_; - std::string time_zone_; - string_set datetime_; - - struct data; - data *d; - + const std::type_info* type; + size_t size; + char* ptr; }; + uint64_t flags_; + int domain_id_; + std::string time_zone_; + string_set datetime_; + }; + /// \brief This namespace includes all manipulators that can be used on IO streams + namespace as { + /// \defgroup manipulators I/O Stream manipulators /// - /// \brief This namespace includes all manipulators that can be used on IO streams - /// - namespace as { - /// - /// \defgroup manipulators I/O Stream manipulators - /// - /// @{ - /// - - /// - /// Format values with "POSIX" or "C" locale. Note, if locale was created with additional non-classic locale then - /// These numbers may be localized - /// - - inline std::ios_base & posix(std::ios_base & ios) - { - ios_info::get(ios).display_flags(flags::posix); - return ios; - } - - /// - /// Format a number. Note, unlike standard number formatting, integers would be treated like real numbers when std::fixed or - /// std::scientific manipulators were applied - /// - inline std::ios_base & number(std::ios_base & ios) - { - ios_info::get(ios).display_flags(flags::number); - return ios; - } - - /// - /// Format currency, number is treated like amount of money - /// - inline std::ios_base & currency(std::ios_base & ios) - { - ios_info::get(ios).display_flags(flags::currency); - return ios; - } - - /// - /// Format percent, value 0.3 is treated as 30%. - /// - inline std::ios_base & percent(std::ios_base & ios) - { - ios_info::get(ios).display_flags(flags::percent); - return ios; - } - - /// - /// Format a date, number is treated as POSIX time - /// - inline std::ios_base & date(std::ios_base & ios) - { - ios_info::get(ios).display_flags(flags::date); - return ios; - } - - /// - /// Format a time, number is treated as POSIX time - /// - inline std::ios_base & time(std::ios_base & ios) - { - ios_info::get(ios).display_flags(flags::time); - return ios; - } - - /// - /// Format a date and time, number is treated as POSIX time - /// - inline std::ios_base & datetime(std::ios_base & ios) - { - ios_info::get(ios).display_flags(flags::datetime); - return ios; - } - - /// - /// Create formatted date time, Please note, this manipulator only changes formatting mode, - /// and not format itself, so you are probably looking for ftime manipulator - /// - inline std::ios_base & strftime(std::ios_base & ios) - { - ios_info::get(ios).display_flags(flags::strftime); - return ios; - } - - /// - /// Spell the number, like "one hundred and ten" - /// - inline std::ios_base & spellout(std::ios_base & ios) - { - ios_info::get(ios).display_flags(flags::spellout); - return ios; - } - - /// - /// Write an order of the number like 4th. - /// - inline std::ios_base & ordinal(std::ios_base & ios) - { - ios_info::get(ios).display_flags(flags::ordinal); - return ios; - } - - /// - /// Set default currency formatting style -- national, like "$" - /// - inline std::ios_base & currency_default(std::ios_base & ios) - { - ios_info::get(ios).currency_flags(flags::currency_default); - return ios; - } - - /// - /// Set ISO currency formatting style, like "USD", (requires ICU >= 4.2) - /// - inline std::ios_base & currency_iso(std::ios_base & ios) - { - ios_info::get(ios).currency_flags(flags::currency_iso); - return ios; - } - - /// - /// Set national currency formatting style, like "$" - /// - inline std::ios_base & currency_national(std::ios_base & ios) - { - ios_info::get(ios).currency_flags(flags::currency_national); - return ios; - } - - /// - /// set default (medium) time formatting style - /// - inline std::ios_base & time_default(std::ios_base & ios) - { - ios_info::get(ios).time_flags(flags::time_default); - return ios; - } - - /// - /// set short time formatting style - /// - inline std::ios_base & time_short(std::ios_base & ios) - { - ios_info::get(ios).time_flags(flags::time_short); - return ios; - } - - /// - /// set medium time formatting style - /// - inline std::ios_base & time_medium(std::ios_base & ios) - { - ios_info::get(ios).time_flags(flags::time_medium); - return ios; - } - - /// - /// set long time formatting style - /// - inline std::ios_base & time_long(std::ios_base & ios) - { - ios_info::get(ios).time_flags(flags::time_long); - return ios; - } - - /// - /// set full time formatting style - /// - inline std::ios_base & time_full(std::ios_base & ios) - { - ios_info::get(ios).time_flags(flags::time_full); - return ios; - } - - /// - /// set default (medium) date formatting style - /// - inline std::ios_base & date_default(std::ios_base & ios) - { - ios_info::get(ios).date_flags(flags::date_default); - return ios; - } - - /// - /// set short date formatting style - /// - inline std::ios_base & date_short(std::ios_base & ios) - { - ios_info::get(ios).date_flags(flags::date_short); - return ios; - } - - /// - /// set medium date formatting style - /// - inline std::ios_base & date_medium(std::ios_base & ios) - { - ios_info::get(ios).date_flags(flags::date_medium); - return ios; - } - - /// - /// set long date formatting style - /// - inline std::ios_base & date_long(std::ios_base & ios) - { - ios_info::get(ios).date_flags(flags::date_long); - return ios; - } - - /// - /// set full date formatting style - /// - inline std::ios_base & date_full(std::ios_base & ios) - { - ios_info::get(ios).date_flags(flags::date_full); - return ios; - } - - - /// \cond INTERNAL - namespace details { - template<typename CharType> - struct add_ftime { - - std::basic_string<CharType> ftime; - - void apply(std::basic_ios<CharType> &ios) const - { - ios_info::get(ios).date_time_pattern(ftime); - as::strftime(ios); - } - - }; - - template<typename CharType> - std::basic_ostream<CharType> &operator<<(std::basic_ostream<CharType> &out,add_ftime<CharType> const &fmt) - { - fmt.apply(out); - return out; - } + /// @{ + + /// Format values with "POSIX" or "C" locale. Note, if locale was created with additional non-classic locale + /// then These numbers may be localized + inline std::ios_base& posix(std::ios_base& ios) + { + ios_info::get(ios).display_flags(flags::posix); + return ios; + } + + /// Format a number. Note, unlike standard number formatting, integers would be treated like real numbers when + /// std::fixed or std::scientific manipulators were applied + inline std::ios_base& number(std::ios_base& ios) + { + ios_info::get(ios).display_flags(flags::number); + return ios; + } + + /// Format currency, number is treated like amount of money + inline std::ios_base& currency(std::ios_base& ios) + { + ios_info::get(ios).display_flags(flags::currency); + return ios; + } + + /// Format percent, value 0.3 is treated as 30%. + inline std::ios_base& percent(std::ios_base& ios) + { + ios_info::get(ios).display_flags(flags::percent); + return ios; + } + + /// Format a date, number is treated as POSIX time + inline std::ios_base& date(std::ios_base& ios) + { + ios_info::get(ios).display_flags(flags::date); + return ios; + } + + /// Format a time, number is treated as POSIX time + inline std::ios_base& time(std::ios_base& ios) + { + ios_info::get(ios).display_flags(flags::time); + return ios; + } + + /// Format a date and time, number is treated as POSIX time + inline std::ios_base& datetime(std::ios_base& ios) + { + ios_info::get(ios).display_flags(flags::datetime); + return ios; + } + + /// Create formatted date time, Please note, this manipulator only changes formatting mode, + /// and not format itself, so you are probably looking for ftime manipulator + inline std::ios_base& strftime(std::ios_base& ios) + { + ios_info::get(ios).display_flags(flags::strftime); + return ios; + } + + /// Spell the number, like "one hundred and ten" + inline std::ios_base& spellout(std::ios_base& ios) + { + ios_info::get(ios).display_flags(flags::spellout); + return ios; + } + + /// Write an order of the number like 4th. + inline std::ios_base& ordinal(std::ios_base& ios) + { + ios_info::get(ios).display_flags(flags::ordinal); + return ios; + } + + /// Set default currency formatting style -- national, like "$" + inline std::ios_base& currency_default(std::ios_base& ios) + { + ios_info::get(ios).currency_flags(flags::currency_default); + return ios; + } + + /// Set ISO currency formatting style, like "USD", (requires ICU >= 4.2) + inline std::ios_base& currency_iso(std::ios_base& ios) + { + ios_info::get(ios).currency_flags(flags::currency_iso); + return ios; + } + + /// Set national currency formatting style, like "$" + inline std::ios_base& currency_national(std::ios_base& ios) + { + ios_info::get(ios).currency_flags(flags::currency_national); + return ios; + } + + /// set default (medium) time formatting style + inline std::ios_base& time_default(std::ios_base& ios) + { + ios_info::get(ios).time_flags(flags::time_default); + return ios; + } + + /// set short time formatting style + inline std::ios_base& time_short(std::ios_base& ios) + { + ios_info::get(ios).time_flags(flags::time_short); + return ios; + } + + /// set medium time formatting style + inline std::ios_base& time_medium(std::ios_base& ios) + { + ios_info::get(ios).time_flags(flags::time_medium); + return ios; + } + + /// set long time formatting style + inline std::ios_base& time_long(std::ios_base& ios) + { + ios_info::get(ios).time_flags(flags::time_long); + return ios; + } + + /// set full time formatting style + inline std::ios_base& time_full(std::ios_base& ios) + { + ios_info::get(ios).time_flags(flags::time_full); + return ios; + } + + /// set default (medium) date formatting style + inline std::ios_base& date_default(std::ios_base& ios) + { + ios_info::get(ios).date_flags(flags::date_default); + return ios; + } + + /// set short date formatting style + inline std::ios_base& date_short(std::ios_base& ios) + { + ios_info::get(ios).date_flags(flags::date_short); + return ios; + } + + /// set medium date formatting style + inline std::ios_base& date_medium(std::ios_base& ios) + { + ios_info::get(ios).date_flags(flags::date_medium); + return ios; + } + + /// set long date formatting style + inline std::ios_base& date_long(std::ios_base& ios) + { + ios_info::get(ios).date_flags(flags::date_long); + return ios; + } + + /// set full date formatting style + inline std::ios_base& date_full(std::ios_base& ios) + { + ios_info::get(ios).date_flags(flags::date_full); + return ios; + } + + /// \cond INTERNAL + namespace detail { + template<typename CharType> + struct add_ftime { + std::basic_string<CharType> ftime; - template<typename CharType> - std::basic_istream<CharType> &operator>>(std::basic_istream<CharType> &in,add_ftime<CharType> const &fmt) + void apply(std::basic_ios<CharType>& ios) const { - fmt.apply(in); - return in; + ios_info::get(ios).date_time_pattern(ftime); + as::strftime(ios); } - - } - /// \endcond - - /// - /// Set strftime like formatting string - /// - /// Please note, formatting flags are very similar but not exactly the same as flags for C function strftime. - /// Differences: some flags as "%e" do not add blanks to fill text up to two spaces, not all flags supported. - /// - /// Flags: - /// - "%a" -- Abbreviated weekday (Sun.) - /// - "%A" -- Full weekday (Sunday) - /// - "%b" -- Abbreviated month (Jan.) - /// - "%B" -- Full month (January) - /// - "%c" -- Locale date-time format. **Note:** prefer using "as::datetime" - /// - "%d" -- Day of Month [01,31] - /// - "%e" -- Day of Month [1,31] - /// - "%h" -- Same as "%b" - /// - "%H" -- 24 clock hour [00,23] - /// - "%I" -- 12 clock hour [01,12] - /// - "%j" -- Day of year [1,366] - /// - "%m" -- Month [01,12] - /// - "%M" -- Minute [00,59] - /// - "%n" -- New Line - /// - "%p" -- AM/PM in locale representation - /// - "%r" -- Time with AM/PM, same as "%I:%M:%S %p" - /// - "%R" -- Same as "%H:%M" - /// - "%S" -- Second [00,61] - /// - "%t" -- Tab character - /// - "%T" -- Same as "%H:%M:%S" - /// - "%x" -- Local date representation. **Note:** prefer using "as::date" - /// - "%X" -- Local time representation. **Note:** prefer using "as::time" - /// - "%y" -- Year [00,99] - /// - "%Y" -- 4 digits year. (2009) - /// - "%Z" -- Time Zone - /// - "%%" -- Percent symbol - /// - + }; template<typename CharType> - #ifdef BOOST_LOCALE_DOXYGEN - unspecified_type - #else - details::add_ftime<CharType> - #endif - ftime(std::basic_string<CharType> const &format) + std::basic_ostream<CharType>& operator<<(std::basic_ostream<CharType>& out, const add_ftime<CharType>& fmt) { - details::add_ftime<CharType> fmt; - fmt.ftime=format; - return fmt; + fmt.apply(out); + return out; } - /// - /// See ftime(std::basic_string<CharType> const &format) - /// template<typename CharType> - #ifdef BOOST_LOCALE_DOXYGEN - unspecified_type - #else - details::add_ftime<CharType> - #endif - ftime(CharType const *format) + std::basic_istream<CharType>& operator>>(std::basic_istream<CharType>& in, const add_ftime<CharType>& fmt) { - details::add_ftime<CharType> fmt; - fmt.ftime=format; - return fmt; - } - - /// \cond INTERNAL - namespace details { - struct set_timezone { - std::string id; - }; - template<typename CharType> - std::basic_ostream<CharType> &operator<<(std::basic_ostream<CharType> &out,set_timezone const &fmt) - { - ios_info::get(out).time_zone(fmt.id); - return out; - } - - template<typename CharType> - std::basic_istream<CharType> &operator>>(std::basic_istream<CharType> &in,set_timezone const &fmt) - { - ios_info::get(in).time_zone(fmt.id); - return in; - } + fmt.apply(in); + return in; } - /// \endcond - /// - /// Set GMT time zone to stream - /// - inline std::ios_base &gmt(std::ios_base &ios) - { - ios_info::get(ios).time_zone("GMT"); - return ios; - } + } // namespace detail + /// \endcond - /// - /// Set local time zone to stream - /// - inline std::ios_base &local_time(std::ios_base &ios) - { - ios_info::get(ios).time_zone(time_zone::global()); - return ios; - } + /// Set strftime like formatting string + /// + /// Please note, formatting flags are very similar but not exactly the same as flags for C function strftime. + /// Differences: some flags as "%e" do not add blanks to fill text up to two spaces, not all flags supported. + /// + /// Flags: + /// - "%a" -- Abbreviated weekday (Sun.) + /// - "%A" -- Full weekday (Sunday) + /// - "%b" -- Abbreviated month (Jan.) + /// - "%B" -- Full month (January) + /// - "%c" -- Locale date-time format. **Note:** prefer using "as::datetime" + /// - "%d" -- Day of Month [01,31] + /// - "%e" -- Day of Month [1,31] + /// - "%h" -- Same as "%b" + /// - "%H" -- 24 clock hour [00,23] + /// - "%I" -- 12 clock hour [01,12] + /// - "%j" -- Day of year [1,366] + /// - "%m" -- Month [01,12] + /// - "%M" -- Minute [00,59] + /// - "%n" -- New Line + /// - "%p" -- AM/PM in locale representation + /// - "%r" -- Time with AM/PM, same as "%I:%M:%S %p" + /// - "%R" -- Same as "%H:%M" + /// - "%S" -- Second [00,61] + /// - "%t" -- Tab character + /// - "%T" -- Same as "%H:%M:%S" + /// - "%x" -- Local date representation. **Note:** prefer using "as::date" + /// - "%X" -- Local time representation. **Note:** prefer using "as::time" + /// - "%y" -- Year [00,99] + /// - "%Y" -- 4 digits year. (2009) + /// - "%Z" -- Time Zone + /// - "%%" -- Percent symbol + /// - /// - /// Set time zone using \a id - /// - inline - #ifdef BOOST_LOCALE_DOXYGEN - unspecified_type - #else - details::set_timezone - #endif - time_zone(char const *id) + template<typename CharType> +#ifdef BOOST_LOCALE_DOXYGEN + unspecified_type +#else + detail::add_ftime<CharType> +#endif + ftime(const std::basic_string<CharType>& format) + { + detail::add_ftime<CharType> fmt; + fmt.ftime = format; + return fmt; + } + + /// See ftime(std::basic_string<CharType> const &format) + template<typename CharType> +#ifdef BOOST_LOCALE_DOXYGEN + unspecified_type +#else + detail::add_ftime<CharType> +#endif + ftime(const CharType* format) + { + detail::add_ftime<CharType> fmt; + fmt.ftime = format; + return fmt; + } + + /// \cond INTERNAL + namespace detail { + struct set_timezone { + std::string id; + }; + template<typename CharType> + std::basic_ostream<CharType>& operator<<(std::basic_ostream<CharType>& out, const set_timezone& fmt) { - details::set_timezone tz; - tz.id=id; - return tz; + ios_info::get(out).time_zone(fmt.id); + return out; } - /// - /// Set time zone using \a id - /// - inline - #ifdef BOOST_LOCALE_DOXYGEN - unspecified_type - #else - details::set_timezone - #endif - time_zone(std::string const &id) + template<typename CharType> + std::basic_istream<CharType>& operator>>(std::basic_istream<CharType>& in, const set_timezone& fmt) { - details::set_timezone tz; - tz.id=id; - return tz; - } - + ios_info::get(in).time_zone(fmt.id); + return in; + } + } // namespace detail + /// \endcond + + /// Set GMT time zone to stream + inline std::ios_base& gmt(std::ios_base& ios) + { + ios_info::get(ios).time_zone("GMT"); + return ios; + } + + /// Set local time zone to stream + inline std::ios_base& local_time(std::ios_base& ios) + { + ios_info::get(ios).time_zone(time_zone::global()); + return ios; + } + + /// Set time zone using \a id + inline +#ifdef BOOST_LOCALE_DOXYGEN + unspecified_type +#else + detail::set_timezone +#endif + time_zone(const char* id) + { + detail::set_timezone tz; + tz.id = id; + return tz; + } + + /// Set time zone using \a id + inline +#ifdef BOOST_LOCALE_DOXYGEN + unspecified_type +#else + detail::set_timezone +#endif + time_zone(const std::string& id) + { + detail::set_timezone tz; + tz.id = id; + return tz; + } - /// /// @} - /// - } // as manipulators + } // namespace as - } // locale -} // boost +}} // namespace boost::locale #ifdef BOOST_MSVC -#pragma warning(pop) +# pragma warning(pop) #endif - #endif diff --git a/contrib/restricted/boost/locale/include/boost/locale/generator.hpp b/contrib/restricted/boost/locale/include/boost/locale/generator.hpp index 75e9389b05..726817c57e 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/generator.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/generator.hpp @@ -9,224 +9,234 @@ #include <boost/locale/config.hpp> #include <boost/locale/hold_ptr.hpp> #include <boost/cstdint.hpp> -#include <string> #include <locale> #include <memory> +#include <string> #ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4275 4251 4231 4660) +# pragma warning(push) +# pragma warning(disable : 4275 4251 4231 4660) #endif namespace boost { +/// +/// \brief This is the main namespace that encloses all localization classes +/// +namespace locale { + + class localization_backend; + class localization_backend_manager; + + /// Type that specifies the character type that locales can be generated for + /// + /// Supports bitwise OR and bitwise AND (the latter returning if the type is set) + enum class char_facet_t : uint32_t { + nochar = 0, ///< Unspecified character category for character independent facets + char_f = 1 << 0, ///< 8-bit character facets + wchar_f = 1 << 1, ///< wide character facets +#ifdef BOOST_LOCALE_ENABLE_CHAR16_T + char16_f = 1 << 2, ///< C++11 char16_t facets +#endif +#ifdef BOOST_LOCALE_ENABLE_CHAR32_T + char32_f = 1 << 3, ///< C++11 char32_t facets +#endif + }; + typedef BOOST_DEPRECATED("Use char_facet_t") char_facet_t character_facet_type; + + /// First facet specific for character type + constexpr char_facet_t character_facet_first = char_facet_t::char_f; + /// Last facet specific for character type + constexpr char_facet_t character_facet_last = +#ifdef BOOST_LOCALE_ENABLE_CHAR32_T + char_facet_t::char32_f; +#elif defined BOOST_LOCALE_ENABLE_CHAR16_T + char_facet_t::char16_f; +#else + char_facet_t::wchar_f; +#endif + /// Special mask -- generate all + constexpr char_facet_t all_characters = char_facet_t(0xFFFFFFFFu); + + /// Type used for more fine grained generation of facets /// - /// \brief This is the main namespace that encloses all localization classes + /// Supports bitwise OR and bitwise AND (the latter returning if the type is set) + enum class category_t : uint32_t { + convert = 1 << 0, ///< Generate conversion facets + collation = 1 << 1, ///< Generate collation facets + formatting = 1 << 2, ///< Generate numbers, currency, date-time formatting facets + parsing = 1 << 3, ///< Generate numbers, currency, date-time formatting facets + message = 1 << 4, ///< Generate message facets + codepage = 1 << 5, ///< Generate character set conversion facets (derived from std::codecvt) + boundary = 1 << 6, ///< Generate boundary analysis facet + calendar = 1 << 16, ///< Generate boundary analysis facet + information = 1 << 17, ///< Generate general locale information facet + }; + typedef BOOST_DEPRECATED("Use category_t") category_t locale_category_type; + + /// First facet specific for character + constexpr category_t per_character_facet_first = category_t::convert; + /// Last facet specific for character + constexpr category_t per_character_facet_last = category_t::boundary; + /// First character independent facet + constexpr category_t non_character_facet_first = category_t::calendar; + /// Last character independent facet + constexpr category_t non_character_facet_last = category_t::information; + /// First category facet + constexpr category_t category_first = category_t::convert; + /// Last category facet + constexpr category_t category_last = category_t::information; + /// Generate all of them + constexpr category_t all_categories = category_t(0xFFFFFFFFu); + + /// \brief the major class used for locale generation /// - namespace locale { + /// This class is used for specification of all parameters required for locale generation and + /// caching. This class const member functions are thread safe if locale class implementation is thread safe. + class BOOST_LOCALE_DECL generator { + public: + /// Create new generator using global localization_backend_manager + generator(); + /// Create new generator using specific localization_backend_manager + generator(const localization_backend_manager&); + + ~generator(); + + /// Set types of facets that should be generated, default all + void categories(category_t cats); + /// Get types of facets that should be generated, default all + category_t categories() const; + + /// Set the characters type for which the facets should be generated, default all supported + void characters(char_facet_t chars); + /// Get the characters type for which the facets should be generated, default all supported + char_facet_t characters() const; + + /// Add a new domain of messages that would be generated. It should be set in order to enable + /// messages support. + /// + /// Messages domain has following format: "name" or "name/encoding" + /// where name is the base name of the "mo" file where the catalog is stored + /// without ".mo" extension. For example for file \c /usr/share/locale/he/LC_MESSAGES/blog.mo + /// it would be \c blog. + /// + /// You can optionally specify the encoding of the keys in the sources by adding "/encoding_name" + /// For example blog/cp1255. + /// + /// If not defined all keys are assumed to be UTF-8 encoded. + /// + /// \note When you select a domain for the program using dgettext or message API, you + /// do not specify the encoding part. So for example if the provided + /// domain name was "blog/windows-1255" then for translation + /// you should use dgettext("blog","Hello") + void add_messages_domain(const std::string& domain); - class localization_backend; - class localization_backend_manager; + /// Set default message domain. If this member was not called, the first added messages domain is used. + /// If the domain \a domain is not added yet it is added. + void set_default_messages_domain(const std::string& domain); - static const uint32_t nochar_facet = 0; ///< Unspecified character category for character independent facets - static const uint32_t char_facet = 1 << 0; ///< 8-bit character facets - static const uint32_t wchar_t_facet = 1 << 1; ///< wide character facets - static const uint32_t char16_t_facet = 1 << 2; ///< C++0x char16_t facets - static const uint32_t char32_t_facet = 1 << 3; ///< C++0x char32_t facets + /// Remove all added domains from the list + void clear_domains(); - static const uint32_t character_first_facet = char_facet; ///< First facet specific for character type - static const uint32_t character_last_facet = char32_t_facet; ///< Last facet specific for character type - static const uint32_t all_characters = 0xFFFF; ///< Special mask -- generate all + /// Add a search path where dictionaries are looked in. + /// + /// \note + /// + /// - Under the Windows platform the path is treated as a path in the locale's encoding so + /// if you create locale "en_US.windows-1251" then path would be treated as cp1255, + /// and if it is en_US.UTF-8 it is treated as UTF-8. File name is always opened with + /// a wide file name as wide file names are the native file name on Windows. + /// + /// - Under POSIX platforms all paths passed as-is regardless of encoding as narrow + /// encodings are the native encodings for POSIX platforms. + /// + void add_messages_path(const std::string& path); - typedef uint32_t character_facet_type; ///<type that specifies the character type that locales can be generated for + /// Remove all added paths + void clear_paths(); - static const uint32_t convert_facet = 1 << 0; ///< Generate conversion facets - static const uint32_t collation_facet = 1 << 1; ///< Generate collation facets - static const uint32_t formatting_facet= 1 << 2; ///< Generate numbers, currency, date-time formatting facets - static const uint32_t parsing_facet = 1 << 3; ///< Generate numbers, currency, date-time formatting facets - static const uint32_t message_facet = 1 << 4; ///< Generate message facets - static const uint32_t codepage_facet = 1 << 5; ///< Generate character set conversion facets (derived from std::codecvt) - static const uint32_t boundary_facet = 1 << 6; ///< Generate boundary analysis facet + /// Remove all cached locales + void clear_cache(); - static const uint32_t per_character_facet_first = convert_facet; ///< First facet specific for character - static const uint32_t per_character_facet_last = boundary_facet; ///< Last facet specific for character + /// Turn locale caching ON + void locale_cache_enabled(bool on); - static const uint32_t calendar_facet = 1 << 16; ///< Generate boundary analysis facet - static const uint32_t information_facet = 1 << 17; ///< Generate general locale information facet + /// Get locale cache option + bool locale_cache_enabled() const; - static const uint32_t non_character_facet_first = calendar_facet; ///< First character independent facet - static const uint32_t non_character_facet_last = information_facet;///< Last character independent facet + /// Check if by default ANSI encoding is selected or UTF-8 onces. The default is false. + bool use_ansi_encoding() const; + /// Select ANSI encodings as default system encoding rather then UTF-8 by default + /// under Windows. + /// + /// The default is the most portable and most powerful encoding, UTF-8, but the user + /// can select "system" one if dealing with legacy applications + void use_ansi_encoding(bool enc); - static const uint32_t all_categories = 0xFFFFFFFFu; ///< Generate all of them + /// Generate a locale with id \a id + std::locale generate(const std::string& id) const; + /// Generate a locale with id \a id. Use \a base as a locale to which all facets are added, + /// instead of std::locale::classic(). + std::locale generate(const std::locale& base, const std::string& id) const; + /// Shortcut to generate(id) + std::locale operator()(const std::string& id) const { return generate(id); } - typedef uint32_t locale_category_type; ///< a type used for more fine grained generation of facets + /// Set backend specific option + void set_option(const std::string& name, const std::string& value); - /// - /// \brief the major class used for locale generation - /// - /// This class is used for specification of all parameters required for locale generation and - /// caching. This class const member functions are thread safe if locale class implementation is thread safe. - /// + /// Clear backend specific options + void clear_options(); - class BOOST_LOCALE_DECL generator { - public: - - /// - /// Create new generator using global localization_backend_manager - /// - generator(); - /// - /// Create new generator using specific localization_backend_manager - /// - generator(localization_backend_manager const &); - - ~generator(); - - /// - /// Set types of facets that should be generated, default all - /// - void categories(locale_category_type cats); - /// - /// Get types of facets that should be generated, default all - /// - locale_category_type categories() const; - - /// - /// Set the characters type for which the facets should be generated, default all supported - /// - void characters(character_facet_type chars); - /// - /// Get the characters type for which the facets should be generated, default all supported - /// - character_facet_type characters() const; - - /// - /// Add a new domain of messages that would be generated. It should be set in order to enable - /// messages support. - /// - /// Messages domain has following format: "name" or "name/encoding" - /// where name is the base name of the "mo" file where the catalog is stored - /// without ".mo" extension. For example for file \c /usr/share/locale/he/LC_MESSAGES/blog.mo - /// it would be \c blog. - /// - /// You can optionally specify the encoding of the keys in the sources by adding "/encoding_name" - /// For example blog/cp1255. - /// - /// If not defined all keys are assumed to be UTF-8 encoded. - /// - /// \note When you select a domain for the program using dgettext or message API, you - /// do not specify the encoding part. So for example if the provided - /// domain name was "blog/windows-1255" then for translation - /// you should use dgettext("blog","Hello") - /// - /// - void add_messages_domain(std::string const &domain); - /// - /// Set default message domain. If this member was not called, the first added messages domain is used. - /// If the domain \a domain is not added yet it is added. - /// - void set_default_messages_domain(std::string const &domain); - - /// - /// Remove all added domains from the list - /// - void clear_domains(); - - /// - /// Add a search path where dictionaries are looked in. - /// - /// \note - /// - /// - Under the Windows platform the path is treated as a path in the locale's encoding so - /// if you create locale "en_US.windows-1251" then path would be treated as cp1255, - /// and if it is en_US.UTF-8 it is treated as UTF-8. File name is always opened with - /// a wide file name as wide file names are the native file name on Windows. - /// - /// - Under POSIX platforms all paths passed as-is regardless of encoding as narrow - /// encodings are the native encodings for POSIX platforms. - /// - /// - void add_messages_path(std::string const &path); - - /// - /// Remove all added paths - /// - void clear_paths(); - - /// - /// Remove all cached locales - /// - void clear_cache(); - - /// - /// Turn locale caching ON - /// - void locale_cache_enabled(bool on); - - /// - /// Get locale cache option - /// - bool locale_cache_enabled() const; - - /// - /// Check if by default ANSI encoding is selected or UTF-8 onces. The default is false. - /// - bool use_ansi_encoding() const; - - /// - /// Select ANSI encodings as default system encoding rather then UTF-8 by default - /// under Windows. - /// - /// The default is the most portable and most powerful encoding, UTF-8, but the user - /// can select "system" one if dealing with legacy applications - /// - void use_ansi_encoding(bool enc); - - /// - /// Generate a locale with id \a id - /// - std::locale generate(std::string const &id) const; - /// - /// Generate a locale with id \a id. Use \a base as a locale to which all facets are added, - /// instead of std::locale::classic(). - /// - std::locale generate(std::locale const &base,std::string const &id) const; - /// - /// Shortcut to generate(id) - /// - std::locale operator()(std::string const &id) const - { - return generate(id); - } - - /// - /// Set backend specific option - /// - void set_option(std::string const &name,std::string const &value); - - /// - /// Clear backend specific options - /// - void clear_options(); - - private: - - void set_all_options(localization_backend& backend,std::string const &id) const; - - generator(generator const &); - void operator=(generator const &); - - struct data; - hold_ptr<data> d; - }; + private: + void set_all_options(localization_backend& backend, const std::string& id) const; + + generator(const generator&); + void operator=(const generator&); + + struct data; + hold_ptr<data> d; + }; + + constexpr char_facet_t operator|(const char_facet_t lhs, const char_facet_t rhs) + { + return char_facet_t(static_cast<uint32_t>(lhs) | static_cast<uint32_t>(rhs)); + } + constexpr char_facet_t operator^(const char_facet_t lhs, const char_facet_t rhs) + { + return char_facet_t(static_cast<uint32_t>(lhs) ^ static_cast<uint32_t>(rhs)); + } + constexpr bool operator&(const char_facet_t lhs, const char_facet_t rhs) + { + return (static_cast<uint32_t>(lhs) & static_cast<uint32_t>(rhs)) != 0u; + } + // Prefix increment: Return the next value + BOOST_CXX14_CONSTEXPR inline char_facet_t& operator++(char_facet_t& v) + { + return v = char_facet_t(static_cast<uint32_t>(v) ? static_cast<uint32_t>(v) << 1 : 1); + } + constexpr category_t operator|(const category_t lhs, const category_t rhs) + { + return category_t(static_cast<uint32_t>(lhs) | static_cast<uint32_t>(rhs)); + } + constexpr category_t operator^(const category_t lhs, const category_t rhs) + { + return category_t(static_cast<uint32_t>(lhs) ^ static_cast<uint32_t>(rhs)); } -} + constexpr bool operator&(const category_t lhs, const category_t rhs) + { + return (static_cast<uint32_t>(lhs) & static_cast<uint32_t>(rhs)) != 0u; + } + // Prefix increment: Return the next value + BOOST_CXX14_CONSTEXPR inline category_t& operator++(category_t& v) + { + return v = category_t(static_cast<uint32_t>(v) << 1); + } +} // namespace locale +} // namespace boost #ifdef BOOST_MSVC -#pragma warning(pop) +# pragma warning(pop) #endif - #endif - diff --git a/contrib/restricted/boost/locale/include/boost/locale/generic_codecvt.hpp b/contrib/restricted/boost/locale/include/boost/locale/generic_codecvt.hpp index ab3d50771e..0ad94bad6a 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/generic_codecvt.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/generic_codecvt.hpp @@ -9,660 +9,575 @@ #include <boost/locale/utf.hpp> #include <boost/cstdint.hpp> -#include <boost/static_assert.hpp> #include <locale> -namespace boost { -namespace locale { +namespace boost { namespace locale { #ifndef BOOST_LOCALE_DOXYGEN -// -// Make sure that mbstate can keep 16 bit of UTF-16 sequence -// -BOOST_STATIC_ASSERT(sizeof(std::mbstate_t)>=2); + // + // 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 +// 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 -/// -/// \brief A base class that used to define constants for generic_codecvt -/// -class generic_codecvt_base { -public: + /// \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 + 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 + }; + }; + + /// \brief Generic codecvt facet for various stateless encodings to UTF-16 and UTF-32 using wchar_t, char32_t + /// and char16_t /// - /// Initail state for converting to or from unicode code points, used by initial_state in derived classes + /// Implementations should derive from this class defining itself as CodecvtImpl and provide following members /// - 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 - }; -}; - -/// -/// \brief Geneneric generic codecvt facet, various stateless encodings to UTF-16 and UTF-32 using wchar_t, char32_t and char16_t -/// -/// Implementations should dervide from this class defining itself as CodecvtImpl and provide following members -/// -/// - `state_type` - a type of special object that allows to store intermediate cached data, for example `iconv_t` descriptor -/// - `state_type initial_state(generic_codecvt_base::initial_convertion_state direction) const` - member function 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 seqnece 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 can not be performed -/// -/// -/// For example implementaion of codecvt for latin1/ISO-8859-1 character set -/// -/// \code -/// -/// template<typename CharType> -/// class latin1_codecvt :boost::locale::generic_codecvt<CharType,latin1_codecvt<CharType> > -/// { -/// public: -/// -/// /* Standard codecvt constructor */ -/// latin1_codecvt(size_t refs = 0) : boost::locale::generic_codecvt<CharType,latin1_codecvt<CharType> >(refs) -/// { -/// } -/// -/// /* State is unused but required by generic_codecvt */ -/// struct state_type {}; -/// -/// state_type initial_state(generic_codecvt_base::initial_convertion_state /*unused*/) const -/// { -/// return state_type(); -/// } -/// -/// int max_encoding_length() const -/// { -/// return 1; -/// } -/// -/// boost::locale::utf::code_point to_unicode(state_type &,char const *&begin,char const *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 -/// { -/// if(u >= 256) -/// return boost::locale::utf::illegal; -/// if(begin == end) -/// return boost::locale::utf::incomplete; -/// *begin = u; -/// return 1; -/// } -/// }; -/// -/// \endcode -/// -/// When external tools used for encoding conversion, the `state_type` is useful to save objects used for conversions. For example, -/// icu::UConverter can be saved in such a state for an efficient use: -/// -/// \code -/// template<typename 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) -/// { ... } -/// -/// /* State is unused but required by generic_codecvt */ -/// struct std::unique_ptr<UConverter,void (*)(UConverter*)> state_type; -/// -/// 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); -/// } -/// -/// boost::locale::utf::code_point to_unicode(state_type &ptr,char const *&begin,char const *end) const -/// { -/// UErrorCode err = U_ZERO_ERROR; -/// boost::locale::utf::code_point cp = ucnv_getNextUChar(ptr.get(),&begin,end,&err); -/// ... -/// } -/// ... -/// }; -/// \endcode -/// -/// -template<typename CharType,typename CodecvtImpl,int CharSize=sizeof(CharType)> -class generic_codecvt; - -/// -/// \brief UTF-16 to/from UTF-8 codecvt facet to use with char16_t or wchar_t on Windows -/// -/// Note in order to fit the requirements of usability by std::wfstream it uses mbstate_t -/// to handle intermediate states in handling of variable length UTF-16 sequences -/// -/// Its member functions implement standard virtual functions of basic codecvt -/// -template<typename CharType,typename CodecvtImpl> -class generic_codecvt<CharType,CodecvtImpl,2> : public std::codecvt<CharType,char,std::mbstate_t>, public generic_codecvt_base -{ -public: - - typedef CharType uchar; - - generic_codecvt(size_t refs = 0) : - std::codecvt<CharType,char,std::mbstate_t>(refs) - { - } - CodecvtImpl const &implementation() const - { - return *static_cast<CodecvtImpl const *>(this); - } - -protected: - - - std::codecvt_base::result do_unshift(std::mbstate_t &s,char *from,char * /*to*/,char *&next) const BOOST_OVERRIDE - { - boost::uint16_t &state = *reinterpret_cast<boost::uint16_t *>(&s); + /// - `state_type` - a type of special object that allows to store intermediate cached data, for example `iconv_t` + /// descriptor + /// - `state_type initial_state(generic_codecvt_base::initial_convertion_state direction) const` - member function + /// 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 + /// can not be performed + /// + /// + /// For example implementation of codecvt for latin1/ISO-8859-1 character set + /// + /// \code + /// + /// template<typename CharType> + /// class latin1_codecvt :boost::locale::generic_codecvt<CharType,latin1_codecvt<CharType> > + /// { + /// public: + /// + /// /* Standard codecvt constructor */ + /// latin1_codecvt(size_t refs = 0): boost::locale::generic_codecvt<CharType,latin1_codecvt<CharType> >(refs) + /// { + /// } + /// + /// /* State is unused but required by generic_codecvt */ + /// struct state_type {}; + /// + /// state_type initial_state(generic_codecvt_base::initial_convertion_state /*unused*/) const + /// { + /// return state_type(); + /// } + /// + /// int max_encoding_length() const + /// { + /// return 1; + /// } + /// + /// boost::locale::utf::code_point to_unicode(state_type &,char const *&begin,char const *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 + /// { + /// if(u >= 256) + /// return boost::locale::utf::illegal; + /// if(begin == end) + /// return boost::locale::utf::incomplete; + /// *begin = u; + /// return 1; + /// } + /// }; + /// + /// \endcode + /// + /// When external tools used for encoding conversion, the `state_type` is useful to save objects used for + /// conversions. For example, icu::UConverter can be saved in such a state for an efficient use: + /// + /// \code + /// template<typename 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) + /// { ... } + /// + /// /* State is unused but required by generic_codecvt */ + /// struct std::unique_ptr<UConverter,void (*)(UConverter*)> state_type; + /// + /// 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); + /// } + /// + /// boost::locale::utf::code_point to_unicode(state_type &ptr,char const *&begin,char const *end) const + /// { + /// UErrorCode err = U_ZERO_ERROR; + /// boost::locale::utf::code_point cp = ucnv_getNextUChar(ptr.get(),&begin,end,&err); + /// ... + /// } + /// ... + /// }; + /// \endcode + /// + template<typename CharType, typename CodecvtImpl, int CharSize = sizeof(CharType)> + class generic_codecvt; + + /// \brief UTF-16 to/from UTF-8 codecvt facet to use with char16_t or wchar_t on Windows + /// + /// Note in order to fit the requirements of usability by std::wfstream it uses mbstate_t + /// to handle intermediate states in handling of variable length UTF-16 sequences + /// + /// Its member functions implement standard virtual functions of basic codecvt + template<typename CharType, typename CodecvtImpl> + class generic_codecvt<CharType, CodecvtImpl, 2> : public std::codecvt<CharType, char, std::mbstate_t>, + public generic_codecvt_base { + public: + typedef CharType uchar; + + generic_codecvt(size_t refs = 0) : std::codecvt<CharType, char, std::mbstate_t>(refs) {} + const CodecvtImpl& implementation() const { return *static_cast<const CodecvtImpl*>(this); } + + 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); #ifdef DEBUG_CODECVT - std::cout << "Entering unshift " << std::hex << state << std::dec << std::endl; + std::cout << "Entering unshift " << std::hex << state << std::dec << std::endl; #endif - if(state != 0) - return std::codecvt_base::error; - next=from; - return std::codecvt_base::ok; - } - int do_encoding() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE - { - return 0; - } - int do_max_length() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE - { - return implementation().max_encoding_length(); - } - bool do_always_noconv() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE - { - return false; - } - - int - do_length( std::mbstate_t - #ifdef BOOST_LOCALE_DO_LENGTH_MBSTATE_CONST - const - #endif - &std_state, - char const *from, - char const *from_end, - size_t max) const BOOST_OVERRIDE - { - #ifndef BOOST_LOCALE_DO_LENGTH_MBSTATE_CONST - char const *save_from = from; - boost::uint16_t &state = *reinterpret_cast<boost::uint16_t *>(&std_state); - #else - size_t save_max = max; - boost::uint16_t state = *reinterpret_cast<boost::uint16_t const *>(&std_state); - #endif - - typename CodecvtImpl::state_type cvt_state = implementation().initial_state(generic_codecvt_base::to_unicode_state); - while(max > 0 && from < from_end){ - char const *prev_from = from; - boost::uint32_t 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 != 0) + return std::codecvt_base::error; + next = from; + return std::codecvt_base::ok; + } + int do_encoding() const noexcept override + { + return 0; + } + 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 + { +#ifndef BOOST_LOCALE_DO_LENGTH_MBSTATE_CONST + const char* save_from = from; + boost::uint16_t& state = *reinterpret_cast<boost::uint16_t*>(&std_state); +#else + size_t save_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); + while(max > 0 && from < from_end) { + const char* prev_from = from; + boost::uint32_t ch = implementation().to_unicode(cvt_state, from, from_end); + if(ch == boost::locale::utf::incomplete || ch == boost::locale::utf::illegal) { from = prev_from; - state = 1; + break; } - else { - state = 0; + max--; + if(ch > 0xFFFF) { + if(state == 0) { + from = prev_from; + state = 1; + } else { + state = 0; + } } } +#ifndef BOOST_LOCALE_DO_LENGTH_MBSTATE_CONST + return static_cast<int>(from - save_from); +#else + return static_cast<int>(save_max - max); +#endif } - #ifndef BOOST_LOCALE_DO_LENGTH_MBSTATE_CONST - return static_cast<int>(from - save_from); - #else - return static_cast<int>(save_max - max); - #endif - } - - - std::codecvt_base::result - do_in( std::mbstate_t &std_state, - char const *from, - char const *from_end, - char const *&from_next, - uchar *to, - uchar *to_end, - uchar *&to_next) const BOOST_OVERRIDE - { - 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 observerd - // 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); - while(to < to_end && from < from_end) + + std::codecvt_base::result do_in(std::mbstate_t& std_state, + const char* from, + const char* from_end, + const char*& from_next, + uchar* to, + uchar* to_end, + uchar*& to_next) const override { + 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 + 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); + while(to < to_end && from < from_end) { #ifdef DEBUG_CODECVT - std::cout << "Entering IN--------------\n"; - std::cout << "State " << std::hex << state << std::endl; - std::cout << "Left in " << std::dec << from_end - from << " out " << to_end -to << std::endl; + std::cout << "Entering IN--------------\n"; + std::cout << "State " << std::hex << state << std::endl; + std::cout << "Left in " << std::dec << from_end - from << " out " << to_end - to << std::endl; #endif - char const *from_saved = from; + const char* from_saved = from; - uint32_t ch=implementation().to_unicode(cvt_state,from,from_end); + uint32_t ch = implementation().to_unicode(cvt_state, from, from_end); - if(ch==boost::locale::utf::illegal) { - from = from_saved; - r=std::codecvt_base::error; - break; - } - if(ch==boost::locale::utf::incomplete) { - from = from_saved; - r=std::codecvt_base::partial; - break; - } - // Normal codepoints go direcly to stream - if(ch <= 0xFFFF) { - *to++ = static_cast<uchar>(ch); - } - else { - // for other codepoints we do following - // - // 1. We can't consume our input as we may find ourselfs - // in state where all input consumed but not all output written,i.e. only - // 1st pair is written - // 2. We only write first pair and mark this in the state, we also revert back - // the from pointer in order to make sure this codepoint would be read - // 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) { + if(ch == boost::locale::utf::illegal) { + from = from_saved; + r = std::codecvt_base::error; + break; + } + if(ch == boost::locale::utf::incomplete) { from = from_saved; - *to++ = w1; - state = 1; + r = std::codecvt_base::partial; + break; } - else { - *to++ = w2; - state = 0; + // Normal codepoints go direcly to stream + if(ch <= 0xFFFF) { + *to++ = static_cast<uchar>(ch); + } else { + // for other codepoints we do following + // + // 1. We can't consume our input as we may find ourselves + // in state where all input consumed but not all output written,i.e. only + // 1st pair is written + // 2. We only write first pair and mark this in the state, we also revert back + // the from pointer in order to make sure this codepoint would be read + // 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) { + from = from_saved; + *to++ = w1; + state = 1; + } else { + *to++ = w2; + state = 0; + } } } - } - from_next=from; - to_next=to; - if(r == std::codecvt_base::ok && (from!=from_end || state!=0)) - r = std::codecvt_base::partial; + from_next = from; + to_next = to; + if(r == std::codecvt_base::ok && (from != from_end || state != 0)) + r = std::codecvt_base::partial; #ifdef DEBUG_CODECVT - std::cout << "Returning "; - switch(r) { - case std::codecvt_base::ok: - std::cout << "ok\n"; - break; - case std::codecvt_base::partial: - std::cout << "partial\n"; - break; - case std::codecvt_base::error: - std::cout << "error\n"; - break; - default: - std::cout << "other\n"; - break; - } - std::cout << "State " << std::hex << state << std::endl; - std::cout << "Left in " << std::dec << from_end - from << " out " << to_end -to << std::endl; + std::cout << "Returning "; + switch(r) { + case std::codecvt_base::ok: std::cout << "ok\n"; break; + case std::codecvt_base::partial: std::cout << "partial\n"; break; + case std::codecvt_base::error: std::cout << "error\n"; break; + default: std::cout << "other\n"; break; + } + std::cout << "State " << std::hex << state << std::endl; + std::cout << "Left in " << std::dec << from_end - from << " out " << to_end - to << std::endl; #endif - return r; - } - - std::codecvt_base::result - do_out( std::mbstate_t &std_state, - uchar const *from, - uchar const *from_end, - uchar const *&from_next, - char *to, - char *to_end, - char *&to_next) const BOOST_OVERRIDE - { - 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 assume that sizeof(mbstate_t) >=2 in order - // to be able to store first observed surrogate pair - // - // State: state!=0 - a first surrogate pair was observerd (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); - while(to < to_end && from < from_end) + return r; + } + + std::codecvt_base::result do_out(std::mbstate_t& std_state, + const uchar* from, + const uchar* from_end, + const uchar*& from_next, + char* to, + char* to_end, + char*& to_next) const override { + 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 assume that sizeof(mbstate_t) >=2 in order + // to be able to store first observed surrogate pair + // + // 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); + while(to < to_end && from < from_end) { #ifdef DEBUG_CODECVT - std::cout << "Entering OUT --------------\n"; - std::cout << "State " << std::hex << state << std::endl; - std::cout << "Left in " << std::dec << from_end - from << " out " << to_end -to << std::endl; + std::cout << "Entering OUT --------------\n"; + std::cout << "State " << std::hex << state << std::endl; + std::cout << "Left in " << std::dec << from_end - from << " out " << to_end - to << std::endl; #endif - boost::uint32_t 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; - // 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; - ch=((uint32_t(vh) << 10) | vl) + 0x10000; + boost::uint32_t 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; + // 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; + ch = ((uint32_t(vh) << 10) | vl) + 0x10000; + } else { + // Invalid surrogate + r = std::codecvt_base::error; + break; + } + } else { + ch = *from; + if(0xD800 <= ch && ch <= 0xDBFF) { + // if this is a first surrogate pair we put + // it into the state and consume it, note we don't + // go forward as it should be illegal so we increase + // the from pointer manually + state = static_cast<uint16_t>(ch); + from++; + continue; + } else if(0xDC00 <= ch && ch <= 0xDFFF) { + // if we observe second surrogate pair and + // first only may be expected we should break from the loop with error + // as it is illegal input + r = std::codecvt_base::error; + break; + } } - else { - // Invalid surrogate - r=std::codecvt_base::error; + if(!boost::locale::utf::is_valid_codepoint(ch)) { + r = std::codecvt_base::error; break; } - } - else { - ch = *from; - if(0xD800 <= ch && ch<=0xDBFF) { - // if this is a first surrogate pair we put - // it into the state and consume it, note we don't - // go forward as it should be illegal so we increase - // the from pointer manually - state = static_cast<uint16_t>(ch); - from++; - continue; - } - else if(0xDC00 <= ch && ch<=0xDFFF) { - // if we observe second surrogate pair and - // first only may be expected we should break from the loop with error - // as it is illegal input - r=std::codecvt_base::error; + boost::uint32_t len = implementation().from_unicode(cvt_state, ch, to, to_end); + if(len == boost::locale::utf::incomplete) { + r = std::codecvt_base::partial; break; - } - } - 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); - if(len == boost::locale::utf::incomplete) { - r=std::codecvt_base::partial; - break; + } else if(len == boost::locale::utf::illegal) { + r = std::codecvt_base::error; + break; + } else + to += len; + state = 0; + from++; } - else if(len == boost::locale::utf::illegal) { - r=std::codecvt_base::error; - break; + from_next = from; + to_next = to; + if(r == std::codecvt_base::ok && from != from_end) + r = std::codecvt_base::partial; +#ifdef DEBUG_CODECVT + std::cout << "Returning "; + switch(r) { + case std::codecvt_base::ok: std::cout << "ok\n"; break; + case std::codecvt_base::partial: std::cout << "partial\n"; break; + case std::codecvt_base::error: std::cout << "error\n"; break; + default: std::cout << "other\n"; break; } - else - to+= len; - state = 0; - from++; + std::cout << "State " << std::hex << state << std::endl; + std::cout << "Left in " << std::dec << from_end - from << " out " << to_end - to << std::endl; +#endif + return r; } - from_next=from; - to_next=to; - if(r==std::codecvt_base::ok && from!=from_end) - r = std::codecvt_base::partial; -#ifdef DEBUG_CODECVT - std::cout << "Returning "; - switch(r) { - case std::codecvt_base::ok: - std::cout << "ok\n"; - break; - case std::codecvt_base::partial: - std::cout << "partial\n"; - break; - case std::codecvt_base::error: - std::cout << "error\n"; - break; - default: - std::cout << "other\n"; - break; + }; + + /// \brief UTF-32 to/from UTF-8 codecvt facet to use with char32_t or wchar_t on POSIX platforms + /// + /// Its member functions implement standard virtual functions of basic codecvt. + /// mbstate_t is not used for UTF-32 handling due to fixed length encoding + template<typename CharType, typename CodecvtImpl> + class generic_codecvt<CharType, CodecvtImpl, 4> : public std::codecvt<CharType, char, std::mbstate_t>, + public generic_codecvt_base { + public: + typedef CharType uchar; + + generic_codecvt(size_t refs = 0) : std::codecvt<CharType, char, std::mbstate_t>(refs) {} + + const CodecvtImpl& implementation() const { return *static_cast<const CodecvtImpl*>(this); } + + protected: + std::codecvt_base::result + do_unshift(std::mbstate_t& /*s*/, char* from, char* /*to*/, char*& next) const override + { + next = from; + return std::codecvt_base::ok; } - std::cout << "State " << std::hex << state << std::endl; - std::cout << "Left in " << std::dec << from_end - from << " out " << to_end -to << std::endl; + int do_encoding() const noexcept override { return 0; } + 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 + { +#ifndef BOOST_LOCALE_DO_LENGTH_MBSTATE_CONST + const char* start_from = from; +#else + size_t save_max = max; #endif - return r; - } - -}; - -/// -/// \brief UTF-32 to/from UTF-8 codecvt facet to use with char32_t or wchar_t on POSIX platforms -/// -/// Its member functions implement standard virtual functions of basic codecvt. -/// mbstate_t is not used for UTF-32 handling due to fixed length encoding -/// -template<typename CharType,typename CodecvtImpl> -class generic_codecvt<CharType,CodecvtImpl,4> : public std::codecvt<CharType,char,std::mbstate_t>, public generic_codecvt_base -{ -public: - typedef CharType uchar; - - generic_codecvt(size_t refs = 0) : - std::codecvt<CharType,char,std::mbstate_t>(refs) - { - } - - CodecvtImpl const &implementation() const - { - return *static_cast<CodecvtImpl const *>(this); - } - -protected: - - std::codecvt_base::result do_unshift(std::mbstate_t &/*s*/,char *from,char * /*to*/,char *&next) const BOOST_OVERRIDE - { - next=from; - return std::codecvt_base::ok; - } - int do_encoding() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE - { - return 0; - } - int do_max_length() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE - { - return implementation().max_encoding_length(); - } - bool do_always_noconv() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE - { - return false; - } - - int - do_length( std::mbstate_t - #ifdef BOOST_LOCALE_DO_LENGTH_MBSTATE_CONST - const - #endif - &/*state*/, - char const *from, - char const *from_end, - size_t max) const BOOST_OVERRIDE - { - #ifndef BOOST_LOCALE_DO_LENGTH_MBSTATE_CONST - char const *start_from = from; - #else - size_t save_max = max; - #endif - typename CodecvtImpl::state_type cvt_state = implementation().initial_state(generic_codecvt_base::to_unicode_state); - while(max > 0 && from < from_end){ - char const *save_from = from; - boost::uint32_t ch=implementation().to_unicode(cvt_state,from,from_end); - if(ch==boost::locale::utf::incomplete || ch==boost::locale::utf::illegal) { - from = save_from; - break; + typename CodecvtImpl::state_type cvt_state = + implementation().initial_state(generic_codecvt_base::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); + if(ch == boost::locale::utf::incomplete || ch == boost::locale::utf::illegal) { + from = save_from; + break; + } + max--; } - max--; +#ifndef BOOST_LOCALE_DO_LENGTH_MBSTATE_CONST + return from - start_from; +#else + return save_max - max; +#endif } - #ifndef BOOST_LOCALE_DO_LENGTH_MBSTATE_CONST - return from - start_from; - #else - return save_max - max; - #endif - } - - - std::codecvt_base::result - do_in( std::mbstate_t &/*state*/, - char const *from, - char const *from_end, - char const *&from_next, - uchar *to, - uchar *to_end, - uchar *&to_next) const BOOST_OVERRIDE - { - 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 observerd - // and first pair is written, but no input consumed - typedef typename CodecvtImpl::state_type state_type; - state_type cvt_state = implementation().initial_state(generic_codecvt_base::to_unicode_state); - while(to < to_end && from < from_end) + + std::codecvt_base::result do_in(std::mbstate_t& /*state*/, + const char* from, + const char* from_end, + const char*& from_next, + uchar* to, + uchar* to_end, + uchar*& to_next) const override { + 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); + while(to < to_end && from < from_end) { #ifdef DEBUG_CODECVT - std::cout << "Entering IN--------------\n"; - std::cout << "State " << std::hex << state << std::endl; - std::cout << "Left in " << std::dec << from_end - from << " out " << to_end -to << std::endl; + std::cout << "Entering IN--------------\n"; + std::cout << "State " << std::hex << state << std::endl; + std::cout << "Left in " << std::dec << from_end - from << " out " << to_end - to << std::endl; #endif - char const *from_saved = from; + const char* from_saved = from; - uint32_t ch=implementation().to_unicode(cvt_state,from,from_end); + uint32_t ch = implementation().to_unicode(cvt_state, from, from_end); - if(ch==boost::locale::utf::illegal) { - r=std::codecvt_base::error; - from = from_saved; - break; - } - if(ch==boost::locale::utf::incomplete) { - r=std::codecvt_base::partial; - from=from_saved; - break; + if(ch == boost::locale::utf::illegal) { + r = std::codecvt_base::error; + from = from_saved; + break; + } + if(ch == boost::locale::utf::incomplete) { + r = std::codecvt_base::partial; + from = from_saved; + break; + } + *to++ = ch; } - *to++=ch; - } - from_next=from; - to_next=to; - if(r == std::codecvt_base::ok && from!=from_end) - r = std::codecvt_base::partial; + from_next = from; + to_next = to; + if(r == std::codecvt_base::ok && from != from_end) + r = std::codecvt_base::partial; #ifdef DEBUG_CODECVT - std::cout << "Returning "; - switch(r) { - case std::codecvt_base::ok: - std::cout << "ok\n"; - break; - case std::codecvt_base::partial: - std::cout << "partial\n"; - break; - case std::codecvt_base::error: - std::cout << "error\n"; - break; - default: - std::cout << "other\n"; - break; - } - std::cout << "State " << std::hex << state << std::endl; - std::cout << "Left in " << std::dec << from_end - from << " out " << to_end -to << std::endl; + std::cout << "Returning "; + switch(r) { + case std::codecvt_base::ok: std::cout << "ok\n"; break; + case std::codecvt_base::partial: std::cout << "partial\n"; break; + case std::codecvt_base::error: std::cout << "error\n"; break; + default: std::cout << "other\n"; break; + } + std::cout << "State " << std::hex << state << std::endl; + std::cout << "Left in " << std::dec << from_end - from << " out " << to_end - to << std::endl; #endif - return r; - } - - std::codecvt_base::result - do_out( std::mbstate_t &/*std_state*/, - uchar const *from, - uchar const *from_end, - uchar const *&from_next, - char *to, - char *to_end, - char *&to_next) const BOOST_OVERRIDE - { - std::codecvt_base::result r=std::codecvt_base::ok; - typedef typename CodecvtImpl::state_type state_type; - state_type cvt_state = implementation().initial_state(generic_codecvt_base::from_unicode_state); - while(to < to_end && from < from_end) + return r; + } + + std::codecvt_base::result do_out(std::mbstate_t& /*std_state*/, + const uchar* from, + const uchar* from_end, + const uchar*& from_next, + char* to, + char* to_end, + 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); + while(to < to_end && from < from_end) { #ifdef DEBUG_CODECVT - std::cout << "Entering OUT --------------\n"; - std::cout << "State " << std::hex << state << std::endl; - std::cout << "Left in " << std::dec << from_end - from << " out " << to_end -to << std::endl; + std::cout << "Entering OUT --------------\n"; + std::cout << "State " << std::hex << state << std::endl; + std::cout << "Left in " << std::dec << from_end - from << " out " << to_end - to << std::endl; #endif - boost::uint32_t ch=0; - 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); - if(len == boost::locale::utf::incomplete) { - r=std::codecvt_base::partial; - break; - } - else if(len == boost::locale::utf::illegal) { - r=std::codecvt_base::error; - break; + boost::uint32_t ch = 0; + 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); + if(len == boost::locale::utf::incomplete) { + r = std::codecvt_base::partial; + break; + } else if(len == boost::locale::utf::illegal) { + r = std::codecvt_base::error; + break; + } + to += len; + from++; } - to+=len; - from++; - } - from_next=from; - to_next=to; - if(r==std::codecvt_base::ok && from!=from_end) - r = std::codecvt_base::partial; + from_next = from; + to_next = to; + if(r == std::codecvt_base::ok && from != from_end) + r = std::codecvt_base::partial; #ifdef DEBUG_CODECVT - std::cout << "Returning "; - switch(r) { - case std::codecvt_base::ok: - std::cout << "ok\n"; - break; - case std::codecvt_base::partial: - std::cout << "partial\n"; - break; - case std::codecvt_base::error: - std::cout << "error\n"; - break; - default: - std::cout << "other\n"; - break; - } - std::cout << "State " << std::hex << state << std::endl; - std::cout << "Left in " << std::dec << from_end - from << " out " << to_end -to << std::endl; + std::cout << "Returning "; + switch(r) { + case std::codecvt_base::ok: std::cout << "ok\n"; break; + case std::codecvt_base::partial: std::cout << "partial\n"; break; + case std::codecvt_base::error: std::cout << "error\n"; break; + default: std::cout << "other\n"; break; + } + std::cout << "State " << std::hex << state << std::endl; + std::cout << "Left in " << std::dec << from_end - from << " out " << to_end - to << std::endl; #endif - return r; - } -}; - + return r; + } + }; -template<typename CharType,typename CodecvtImpl> -class generic_codecvt<CharType,CodecvtImpl,1> : public std::codecvt<CharType,char,std::mbstate_t>, public generic_codecvt_base -{ -public: - typedef CharType uchar; + template<typename CharType, typename CodecvtImpl> + class generic_codecvt<CharType, CodecvtImpl, 1> : public std::codecvt<CharType, char, std::mbstate_t>, + public generic_codecvt_base { + public: + typedef CharType uchar; - CodecvtImpl const &implementation() const - { - return *static_cast<CodecvtImpl const *>(this); - } + const CodecvtImpl& implementation() const { return *static_cast<const CodecvtImpl*>(this); } - generic_codecvt(size_t refs = 0) : std::codecvt<char,char,std::mbstate_t>(refs) - { - } -}; + generic_codecvt(size_t refs = 0) : std::codecvt<char, char, std::mbstate_t>(refs) {} + }; -} // locale -} // namespace boost +}} // namespace boost::locale #endif -/// 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 7981119a86..675f5192c4 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/gnu_gettext.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/gnu_gettext.hpp @@ -8,159 +8,119 @@ #define BOOST_LOCLAE_GNU_GETTEXT_HPP #include <boost/locale/message.hpp> -#include <boost/function.hpp> +#include <functional> #include <stdexcept> #include <vector> -namespace boost { -namespace locale { -/// \addtogroup message -/// @{ - - -/// -/// \brief This namespace holds classes that provide GNU Gettext message catalogs support. -/// -namespace gnu_gettext { - - /// - /// \brief This structure holds all information required for creating gnu-gettext message catalogs, - /// - /// The user is expected to set its parameters to load these catalogs correctly. This structure - /// 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 { - messages_info() : - language("C"), - locale_category("LC_MESSAGES") - { - } - - std::string language; ///< The language we load the catalog for, like "ru", "en", "de" - std::string country; ///< The country we load the catalog for, like "US", "IL" - std::string variant; ///< Language variant, like "euro" so it would look for catalog like de_DE\@euro - std::string encoding; ///< Required target charset encoding. Ignored for wide characters. - ///< For narrow, should specify the correct encoding required for this catalog - std::string locale_category; ///< Locale category, is set by default to LC_MESSAGES, but may be changed - /// - /// \brief This type represents GNU Gettext domain name for the messages. - /// - /// It consists of two parameters: - /// - /// - name - the name of the domain - used for opening the file name - /// - encoding - the encoding of the keys in the sources, default - UTF-8 - /// - struct domain { - - std::string name; ///< The name of the domain - std::string encoding; ///< The character encoding for the domain - domain() {} - /// - /// Create a domain object from the name that can hold an encoding after symbol "/" - /// such that if n is "hello/cp1255" then the name would be "hello" and "encoding" would - /// be "cp1255" and if n is "hello" then the name would be the same but encoding would be - /// "UTF-8" - /// - domain(std::string const &n) - { - size_t pos = n.find('/'); - if(pos==std::string::npos) { - name = n; - encoding = "UTF-8"; - } - else { - name = n.substr(0,pos); - encoding = n.substr(pos+1); - } +namespace boost { namespace locale { + /// \addtogroup message + /// @{ - } + /// \brief This namespace holds classes that provide GNU Gettext message catalogs support. + namespace gnu_gettext { + /// \brief This structure holds all information required for creating gnu-gettext message catalogs, + /// + /// The user is expected to set its parameters to load these catalogs correctly. This structure + /// 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 { + messages_info() : language("C"), locale_category("LC_MESSAGES") {} + + std::string language; ///< The language we load the catalog for, like "ru", "en", "de" + std::string country; ///< The country we load the catalog for, like "US", "IL" + std::string variant; ///< Language variant, like "euro" so it would look for catalog like de_DE\@euro + std::string encoding; ///< Required target charset encoding. Ignored for wide characters. + ///< For narrow, should specify the correct encoding required for this catalog + std::string locale_category; ///< Locale category, is set by default to LC_MESSAGES, but may be changed /// - /// Check whether two objects are equivalent, only names are compared, encoding is ignored + /// \brief This type represents GNU Gettext domain name for the messages. /// - bool operator==(domain const &other) const - { - return name==other.name; - } + /// It consists of two parameters: /// - /// Check whether two objects are distinct, only names are compared, encoding is ignored + /// - name - the name of the domain - used for opening the file name + /// - encoding - the encoding of the keys in the sources, default - UTF-8 /// - bool operator!=(domain const &other) const - { - return !(*this==other); - } + struct domain { + std::string name; ///< The name of the domain + std::string encoding; ///< The character encoding for the domain + domain() = default; + + /// Create a domain object from the name that can hold an encoding after symbol "/" + /// such that if n is "hello/cp1255" then the name would be "hello" and "encoding" would + /// be "cp1255" and if n is "hello" then the name would be the same but encoding would be + /// "UTF-8" + domain(const std::string& n) + { + size_t pos = n.find('/'); + if(pos == std::string::npos) { + name = n; + encoding = "UTF-8"; + } else { + name = n.substr(0, pos); + encoding = n.substr(pos + 1); + } + } + /// Check whether two objects are equivalent, only names are compared, encoding is ignored + bool operator==(const domain& other) const { return name == other.name; } + /// Check whether two objects are distinct, only names are compared, encoding is ignored + bool operator!=(const domain& other) const { return !(*this == other); } + }; + + typedef std::vector<domain> domains_type; ///< Type that defines a list of domains that are loaded + ///< The first one is the default one + domains_type domains; ///< Message domains - application name, like my_app. So files named my_app.mo + ///< would be loaded + std::vector<std::string> paths; ///< Paths to search files in. Under MS Windows it uses encoding + ///< parameter to convert them to wide OS specific paths. + + /// The callback for custom file system support. This callback should read the file named \a file_name + /// 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. + /// + /// \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. + typedef std::function<std::vector<char>(const std::string& file_name, const std::string& encoding)> + callback_type; + + /// The callback for handling custom file systems, if it is empty, the real OS file-system + /// is being used. + callback_type callback; }; - typedef std::vector<domain> domains_type; ///< Type that defines a list of domains that are loaded - ///< The first one is the default one - domains_type domains; ///< Message domains - application name, like my_app. So files named my_app.mo - ///< would be loaded - std::vector<std::string> paths; ///< Paths to search files in. Under MS Windows it uses encoding - ///< parameter to convert them to wide OS specific paths. - - /// - /// The callback for custom file system support. This callback should read the file named \a file_name - /// 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. - /// - /// \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. - /// - typedef function< - std::vector<char>( - std::string const &file_name, - std::string const &encoding - ) - > callback_type; - - /// - /// The callback for handling custom file systems, if it is empty, the real OS file-system - /// is being used. - /// - callback_type callback; + /// 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 - /// - /// 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<> + BOOST_LOCALE_DECL message_format<char>* create_messages_facet(const messages_info& info); - template<typename CharType> - message_format<CharType> *create_messages_facet(messages_info const &info); + template<> + BOOST_LOCALE_DECL message_format<wchar_t>* create_messages_facet(const messages_info& info); - /// \cond INTERNAL - - template<> - BOOST_LOCALE_DECL message_format<char> *create_messages_facet(messages_info const &info); - - template<> - BOOST_LOCALE_DECL message_format<wchar_t> *create_messages_facet(messages_info const &info); - - #ifdef BOOST_LOCALE_ENABLE_CHAR16_T - template<> - BOOST_LOCALE_DECL message_format<char16_t> *create_messages_facet(messages_info const &info); - #endif +#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(messages_info const &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 + /// \endcond -} // gnu_gettext + } // namespace gnu_gettext -/// @} + /// @} -} // locale -} // boost +}} // namespace boost::locale #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 aa29f42d18..851ddbf210 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/hold_ptr.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/hold_ptr.hpp @@ -9,85 +9,78 @@ #include <boost/locale/config.hpp> -namespace boost { -namespace locale { - /// - /// \brief a smart pointer similar to std::auto_ptr but it is non-copyable and the +namespace boost { namespace locale { + /// \brief a smart pointer similar to std::unique_ptr but the /// underlying object has the same constness as the pointer itself (unlike an ordinary pointer). - /// template<typename T> class hold_ptr { - hold_ptr(hold_ptr const &other); // non copyable - hold_ptr const &operator=(hold_ptr const &other); // non assignable public: - /// /// Create new empty pointer - /// - hold_ptr() : ptr_(0) {} - /// + hold_ptr() : ptr_(nullptr) {} + /// Create a pointer that holds \a v, ownership is transferred to smart pointer - /// - explicit hold_ptr(T *v) : ptr_(v) {} + explicit hold_ptr(T* v) : ptr_(v) {} - /// /// Destroy smart pointer and the object it owns. - /// - ~hold_ptr() + ~hold_ptr() { delete ptr_; } + + // Non-copyable + 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& operator=(hold_ptr&& other) noexcept { - delete ptr_; + swap(other); + return *this; } - /// /// Get a const pointer to the object - /// - T const *get() const { return ptr_; } - /// + T const* get() const { return ptr_; } /// Get a mutable pointer to the object - /// - T *get() { return ptr_; } + T* get() { return ptr_; } + + /// Explicitly convertible to bool. Returns: get() != nullptr + explicit operator bool() const { return ptr_ != nullptr; } - /// /// Get a const reference to the object - /// - T const &operator *() const { return *ptr_; } - /// + T const& operator*() const { return *ptr_; } /// Get a mutable reference to the object - /// - T &operator *() { return *ptr_; } - /// + T& operator*() { return *ptr_; } + /// Get a const pointer to the object - /// - T const *operator->() const { return ptr_; } - /// + T const* operator->() const { return ptr_; } /// Get a mutable pointer to the object - /// - T *operator->() { return ptr_; } + T* operator->() { return ptr_; } - /// /// Transfer an ownership on the pointer to user - /// - T *release() { T *tmp=ptr_; ptr_=0; return tmp; } + T* release() + { + T* tmp = ptr_; + ptr_ = nullptr; + return tmp; + } - /// /// Set new value to pointer, previous object is destroyed, ownership on new object is transferred - /// - void reset(T *p=0) + void reset(T* p = nullptr) { - if(ptr_) delete ptr_; - ptr_=p; + if(ptr_) + delete ptr_; + ptr_ = p; } + /// Swap two pointers - void swap(hold_ptr &other) + void swap(hold_ptr& other) { - T *tmp=other.ptr_; - other.ptr_=ptr_; - ptr_=tmp; + T* tmp = other.ptr_; + other.ptr_ = ptr_; + ptr_ = tmp; } + private: - T *ptr_; + T* ptr_; }; -} // locale -} // boost +}} // namespace boost::locale #endif diff --git a/contrib/restricted/boost/locale/include/boost/locale/info.hpp b/contrib/restricted/boost/locale/include/boost/locale/info.hpp index 92e11f44e1..e10f134f86 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/info.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/info.hpp @@ -12,115 +12,63 @@ #include <string> #ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4275 4251 4231 4660) +# pragma warning(push) +# pragma warning(disable : 4275 4251 4231 4660) #endif -namespace boost { - namespace locale { +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 - { - public: - ~info(); + /// \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 { + public: + ~info(); - static std::locale::id id; ///< This member uniquely defines this facet, required by STL + 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 - country_property, ///< ISO 3166 country id - variant_property, ///< Variant for locale - encoding_property, ///< encoding name - name_property ///< locale name - }; - - /// - /// Integer information about locale - /// - enum integer_property { - utf8_property ///< Non zero value if uses UTF-8 encoding - }; + /// String information about the locale + enum string_propery { + language_property, ///< ISO 639 language id + country_property, ///< ISO 3166 country id + variant_property, ///< Variant for locale + encoding_property, ///< encoding name + name_property ///< locale name + }; + /// Integer information about locale + enum integer_property { + utf8_property ///< Non zero value if uses UTF-8 encoding + }; - /// - /// Standard facet's constructor - /// - info(size_t refs = 0) : std::locale::facet(refs) - { - } - /// - /// Get language name - /// - std::string language() const - { - return get_string_property(language_property); - } - /// - /// Get country name - /// - std::string country() const - { - return get_string_property(country_property); - } - /// - /// Get locale variant - /// - std::string variant() const - { - return get_string_property(variant_property); - } - /// - /// Get encoding - /// - std::string encoding() const - { - return get_string_property(encoding_property); - } + /// Standard facet's constructor + info(size_t refs = 0) : std::locale::facet(refs) {} + /// Get language name + std::string language() const { return get_string_property(language_property); } + /// Get country name + std::string country() const { return get_string_property(country_property); } + /// Get locale variant + std::string variant() const { return get_string_property(variant_property); } + /// Get encoding + std::string encoding() const { return get_string_property(encoding_property); } - /// - /// Get the name of the locale, like en_US.UTF-8 - /// - std::string name() const - { - return get_string_property(name_property); - } + /// Get the name of the locale, like en_US.UTF-8 + std::string name() const { return get_string_property(name_property); } - /// - /// True if the underlying encoding is UTF-8 (for char streams and strings) - /// - bool utf8() const - { - return get_integer_property(utf8_property) != 0; - } + /// True if the underlying encoding is UTF-8 (for char streams and strings) + bool utf8() const { return get_integer_property(utf8_property) != 0; } -#if defined (__SUNPRO_CC) && defined (_RWSTD_VER) - std::locale::id& __get_id (void) const { return id; } -#endif - protected: - /// - /// Get string property by its id \a v - /// - virtual std::string get_string_property(string_propery v) const = 0; - /// - /// Get integer property by its id \a v - /// - virtual int get_integer_property(integer_property v) const = 0; - }; + protected: + /// Get string property by its id \a v + virtual std::string get_string_property(string_propery v) const = 0; + /// Get integer property by its id \a v + virtual int get_integer_property(integer_property v) const = 0; + }; - } -} +}} // namespace boost::locale #ifdef BOOST_MSVC -#pragma warning(pop) +# pragma warning(pop) #endif #endif - 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 fedc3462b3..a4b79bf4c5 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/localization_backend.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/localization_backend.hpp @@ -16,168 +16,113 @@ #include <vector> #ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4275 4251 4231 4660) +# pragma warning(push) +# pragma warning(disable : 4275 4251 4231 4660) #endif -namespace boost { - namespace locale { - - /// - /// \brief this class represents a localization backend that can be used for localizing your application. - /// - /// Backends are usually registered inside the localization backends manager and allow transparent support - /// of different backends, so a user can switch the backend by simply linking the application to the correct one. - /// - /// Backends may support different tuning options, but these are the default options available to the user - /// for all of them - /// - /// -# \c locale - the name of the locale in POSIX format like en_US.UTF-8 - /// -# \c use_ansi_encoding - select system locale using ANSI codepages rather then UTF-8 under Windows - /// by default - /// -# \c message_path - path to the location of message catalogs (vector of strings) - /// -# \c message_application - the name of applications that use message catalogs (vector of strings) - /// - /// Each backend can be installed with a different default priotiry so when you work with two different backends, you - /// can specify priotiry so this backend will be chosen according to their priority. +namespace boost { namespace locale { + + /// \brief this class represents a localization backend that can be used for localizing your application. + /// + /// Backends are usually registered inside the localization backends manager and allow transparent support + /// of different backends, so a user can switch the backend by simply linking the application to the correct one. + /// + /// Backends may support different tuning options, but these are the default options available to the user + /// for all of them + /// + /// -# \c locale - the name of the locale in POSIX format like en_US.UTF-8 + /// -# \c use_ansi_encoding - select system locale using ANSI codepages rather then UTF-8 under Windows + /// by default + /// -# \c message_path - path to the location of message catalogs (vector of strings) + /// -# \c message_application - the name of applications that use message catalogs (vector of strings) + /// + /// Each backend can be installed with a different default priority so when you work with two different backends, + /// you can specify priority so this backend will be chosen according to their priority. + class BOOST_LOCALE_DECL localization_backend { + protected: + localization_backend(const localization_backend&) = default; + localization_backend& operator=(const localization_backend&) = default; + + public: + localization_backend() = default; + virtual ~localization_backend(); + + /// Make a polymorphic copy of the backend + virtual localization_backend* clone() const = 0; + + /// Set option for backend, for example "locale" or "encoding" + virtual void set_option(const std::string& name, const std::string& value) = 0; + + /// Clear all options + virtual void clear_options() = 0; + + /// Create a facet for category \a category and character type \a type + virtual std::locale install(const std::locale& base, category_t category, char_facet_t type) = 0; + + }; // localization_backend + + /// \brief Localization backend manager is a class that holds various backend and allows creation + /// of their combination or selection + class BOOST_LOCALE_DECL localization_backend_manager { + public: + /// New empty localization_backend_manager + localization_backend_manager(); + /// Copy localization_backend_manager + localization_backend_manager(const localization_backend_manager&); + /// Assign localization_backend_manager + localization_backend_manager& operator=(const localization_backend_manager&); + + /// Destructor + ~localization_backend_manager(); + + /// Create new localization backend according to current settings. + std::unique_ptr<localization_backend> get() const; + + BOOST_DEPRECATED("This function is deprecated, use 'get()' instead") + std::unique_ptr<localization_backend> get_unique_ptr() const { return get(); } + + /// 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); - class localization_backend { - localization_backend(localization_backend const &); - void operator=(localization_backend const &); - public: + /// Create new localization backend according to current settings. Ownership is passed to caller + localization_backend* create() const; - localization_backend() {} - - virtual ~localization_backend() {} - - /// - /// Make a polymorphic copy of the backend - /// - virtual localization_backend *clone() const = 0; - - /// - /// Set option for backend, for example "locale" or "encoding" - /// - virtual void set_option(std::string const &name,std::string const &value) = 0; - - /// - /// Clear all options - /// - virtual void clear_options() = 0; + /// 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); - /// - /// Create a facet for category \a category and character type \a type - /// - virtual std::locale install(std::locale const &base,locale_category_type category,character_facet_type type = nochar_facet) = 0; + /// Clear backend + void remove_all_backends(); - }; // localization_backend + /// Get list of all available backends + std::vector<std::string> get_all_backends() const; + /// Select specific backend by name for a category \a category. It allows combining different + /// backends for user preferences. + void select(const std::string& backend_name, category_t category = all_categories); + /// Set new global backend manager, the old one is returned. /// - /// \brief Localization backend manager is a class that holds various backend and allows creation - /// of their combination or selection + /// This function is thread safe + static localization_backend_manager global(const localization_backend_manager&); + /// Get global backend manager /// + /// This function is thread safe + static localization_backend_manager global(); - class BOOST_LOCALE_DECL localization_backend_manager { - public: - /// - /// New empty localization_backend_manager - /// - localization_backend_manager(); - /// - /// Copy localization_backend_manager - /// - localization_backend_manager(localization_backend_manager const &); - /// - /// Assign localization_backend_manager - /// - localization_backend_manager const &operator=(localization_backend_manager const &); - - /// - /// Destructor - /// - ~localization_backend_manager(); - - #if BOOST_LOCALE_USE_AUTO_PTR - /// - /// Create new localization backend according to current settings. - /// - std::auto_ptr<localization_backend> get() const; - - /// - /// 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(std::string const &name,std::auto_ptr<localization_backend> backend); - #endif - - /// - /// 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(std::string const &name,localization_backend *backend); - #ifndef BOOST_NO_CXX11_SMART_PTR - /// - /// Create new localization backend according to current settings. - /// - std::unique_ptr<localization_backend> get_unique_ptr() const; - - /// - /// 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(std::string const &name,std::unique_ptr<localization_backend> backend); - #endif - - /// - /// Clear backend - /// - void remove_all_backends(); - - /// - /// Get list of all available backends - /// - std::vector<std::string> get_all_backends() const; - - /// - /// Select specific backend by name for a category \a category. It allows combining different - /// backends for user preferences. - /// - void select(std::string const &backend_name,locale_category_type category = all_categories); - - /// - /// Set new global backend manager, the old one is returned. - /// - /// This function is thread safe - /// - static localization_backend_manager global(localization_backend_manager const &); - /// - /// Get global backend manager - /// - /// This function is thread safe - /// - static localization_backend_manager global(); - private: - class impl; - hold_ptr<impl> pimpl_; - }; - - } // locale -} // boost + private: + class impl; + hold_ptr<impl> pimpl_; + }; +}} // namespace boost::locale #ifdef BOOST_MSVC -#pragma warning(pop) +# pragma warning(pop) #endif #endif - diff --git a/contrib/restricted/boost/locale/include/boost/locale/message.hpp b/contrib/restricted/boost/locale/include/boost/locale/message.hpp index 4e2fdf9e1b..690c224d7d 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/message.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/message.hpp @@ -8,798 +8,581 @@ #define BOOST_LOCALE_MESSAGE_HPP_INCLUDED #include <boost/locale/formatting.hpp> +#include <boost/locale/util/string.hpp> #include <locale> #include <memory> #include <set> #include <string> #ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4275 4251 4231 4660) +# pragma warning(push) +# pragma warning(disable : 4275 4251 4231 4660) #endif // glibc < 2.3.4 declares those as macros if compiled with optimization turned on #ifdef gettext -# undef gettext -# undef ngettext -# undef dgettext -# undef dngettext +# undef gettext +# undef ngettext +# undef dgettext +# undef dngettext #endif -namespace boost { - namespace locale { - /// - /// \defgroup message Message Formatting (translation) - /// - ///This module provides message translation functionality, i.e. allow your application to speak native language - /// - /// @{ - /// +namespace boost { namespace locale { + /// + /// \defgroup message Message Formatting (translation) + /// + /// This module provides message translation functionality, i.e. allow your application to speak native language + /// + /// @{ + /// - /// \cond INTERNAL + /// \cond INTERNAL - template<typename CharType> - struct base_message_format; + template<typename CharType> + struct base_message_format; - /// \endcond + /// \endcond - /// - /// \brief This facet provides message formatting abilities - /// - template<typename CharType> - class BOOST_SYMBOL_VISIBLE message_format : public base_message_format<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) - { - } + /// \brief This facet provides message formatting abilities + template<typename CharType> + class BOOST_SYMBOL_VISIBLE message_format : public base_message_format<CharType> { + public: + /// Character type + typedef CharType char_type; + /// String type + typedef std::basic_string<CharType> string_type; - /// - /// 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 - /// a domain defined by \a domain_id. - /// - /// If \a context is NULL it is not considered to be a part of the key - /// - /// If a translated string is found, it is returned, otherwise NULL is returned - /// - /// - virtual char_type const *get(int domain_id,char_type const *context,char_type const *id) const = 0; - /// - /// This function returns a pointer to the string for a plural message defined by a \a context - /// and identification string \a single_id. - /// - /// If \a context is NULL it is not considered to be a part of the key - /// - /// Both create a single key for message lookup in - /// a domain defined \a domain_id. \a n is used to pick the correct translation string for a specific - /// number. - /// - /// If a translated string is found, it is returned, otherwise NULL is returned - /// - /// - virtual char_type const *get(int domain_id,char_type const *context,char_type const *single_id,int n) const = 0; - - /// - /// Convert a string that defines \a domain to the integer id used by \a get functions - /// - virtual int domain(std::string const &domain) const = 0; - - /// - /// Convert the string \a msg to target locale's encoding. If \a msg is already - /// in target encoding it would be returned otherwise the converted - /// string is stored in temporary \a buffer and buffer.c_str() is returned. - /// - /// Note: for char_type that is char16_t, char32_t and wchar_t it is no-op, returns - /// msg - /// - virtual char_type const *convert(char_type const *msg,string_type &buffer) const = 0; - -#if defined (__SUNPRO_CC) && defined (_RWSTD_VER) - std::locale::id& __get_id (void) const { return id; } -#endif - protected: - virtual ~message_format() {} - }; + /// Default constructor + message_format(size_t refs = 0) : base_message_format<CharType>(refs) {} - /// \cond INTERNAL - - namespace details { - inline bool is_us_ascii_char(char c) - { - // works for null terminated strings regardless char "signness" - return 0<c && c<0x7F; - } - inline bool is_us_ascii_string(char const *msg) - { - while(*msg) { - if(!is_us_ascii_char(*msg++)) - return false; - } - return true; - } - - template<typename CharType> - struct string_cast_traits { - static CharType const *cast(CharType const *msg,std::basic_string<CharType> &/*unused*/) - { - return msg; - } - }; - - template<> - struct string_cast_traits<char> { - static char const *cast(char const *msg,std::string &buffer) - { - if(is_us_ascii_string(msg)) - return msg; - buffer.reserve(strlen(msg)); - char c; - while((c=*msg++)!=0) { - if(is_us_ascii_char(c)) - buffer+=c; - } - return buffer.c_str(); - } - }; - } // details - - /// \endcond + /// 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 + /// a domain defined by \a domain_id. + /// + /// If \a context is NULL it is not considered to be a part of the key + /// + /// 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* id) const = 0; + /// This function returns a pointer to the string for a plural message defined by a \a context + /// and identification string \a single_id. /// - /// \brief This class represents a message that can be converted to a specific locale message + /// If \a context is NULL it is not considered to be a part of the key /// - /// It holds the original ASCII string that is queried in the dictionary when converting to the output string. - /// The created string may be UTF-8, UTF-16, UTF-32 or other 8-bit encoded string according to the target - /// character type and locale encoding. + /// Both create a single key for message lookup in + /// a domain defined \a domain_id. \a n is used to pick the correct translation string for a specific + /// number. /// - template<typename CharType> - class basic_message { - public: - - typedef CharType char_type; ///< The character this message object is used with - typedef std::basic_string<char_type> string_type; ///< The string type this object can be used with - 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) - { - } - - /// - /// 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(char_type const *id) : - n_(0), - c_id_(id), - c_context_(0), - c_plural_(0) - { - } - - /// - /// 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(char_type const *single,char_type const *plural,int n) : - n_(n), - c_id_(single), - c_context_(0), - 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(char_type const *context,char_type const *id) : - n_(0), - c_id_(id), - c_context_(context), - c_plural_(0) - { - } - - /// - /// 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(char_type const *context,char_type const *single,char_type const *plural,int n) : - n_(n), - c_id_(single), - c_context_(context), - c_plural_(plural) - { - } - - - /// - /// Create a simple message from a string. - /// - explicit basic_message(string_type const &id) : - n_(0), - c_id_(0), - c_context_(0), - c_plural_(0), - 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(string_type const &single,string_type const &plural,int number) : - n_(number), - c_id_(0), - c_context_(0), - c_plural_(0), - id_(single), - plural_(plural) - { - } + /// 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; - /// - /// Create a simple message from a string with context. - /// - explicit basic_message(string_type const &context,string_type const &id) : - n_(0), - c_id_(0), - c_context_(0), - c_plural_(0), - id_(id), - context_(context) - { - } - - /// - /// 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(string_type const &context,string_type const &single,string_type const &plural,int number) : - n_(number), - c_id_(0), - c_context_(0), - c_plural_(0), - id_(single), - context_(context), - plural_(plural) - { - } - - /// - /// Copy an object - /// - basic_message(basic_message const &other) : - n_(other.n_), - c_id_(other.c_id_), - c_context_(other.c_context_), - c_plural_(other.c_plural_), - id_(other.id_), - context_(other.context_), - plural_(other.plural_) - { - } + /// 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; - /// - /// Assign other message object to this one - /// - basic_message const &operator=(basic_message const &other) - { - if(this==&other) { - return *this; - } - basic_message tmp(other); - swap(tmp); - return *this; - } - - /// - /// Swap two message objects - /// - void swap(basic_message &other) - { - 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_); - } - - /// - /// 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); - } - - /// - /// Translate message to a string in the locale \a locale, using default domain - /// - string_type str(std::locale const &locale) const - { - return str(locale,0); - } - - /// - /// Translate message to a string using locale \a locale and message domain \a domain_id - /// - string_type str(std::locale const &locale,std::string const &domain_id) const - { - int id=0; - if(std::has_facet<facet_type>(locale)) - id=std::use_facet<facet_type>(locale).domain(domain_id); - return str(locale,id); - } - - /// - /// Translate message to a string using the default locale and message domain \a domain_id - /// - string_type str(std::string const &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); - } - - - /// - /// Translate message to a string using locale \a loc and message domain index \a id - /// - string_type str(std::locale const &loc,int id) const - { - string_type buffer; - char_type const *ptr = write(loc,id,buffer); - if(ptr == buffer.c_str()) - return buffer; - else - buffer = ptr; - return buffer; - } + /// Convert the string \a msg to target locale's encoding. If \a msg is already + /// in target encoding it would be returned otherwise the converted + /// string is stored in temporary \a buffer and buffer.c_str() is returned. + /// + /// 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; + }; - /// - /// Translate message and write to stream \a out, using imbued locale and domain set to the - /// stream - /// - void write(std::basic_ostream<char_type> &out) const - { - std::locale const &loc = out.getloc(); - int id = ios_info::get(out).domain_id(); - string_type buffer; - out << write(loc,id,buffer); - } + /// \cond INTERNAL - private: - char_type const *plural() const - { - if(c_plural_) - return c_plural_; - if(plural_.empty()) - return 0; - return plural_.c_str(); - } - char_type const *context() const - { - if(c_context_) - return c_context_; - if(context_.empty()) - return 0; - return context_.c_str(); + namespace detail { + inline bool is_us_ascii_char(char c) + { + // works for null terminated strings regardless char "signedness" + return 0 < c && c < 0x7F; + } + inline bool is_us_ascii_string(const char* msg) + { + while(*msg) { + if(!is_us_ascii_char(*msg++)) + return false; } + return true; + } - char_type const *id() const - { - return c_id_ ? c_id_ : id_.c_str(); - } + template<typename CharType> + struct string_cast_traits { + static const CharType* cast(const CharType* msg, std::basic_string<CharType>& /*unused*/) { return msg; } + }; - char_type const *write(std::locale const &loc,int domain_id,string_type &buffer) const + template<> + struct string_cast_traits<char> { + static const char* cast(const char* msg, std::string& buffer) { - char_type const *translated = 0; - static const char_type empty_string[1] = {0}; - - char_type const *id = this->id(); - char_type const *context = this->context(); - char_type const *plural = this->plural(); - - if(*id == 0) - return empty_string; - - facet_type const *facet = 0; - if(std::has_facet<facet_type>(loc)) - facet = &std::use_facet<facet_type>(loc); - - if(facet) { - if(!plural) { - translated = facet->get(domain_id,context,id); - } - else { - translated = facet->get(domain_id,context,id,n_); - } - } - - if(!translated) { - char_type const *msg = plural ? ( n_ == 1 ? id : plural) : id; - - if(facet) { - translated = facet->convert(msg,buffer); - } - else { - translated = details::string_cast_traits<char_type>::cast(msg,buffer); - } + if(is_us_ascii_string(msg)) + return msg; + buffer.reserve(strlen(msg)); + char c; + while((c = *msg++) != 0) { + if(is_us_ascii_char(c)) + buffer += c; } - return translated; + return buffer.c_str(); } - - /// members - - int n_; - char_type const *c_id_; - char_type const *c_context_; - char_type const *c_plural_; - string_type id_; - string_type context_; - string_type plural_; }; - - - /// - /// Convenience typedef for char - /// - typedef basic_message<char> message; - /// - /// Convenience typedef for wchar_t - /// - typedef basic_message<wchar_t> wmessage; - #ifdef BOOST_LOCALE_ENABLE_CHAR16_T - /// - /// Convenience typedef for char16_t - /// - typedef basic_message<char16_t> u16message; - #endif - #ifdef BOOST_LOCALE_ENABLE_CHAR32_T - /// - /// Convenience typedef for char32_t - /// - typedef basic_message<char32_t> u32message; - #endif - - /// - /// Translate message \a msg and write it to stream - /// - template<typename CharType> - std::basic_ostream<CharType> &operator<<(std::basic_ostream<CharType> &out,basic_message<CharType> const &msg) + } // namespace detail + + /// \endcond + + /// \brief This class represents a message that can be converted to a specific locale message + /// + /// It holds the original ASCII string that is queried in the dictionary when converting to the output string. + /// The created string may be UTF-8, UTF-16, UTF-32 or other 8-bit encoded string according to the target + /// character type and locale encoding. + template<typename CharType> + class basic_message { + public: + typedef CharType char_type; ///< The character this message object is used with + typedef std::basic_string<char_type> string_type; ///< The string type this object can be used with + 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) {} + + /// 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) {} + + /// 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) + {} + + /// 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) + {} + + /// 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) + {} + + /// 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) {} + + /// 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) + {} + + /// 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) + {} + + /// 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& context, + const string_type& single, + const string_type& plural, + int number) : + n_(number), + c_id_(0), c_context_(0), c_plural_(0), id_(single), context_(context), plural_(plural) + {} + + /// Copy an object + basic_message(const basic_message& other) = default; + basic_message(basic_message&& other) = default; + + /// Assign other message object to this one + basic_message& operator=(const basic_message& other) = default; + basic_message& operator=(basic_message&& other) = default; + + /// Swap two message objects + void swap(basic_message& other) { - msg.write(out); - return out; + 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_); } - /// - /// \anchor boost_locale_translate_family \name Indirect message translation function family - /// @{ + /// Message class can be explicitly converted to string class + operator string_type() const { return str(); } - /// - /// \brief Translate a message, \a msg is not copied - /// - template<typename CharType> - inline basic_message<CharType> translate(CharType const *msg) + /// Translate message to a string in the default global locale, using default domain + string_type str() const { - return basic_message<CharType>(msg); + std::locale loc; + return str(loc, 0); } - /// - /// \brief Translate a message in context, \a msg and \a context are not copied - /// - template<typename CharType> - inline basic_message<CharType> translate( CharType const *context, - CharType const *msg) + + /// 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); } + + /// Translate message to a string using locale \a locale and message domain \a domain_id + string_type str(const std::locale& locale, const std::string& domain_id) const { - return basic_message<CharType>(context,msg); + int id = 0; + if(std::has_facet<facet_type>(locale)) + id = std::use_facet<facet_type>(locale).domain(domain_id); + return str(locale, id); } - /// - /// \brief Translate a plural message form, \a single and \a plural are not copied - /// - template<typename CharType> - inline basic_message<CharType> translate( CharType const *single, - CharType const *plural, - int n) + + /// Translate message to a string using the default locale and message domain \a domain_id + string_type str(const std::string& domain_id) const { - return basic_message<CharType>(single,plural,n); + 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); } - /// - /// \brief Translate a plural message from in constext, \a context, \a single and \a plural are not copied - /// - template<typename CharType> - inline basic_message<CharType> translate( CharType const *context, - CharType const *single, - CharType const *plural, - int n) + + /// 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 { - return basic_message<CharType>(context,single,plural,n); + string_type buffer; + const char_type* ptr = write(loc, id, buffer); + if(ptr == buffer.c_str()) + return buffer; + else + buffer = ptr; + return buffer; } - /// - /// \brief Translate a message, \a msg is copied - /// - template<typename CharType> - inline basic_message<CharType> translate(std::basic_string<CharType> const &msg) + /// Translate message and write to stream \a out, using imbued locale and domain set to the + /// stream + void write(std::basic_ostream<char_type>& out) const { - return basic_message<CharType>(msg); + const std::locale& loc = out.getloc(); + int id = ios_info::get(out).domain_id(); + string_type buffer; + out << write(loc, id, buffer); } - /// - /// \brief Translate a message in context,\a context and \a msg is copied - /// - template<typename CharType> - inline basic_message<CharType> translate( std::basic_string<CharType> const &context, - std::basic_string<CharType> const &msg) + private: + const char_type* plural() const { - return basic_message<CharType>(context,msg); + if(c_plural_) + return c_plural_; + if(plural_.empty()) + return 0; + return plural_.c_str(); } - /// - /// \brief Translate a plural message form in constext, \a context, \a single and \a plural are copied - /// - template<typename CharType> - inline basic_message<CharType> translate( std::basic_string<CharType> const &context, - std::basic_string<CharType> const &single, - std::basic_string<CharType> const &plural, - int n) + const char_type* context() const { - return basic_message<CharType>(context,single,plural,n); + if(c_context_) + return c_context_; + if(context_.empty()) + return 0; + return context_.c_str(); } - /// - /// \brief Translate a plural message form, \a single and \a plural are copied - /// + const char_type* id() const { return c_id_ ? c_id_ : id_.c_str(); } - template<typename CharType> - inline basic_message<CharType> translate( std::basic_string<CharType> const &single, - std::basic_string<CharType> const &plural, - int n) + const char_type* write(const std::locale& loc, int domain_id, string_type& buffer) const { - return basic_message<CharType>(single,plural,n); - } + const char_type* translated = 0; + static const char_type empty_string[1] = {0}; - /// @} + const char_type* id = this->id(); + const char_type* context = this->context(); + const char_type* plural = this->plural(); - /// - /// \anchor boost_locale_gettext_family \name Direct message translation functions family - /// + if(*id == 0) + return empty_string; - /// - /// Translate message \a id according to locale \a loc - /// - template<typename CharType> - std::basic_string<CharType> gettext(CharType const *id, - std::locale const &loc=std::locale()) - { - return basic_message<CharType>(id).str(loc); - } - /// - /// Translate plural form according to locale \a loc - /// - template<typename CharType> - std::basic_string<CharType> ngettext( CharType const *s, - CharType const *p, - int n, - std::locale const &loc=std::locale()) - { - return basic_message<CharType>(s,p,n).str(loc); - } - /// - /// Translate message \a id according to locale \a loc in domain \a domain - /// - template<typename CharType> - std::basic_string<CharType> dgettext( char const *domain, - CharType const *id, - std::locale const &loc=std::locale()) - { - return basic_message<CharType>(id).str(loc,domain); - } + const facet_type* facet = 0; + if(std::has_facet<facet_type>(loc)) + facet = &std::use_facet<facet_type>(loc); - /// - /// Translate plural form according to locale \a loc in domain \a domain - /// - template<typename CharType> - std::basic_string<CharType> dngettext( char const *domain, - CharType const *s, - CharType const *p, - int n, - std::locale const &loc=std::locale()) - { - return basic_message<CharType>(s,p,n).str(loc,domain); - } - /// - /// Translate message \a id according to locale \a loc in context \a context - /// - template<typename CharType> - std::basic_string<CharType> pgettext( CharType const *context, - CharType const *id, - std::locale const &loc=std::locale()) - { - return basic_message<CharType>(context,id).str(loc); - } - /// - /// Translate plural form according to locale \a loc in context \a context - /// - template<typename CharType> - std::basic_string<CharType> npgettext( CharType const *context, - CharType const *s, - CharType const *p, - int n, - std::locale const &loc=std::locale()) - { - return basic_message<CharType>(context,s,p,n).str(loc); - } - /// - /// Translate message \a id according to locale \a loc in domain \a domain in context \a context - /// - template<typename CharType> - std::basic_string<CharType> dpgettext( char const *domain, - CharType const *context, - CharType const *id, - std::locale const &loc=std::locale()) - { - return basic_message<CharType>(context,id).str(loc,domain); - } - /// - /// Translate plural form according to locale \a loc in domain \a domain in context \a context - /// - template<typename CharType> - std::basic_string<CharType> dnpgettext(char const *domain, - CharType const *context, - CharType const *s, - CharType const *p, - int n, - std::locale const &loc=std::locale()) - { - return basic_message<CharType>(context,s,p,n).str(loc,domain); - } + if(facet) { + if(!plural) { + translated = facet->get(domain_id, context, id); + } else { + translated = facet->get(domain_id, context, id, n_); + } + } - /// - /// \cond INTERNAL - /// + if(!translated) { + const char_type* msg = plural ? (n_ == 1 ? id : plural) : id; - template<> - struct BOOST_LOCALE_DECL base_message_format<char> : public std::locale::facet - { - base_message_format(size_t refs = 0) : std::locale::facet(refs) - { + if(facet) { + translated = facet->convert(msg, buffer); + } else { + translated = detail::string_cast_traits<char_type>::cast(msg, buffer); + } } - static std::locale::id id; - }; + return translated; + } - 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) - { - } - static std::locale::id id; - }; + /// members + + int n_; + const char_type* c_id_; + const char_type* c_context_; + const char_type* c_plural_; + string_type id_; + string_type context_; + string_type plural_; + }; + + /// Convenience typedef for char + typedef basic_message<char> message; + /// Convenience typedef for wchar_t + typedef basic_message<wchar_t> wmessage; +#ifdef BOOST_LOCALE_ENABLE_CHAR16_T + /// Convenience typedef for char16_t + typedef basic_message<char16_t> u16message; +#endif +#ifdef BOOST_LOCALE_ENABLE_CHAR32_T + /// Convenience typedef for char32_t + typedef basic_message<char32_t> u32message; +#endif - #ifdef BOOST_LOCALE_ENABLE_CHAR16_T + /// Translate message \a msg and write it to stream + template<typename CharType> + std::basic_ostream<CharType>& operator<<(std::basic_ostream<CharType>& out, const basic_message<CharType>& msg) + { + msg.write(out); + return out; + } + + /// \anchor boost_locale_translate_family \name Indirect message translation function family + /// @{ + + /// \brief Translate a message, \a msg is not copied + template<typename CharType> + inline basic_message<CharType> translate(const CharType* msg) + { + return basic_message<CharType>(msg); + } + + /// \brief Translate a message in context, \a msg and \a context are not copied + template<typename CharType> + inline basic_message<CharType> translate(const CharType* context, const CharType* msg) + { + return basic_message<CharType>(context, msg); + } + + /// \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) + { + 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 + template<typename CharType> + inline basic_message<CharType> + translate(const CharType* context, const CharType* single, const CharType* plural, int n) + { + return basic_message<CharType>(context, single, plural, n); + } + + /// \brief Translate a message, \a msg is copied + template<typename CharType> + inline basic_message<CharType> translate(const std::basic_string<CharType>& msg) + { + return basic_message<CharType>(msg); + } + + /// \brief Translate a message in context,\a context and \a msg is copied + template<typename CharType> + inline basic_message<CharType> translate(const std::basic_string<CharType>& context, + const std::basic_string<CharType>& msg) + { + return basic_message<CharType>(context, msg); + } + + /// \brief Translate a plural message form in constext, \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) + { + return basic_message<CharType>(context, single, plural, n); + } + + /// \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) + { + return basic_message<CharType>(single, plural, n); + } + + /// @} + + /// \anchor boost_locale_gettext_family \name Direct message translation functions family + + /// Translate message \a id according to locale \a loc + template<typename CharType> + std::basic_string<CharType> gettext(const CharType* id, const std::locale& loc = std::locale()) + { + return basic_message<CharType>(id).str(loc); + } + /// 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()) + { + return basic_message<CharType>(s, p, n).str(loc); + } + + /// Translate message \a id according to locale \a loc in domain \a domain + template<typename CharType> + std::basic_string<CharType> dgettext(const char* domain, const CharType* id, const std::locale& loc = std::locale()) + { + return basic_message<CharType>(id).str(loc, domain); + } + + /// 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()) + { + return basic_message<CharType>(s, p, n).str(loc, domain); + } + + /// Translate message \a id according to locale \a loc in context \a context + template<typename CharType> + std::basic_string<CharType> + pgettext(const CharType* context, const CharType* id, const std::locale& loc = std::locale()) + { + return basic_message<CharType>(context, id).str(loc); + } + + /// Translate plural form according to locale \a loc in context \a context + template<typename CharType> + std::basic_string<CharType> npgettext(const CharType* context, + const CharType* s, + const CharType* p, + int n, + const std::locale& loc = std::locale()) + { + return basic_message<CharType>(context, s, p, n).str(loc); + } + + /// Translate message \a id according to locale \a loc in domain \a domain in context \a context + template<typename CharType> + std::basic_string<CharType> + dpgettext(const char* domain, const CharType* context, const CharType* id, const std::locale& loc = std::locale()) + { + return basic_message<CharType>(context, id).str(loc, domain); + } + + /// Translate plural form according to locale \a loc in domain \a domain in context \a context + template<typename CharType> + std::basic_string<CharType> dnpgettext(const char* domain, + const CharType* context, + const CharType* s, + const CharType* p, + int 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; + }; - 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) - { - } - static std::locale::id id; - }; +#endif - #endif +#ifdef BOOST_LOCALE_ENABLE_CHAR32_T - #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; + }; - 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) - { - } - static std::locale::id id; - }; +#endif - #endif + /// \endcond + /// @} + namespace as { + /// \cond INTERNAL + namespace detail { + struct set_domain { + std::string domain_id; + }; + template<typename CharType> + std::basic_ostream<CharType>& operator<<(std::basic_ostream<CharType>& out, const set_domain& dom) + { + int id = std::use_facet<message_format<CharType>>(out.getloc()).domain(dom.domain_id); + ios_info::get(out).domain_id(id); + return out; + } + } // namespace detail /// \endcond + /// \addtogroup manipulators /// - /// @} - /// + /// @{ - namespace as { - /// \cond INTERNAL - namespace details { - struct set_domain { - std::string domain_id; - }; - template<typename CharType> - std::basic_ostream<CharType> &operator<<(std::basic_ostream<CharType> &out, set_domain const &dom) - { - int id = std::use_facet<message_format<CharType> >(out.getloc()).domain(dom.domain_id); - ios_info::get(out).domain_id(id); - return out; - } - } // details - /// \endcond - - /// - /// \addtogroup manipulators - /// - /// @{ - - /// - /// Manipulator for switching message domain in ostream, - /// - /// \note The returned object throws std::bad_cast if the I/O stream does not have \ref message_format facet installed - /// - inline - #ifdef BOOST_LOCALE_DOXYGEN - unspecified_type - #else - details::set_domain - #endif - domain(std::string const &id) - { - details::set_domain tmp = { id }; - return tmp; - } - /// @} - } // as - } // locale -} // boost + /// Manipulator for switching message domain in ostream, + /// + /// \note The returned object throws std::bad_cast if the I/O stream does not have \ref message_format facet + /// installed + inline +#ifdef BOOST_LOCALE_DOXYGEN + unspecified_type +#else + detail::set_domain +#endif + domain(const std::string& id) + { + detail::set_domain tmp = {id}; + return tmp; + } + /// @} + } // namespace as +}} // namespace boost::locale #ifdef BOOST_MSVC -#pragma warning(pop) +# pragma warning(pop) #endif - #endif - - diff --git a/contrib/restricted/boost/locale/include/boost/locale/time_zone.hpp b/contrib/restricted/boost/locale/include/boost/locale/time_zone.hpp index d3af0fa8d4..1ee988cf14 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/time_zone.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/time_zone.hpp @@ -11,41 +11,30 @@ #include <string> #ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4275 4251 4231 4660) +# pragma warning(push) +# pragma warning(disable : 4275 4251 4231 4660) #endif -namespace boost { - namespace locale { - /// - /// \addtogroup date_time - /// - /// @{ - - /// - /// \brief namespace that holds functions for operating with global - /// time zone - /// - namespace time_zone { - /// - /// Get global time zone identifier. If empty, system time zone is used - /// - BOOST_LOCALE_DECL std::string global(); - /// - /// Set global time zone identifier returning previous one. If empty, system time zone is used - /// - BOOST_LOCALE_DECL std::string global(std::string const &new_tz); - } - - /// @} - - } // locale -} // boost +namespace boost { namespace locale { + /// \addtogroup date_time + /// + /// @{ -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif + /// \brief namespace that holds functions for operating with global + /// time zone + namespace time_zone { + /// Get global time zone identifier. If empty, system time zone is used + BOOST_LOCALE_DECL std::string global(); + /// Set global time zone identifier returning previous one. If empty, system time zone is used + BOOST_LOCALE_DECL std::string global(const std::string& new_tz); + } // namespace time_zone + + /// @} +}} // namespace boost::locale +#ifdef BOOST_MSVC +# pragma warning(pop) #endif +#endif diff --git a/contrib/restricted/boost/locale/include/boost/locale/utf.hpp b/contrib/restricted/boost/locale/include/boost/locale/utf.hpp index e31e29b081..841b10f67e 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/utf.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/utf.hpp @@ -10,454 +10,362 @@ #include <boost/locale/config.hpp> #include <boost/cstdint.hpp> -namespace boost { -namespace locale { -/// -/// \brief Namespace that holds basic operations on UTF encoded sequences -/// -/// All functions defined in this namespace do not require linking with Boost.Locale library -/// -namespace utf { - /// \cond INTERNAL - #ifdef __GNUC__ - # define BOOST_LOCALE_LIKELY(x) __builtin_expect((x),1) - # define BOOST_LOCALE_UNLIKELY(x) __builtin_expect((x),0) - #else - # define BOOST_LOCALE_LIKELY(x) (x) - # define BOOST_LOCALE_UNLIKELY(x) (x) - #endif - /// \endcond - - /// - /// \brief The integral type that can hold a Unicode code point - /// - typedef uint32_t code_point; - - /// - /// \brief Special constant that defines illegal code point - /// - static const code_point illegal = 0xFFFFFFFFu; - +namespace boost { namespace locale { + /// \brief Namespace that holds basic operations on UTF encoded sequences /// - /// \brief Special constant that defines incomplete code point - /// - static const code_point incomplete = 0xFFFFFFFEu; - - /// - /// \brief the function checks if \a v is a valid code point - /// - inline bool is_valid_codepoint(code_point v) - { - if(v>0x10FFFF) - return false; - if(0xD800 <=v && v<= 0xDFFF) // surrogates - return false; - return true; - } - - #ifdef BOOST_LOCALE_DOXYGEN - /// - /// \brief UTF Traits class - functions to convert UTF sequences to and from Unicode code points - /// - template<typename CharType,int size=sizeof(CharType)> - struct utf_traits { - /// - /// The type of the character - /// - typedef CharType char_type; - /// - /// Read one code point from the range [p,e) and return it. - /// - /// - If the sequence that was read is incomplete sequence returns \ref incomplete, - /// - If illegal sequence detected returns \ref illegal - /// - /// Requirements - /// - /// - Iterator is valid input iterator - /// - /// Postconditions - /// - /// - p points to the last consumed character - /// - template<typename Iterator> - static code_point decode(Iterator &p,Iterator e); - - /// - /// Maximal width of valid sequence in the code units: - /// - /// - UTF-8 - 4 - /// - UTF-16 - 2 - /// - UTF-32 - 1 - /// - static const int max_width; - /// - /// The width of specific code point in the code units. - /// - /// Requirement: value is a valid Unicode code point - /// Returns value in range [1..max_width] - /// - static int width(code_point value); - - /// - /// Get the size of the trail part of variable length encoded sequence. - /// - /// Returns -1 if C is not valid lead character - /// - static int trail_length(char_type c); - /// - /// Returns true if c is trail code unit, always false for UTF-32 - /// - static bool is_trail(char_type c); - /// - /// Returns true if c is lead code unit, always true of UTF-32 - /// - static bool is_lead(char_type c); - - /// - /// Convert valid Unicode code point \a value to the UTF sequence. - /// - /// Requirements: - /// - /// - \a value is valid code point - /// - \a out is an output iterator should be able to accept at least width(value) units - /// - /// Returns the iterator past the last written code unit. - /// - template<typename Iterator> - static Iterator encode(code_point value,Iterator out); - /// - /// Decodes valid UTF sequence that is pointed by p into code point. - /// - /// If the sequence is invalid or points to end the behavior is undefined - /// - template<typename Iterator> - static code_point decode_valid(Iterator &p); - }; - - #else - - template<typename CharType,int size=sizeof(CharType)> - struct utf_traits; - - template<typename CharType> - struct utf_traits<CharType,1> { - - typedef CharType char_type; - - static int trail_length(char_type ci) + /// 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; + + /// \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; + + /// \brief the function checks if \a v is a valid code point + inline bool is_valid_codepoint(code_point v) { - unsigned char c = ci; - if(c < 128) - return 0; - if(BOOST_LOCALE_UNLIKELY(c < 194)) - return -1; - if(c < 224) - return 1; - if(c < 240) - return 2; - if(BOOST_LOCALE_LIKELY(c <=244)) - return 3; - return -1; + if(v > 0x10FFFF) + return false; + if(0xD800 <= v && v <= 0xDFFF) // surrogates + return false; + return true; } - static const int max_width = 4; - - static int width(code_point value) - { - if(value <=0x7F) { - return 1; - } - else if(value <=0x7FF) { - return 2; - } - else if(BOOST_LOCALE_LIKELY(value <=0xFFFF)) { - return 3; - } - else { - return 4; +#ifdef BOOST_LOCALE_DOXYGEN + + /// \brief UTF Traits class - functions to convert UTF sequences to and from Unicode code points + template<typename CharType, int size = sizeof(CharType)> + struct utf_traits { + /// The type of the character + typedef CharType char_type; + + /// Read one code point from the range [p,e) and return it. + /// + /// - If the sequence that was read is incomplete sequence returns \ref incomplete, + /// - If illegal sequence detected returns \ref illegal + /// + /// Requirements + /// + /// - Iterator is valid input iterator + /// + /// Postconditions + /// + /// - p points to the last consumed character + template<typename Iterator> + static code_point decode(Iterator& p, Iterator e); + + /// Maximal width of valid sequence in the code units: + /// + /// - UTF-8 - 4 + /// - UTF-16 - 2 + /// - UTF-32 - 1 + static constexpr int max_width; + + /// The width of specific code point in the code units. + /// + /// Requirement: value is a valid Unicode code point + /// Returns value in range [1..max_width] + static int width(code_point value); + + /// Get the size of the trail part of variable length encoded sequence. + /// + /// Returns -1 if C is not valid lead character + static int trail_length(char_type c); + /// Returns true if c is trail code unit, always false for UTF-32 + static bool is_trail(char_type c); + /// Returns true if c is lead code unit, always true of UTF-32 + static bool is_lead(char_type c); + + /// Convert valid Unicode code point \a value to the UTF sequence. + /// + /// Requirements: + /// + /// - \a value is valid code point + /// - \a out is an output iterator should be able to accept at least width(value) units + /// + /// Returns the iterator past the last written code unit. + template<typename Iterator> + static Iterator encode(code_point value, Iterator out); + + /// Decodes valid UTF sequence that is pointed by p into code point. + /// + /// If the sequence is invalid or points to end the behavior is undefined + template<typename Iterator> + static code_point decode_valid(Iterator& p); + }; + +#else + + template<typename CharType, int size = sizeof(CharType)> + struct utf_traits; + + template<typename CharType> + struct utf_traits<CharType, 1> { + typedef CharType char_type; + + static int trail_length(char_type ci) + { + unsigned char c = ci; + if(c < 128) + return 0; + if(BOOST_UNLIKELY(c < 194)) + return -1; + if(c < 224) + return 1; + if(c < 240) + return 2; + if(BOOST_LIKELY(c <= 244)) + return 3; + return -1; } - } - - static bool is_trail(char_type ci) - { - unsigned char c=ci; - return (c & 0xC0)==0x80; - } - static bool is_lead(char_type ci) - { - return !is_trail(ci); - } - - template<typename Iterator> - static code_point decode(Iterator &p,Iterator e) - { - if(BOOST_LOCALE_UNLIKELY(p==e)) - return incomplete; + static constexpr int max_width = 4; + + static int width(code_point value) + { + if(value <= 0x7F) { + return 1; + } else if(value <= 0x7FF) { + return 2; + } else if(BOOST_LIKELY(value <= 0xFFFF)) { + return 3; + } else { + return 4; + } + } - unsigned char lead = *p++; + static bool is_trail(char_type ci) + { + unsigned char c = ci; + return (c & 0xC0) == 0x80; + } - // First byte is fully validated here - int trail_size = trail_length(lead); + static bool is_lead(char_type ci) { return !is_trail(ci); } - if(BOOST_LOCALE_UNLIKELY(trail_size < 0)) - return illegal; + template<typename Iterator> + static code_point decode(Iterator& p, Iterator e) + { + if(BOOST_UNLIKELY(p == e)) + return incomplete; - // - // Ok as only ASCII may be of size = 0 - // also optimize for ASCII text - // - if(trail_size == 0) - return lead; + unsigned char lead = *p++; - code_point c = lead & ((1 << (6-trail_size))-1); + // First byte is fully validated here + int trail_size = trail_length(lead); - // Read the rest - unsigned char tmp; - switch(trail_size) { - case 3: - if(BOOST_LOCALE_UNLIKELY(p==e)) - return incomplete; - tmp = *p++; - if (!is_trail(tmp)) + if(BOOST_UNLIKELY(trail_size < 0)) return illegal; - c = (c << 6) | ( tmp & 0x3F); - BOOST_FALLTHROUGH; - case 2: - if(BOOST_LOCALE_UNLIKELY(p==e)) - return incomplete; - tmp = *p++; - if (!is_trail(tmp)) - return illegal; - c = (c << 6) | ( tmp & 0x3F); - BOOST_FALLTHROUGH; - case 1: - if(BOOST_LOCALE_UNLIKELY(p==e)) - return incomplete; - tmp = *p++; - if (!is_trail(tmp)) - return illegal; - c = (c << 6) | ( tmp & 0x3F); - } - // Check code point validity: no surrogates and - // valid range - if(BOOST_LOCALE_UNLIKELY(!is_valid_codepoint(c))) - return illegal; + // Ok as only ASCII may be of size = 0 + // also optimize for ASCII text + if(trail_size == 0) + return lead; + + code_point c = lead & ((1 << (6 - trail_size)) - 1); + + // Read the rest + unsigned char tmp; + switch(trail_size) { + case 3: + if(BOOST_UNLIKELY(p == e)) + return incomplete; + tmp = *p++; + if(!is_trail(tmp)) + return illegal; + c = (c << 6) | (tmp & 0x3F); + BOOST_FALLTHROUGH; + case 2: + if(BOOST_UNLIKELY(p == e)) + return incomplete; + tmp = *p++; + if(!is_trail(tmp)) + return illegal; + c = (c << 6) | (tmp & 0x3F); + BOOST_FALLTHROUGH; + case 1: + if(BOOST_UNLIKELY(p == e)) + return incomplete; + tmp = *p++; + if(!is_trail(tmp)) + return illegal; + c = (c << 6) | (tmp & 0x3F); + } + + // Check code point validity: no surrogates and + // valid range + if(BOOST_UNLIKELY(!is_valid_codepoint(c))) + return illegal; - // make sure it is the most compact representation - if(BOOST_LOCALE_UNLIKELY(width(c)!=trail_size + 1)) - return illegal; + // make sure it is the most compact representation + if(BOOST_UNLIKELY(width(c) != trail_size + 1)) + return illegal; - return c; + return c; + } - } + template<typename Iterator> + static code_point decode_valid(Iterator& p) + { + unsigned char lead = *p++; + if(lead < 192) + return lead; - template<typename Iterator> - static code_point decode_valid(Iterator &p) - { - unsigned char lead = *p++; - if(lead < 192) - return lead; - - int trail_size; - - if(lead < 224) - trail_size = 1; - else if(BOOST_LOCALE_LIKELY(lead < 240)) // non-BMP rare - trail_size = 2; - else - trail_size = 3; - - code_point c = lead & ((1 << (6-trail_size))-1); - - switch(trail_size) { - case 3: - c = (c << 6) | ( static_cast<unsigned char>(*p++) & 0x3F); - BOOST_FALLTHROUGH; - case 2: - c = (c << 6) | ( static_cast<unsigned char>(*p++) & 0x3F); - BOOST_FALLTHROUGH; - case 1: - c = (c << 6) | ( static_cast<unsigned char>(*p++) & 0x3F); - } + int trail_size; - return c; - } + if(lead < 224) + trail_size = 1; + else if(BOOST_LIKELY(lead < 240)) // non-BMP rare + trail_size = 2; + else + trail_size = 3; + code_point c = lead & ((1 << (6 - trail_size)) - 1); + switch(trail_size) { + case 3: c = (c << 6) | (static_cast<unsigned char>(*p++) & 0x3F); BOOST_FALLTHROUGH; + case 2: c = (c << 6) | (static_cast<unsigned char>(*p++) & 0x3F); BOOST_FALLTHROUGH; + case 1: c = (c << 6) | (static_cast<unsigned char>(*p++) & 0x3F); + } - template<typename Iterator> - static Iterator encode(code_point value,Iterator out) - { - if(value <= 0x7F) { - *out++ = static_cast<char_type>(value); + return c; } - else if(value <= 0x7FF) { - *out++ = static_cast<char_type>((value >> 6) | 0xC0); - *out++ = static_cast<char_type>((value & 0x3F) | 0x80); + + template<typename Iterator> + static Iterator encode(code_point value, Iterator out) + { + if(value <= 0x7F) { + *out++ = static_cast<char_type>(value); + } 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)) { + *out++ = static_cast<char_type>((value >> 12) | 0xE0); + *out++ = static_cast<char_type>(((value >> 6) & 0x3F) | 0x80); + *out++ = static_cast<char_type>((value & 0x3F) | 0x80); + } else { + *out++ = static_cast<char_type>((value >> 18) | 0xF0); + *out++ = static_cast<char_type>(((value >> 12) & 0x3F) | 0x80); + *out++ = static_cast<char_type>(((value >> 6) & 0x3F) | 0x80); + *out++ = static_cast<char_type>((value & 0x3F) | 0x80); + } + return out; } - else if(BOOST_LOCALE_LIKELY(value <= 0xFFFF)) { - *out++ = static_cast<char_type>((value >> 12) | 0xE0); - *out++ = static_cast<char_type>(((value >> 6) & 0x3F) | 0x80); - *out++ = static_cast<char_type>((value & 0x3F) | 0x80); + }; // utf8 + + template<typename CharType> + struct utf_traits<CharType, 2> { + typedef CharType char_type; + + // See RFC 2781 + static bool is_first_surrogate(uint16_t x) { return 0xD800 <= x && x <= 0xDBFF; } + static bool is_second_surrogate(uint16_t x) { return 0xDC00 <= x && x <= 0xDFFF; } + static code_point combine_surrogate(uint16_t w1, uint16_t w2) + { + return ((code_point(w1 & 0x3FF) << 10) | (w2 & 0x3FF)) + 0x10000; } - else { - *out++ = static_cast<char_type>((value >> 18) | 0xF0); - *out++ = static_cast<char_type>(((value >> 12) & 0x3F) | 0x80); - *out++ = static_cast<char_type>(((value >> 6) & 0x3F) | 0x80); - *out++ = static_cast<char_type>((value & 0x3F) | 0x80); + static int trail_length(char_type c) + { + if(is_first_surrogate(c)) + return 1; + if(is_second_surrogate(c)) + return -1; + return 0; } - return out; - } - }; // utf8 - template<typename CharType> - struct utf_traits<CharType,2> { - typedef CharType char_type; + /// Returns true if c is trail code unit, always false for UTF-32 + static bool is_trail(char_type c) { return is_second_surrogate(c); } + /// Returns true if c is lead code unit, always true of UTF-32 + static bool is_lead(char_type c) { return !is_second_surrogate(c); } - // See RFC 2781 - static bool is_first_surrogate(uint16_t x) - { - return 0xD800 <=x && x<= 0xDBFF; - } - static bool is_second_surrogate(uint16_t x) - { - return 0xDC00 <=x && x<= 0xDFFF; - } - static code_point combine_surrogate(uint16_t w1,uint16_t w2) - { - return ((code_point(w1 & 0x3FF) << 10) | (w2 & 0x3FF)) + 0x10000; - } - static int trail_length(char_type c) - { - if(is_first_surrogate(c)) - return 1; - if(is_second_surrogate(c)) - return -1; - return 0; - } - /// - /// Returns true if c is trail code unit, always false for UTF-32 - /// - static bool is_trail(char_type c) - { - return is_second_surrogate(c); - } - /// - /// Returns true if c is lead code unit, always true of UTF-32 - /// - static bool is_lead(char_type c) - { - return !is_second_surrogate(c); - } - - template<typename It> - static code_point decode(It ¤t,It last) - { - if(BOOST_LOCALE_UNLIKELY(current == last)) - return incomplete; - uint16_t w1=*current++; - if(BOOST_LOCALE_LIKELY(w1 < 0xD800 || 0xDFFF < w1)) { - return w1; + template<typename It> + static code_point decode(It& current, It last) + { + if(BOOST_UNLIKELY(current == last)) + return incomplete; + uint16_t w1 = *current++; + if(BOOST_LIKELY(w1 < 0xD800 || 0xDFFF < w1)) { + return w1; + } + if(w1 > 0xDBFF) + return illegal; + if(current == last) + return incomplete; + uint16_t w2 = *current++; + if(w2 < 0xDC00 || 0xDFFF < w2) + return illegal; + return combine_surrogate(w1, w2); } - if(w1 > 0xDBFF) - return illegal; - if(current==last) - return incomplete; - uint16_t w2=*current++; - if(w2 < 0xDC00 || 0xDFFF < w2) - return illegal; - return combine_surrogate(w1,w2); - } - template<typename It> - static code_point decode_valid(It ¤t) - { - uint16_t w1=*current++; - if(BOOST_LOCALE_LIKELY(w1 < 0xD800 || 0xDFFF < w1)) { - return w1; + template<typename It> + static code_point decode_valid(It& current) + { + uint16_t w1 = *current++; + if(BOOST_LIKELY(w1 < 0xD800 || 0xDFFF < w1)) { + return w1; + } + uint16_t w2 = *current++; + return combine_surrogate(w1, w2); } - uint16_t w2=*current++; - return combine_surrogate(w1,w2); - } - static const int max_width = 2; - static int width(code_point u) - { - return u>=0x10000 ? 2 : 1; - } - template<typename It> - static It encode(code_point u,It out) - { - if(BOOST_LOCALE_LIKELY(u<=0xFFFF)) { - *out++ = static_cast<char_type>(u); + static constexpr int max_width = 2; + static int width(code_point u) { return u >= 0x10000 ? 2 : 1; } + template<typename It> + static It encode(code_point u, It out) + { + if(BOOST_LIKELY(u <= 0xFFFF)) { + *out++ = static_cast<char_type>(u); + } else { + u -= 0x10000; + *out++ = static_cast<char_type>(0xD800 | (u >> 10)); + *out++ = static_cast<char_type>(0xDC00 | (u & 0x3FF)); + } + return out; } - else { - u -= 0x10000; - *out++ = static_cast<char_type>(0xD800 | (u>>10)); - *out++ = static_cast<char_type>(0xDC00 | (u & 0x3FF)); + }; // utf16; + + template<typename CharType> + struct utf_traits<CharType, 4> { + typedef CharType char_type; + static int trail_length(char_type c) + { + if(is_valid_codepoint(c)) + return 0; + return -1; } - return out; - } - }; // utf16; - - - template<typename CharType> - struct utf_traits<CharType,4> { - typedef CharType char_type; - static int trail_length(char_type c) - { - if(is_valid_codepoint(c)) - return 0; - return -1; - } - static bool is_trail(char_type /*c*/) - { - return false; - } - static bool is_lead(char_type /*c*/) - { - return true; - } - - template<typename It> - static code_point decode_valid(It ¤t) - { - return *current++; - } - - template<typename It> - static code_point decode(It ¤t,It last) - { - if(BOOST_LOCALE_UNLIKELY(current == last)) - return boost::locale::utf::incomplete; - code_point c=*current++; - if(BOOST_LOCALE_UNLIKELY(!is_valid_codepoint(c))) - return boost::locale::utf::illegal; - return c; - } - static const int max_width = 1; - static int width(code_point /*u*/) - { - return 1; - } - template<typename It> - static It encode(code_point u,It out) - { - *out++ = static_cast<char_type>(u); - return out; - } - - }; // utf32 - - #endif + static bool is_trail(char_type /*c*/) { return false; } + static bool is_lead(char_type /*c*/) { return true; } + template<typename It> + static code_point decode_valid(It& current) + { + return *current++; + } -} // utf -} // locale -} // boost + template<typename It> + static code_point decode(It& current, It last) + { + if(BOOST_UNLIKELY(current == last)) + return boost::locale::utf::incomplete; + code_point c = *current++; + if(BOOST_UNLIKELY(!is_valid_codepoint(c))) + return boost::locale::utf::illegal; + return c; + } + static constexpr int max_width = 1; + static int width(code_point /*u*/) { return 1; } + template<typename It> + static It encode(code_point u, It out) + { + *out++ = static_cast<char_type>(u); + return out; + } + }; // utf32 #endif + } // namespace utf +}} // namespace boost::locale +#endif 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 8f02899e6d..d2884c6770 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/utf8_codecvt.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/utf8_codecvt.hpp @@ -7,61 +7,50 @@ #ifndef BOOST_LOCALE_UTF8_CODECVT_HPP #define BOOST_LOCALE_UTF8_CODECVT_HPP -#include <boost/locale/utf.hpp> #include <boost/locale/generic_codecvt.hpp> +#include <boost/locale/utf.hpp> #include <boost/cstdint.hpp> #include <locale> -namespace boost { -namespace locale { - -/// -/// \brief Geneneric utf8 codecvt facet, it allows to convert UTF-8 strings to UTF-16 and UTF-32 using wchar_t, char32_t and char16_t -/// -template<typename CharType> -class utf8_codecvt : public generic_codecvt<CharType,utf8_codecvt<CharType> > -{ -public: - - struct state_type {}; - - utf8_codecvt(size_t refs = 0) : generic_codecvt<CharType,utf8_codecvt<CharType> >(refs) - { - } - - static int max_encoding_length() - { - return 4; - } - - static state_type initial_state(generic_codecvt_base::initial_convertion_state /* unused */) - { - return state_type(); - } - static utf::code_point to_unicode(state_type &,char const *&begin,char const *end) - { - char const *p=begin; - - utf::code_point c = utf::utf_traits<char>::decode(p,end); - if(c!=utf::illegal && c!=utf::incomplete) - begin = p; - return c; - } - - static utf::code_point from_unicode(state_type &,utf::code_point u,char *begin,char const *end) - { - if(!utf::is_valid_codepoint(u)) - return utf::illegal; - int width; - if((width=utf::utf_traits<char>::width(u)) > end - begin) - return utf::incomplete; - utf::utf_traits<char>::encode(u,begin); - return width; - } -}; - -} // locale -} // namespace boost +namespace boost { namespace locale { + + /// \brief Geneneric utf8 codecvt facet, it allows to convert UTF-8 strings to UTF-16 and UTF-32 using wchar_t, + /// char32_t and char16_t + template<typename CharType> + class utf8_codecvt : public generic_codecvt<CharType, utf8_codecvt<CharType>> { + public: + struct state_type {}; + + utf8_codecvt(size_t refs = 0) : generic_codecvt<CharType, utf8_codecvt<CharType>>(refs) {} + + static int max_encoding_length() { return 4; } + + static state_type initial_state(generic_codecvt_base::initial_convertion_state /* unused */) + { + return state_type(); + } + static utf::code_point to_unicode(state_type&, const char*& begin, const char* end) + { + const char* p = begin; + + utf::code_point c = utf::utf_traits<char>::decode(p, end); + if(c != utf::illegal && c != utf::incomplete) + begin = p; + return c; + } + + static utf::code_point 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) + return utf::incomplete; + utf::utf_traits<char>::encode(u, begin); + return width; + } + }; + +}} // namespace boost::locale #endif -/// diff --git a/contrib/restricted/boost/locale/include/boost/locale/util.hpp b/contrib/restricted/boost/locale/include/boost/locale/util.hpp index 1b444740fd..0ef67ef7de 100644 --- a/contrib/restricted/boost/locale/include/boost/locale/util.hpp +++ b/contrib/restricted/boost/locale/include/boost/locale/util.hpp @@ -12,274 +12,204 @@ #include <boost/assert.hpp> #include <boost/cstdint.hpp> #include <locale> -#ifndef BOOST_NO_CXX11_SMART_PTR #include <memory> -#endif #include <typeinfo> -namespace boost { -namespace locale { -/// -/// \brief This namespace provides various utility function useful for Boost.Locale backends -/// implementations -/// -namespace util { - - /// - /// \brief Return default system locale name in POSIX format. - /// - /// This function tries to detect the locale using, LC_CTYPE, LC_ALL and LANG environment - /// variables in this order and if all of them unset, in POSIX platforms it returns "C" - /// - /// On Windows additionally to check the above environment variables, this function - /// tries to creates locale name from ISO-339 and ISO-3199 country codes defined - /// for user default locale. - /// If \a use_utf8_on_windows is true it sets the encoding to UTF-8, otherwise, if system - /// locale supports ANSI code-page it defines the ANSI encoding like windows-1252, otherwise it fall-backs - /// to UTF-8 encoding if ANSI code-page is not available. - /// - BOOST_LOCALE_DECL - std::string get_system_locale(bool use_utf8_on_windows = false); - - /// - /// \brief Installs information facet to locale in based on locale name \a name - /// - /// This function installs boost::locale::info facet into the locale \a in and returns - /// newly created locale. - /// - /// Note: all information is based only on parsing of string \a name; - /// - /// The name has following format: language[_COUNTRY][.encoding][\@variant] - /// Where language is ISO-639 language code like "en" or "ru", COUNTRY is ISO-3166 - /// country identifier like "US" or "RU". the Encoding is a charracter set name - /// like UTF-8 or ISO-8859-1. Variant is backend specific variant like \c euro or - /// calendar=hebrew. - /// - /// If some parameters are missing they are specified as blanks, default encoding - /// is assumed to be US-ASCII and missing language is assumed to be "C" - /// - BOOST_LOCALE_DECL - std::locale create_info(std::locale const &in,std::string const &name); +namespace boost { namespace locale { + /// \brief This namespace provides various utility function useful for Boost.Locale's backends + /// implementations + namespace util { + + /// \brief Return default system locale name in POSIX format. + /// + /// This function tries to detect the locale using, LC_CTYPE, LC_ALL and LANG environment + /// variables in this order and if all of them unset, in POSIX platforms it returns "C" + /// + /// On Windows additionally to check the above environment variables, this function + /// tries to creates locale name from ISO-339 and ISO-3199 country codes defined + /// for user default locale. + /// If \a use_utf8_on_windows is true it sets the encoding to UTF-8, otherwise, if system + /// locale supports ANSI code-page it defines the ANSI encoding like windows-1252, otherwise it fall-backs + /// to UTF-8 encoding if ANSI code-page is not available. + BOOST_LOCALE_DECL + std::string get_system_locale(bool use_utf8_on_windows = false); + + /// \brief Installs information facet to locale in based on locale name \a name + /// + /// This function installs boost::locale::info facet into the locale \a in and returns + /// newly created locale. + /// + /// Note: all information is based only on parsing of string \a name; + /// + /// The name has following format: language[_COUNTRY][.encoding][\@variant] + /// Where language is ISO-639 language code like "en" or "ru", COUNTRY is ISO-3166 + /// country identifier like "US" or "RU". the Encoding is a charracter set name + /// like UTF-8 or ISO-8859-1. Variant is backend specific variant like \c euro or + /// calendar=hebrew. + /// + /// If some parameters are missing they are specified as blanks, default encoding + /// is assumed to be US-ASCII and missing language is assumed to be "C" + BOOST_LOCALE_DECL + std::locale create_info(const std::locale& in, const std::string& name); + + /// \brief This class represent a simple stateless converter from UCS-4 and to UCS-4 for + /// each single code point + /// + /// This class is used for creation of std::codecvt facet for converting utf-16/utf-32 encoding + /// to encoding supported by this converter + /// + /// Please note, this converter should be fully stateless. Fully stateless means it should + /// never assume that it is called in any specific order on the text. Even if the + /// encoding itself seems to be stateless like windows-1255 or shift-jis, some + /// encoders (most notably iconv) can actually compose several code-point into one or + /// decompose them in case composite characters are found. So be very careful when implementing + /// these converters for certain character set. + class BOOST_LOCALE_DECL base_converter { + public: + /// 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; + + /// 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; + + virtual ~base_converter(); + + /// Return the maximal length that one Unicode code-point can be converted to, for example + /// for UTF-8 it is 4, for Shift-JIS it is 2 and ISO-8859-1 is 1 + virtual int max_len() const { return 1; } + + /// Returns true if calling the functions from_unicode, to_unicode, and max_len is thread safe. + /// + /// Rule of thumb: if this class' implementation uses simple tables that are unchanged + /// or is purely algorithmic like UTF-8 - so it does not share any mutable bit for + /// independent to_unicode, from_unicode calls, you may set it to true, otherwise, + /// for example if you use iconv_t descriptor or UConverter as conversion object return false, + /// and this object will be cloned for each use. + virtual bool is_thread_safe() const { return false; } + + /// Create a polymorphic copy of this object, usually called only if is_thread_safe() return false + virtual base_converter* clone() const + { + BOOST_ASSERT(typeid(*this) == typeid(base_converter)); + return new base_converter(); + } + /// Convert a single character starting at begin and ending at most at end to Unicode code-point. + /// + /// if valid input sequence found in [\a begin,\a code_point_end) such as \a begin < \a code_point_end && \a + /// code_point_end <= \a end it is converted to its Unicode code point equivalent, \a begin is set to \a + /// code_point_end + /// + /// if incomplete input sequence found in [\a begin,\a end), i.e. there my be such \a code_point_end that \a + /// code_point_end > \a end and [\a begin, \a code_point_end) would be valid input sequence, then \a + /// incomplete is returned begin stays unchanged, for example for UTF-8 conversion a *begin = 0xc2, \a begin + /// +1 = \a end is such situation. + /// + /// 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) + { + if(begin == end) + return incomplete; + unsigned char cp = *begin; + if(cp <= 0x7F) { + begin++; + return cp; + } + return illegal; + } - /// - /// \brief This class represent a simple stateless converter from UCS-4 and to UCS-4 for - /// each single code point - /// - /// This class is used for creation of std::codecvt facet for converting utf-16/utf-32 encoding - /// to encoding supported by this converter - /// - /// Please note, this converter should be fully stateless. Fully stateless means it should - /// never assume that it is called in any specific order on the text. Even if the - /// encoding itself seems to be stateless like windows-1255 or shift-jis, some - /// encoders (most notably iconv) can actually compose several code-point into one or - /// decompose them in case composite characters are found. So be very careful when implementing - /// these converters for certain character set. - /// - class BOOST_LOCALE_DECL base_converter { - public: + /// Convert a single code-point \a u into encoding and store it in [begin,end) range. + /// + /// If u is invalid Unicode code-point, or it can not be mapped correctly to represented character set, + /// \a illegal should be returned + /// + /// If u can be converted to a sequence of bytes c1, ... , cN (1<= N <= max_len() ) then + /// + /// -# 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) + { + if(begin == end) + return incomplete; + if(u >= 0x80) + return illegal; + *begin = static_cast<char>(u); + return 1; + } + }; - /// - /// 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 const uint32_t illegal=utf::illegal; + /// This function creates a \a base_converter that can be used for conversion between UTF-8 and + /// unicode code points + BOOST_LOCALE_DECL std::unique_ptr<base_converter> create_utf8_converter(); - /// - /// 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 const uint32_t incomplete=utf::incomplete; - - virtual ~base_converter(); - /// - /// Return the maximal length that one Unicode code-point can be converted to, for example - /// for UTF-8 it is 4, for Shift-JIS it is 2 and ISO-8859-1 is 1 - /// - virtual int max_len() const - { - return 1; - } - /// - /// Returns true if calling the functions from_unicode, to_unicode, and max_len is thread safe. - /// - /// Rule of thumb: if this class' implementation uses simple tables that are unchanged - /// or is purely algorithmic like UTF-8 - so it does not share any mutable bit for - /// independent to_unicode, from_unicode calls, you may set it to true, otherwise, - /// for example if you use iconv_t descriptor or UConverter as conversion object return false, - /// and this object will be cloned for each use. - /// - virtual bool is_thread_safe() const + BOOST_DEPRECATED("This function is deprecated, use 'create_utf8_converter()'") + inline std::unique_ptr<base_converter> create_utf8_converter_unique_ptr() { - return false; - } - /// - /// Create a polymorphic copy of this object, usually called only if is_thread_safe() return false - /// - virtual base_converter *clone() const - { - BOOST_ASSERT(typeid(*this)==typeid(base_converter)); - return new base_converter(); + return create_utf8_converter(); } + /// 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, /// - /// Convert a single character starting at begin and ending at most at end to Unicode code-point. - /// - /// if valid input sequence found in [\a begin,\a code_point_end) such as \a begin < \a code_point_end && \a code_point_end <= \a end - /// it is converted to its Unicode code point equivalent, \a begin is set to \a code_point_end - /// - /// if incomplete input sequence found in [\a begin,\a end), i.e. there my be such \a code_point_end that \a code_point_end > \a end - /// and [\a begin, \a code_point_end) would be valid input sequence, then \a incomplete is returned begin stays unchanged, for example - /// for UTF-8 conversion a *begin = 0xc2, \a begin +1 = \a end is such situation. - /// - /// 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(char const *&begin,char const *end) + /// If \a encoding is not supported, empty pointer is returned. + /// So you should check whether the returned pointer is valid/non-NULL + BOOST_LOCALE_DECL std::unique_ptr<base_converter> create_simple_converter(const std::string& encoding); + + BOOST_DEPRECATED("This function is deprecated, use 'create_simple_converter()'") + inline std::unique_ptr<base_converter> create_simple_converter_unique_ptr(const std::string& encoding) { - if(begin == end) - return incomplete; - unsigned char cp = *begin; - if(cp <= 0x7F) { - begin++; - return cp; - } - return illegal; + return create_simple_converter(encoding); } + + /// Install codecvt facet into locale \a in and return new locale that is based on \a in and uses new + /// facet. /// - /// Convert a single code-point \a u into encoding and store it in [begin,end) range. - /// - /// If u is invalid Unicode code-point, or it can not be mapped correctly to represented character set, - /// \a illegal should be returned - /// - /// If u can be converted to a sequence of bytes c1, ... , cN (1<= N <= max_len() ) then + /// codecvt facet would convert between narrow and wide/char16_t/char32_t encodings using \a cvt converter. + /// If \a cvt is null pointer, always failure conversion would be used that fails on every first input or + /// output. /// - /// -# 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) + /// Note: the codecvt facet handles both UTF-16 and UTF-32 wide encodings, it knows to break and join + /// Unicode code-points above 0xFFFF to and from surrogate pairs correctly. \a cvt should be unaware + /// of wide encoding type + BOOST_LOCALE_DECL + std::locale create_codecvt(const std::locale& in, std::unique_ptr<base_converter> cvt, char_facet_t type); - virtual uint32_t from_unicode(uint32_t u,char *begin,char const *end) + BOOST_DEPRECATED("This function is deprecated, use 'create_codecvt()'") + inline std::locale create_codecvt_from_pointer(const std::locale& in, base_converter* cvt, char_facet_t type) { - if(begin==end) - return incomplete; - if(u >= 0x80) - return illegal; - *begin = static_cast<char>(u); - return 1; + return create_codecvt(in, std::unique_ptr<base_converter>(cvt), type); } - }; - - #if BOOST_LOCALE_USE_AUTO_PTR - /// - /// This function creates a \a base_converter that can be used for conversion between UTF-8 and - /// unicode code points - /// - BOOST_LOCALE_DECL std::auto_ptr<base_converter> create_utf8_converter(); - /// - /// 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 - /// std::auto_ptr<base_converter>::get() != 0 - /// - BOOST_LOCALE_DECL std::auto_ptr<base_converter> create_simple_converter(std::string const &encoding); - - /// - /// Install codecvt facet into locale \a in and return new locale that is based on \a in and uses new - /// facet. - /// - /// codecvt facet would convert between narrow and wide/char16_t/char32_t encodings using \a cvt converter. - /// If \a cvt is null pointer, always failure conversion would be used that fails on every first input or output. - /// - /// Note: the codecvt facet handles both UTF-16 and UTF-32 wide encodings, it knows to break and join - /// Unicode code-points above 0xFFFF to and from surrogate pairs correctly. \a cvt should be unaware - /// of wide encoding type - /// - BOOST_LOCALE_DECL - std::locale create_codecvt(std::locale const &in,std::auto_ptr<base_converter> cvt,character_facet_type type); - #endif + /// This function creates a \a base_converter that can be used for conversion between UTF-8 and + /// unicode code points + BOOST_LOCALE_DECL base_converter* create_utf8_converter_new_ptr(); - #ifndef BOOST_NO_CXX11_SMART_PTR - /// - /// This function creates a \a base_converter that can be used for conversion between UTF-8 and - /// unicode code points - /// - BOOST_LOCALE_DECL std::unique_ptr<base_converter> create_utf8_converter_unique_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 - /// std::unique_ptr<base_converter>::get() != 0 - /// - BOOST_LOCALE_DECL std::unique_ptr<base_converter> create_simple_converter_unique_ptr(std::string const &encoding); - - /// - /// Install codecvt facet into locale \a in and return new locale that is based on \a in and uses new - /// facet. - /// - /// codecvt facet would convert between narrow and wide/char16_t/char32_t encodings using \a cvt converter. - /// If \a cvt is null pointer, always failure conversion would be used that fails on every first input or output. - /// - /// Note: the codecvt facet handles both UTF-16 and UTF-32 wide encodings, it knows to break and join - /// Unicode code-points above 0xFFFF to and from surrogate pairs correctly. \a cvt should be unaware - /// of wide encoding type - /// - BOOST_LOCALE_DECL - std::locale create_codecvt(std::locale const &in,std::unique_ptr<base_converter> cvt,character_facet_type type); - #endif - - /// - /// This function creates a \a base_converter that can be used for conversion between UTF-8 and - /// unicode code points - /// - 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 - /// std::unique_ptr<base_converter>::get() != 0 - /// - BOOST_LOCALE_DECL base_converter *create_simple_converter_new_ptr(std::string const &encoding); - - /// - /// Install codecvt facet into locale \a in and return new locale that is based on \a in and uses new - /// facet. - /// - /// codecvt facet would convert between narrow and wide/char16_t/char32_t encodings using \a cvt converter. - /// If \a cvt is null pointer, always failure conversion would be used that fails on every first input or output. - /// - /// Note: the codecvt facet handles both UTF-16 and UTF-32 wide encodings, it knows to break and join - /// Unicode code-points above 0xFFFF to and from surrogate pairs correctly. \a cvt should be unaware - /// of wide encoding type - /// - /// ownership of cvt is transfered - /// - BOOST_LOCALE_DECL - std::locale create_codecvt_from_pointer(std::locale const &in,base_converter *cvt,character_facet_type type); + /// 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_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 - /// new locale that is based on \a in and uses new facet. - /// - BOOST_LOCALE_DECL - std::locale create_utf8_codecvt(std::locale const &in,character_facet_type type); + /// Install utf8 codecvt to UTF-16 or UTF-32 into locale \a in and return + /// new locale that is based on \a in and uses new facet. + BOOST_LOCALE_DECL + std::locale create_utf8_codecvt(const std::locale& in, char_facet_t type); - /// - /// 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 chacater set is not supported or isn't single byte character - /// set - BOOST_LOCALE_DECL - std::locale create_simple_codecvt(std::locale const &in,std::string const &encoding,character_facet_type type); -} // util -} // locale -} // boost + /// 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 + BOOST_LOCALE_DECL + std::locale create_simple_codecvt(const std::locale& in, const std::string& encoding, char_facet_t type); + } // namespace util +}} // namespace boost::locale #endif 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 9888c8925a..744e0452cd 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/encoding/codepage.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/encoding/codepage.cpp @@ -14,185 +14,169 @@ #include "boost/locale/encoding/conv.hpp" #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) -#define BOOST_LOCALE_WITH_WCONV +# define BOOST_LOCALE_WITH_WCONV #endif #ifdef BOOST_LOCALE_WITH_ICONV -#include "boost/locale/encoding/iconv_codepage.ipp" +# include "boost/locale/encoding/iconv_codepage.ipp" #endif #ifdef BOOST_LOCALE_WITH_ICU -#include "boost/locale/encoding/uconv_codepage.ipp" +# include "boost/locale/encoding/uconv_codepage.ipp" #endif #ifdef BOOST_LOCALE_WITH_WCONV -#include "boost/locale/encoding/wconv_codepage.ipp" +# include "boost/locale/encoding/wconv_codepage.ipp" #endif +namespace boost { namespace locale { namespace conv { + namespace impl { -namespace boost { - namespace locale { - namespace conv { - namespace impl { - - std::string convert_between(char const *begin, - char const *end, - char const *to_charset, - char const *from_charset, - method_type how) - { - hold_ptr<converter_between> cvt; - #ifdef BOOST_LOCALE_WITH_ICONV - cvt.reset(new iconv_between()); - if(cvt->open(to_charset,from_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); - #endif - #ifdef BOOST_LOCALE_WITH_WCONV - cvt.reset(new wconv_between()); - 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> convert_to( - char const *begin, - char const *end, - char const *charset, - method_type how) - { - 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); - #endif - #ifdef BOOST_LOCALE_WITH_ICU - cvt.reset(new uconv_to_utf<CharType>()); - if(cvt->open(charset,how)) - return cvt->convert(begin,end); - #endif - #ifdef BOOST_LOCALE_WITH_WCONV - cvt.reset(new wconv_to_utf<CharType>()); - if(cvt->open(charset,how)) - return cvt->convert(begin,end); - #endif - throw invalid_charset_error(charset); - } - - template<typename CharType> - std::string convert_from( - CharType const *begin, - CharType const *end, - char const *charset, - method_type how) - { - 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); - #endif - #ifdef BOOST_LOCALE_WITH_ICU - cvt.reset(new uconv_from_utf<CharType>()); - if(cvt->open(charset,how)) - return cvt->convert(begin,end); - #endif - #ifdef BOOST_LOCALE_WITH_WCONV - cvt.reset(new wconv_from_utf<CharType>()); - if(cvt->open(charset,how)) - return cvt->convert(begin,end); - #endif - throw invalid_charset_error(charset); - } - - std::string normalize_encoding(char const *ccharset) - { - std::string charset; - charset.reserve(std::strlen(ccharset)); - while(*ccharset!=0) { - char c=*ccharset++; - if('0' <= c && c<= '9') - charset+=c; - else if('a' <=c && c <='z') - charset+=c; - else if('A' <=c && c <='Z') - charset+=char(c-'A'+'a'); - } - return charset; - } - - - } // impl - - using namespace impl; - - std::string between(char const *begin,char const *end, - std::string const &to_charset,std::string const &from_charset,method_type how) - { - return convert_between(begin,end,to_charset.c_str(),from_charset.c_str(),how); - } + std::string convert_between(const char* begin, + const char* end, + const char* to_charset, + const char* from_charset, + method_type how) + { + hold_ptr<converter_between> cvt; +#ifdef BOOST_LOCALE_WITH_ICONV + cvt.reset(new iconv_between()); + if(cvt->open(to_charset, from_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); +#endif +#ifdef BOOST_LOCALE_WITH_WCONV + cvt.reset(new wconv_between()); + 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<> - std::basic_string<char> to_utf(char const *begin,char const *end,std::string const &charset,method_type how) - { - return convert_to<char>(begin,end,charset.c_str(),how); - } + template<typename CharType> + std::basic_string<CharType> convert_to(const char* begin, const char* end, const char* charset, method_type how) + { + 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); +#endif +#ifdef BOOST_LOCALE_WITH_ICU + cvt.reset(new uconv_to_utf<CharType>()); + if(cvt->open(charset, how)) + return cvt->convert(begin, end); +#endif +#ifdef BOOST_LOCALE_WITH_WCONV + cvt.reset(new wconv_to_utf<CharType>()); + if(cvt->open(charset, how)) + return cvt->convert(begin, end); +#endif + throw invalid_charset_error(charset); + } - template<> - std::string from_utf(char const *begin,char const *end,std::string const &charset,method_type how) - { - return convert_from<char>(begin,end,charset.c_str(),how); - } + template<typename CharType> + std::string convert_from(const CharType* begin, const CharType* end, const char* charset, method_type how) + { + 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); +#endif +#ifdef BOOST_LOCALE_WITH_ICU + cvt.reset(new uconv_from_utf<CharType>()); + if(cvt->open(charset, how)) + return cvt->convert(begin, end); +#endif +#ifdef BOOST_LOCALE_WITH_WCONV + cvt.reset(new wconv_from_utf<CharType>()); + if(cvt->open(charset, how)) + return cvt->convert(begin, end); +#endif + throw invalid_charset_error(charset); + } - template<> - std::basic_string<wchar_t> to_utf(char const *begin,char const *end,std::string const &charset,method_type how) - { - return convert_to<wchar_t>(begin,end,charset.c_str(),how); + std::string normalize_encoding(const char* ccharset) + { + std::string charset; + charset.reserve(std::strlen(ccharset)); + while(*ccharset != 0) { + char c = *ccharset++; + if('0' <= c && c <= '9') + charset += c; + else if('a' <= c && c <= 'z') + charset += c; + else if('A' <= c && c <= 'Z') + charset += char(c - 'A' + 'a'); } + return charset; + } - template<> - std::string from_utf(wchar_t const *begin,wchar_t const *end,std::string const &charset,method_type how) - { - return convert_from<wchar_t>(begin,end,charset.c_str(),how); - } + } // namespace impl - #ifdef BOOST_LOCALE_ENABLE_CHAR16_T - template<> - std::basic_string<char16_t> to_utf(char const *begin,char const *end,std::string const &charset,method_type how) - { - return convert_to<char16_t>(begin,end,charset.c_str(),how); - } + using namespace impl; - template<> - std::string from_utf(char16_t const *begin,char16_t const *end,std::string const &charset,method_type how) - { - return convert_from<char16_t>(begin,end,charset.c_str(),how); - } - #endif + 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); + } - #ifdef BOOST_LOCALE_ENABLE_CHAR32_T - template<> - std::basic_string<char32_t> to_utf(char const *begin,char const *end,std::string const &charset,method_type how) - { - return convert_to<char32_t>(begin,end,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(char32_t const *begin,char32_t const *end,std::string const &charset,method_type how) - { - return convert_from<char32_t>(begin,end,charset.c_str(),how); - } - #endif + 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); + } - } + 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); + } + +#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); + } +#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); + } +#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 index ddcf9c4de6..bbb287e566 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/encoding/conv.hpp +++ b/contrib/restricted/boost/locale/src/boost/locale/encoding/conv.hpp @@ -9,101 +9,76 @@ #include <boost/locale/config.hpp> #include <boost/locale/encoding.hpp> -namespace boost { - namespace locale { - namespace conv { - namespace impl { - - template<typename CharType> - char const *utf_name() - { - union { - char first; - uint16_t u16; - uint32_t u32; - } v; - - if(sizeof(CharType) == 1) { - return "UTF-8"; - } - else if(sizeof(CharType) == 2) { - v.u16 = 1; - if(v.first == 1) { - return "UTF-16LE"; - } - else { - return "UTF-16BE"; - } - } - else if(sizeof(CharType) == 4) { - v.u32 = 1; - if(v.first == 1) { - return "UTF-32LE"; - } - else { - return "UTF-32BE"; - } - - } - else { - return "Unknown Character Encoding"; - } - } - - std::string normalize_encoding(char const *encoding); - - inline int compare_encodings(char const *l,char const *r) - { - return normalize_encoding(l).compare(normalize_encoding(r)); - } - - #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) - int encoding_to_windows_codepage(char const *ccharset); - #endif - - class converter_between { - public: - typedef char char_type; - - typedef std::string string_type; - - virtual bool open(char const *to_charset,char const *from_charset,method_type how) = 0; - - virtual std::string convert(char const *begin,char const *end) = 0; - - virtual ~converter_between() {} - }; - - template<typename CharType> - class converter_from_utf { - public: - typedef CharType char_type; - - typedef std::basic_string<char_type> string_type; - - virtual bool open(char const *charset,method_type how) = 0; - - virtual std::string convert(CharType const *begin,CharType const *end) = 0; - - virtual ~converter_from_utf() {} - }; - - template<typename CharType> - class converter_to_utf { - public: - typedef CharType char_type; - - typedef std::basic_string<char_type> string_type; - - virtual bool open(char const *charset,method_type how) = 0; - - virtual string_type convert(char const *begin,char const *end) = 0; - - virtual ~converter_to_utf() {} - }; + +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"; + } + + BOOST_LOCALE_DECL std::string normalize_encoding(const char* encoding); + + inline int compare_encodings(const char* l, const char* r) + { + return normalize_encoding(l).compare(normalize_encoding(r)); } -} + +#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) + int encoding_to_windows_codepage(const char* ccharset); +#endif + + 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 index 8e8ead191c..a5f7ab3f00 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/encoding/iconv_codepage.ipp +++ b/contrib/restricted/boost/locale/src/boost/locale/encoding/iconv_codepage.ipp @@ -8,200 +8,168 @@ #define BOOST_LOCALE_IMPL_ICONV_CODEPAGE_HPP #include <boost/locale/encoding.hpp> -#include <cerrno> -#include "boost/locale/util/iconv.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(); - } - - size_t conv(char const **inbufc,size_t *inchar_left, - char **outbuf,size_t *outchar_left) - { - char **inbuf = const_cast<char **>(inbufc); - return call_iconv(cvt_,inbuf,inchar_left,outbuf,outchar_left); - } +namespace boost { namespace locale { namespace conv { namespace impl { - bool do_open(char const *to,char const *from,method_type how) - { - close(); - cvt_ = iconv_open(to,from); - how_ = how; - return cvt_ != (iconv_t)(-1); - } + class iconverter_base { + public: + iconverter_base() : cvt_((iconv_t)(-1)) {} + ~iconverter_base() { close(); } - template<typename OutChar,typename InChar> - std::basic_string<OutChar> real_convert(InChar const *ubegin,InChar const *uend) - { - std::basic_string<OutChar> sresult; + 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); + } - sresult.reserve(uend - ubegin); + template<typename OutChar, typename InChar> + std::basic_string<OutChar> real_convert(const InChar* ubegin, const InChar* uend) + { + std::basic_string<OutChar> sresult; - OutChar result[64]; + sresult.reserve(uend - ubegin); - char *out_start = reinterpret_cast<char *>(&result[0]); - char const *begin = reinterpret_cast<char const *>(ubegin); - char const *end = reinterpret_cast<char const *>(uend); + OutChar result[64]; - enum { normal , unshifting , done } state = normal; + char* out_start = reinterpret_cast<char*>(&result[0]); + const char* begin = reinterpret_cast<const char*>(ubegin); + const char* end = reinterpret_cast<const char*>(uend); - while(state!=done) { + enum { normal, unshifting, done } state = normal; - size_t in_left = end - begin; - size_t out_left = sizeof(result); + 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; + 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); + if(state == normal) + res = conv(&begin, &in_left, &out_ptr, &out_left); + else + res = conv(0, 0, &out_ptr, &out_left); - int err = errno; + int err = errno; - size_t output_count = (out_ptr - out_start) / sizeof(OutChar); + size_t output_count = (out_ptr - out_start) / sizeof(OutChar); - if(res!=0 && res!=(size_t)(-1)) { + if(res != 0 && res != (size_t)(-1)) { if(how_ == stop) { throw conversion_error(); } - } + } - sresult.append(&result[0],output_count); + sresult.append(&result[0], output_count); - if(res == (size_t)(-1)) { - if(err == EILSEQ || err == EINVAL) { - if(how_ == stop) { - throw conversion_error(); - } + 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) + 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; - } - 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; } - if(state == unshifting) - state = done; + return sresult; } - return sresult; - } - - -private: - void close() - { - if(cvt_!=(iconv_t)(-1)) { - iconv_close(cvt_); - cvt_ = (iconv_t)(-1); + private: + void close() + { + if(cvt_ != (iconv_t)(-1)) { + iconv_close(cvt_); + cvt_ = (iconv_t)(-1); + } } - } - - 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(char const *charset,method_type how) BOOST_OVERRIDE - { - return self_.do_open(charset,utf_name<CharType>(),how); - } - - std::string convert(char_type const *ubegin,char_type const *uend) BOOST_OVERRIDE - { - return self_.template real_convert<char,char_type>(ubegin,uend); - } -private: - iconverter_base self_; -}; + 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); + } -class iconv_between: public converter_between -{ -public: - bool open(char const *to_charset,char const *from_charset,method_type how) BOOST_OVERRIDE - { - return self_.do_open(to_charset,from_charset,how); - } - std::string convert(char const *begin,char const *end) BOOST_OVERRIDE - { - return self_.real_convert<char,char>(begin,end); - } -private: - iconverter_base self_; + iconv_t cvt_; + method_type how_; + }; -}; + template<typename CharType> + class iconv_from_utf : public converter_from_utf<CharType> { + public: + typedef CharType char_type; -template<typename CharType> -class iconv_to_utf : public converter_to_utf<CharType> -{ -public: + bool open(const char* charset, method_type how) override + { + return self_.do_open(charset, utf_name<CharType>(), how); + } - typedef CharType char_type; - typedef std::basic_string<char_type> string_type; + std::string convert(const char_type* ubegin, const char_type* uend) override + { + return self_.template real_convert<char, char_type>(ubegin, uend); + } - bool open(char const *charset,method_type how) BOOST_OVERRIDE - { - return self_.do_open(utf_name<CharType>(),charset,how); - } + private: + iconverter_base self_; + }; - string_type convert(char const *begin,char const *end) BOOST_OVERRIDE - { - return self_.template real_convert<char_type,char>(begin,end); - } -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; -} // impl -} // conv -} // locale -} // boost + 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/uconv_codepage.ipp b/contrib/restricted/boost/locale/src/boost/locale/encoding/uconv_codepage.ipp index a9c679e693..1c2b7ed73b 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/encoding/uconv_codepage.ipp +++ b/contrib/restricted/boost/locale/src/boost/locale/encoding/uconv_codepage.ipp @@ -8,16 +8,13 @@ #define BOOST_LOCALE_IMPL_UCONV_CODEPAGE_HPP #include <boost/locale/encoding.hpp> #include <boost/locale/hold_ptr.hpp> -#include <unicode/ucnv.h> -#include <unicode/ucnv_err.h> #include "boost/locale/encoding/conv.hpp" #include "boost/locale/icu/icu_util.hpp" #include "boost/locale/icu/uconv.hpp" +#include <unicode/ucnv.h> +#include <unicode/ucnv_err.h> -namespace boost { -namespace locale { -namespace conv { -namespace impl { +namespace boost { namespace locale { namespace conv { namespace impl { template<typename CharType> class uconv_to_utf : public converter_to_utf<CharType> { public: @@ -25,14 +22,14 @@ namespace impl { typedef std::basic_string<char_type> string_type; - bool open(char const *charset,method_type how) BOOST_OVERRIDE + bool open(const char* charset, method_type how) override { close(); try { - cvt_from_.reset(new from_type(charset,how == skip ? impl_icu::cvt_skip : impl_icu::cvt_stop)); - cvt_to_.reset(new to_type("UTF-8",how == skip ? impl_icu::cvt_skip : impl_icu::cvt_stop)); - } - catch(std::exception const &/*e*/) { + 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(); return false; } @@ -44,39 +41,35 @@ namespace impl { cvt_to_.reset(); } - string_type convert(char const *begin,char const *end) BOOST_OVERRIDE + string_type convert(const char* begin, const char* end) override { try { - return cvt_to_->std(cvt_from_->icu_checked(begin,end)); - } - catch(std::exception const &/*e*/) { + return cvt_to_->std(cvt_from_->icu_checked(begin, end)); + } catch(const std::exception& /*e*/) { throw conversion_error(); } } private: - typedef impl_icu::icu_std_converter<char> from_type; typedef impl_icu::icu_std_converter<CharType> to_type; hold_ptr<from_type> cvt_from_; hold_ptr<to_type> cvt_to_; - }; - template<typename CharType> class uconv_from_utf : public converter_from_utf<CharType> { public: typedef CharType char_type; - bool open(char const *charset,method_type how) BOOST_OVERRIDE + bool open(const char* charset, method_type how) override { close(); try { - cvt_from_.reset(new from_type("UTF-8",how == skip ? impl_icu::cvt_skip : impl_icu::cvt_stop)); - cvt_to_.reset(new to_type(charset,how == skip ? impl_icu::cvt_skip : impl_icu::cvt_stop)); - } - catch(std::exception const &/*e*/) { + 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(); return false; } @@ -88,36 +81,33 @@ namespace impl { cvt_to_.reset(); } - std::string convert(CharType const *begin,CharType const *end) BOOST_OVERRIDE + std::string convert(const CharType* begin, const CharType* end) override { try { - return cvt_to_->std(cvt_from_->icu_checked(begin,end)); - } - catch(std::exception const &/*e*/) { + return cvt_to_->std(cvt_from_->icu_checked(begin, end)); + } catch(const std::exception& /*e*/) { throw conversion_error(); } } private: - typedef impl_icu::icu_std_converter<CharType> from_type; typedef impl_icu::icu_std_converter<char> to_type; hold_ptr<from_type> cvt_from_; hold_ptr<to_type> cvt_to_; - }; class uconv_between : public converter_between { public: - bool open(char const *to_charset,char const *from_charset,method_type how) BOOST_OVERRIDE + bool open(const char* to_charset, const char* from_charset, method_type how) override { close(); try { - cvt_from_.reset(new from_type(from_charset,how == skip ? impl_icu::cvt_skip : impl_icu::cvt_stop)); - cvt_to_.reset(new to_type(to_charset,how == skip ? impl_icu::cvt_skip : impl_icu::cvt_stop)); - } - catch(std::exception const &/*e*/) { + 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(); return false; } @@ -129,31 +119,23 @@ namespace impl { cvt_to_.reset(); } - std::string convert(char const *begin,char const *end) BOOST_OVERRIDE + std::string convert(const char* begin, const char* end) override { try { - return cvt_to_->std(cvt_from_->icu(begin,end)); - } - catch(std::exception const &/*e*/) { + return cvt_to_->std(cvt_from_->icu(begin, end)); + } catch(const std::exception& /*e*/) { throw conversion_error(); } } private: - typedef impl_icu::icu_std_converter<char> from_type; typedef impl_icu::icu_std_converter<char> to_type; hold_ptr<from_type> cvt_from_; hold_ptr<to_type> cvt_to_; - }; - -} // impl -} // conv -} // locale -} // boost - +}}}} // namespace boost::locale::conv::impl #endif diff --git a/contrib/restricted/boost/locale/src/boost/locale/encoding/wconv_codepage.ipp b/contrib/restricted/boost/locale/src/boost/locale/encoding/wconv_codepage.ipp index 0fc23c2893..a099bc6857 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/encoding/wconv_codepage.ipp +++ b/contrib/restricted/boost/locale/src/boost/locale/encoding/wconv_codepage.ipp @@ -15,148 +15,106 @@ #include <string> #include <vector> #ifndef NOMINMAX -# define NOMINMAX +# define NOMINMAX #endif -#include <windows.h> - #include "boost/locale/encoding/conv.hpp" +#include "boost/locale/encoding/win_codepages.hpp" +#include <windows.h> -namespace boost { -namespace locale { -namespace conv { -namespace impl { - - struct windows_encoding { - char const *name; - unsigned codepage; - unsigned was_tested; - }; - - bool operator<(windows_encoding const &l,windows_encoding const &r) - { - return strcmp(l.name,r.name) < 0; - } - - windows_encoding all_windows_encodings[] = { - { "big5", 950, 0 }, - { "cp1250", 1250, 0 }, - { "cp1251", 1251, 0 }, - { "cp1252", 1252, 0 }, - { "cp1253", 1253, 0 }, - { "cp1254", 1254, 0 }, - { "cp1255", 1255, 0 }, - { "cp1256", 1256, 0 }, - { "cp1257", 1257, 0 }, - { "cp874", 874, 0 }, - { "cp932", 932, 0 }, - { "cp936", 936, 0 }, - { "eucjp", 20932, 0 }, - { "euckr", 51949, 0 }, - { "gb18030", 54936, 0 }, - { "gb2312", 20936, 0 }, - { "gbk", 936, 0 }, - { "iso2022jp", 50220, 0 }, - { "iso2022kr", 50225, 0 }, - { "iso88591", 28591, 0 }, - { "iso885913", 28603, 0 }, - { "iso885915", 28605, 0 }, - { "iso88592", 28592, 0 }, - { "iso88593", 28593, 0 }, - { "iso88594", 28594, 0 }, - { "iso88595", 28595, 0 }, - { "iso88596", 28596, 0 }, - { "iso88597", 28597, 0 }, - { "iso88598", 28598, 0 }, - { "iso88599", 28599, 0 }, - { "koi8r", 20866, 0 }, - { "koi8u", 21866, 0 }, - { "ms936", 936, 0 }, - { "shiftjis", 932, 0 }, - { "sjis", 932, 0 }, - { "usascii", 20127, 0 }, - { "utf8", 65001, 0 }, - { "windows1250", 1250, 0 }, - { "windows1251", 1251, 0 }, - { "windows1252", 1252, 0 }, - { "windows1253", 1253, 0 }, - { "windows1254", 1254, 0 }, - { "windows1255", 1255, 0 }, - { "windows1256", 1256, 0 }, - { "windows1257", 1257, 0 }, - { "windows874", 874, 0 }, - { "windows932", 932, 0 }, - { "windows936", 936, 0 }, - }; +namespace boost { namespace locale { namespace conv { namespace impl { - size_t remove_substitutions(std::vector<char> &v) + size_t remove_substitutions(std::vector<char>& v) { - if(std::find(v.begin(),v.end(),0) == v.end()) { + 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) + 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,char const *begin,char const *end,std::vector<wchar_t> &buf) + void multibyte_to_wide_one_by_one(int codepage, const char* begin, const char* end, std::vector<wchar_t>& buf) { - buf.reserve(end-begin); - while(begin!=end) { + buf.reserve(end - begin); + DWORD flags = MB_ERR_INVALID_CHARS; + while(begin != end) { wchar_t wide_buf[4]; int n = 0; - int len = IsDBCSLeadByteEx(codepage,*begin) ? 2 : 1; - if(len == 2 && begin+1==end) + int len = IsDBCSLeadByteEx(codepage, *begin) ? 2 : 1; + if(len == 2 && begin + 1 == end) return; - n = MultiByteToWideChar(codepage,MB_ERR_INVALID_CHARS,begin,len,wide_buf,4); - for(int i=0;i<n;i++) + n = MultiByteToWideChar(codepage, flags, begin, len, wide_buf, 4); + if(n == 0 && flags != 0 && GetLastError() == ERROR_INVALID_FLAGS) { + flags = 0; + n = MultiByteToWideChar(codepage, flags, begin, len, wide_buf, 4); + } + for(int i = 0; i < n; i++) buf.push_back(wide_buf[i]); - begin+=len; + begin += len; } } - - void multibyte_to_wide(int codepage,char const *begin,char const *end,bool do_skip,std::vector<wchar_t> &buf) + void multibyte_to_wide(int codepage, const char* begin, const char* end, bool do_skip, std::vector<wchar_t>& buf) { - if(begin==end) + if(begin == end) return; - const std::ptrdiff_t num_chars = end-begin; + const std::ptrdiff_t num_chars = end - begin; if(num_chars > std::numeric_limits<int>::max()) throw conversion_error(); - int n = MultiByteToWideChar(codepage,MB_ERR_INVALID_CHARS,begin,static_cast<int>(num_chars),0,0); + DWORD flags = MB_ERR_INVALID_CHARS; + int n = MultiByteToWideChar(codepage, flags, begin, static_cast<int>(num_chars), 0, 0); + if(n == 0 && GetLastError() == ERROR_INVALID_FLAGS) { + flags = 0; + n = MultiByteToWideChar(codepage, flags, begin, static_cast<int>(num_chars), 0, 0); + } + if(n == 0) { if(do_skip) { - multibyte_to_wide_one_by_one(codepage,begin,end,buf); + multibyte_to_wide_one_by_one(codepage, begin, end, buf); return; } throw conversion_error(); } buf.resize(n); - if(MultiByteToWideChar(codepage,MB_ERR_INVALID_CHARS,begin,static_cast<int>(num_chars),&buf.front(),n)==0) + if(MultiByteToWideChar(codepage, flags, begin, static_cast<int>(num_chars), &buf.front(), n) == 0) throw conversion_error(); } - void wide_to_multibyte_non_zero(int codepage,wchar_t const *begin,wchar_t const *end,bool do_skip,std::vector<char> &buf) + void wide_to_multibyte_non_zero(int codepage, + const wchar_t* begin, + const wchar_t* end, + bool do_skip, + std::vector<char>& buf) { - if(begin==end) + if(begin == end) return; BOOL substitute = FALSE; - BOOL *substitute_ptr = codepage == 65001 || codepage == 65000 ? 0 : &substitute; + BOOL* substitute_ptr = codepage == 65001 || codepage == 65000 ? 0 : &substitute; char subst_char = 0; - char *subst_char_ptr = codepage == 65001 || codepage == 65000 ? 0 : &subst_char; + char* subst_char_ptr = codepage == 65001 || codepage == 65000 ? 0 : &subst_char; const std::ptrdiff_t num_chars = end - begin; if(num_chars > 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); + int n = + WideCharToMultiByte(codepage, 0, begin, static_cast<int>(num_chars), 0, 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, + static_cast<int>(num_chars), + &buf[0], + n, + subst_char_ptr, + substitute_ptr) + == 0) throw conversion_error(); if(substitute) { if(do_skip) @@ -166,104 +124,90 @@ namespace impl { } } - void wide_to_multibyte(int codepage,wchar_t const *begin,wchar_t const *end,bool do_skip,std::vector<char> &buf) + void wide_to_multibyte(int codepage, const wchar_t* begin, const wchar_t* end, bool do_skip, std::vector<char>& buf) { - if(begin==end) + if(begin == end) return; - buf.reserve(end-begin); - wchar_t const *e = std::find(begin,end,L'\0'); - wchar_t const *b = begin; + buf.reserve(end - begin); + const wchar_t* e = std::find(begin, end, L'\0'); + const wchar_t* b = begin; for(;;) { std::vector<char> tmp; - wide_to_multibyte_non_zero(codepage,b,e,do_skip,tmp); + wide_to_multibyte_non_zero(codepage, b, e, do_skip, tmp); size_t osize = buf.size(); - buf.resize(osize+tmp.size()); - std::copy(tmp.begin(),tmp.end(),buf.begin()+osize); - if(e!=end) { + 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 + b = e + 1; + e = std::find(b, end, L'0'); + } else break; } } - - int encoding_to_windows_codepage(char const *ccharset) + int encoding_to_windows_codepage(const char* ccharset) { - std::string charset = normalize_encoding(ccharset); - windows_encoding ref; - ref.name = charset.c_str(); - 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 *ptr = std::lower_bound(begin,end,ref); - if(ptr!=end && strcmp(ptr->name,charset.c_str())==0) { - if(ptr->was_tested) { + 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; + + const std::string charset = normalize_encoding(ccharset); + windows_encoding* ptr = std::lower_bound(begin, end, charset.c_str()); + while(ptr != end && strcmp(ptr->name, charset.c_str()) == 0) { + if(ptr->was_tested) return ptr->codepage; - } else if(IsValidCodePage(ptr->codepage)) { // the thread safety is not an issue, maximum // it would be checked more then once - ptr->was_tested=1; + ptr->was_tested = 1; return ptr->codepage; - } - else { - return -1; - } + } else + ++ptr; } return -1; - } template<typename CharType> - bool validate_utf16(CharType const *str,size_t len) + bool validate_utf16(const CharType* str, size_t len) { - CharType const *begin = str; - CharType const *end = str+len; - while(begin!=end) { - utf::code_point c = utf::utf_traits<CharType,2>::template decode<CharType const *>(begin,end); - if(c==utf::illegal || c==utf::incomplete) + 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); + if(c == utf::illegal || c == utf::incomplete) return false; } return true; } - template<typename CharType,typename OutChar> - void clean_invalid_utf16(CharType const *str,size_t len,std::vector<OutChar> &out) + template<typename CharType, typename OutChar> + void clean_invalid_utf16(const CharType* str, size_t len, std::vector<OutChar>& out) { out.reserve(len); - for(size_t i=0;i<len;i++) { + for(size_t i = 0; i < len; i++) { uint16_t c = static_cast<uint16_t>(str[i]); - if(0xD800 <= c && c<= 0xDBFF) { + if(0xD800 <= c && c <= 0xDBFF) { i++; - if(i>=len) + if(i >= len) return; - uint16_t c2=static_cast<uint16_t>(str[i]); + uint16_t c2 = static_cast<uint16_t>(str[i]); if(0xDC00 <= c2 && c2 <= 0xDFFF) { out.push_back(static_cast<OutChar>(c)); out.push_back(static_cast<OutChar>(c2)); } - } - else if(0xDC00 <= c && c <=0xDFFF) + } else if(0xDC00 <= c && c <= 0xDFFF) continue; else out.push_back(static_cast<OutChar>(c)); } } - class wconv_between : public converter_between { public: - wconv_between() : - how_(skip), - to_code_page_ (-1), - from_code_page_ ( -1) - { - } - bool open(char const *to_charset,char const *from_charset,method_type how) BOOST_OVERRIDE + 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 { how_ = how; to_code_page_ = encoding_to_windows_codepage(to_charset); @@ -272,27 +216,26 @@ namespace impl { return false; return true; } - std::string convert(char const *begin,char const *end) BOOST_OVERRIDE + std::string convert(const char* begin, const char* end) override { if(to_code_page_ == 65001 && from_code_page_ == 65001) - return utf_to_utf<char>(begin,end,how_); + 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 - wchar_t const *wbegin=0; - wchar_t const *wend=0; + 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; if(from_code_page_ == 65001) { - tmps = utf_to_utf<wchar_t>(begin,end,how_); + tmps = utf_to_utf<wchar_t>(begin, end, how_); if(tmps.empty()) return res; wbegin = tmps.c_str(); wend = wbegin + tmps.size(); - } - else { - multibyte_to_wide(from_code_page_,begin,end,how_ == skip,tmp); + } else { + multibyte_to_wide(from_code_page_, begin, end, how_ == skip, tmp); if(tmp.empty()) return res; wbegin = &tmp[0]; @@ -300,56 +243,47 @@ namespace impl { } if(to_code_page_ == 65001) { - return utf_to_utf<char>(wbegin,wend,how_); + return utf_to_utf<char>(wbegin, wend, how_); } std::vector<char> ctmp; - wide_to_multibyte(to_code_page_,wbegin,wend,how_ == skip,ctmp); + 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.front(), ctmp.size()); return res; } + private: method_type how_; int to_code_page_; int from_code_page_; }; - template<typename CharType, int size = sizeof(CharType) > + template<typename CharType, int size = sizeof(CharType)> class wconv_to_utf; - template<typename CharType, int size = sizeof(CharType) > + template<typename CharType, int size = sizeof(CharType)> class wconv_from_utf; template<> class wconv_to_utf<char, 1> : public converter_to_utf<char> { public: - bool open(char const *cs,method_type how) BOOST_OVERRIDE - { - return cvt.open("UTF-8",cs,how); - } - std::string convert(char const *begin,char const *end) BOOST_OVERRIDE - { - return cvt.convert(begin,end); - } + bool open(const char* cs, method_type how) override { return cvt.open("UTF-8", cs, how); } + std::string convert(const char* begin, const char* end) override { return cvt.convert(begin, end); } + private: - wconv_between cvt; + wconv_between cvt; }; template<> class wconv_from_utf<char, 1> : public converter_from_utf<char> { public: - bool open(char const *cs,method_type how) BOOST_OVERRIDE - { - return cvt.open(cs,"UTF-8",how); - } - std::string convert(char const *begin,char const *end) BOOST_OVERRIDE - { - return cvt.convert(begin,end); - } + bool open(const char* cs, method_type how) override { return cvt.open(cs, "UTF-8", how); } + std::string convert(const char* begin, const char* end) override { return cvt.convert(begin, end); } + private: - wconv_between cvt; + wconv_between cvt; }; template<typename CharType> @@ -359,29 +293,25 @@ namespace impl { typedef std::basic_string<char_type> string_type; - wconv_to_utf() : - how_(skip), - code_page_(-1) - { - } + wconv_to_utf() : how_(skip), code_page_(-1) {} - bool open(char const *charset,method_type how) BOOST_OVERRIDE + bool open(const char* charset, method_type how) override { how_ = how; code_page_ = encoding_to_windows_codepage(charset); return code_page_ != -1; } - string_type convert(char const *begin,char const *end) BOOST_OVERRIDE + string_type convert(const char* begin, const char* end) override { if(code_page_ == 65001) { - return utf_to_utf<char_type>(begin,end,how_); + return utf_to_utf<char_type>(begin, end, how_); } std::vector<wchar_t> tmp; - multibyte_to_wide(code_page_,begin,end,how_ == skip,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()); + res.assign(reinterpret_cast<char_type*>(&tmp.front()), tmp.size()); return res; } @@ -397,39 +327,33 @@ namespace impl { typedef std::basic_string<char_type> string_type; - wconv_from_utf() : - how_(skip), - code_page_(-1) - { - } + wconv_from_utf() : how_(skip), code_page_(-1) {} - bool open(char const *charset,method_type how) BOOST_OVERRIDE + bool open(const char* charset, method_type how) override { how_ = how; code_page_ = encoding_to_windows_codepage(charset); return code_page_ != -1; } - std::string convert(CharType const *begin,CharType const *end) BOOST_OVERRIDE + std::string convert(const CharType* begin, const CharType* end) override { if(code_page_ == 65001) { - return utf_to_utf<char>(begin,end,how_); + return utf_to_utf<char>(begin, end, how_); } - wchar_t const *wbegin = 0; - wchar_t const *wend = 0; + const wchar_t* wbegin = 0; + const wchar_t* wend = 0; std::vector<wchar_t> buffer; // if needed - if(begin==end) + if(begin == end) return std::string(); - if(validate_utf16(begin,end-begin)) { - wbegin = reinterpret_cast<wchar_t const *>(begin); - wend = reinterpret_cast<wchar_t const *>(end); - } - else { + if(validate_utf16(begin, end - begin)) { + wbegin = reinterpret_cast<const wchar_t*>(begin); + wend = reinterpret_cast<const wchar_t*>(end); + } else { if(how_ == stop) { - throw conversion_error(); - } - else { - clean_invalid_utf16(begin,end-begin,buffer); + throw conversion_error(); + } else { + clean_invalid_utf16(begin, end - begin, buffer); if(!buffer.empty()) { wbegin = &buffer[0]; wend = wbegin + buffer.size(); @@ -437,13 +361,13 @@ namespace impl { } } std::string res; - if(wbegin==wend) + if(wbegin == wend) return res; std::vector<char> ctmp; - wide_to_multibyte(code_page_,wbegin,wend,how_ == skip,ctmp); + wide_to_multibyte(code_page_, wbegin, wend, how_ == skip, ctmp); if(ctmp.empty()) return res; - res.assign(&ctmp.front(),ctmp.size()); + res.assign(&ctmp.front(), ctmp.size()); return res; } @@ -452,81 +376,71 @@ namespace impl { int code_page_; }; - - template<typename CharType> - class wconv_to_utf<CharType,4> : public converter_to_utf<CharType> { + class wconv_to_utf<CharType, 4> : public converter_to_utf<CharType> { public: typedef CharType char_type; typedef std::basic_string<char_type> string_type; - wconv_to_utf() : - how_(skip), - code_page_(-1) - { - } + wconv_to_utf() : how_(skip), code_page_(-1) {} - bool open(char const *charset,method_type how) BOOST_OVERRIDE + bool open(const char* charset, method_type how) override { how_ = how; code_page_ = encoding_to_windows_codepage(charset); return code_page_ != -1; } - string_type convert(char const *begin,char const *end) BOOST_OVERRIDE + string_type convert(const char* begin, const char* end) override { if(code_page_ == 65001) { - return utf_to_utf<char_type>(begin,end,how_); + return utf_to_utf<char_type>(begin, end, how_); } std::vector<wchar_t> buf; - multibyte_to_wide(code_page_,begin,end,how_ == skip,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[0], &buf[0] + buf.size(), how_); } + private: method_type how_; int code_page_; }; template<typename CharType> - class wconv_from_utf<CharType,4> : public converter_from_utf<CharType> { + class wconv_from_utf<CharType, 4> : public converter_from_utf<CharType> { public: typedef CharType char_type; typedef std::basic_string<char_type> string_type; - wconv_from_utf() : - how_(skip), - code_page_(-1) - { - } + wconv_from_utf() : how_(skip), code_page_(-1) {} - bool open(char const *charset,method_type how) BOOST_OVERRIDE + bool open(const char* charset, method_type how) override { how_ = how; code_page_ = encoding_to_windows_codepage(charset); return code_page_ != -1; } - std::string convert(CharType const *begin,CharType const *end) BOOST_OVERRIDE + std::string convert(const CharType* begin, const CharType* end) override { if(code_page_ == 65001) { - return utf_to_utf<char>(begin,end,how_); + return utf_to_utf<char>(begin, end, how_); } - std::wstring tmp = utf_to_utf<wchar_t>(begin,end,how_); + std::wstring tmp = utf_to_utf<wchar_t>(begin, end, how_); std::vector<char> ctmp; - wide_to_multibyte(code_page_,tmp.c_str(),tmp.c_str()+tmp.size(),how_ == skip,ctmp); + wide_to_multibyte(code_page_, tmp.c_str(), tmp.c_str() + tmp.size(), how_ == skip, ctmp); std::string res; if(ctmp.empty()) return res; - res.assign(&ctmp.front(),ctmp.size()); + res.assign(&ctmp.front(), ctmp.size()); return res; - } private: @@ -534,14 +448,7 @@ namespace impl { int code_page_; }; +}}}} // namespace boost::locale::conv::impl - - - -} // impl -} // conv -} // locale -} // boost - -#endif // boostinspect:nominmax +#endif diff --git a/contrib/restricted/boost/locale/src/boost/locale/encoding/win_codepages.hpp b/contrib/restricted/boost/locale/src/boost/locale/encoding/win_codepages.hpp new file mode 100644 index 0000000000..8dd4bfe3b7 --- /dev/null +++ b/contrib/restricted/boost/locale/src/boost/locale/encoding/win_codepages.hpp @@ -0,0 +1,182 @@ +#ifndef BOOST_LOCALE_IMPL_WIN_CODEPAGES_HPP +#define BOOST_LOCALE_IMPL_WIN_CODEPAGES_HPP + +#include <boost/locale/config.hpp> +#include <cstring> +#include <string> + +namespace boost { namespace locale { namespace conv { namespace impl { + + struct windows_encoding { + const char* name; + unsigned codepage; + unsigned was_tested; + }; + + inline bool operator<(const windows_encoding& l, const char* name) + { + return strcmp(l.name, name) < 0; + } + + static windows_encoding all_windows_encodings[] = { + {"asmo708", 708, 0}, + {"big5", 950, 0}, + {"cp1025", 21025, 0}, + {"cp1250", 1250, 0}, + {"cp1251", 1251, 0}, + {"cp1252", 1252, 0}, + {"cp1253", 1253, 0}, + {"cp1254", 1254, 0}, + {"cp1255", 1255, 0}, + {"cp1256", 1256, 0}, + {"cp1257", 1257, 0}, + {"cp866", 866, 0}, + {"cp874", 874, 0}, + {"cp875", 875, 0}, + {"cp932", 932, 0}, + {"cp936", 936, 0}, + {"csiso2022jp", 50221, 0}, + {"dos720", 720, 0}, + {"dos862", 862, 0}, + {"euccn", 51936, 0}, + {"eucjp", 20932, 0}, + {"euckr", 51949, 0}, + {"gb18030", 54936, 0}, + {"gb2312", 936, 0}, + {"gbk", 936, 0}, + {"hzgb2312", 52936, 0}, + {"ibm00858", 858, 0}, + {"ibm00924", 20924, 0}, + {"ibm01026", 1026, 0}, + {"ibm01047", 1047, 0}, + {"ibm01140", 1140, 0}, + {"ibm01141", 1141, 0}, + {"ibm01142", 1142, 0}, + {"ibm01143", 1143, 0}, + {"ibm01144", 1144, 0}, + {"ibm01145", 1145, 0}, + {"ibm01146", 1146, 0}, + {"ibm01147", 1147, 0}, + {"ibm01148", 1148, 0}, + {"ibm01149", 1149, 0}, + {"ibm037", 37, 0}, + {"ibm273", 20273, 0}, + {"ibm277", 20277, 0}, + {"ibm278", 20278, 0}, + {"ibm280", 20280, 0}, + {"ibm284", 20284, 0}, + {"ibm285", 20285, 0}, + {"ibm290", 20290, 0}, + {"ibm297", 20297, 0}, + {"ibm420", 20420, 0}, + {"ibm423", 20423, 0}, + {"ibm424", 20424, 0}, + {"ibm437", 437, 0}, + {"ibm500", 500, 0}, + {"ibm737", 737, 0}, + {"ibm775", 775, 0}, + {"ibm850", 850, 0}, + {"ibm852", 852, 0}, + {"ibm855", 855, 0}, + {"ibm857", 857, 0}, + {"ibm860", 860, 0}, + {"ibm861", 861, 0}, + {"ibm863", 863, 0}, + {"ibm864", 864, 0}, + {"ibm865", 865, 0}, + {"ibm869", 869, 0}, + {"ibm870", 870, 0}, + {"ibm871", 20871, 0}, + {"ibm880", 20880, 0}, + {"ibm905", 20905, 0}, + {"ibmthai", 20838, 0}, + {"iso2022jp", 50220, 0}, + {"iso2022jp", 50222, 0}, + {"iso2022kr", 50225, 0}, + {"iso88591", 28591, 0}, + {"iso885913", 28603, 0}, + {"iso885915", 28605, 0}, + {"iso88592", 28592, 0}, + {"iso88593", 28593, 0}, + {"iso88594", 28594, 0}, + {"iso88595", 28595, 0}, + {"iso88596", 28596, 0}, + {"iso88597", 28597, 0}, + {"iso88598", 28598, 0}, + {"iso88598i", 38598, 0}, + {"iso88599", 28599, 0}, + {"johab", 1361, 0}, + {"koi8r", 20866, 0}, + {"koi8u", 21866, 0}, + {"ksc56011987", 949, 0}, + {"latin1", 28591, 0}, + {"latin1", 1252, 0}, + {"macintosh", 10000, 0}, + {"ms936", 936, 0}, + {"shiftjis", 932, 0}, + {"sjis", 932, 0}, + {"unicodefffe", 1201, 0}, + {"usascii", 20127, 0}, + {"utf16", 1200, 0}, + {"utf32", 12000, 0}, + {"utf32be", 12001, 0}, + {"utf7", 65000, 0}, + {"utf8", 65001, 0}, + {"windows1250", 1250, 0}, + {"windows1251", 1251, 0}, + {"windows1252", 1252, 0}, + {"windows1253", 1253, 0}, + {"windows1254", 1254, 0}, + {"windows1255", 1255, 0}, + {"windows1256", 1256, 0}, + {"windows1257", 1257, 0}, + {"windows1258", 1258, 0}, + {"windows874", 874, 0}, + {"windows932", 932, 0}, + {"windows936", 936, 0}, + {"xchinesecns", 20000, 0}, + {"xchineseeten", 20002, 0}, + {"xcp20001", 20001, 0}, + {"xcp20003", 20003, 0}, + {"xcp20004", 20004, 0}, + {"xcp20005", 20005, 0}, + {"xcp20261", 20261, 0}, + {"xcp20269", 20269, 0}, + {"xcp20936", 20936, 0}, + {"xcp20949", 20949, 0}, + {"xcp50227", 50227, 0}, + {"xebcdickoreanextended", 20833, 0}, + {"xeuropa", 29001, 0}, + {"xia5", 20105, 0}, + {"xia5german", 20106, 0}, + {"xia5norwegian", 20108, 0}, + {"xia5swedish", 20107, 0}, + {"xisciias", 57006, 0}, + {"xisciibe", 57003, 0}, + {"xisciide", 57002, 0}, + {"xisciigu", 57010, 0}, + {"xisciika", 57008, 0}, + {"xisciima", 57009, 0}, + {"xisciior", 57007, 0}, + {"xisciipa", 57011, 0}, + {"xisciita", 57004, 0}, + {"xisciite", 57005, 0}, + {"xmacarabic", 10004, 0}, + {"xmacce", 10029, 0}, + {"xmacchinesesimp", 10008, 0}, + {"xmacchinesetrad", 10002, 0}, + {"xmaccroatian", 10082, 0}, + {"xmaccyrillic", 10007, 0}, + {"xmacgreek", 10006, 0}, + {"xmachebrew", 10005, 0}, + {"xmacicelandic", 10079, 0}, + {"xmacjapanese", 10001, 0}, + {"xmackorean", 10003, 0}, + {"xmacromanian", 10010, 0}, + {"xmacthai", 10021, 0}, + {"xmacturkish", 10081, 0}, + {"xmacukrainian", 10017, 0}, + }; +}}}} // namespace boost::locale::conv::impl + +#endif
\ No newline at end of file diff --git a/contrib/restricted/boost/locale/src/boost/locale/icu/all_generator.hpp b/contrib/restricted/boost/locale/src/boost/locale/icu/all_generator.hpp index 6b4542cf53..d1e2279b86 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/icu/all_generator.hpp +++ b/contrib/restricted/boost/locale/src/boost/locale/icu/all_generator.hpp @@ -9,20 +9,16 @@ #include <boost/locale/generator.hpp> -namespace boost { - namespace locale { - namespace impl_icu { - struct cdata; - std::locale create_convert(std::locale const &,cdata const &,character_facet_type); // ok - std::locale create_collate(std::locale const &,cdata const &,character_facet_type); // ok - std::locale create_formatting(std::locale const &,cdata const &,character_facet_type); // ok - std::locale create_parsing(std::locale const &,cdata const &,character_facet_type); // ok - std::locale create_codecvt(std::locale const &,std::string const &encoding,character_facet_type); // ok - std::locale create_boundary(std::locale const &,cdata const &,character_facet_type); // ok - std::locale create_calendar(std::locale const &,cdata const &); // ok +namespace boost { namespace locale { namespace impl_icu { + struct cdata; + std::locale create_convert(const std::locale&, const cdata&, char_facet_t); // ok + std::locale create_collate(const std::locale&, const cdata&, char_facet_t); // ok + std::locale create_formatting(const std::locale&, const cdata&, char_facet_t); // ok + std::locale create_parsing(const std::locale&, const cdata&, char_facet_t); // ok + std::locale create_codecvt(const std::locale&, const std::string& encoding, char_facet_t); // ok + std::locale create_boundary(const std::locale&, const cdata&, char_facet_t); // ok + std::locale create_calendar(const std::locale&, const cdata&); // ok - } - } -} +}}} // namespace boost::locale::impl_icu #endif 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 e3aaf83c3b..11d0de8a1d 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/icu/boundary.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/icu/boundary.cpp @@ -1,5 +1,6 @@ // // Copyright (c) 2009-2011 Artyom Beilis (Tonkikh) +// Copyright (c) 2021-2022 Alexander Grund // // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt @@ -7,229 +8,206 @@ #define BOOST_LOCALE_SOURCE #include <boost/locale/boundary.hpp> #include <boost/locale/generator.hpp> -#include <boost/locale/hold_ptr.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 <unicode/utext.h> +# include <unicode/utext.h> #endif +#include <memory> #include <unicode/brkiter.h> #include <unicode/rbbi.h> #include <vector> #ifdef BOOST_MSVC -#pragma warning(disable:4244) // 'argument' : conversion from 'int' -#pragma warning(disable:4267) // 'argument' : conversion from 'size_t' +# pragma warning(disable : 4244) // 'argument' : conversion from 'int' +# pragma warning(disable : 4267) // 'argument' : conversion from 'size_t' #endif -namespace boost { -namespace locale { -namespace boundary { -namespace impl_icu { +namespace boost { namespace locale { + namespace boundary { namespace impl_icu { -using namespace boost::locale::impl_icu; + using namespace boost::locale::impl_icu; -index_type map_direct(boundary_type t,icu::BreakIterator *it,int reserve) -{ - index_type indx; - indx.reserve(reserve); + index_type map_direct(boundary_type t, icu::BreakIterator* it, int reserve) + { + index_type indx; + indx.reserve(reserve); #if U_ICU_VERSION_MAJOR_NUM >= 52 - icu::BreakIterator *rbbi=it; + icu::BreakIterator* rbbi = it; #else - icu::RuleBasedBreakIterator *rbbi=dynamic_cast<icu::RuleBasedBreakIterator *>(it); + icu::RuleBasedBreakIterator* rbbi = icu_cast<icu::RuleBasedBreakIterator>(it); #endif - indx.push_back(break_info()); - it->first(); - int pos=0; - while((pos=it->next())!=icu::BreakIterator::DONE) { - indx.push_back(break_info(pos)); - /// 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; - - UErrorCode err=U_ZERO_ERROR; - int n = rbbi->getRuleStatusVec(buf,8,err); - - if(err == U_BUFFER_OVERFLOW_ERROR) { - buf=&buffer.front(); - buffer.resize(n,0); - n = rbbi->getRuleStatusVec(buf,buffer.size(),err); - } - - check_and_throw_icu_error(err); - - for(int i=0;i<n;i++) { - switch(t) { - case word: - if(UBRK_WORD_NONE<=buf[i] && buf[i]<UBRK_WORD_NONE_LIMIT) - indx.back().rule |= word_none; - else if(UBRK_WORD_NUMBER<=buf[i] && buf[i]<UBRK_WORD_NUMBER_LIMIT) - indx.back().rule |= word_number; - else if(UBRK_WORD_LETTER<=buf[i] && buf[i]<UBRK_WORD_LETTER_LIMIT) - indx.back().rule |= word_letter; - else if(UBRK_WORD_KANA<=buf[i] && buf[i]<UBRK_WORD_KANA_LIMIT) - indx.back().rule |= word_kana; - else if(UBRK_WORD_IDEO<=buf[i] && buf[i]<UBRK_WORD_IDEO_LIMIT) - indx.back().rule |= word_ideo; - break; - - case line: - if(UBRK_LINE_SOFT<=buf[i] && buf[i]<UBRK_LINE_SOFT_LIMIT) - indx.back().rule |= line_soft; - else if(UBRK_LINE_HARD<=buf[i] && buf[i]<UBRK_LINE_HARD_LIMIT) - indx.back().rule |= line_hard; - break; - - case sentence: - if(UBRK_SENTENCE_TERM<=buf[i] && buf[i]<UBRK_SENTENCE_TERM_LIMIT) - indx.back().rule |= sentence_term; - else if(UBRK_SENTENCE_SEP<=buf[i] && buf[i]<UBRK_SENTENCE_SEP_LIMIT) - indx.back().rule |= sentence_sep; - break; - default: - ; + indx.push_back(break_info()); + it->first(); + int pos = 0; + while((pos = it->next()) != icu::BreakIterator::DONE) { + indx.push_back(break_info(pos)); + /// 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; + + UErrorCode err = U_ZERO_ERROR; + int n = rbbi->getRuleStatusVec(buf, 8, err); + + if(err == U_BUFFER_OVERFLOW_ERROR) { + buf = &buffer.front(); + buffer.resize(n, 0); + n = rbbi->getRuleStatusVec(buf, buffer.size(), err); + } + + check_and_throw_icu_error(err); + + for(int i = 0; i < n; i++) { + switch(t) { + case word: + if(UBRK_WORD_NONE <= buf[i] && buf[i] < UBRK_WORD_NONE_LIMIT) + indx.back().rule |= word_none; + else if(UBRK_WORD_NUMBER <= buf[i] && buf[i] < UBRK_WORD_NUMBER_LIMIT) + indx.back().rule |= word_number; + else if(UBRK_WORD_LETTER <= buf[i] && buf[i] < UBRK_WORD_LETTER_LIMIT) + indx.back().rule |= word_letter; + else if(UBRK_WORD_KANA <= buf[i] && buf[i] < UBRK_WORD_KANA_LIMIT) + indx.back().rule |= word_kana; + else if(UBRK_WORD_IDEO <= buf[i] && buf[i] < UBRK_WORD_IDEO_LIMIT) + indx.back().rule |= word_ideo; + break; + + case line: + if(UBRK_LINE_SOFT <= buf[i] && buf[i] < UBRK_LINE_SOFT_LIMIT) + indx.back().rule |= line_soft; + else if(UBRK_LINE_HARD <= buf[i] && buf[i] < UBRK_LINE_HARD_LIMIT) + indx.back().rule |= line_hard; + break; + + case sentence: + if(UBRK_SENTENCE_TERM <= buf[i] && buf[i] < UBRK_SENTENCE_TERM_LIMIT) + indx.back().rule |= sentence_term; + else if(UBRK_SENTENCE_SEP <= buf[i] && buf[i] < UBRK_SENTENCE_SEP_LIMIT) + indx.back().rule |= sentence_sep; + break; + case character: BOOST_UNREACHABLE_RETURN(0); + } + } + } else { + indx.back().rule |= character_any; // Baisc mark... for character } } + return indx; } - else { - indx.back().rule |=character_any; // Baisc mark... for character + + std::unique_ptr<icu::BreakIterator> get_iterator(boundary_type t, const icu::Locale& loc) + { + UErrorCode err = U_ZERO_ERROR; + std::unique_ptr<icu::BreakIterator> bi; + switch(t) { + case character: bi.reset(icu::BreakIterator::createCharacterInstance(loc, err)); break; + case word: bi.reset(icu::BreakIterator::createWordInstance(loc, err)); break; + case sentence: bi.reset(icu::BreakIterator::createSentenceInstance(loc, err)); break; + case line: bi.reset(icu::BreakIterator::createLineInstance(loc, err)); break; + } + check_and_throw_icu_error(err); + if(!bi) + throw std::runtime_error("Failed to create break iterator"); + return bi; } - } - return indx; -} - -icu::BreakIterator *get_iterator(boundary_type t,icu::Locale const &loc) -{ - UErrorCode err=U_ZERO_ERROR; - hold_ptr<icu::BreakIterator> bi; - switch(t) { - case character: - bi.reset(icu::BreakIterator::createCharacterInstance(loc,err)); - break; - case word: - bi.reset(icu::BreakIterator::createWordInstance(loc,err)); - break; - case sentence: - bi.reset(icu::BreakIterator::createSentenceInstance(loc,err)); - break; - case line: - bi.reset(icu::BreakIterator::createLineInstance(loc,err)); - break; - default: - throw std::runtime_error("Invalid iteration type"); - } - check_and_throw_icu_error(err); - if(!bi.get()) - throw std::runtime_error("Failed to create break iterator"); - return bi.release(); -} - - -template<typename CharType> -index_type do_map(boundary_type t,CharType const *begin,CharType const *end,icu::Locale const &loc,std::string const &encoding) -{ - index_type indx; - hold_ptr<icu::BreakIterator> bi(get_iterator(t,loc)); + + template<typename CharType> + index_type do_map(boundary_type t, + const CharType* begin, + const CharType* end, + 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 - UErrorCode err=U_ZERO_ERROR; -BOOST_LOCALE_START_CONST_CONDITION - if(sizeof(CharType) == 2 || (sizeof(CharType)==1 && encoding=="UTF-8")) - { - UText *ut=0; - try { - if(sizeof(CharType)==1) - ut=utext_openUTF8(0,reinterpret_cast<char const *>(begin),end-begin,&err); - else // sizeof(CharType)==2 - ut=utext_openUChars(0,reinterpret_cast<UChar const *>(begin),end-begin,&err); -BOOST_LOCALE_END_CONST_CONDITION + UErrorCode err = U_ZERO_ERROR; + BOOST_LOCALE_START_CONST_CONDITION + if(sizeof(CharType) == 2 || (sizeof(CharType) == 1 && encoding == "UTF-8")) { + 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; + } + if(ut) + utext_close(ut); + } else +#endif + { + icu_std_converter<CharType> cvt(encoding); + icu::UnicodeString str = cvt.icu(begin, end); + bi->setText(str); + index_type indirect = map_direct(t, bi.get(), str.length()); + 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); + } + } + return indx; + } // do_map + + template<typename CharType> + class boundary_indexing_impl : public boundary_indexing<CharType> { + public: + boundary_indexing_impl(const cdata& data) : locale_(data.locale), encoding_(data.encoding) {} + index_type map(boundary_type t, const CharType* begin, const CharType* end) const + { + return do_map<CharType>(t, begin, end, locale_, encoding_); + } - 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; - } - if(ut) utext_close(ut); - } - else + private: + icu::Locale locale_; + std::string encoding_; + }; + + }} // namespace boundary::impl_icu + + namespace impl_icu { + std::locale create_boundary(const std::locale& in, const cdata& cd, char_facet_t type) + { + using namespace boost::locale::boundary::impl_icu; + switch(type) { + case char_facet_t::nochar: break; + case char_facet_t::char_f: return std::locale(in, new boundary_indexing_impl<char>(cd)); + case char_facet_t::wchar_f: return std::locale(in, new boundary_indexing_impl<wchar_t>(cd)); +#ifdef BOOST_LOCALE_ENABLE_CHAR16_T + case char_facet_t::char16_f: return std::locale(in, new boundary_indexing_impl<char16_t>(cd)); #endif - { - icu_std_converter<CharType> cvt(encoding); - icu::UnicodeString str=cvt.icu(begin,end); - bi->setText(str); - index_type indirect = map_direct(t,bi.get(),str.length()); - 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); - } - } - return indx; -} // do_map - -template<typename CharType> -class boundary_indexing_impl : public boundary_indexing<CharType> { -public: - boundary_indexing_impl(cdata const &data) : - locale_(data.locale), - encoding_(data.encoding) - { - } - index_type map(boundary_type t,CharType const *begin,CharType const *end) const - { - return do_map<CharType>(t,begin,end,locale_,encoding_); - } -private: - icu::Locale locale_; - std::string encoding_; -}; - - - -} // impl_icu -} // boundary - -namespace impl_icu { - std::locale create_boundary(std::locale const &in,cdata const &cd,character_facet_type type) - { - using namespace boost::locale::boundary::impl_icu; - switch(type) { - case char_facet: - return std::locale(in,new boundary_indexing_impl<char>(cd)); - case wchar_t_facet: - return std::locale(in,new boundary_indexing_impl<wchar_t>(cd)); - #ifdef BOOST_LOCALE_ENABLE_CHAR16_T - case char16_t_facet: - return std::locale(in,new boundary_indexing_impl<char16_t>(cd)); - #endif - #ifdef BOOST_LOCALE_ENABLE_CHAR32_T - case char32_t_facet: - return std::locale(in,new boundary_indexing_impl<char32_t>(cd)); - #endif - default: +#ifdef BOOST_LOCALE_ENABLE_CHAR32_T + case char_facet_t::char32_f: return std::locale(in, new boundary_indexing_impl<char32_t>(cd)); +#endif + } return in; } - } -} // impl_icu + } // namespace impl_icu -} // locale -} // boost +}} // namespace boost::locale diff --git a/contrib/restricted/boost/locale/src/boost/locale/icu/cdata.hpp b/contrib/restricted/boost/locale/src/boost/locale/icu/cdata.hpp index 9049e5eba6..851a265b5a 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/icu/cdata.hpp +++ b/contrib/restricted/boost/locale/src/boost/locale/icu/cdata.hpp @@ -8,20 +8,15 @@ #define BOOST_LOCALE_ICU_CDATA_HPP #include <boost/locale/config.hpp> -#include <unicode/locid.h> #include <string> +#include <unicode/locid.h> -namespace boost { - namespace locale { - namespace impl_icu { - struct cdata { - icu::Locale locale; - std::string encoding; - bool utf8; - }; - } - } -} - +namespace boost { namespace locale { namespace impl_icu { + struct cdata { + icu::Locale locale; + std::string encoding; + bool utf8; + }; +}}} // namespace boost::locale::impl_icu #endif 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 c657aaec54..f7bf5503a8 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/icu/codecvt.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/icu/codecvt.cpp @@ -5,38 +5,34 @@ // https://www.boost.org/LICENSE_1_0.txt #define BOOST_LOCALE_SOURCE +#include "boost/locale/icu/codecvt.hpp" #include <boost/locale/encoding.hpp> #include <boost/locale/encoding_errors.hpp> -#include <boost/locale/util.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/uconv.hpp" -#include "boost/locale/icu/codecvt.hpp" #include "boost/locale/icu/icu_util.hpp" +#include "boost/locale/icu/uconv.hpp" #include <unicode/ucnv.h> #include <unicode/ucnv_err.h> #ifdef BOOST_MSVC -# pragma warning(disable : 4244) // loose data +# pragma warning(disable : 4244) // loose data #endif -namespace boost { -namespace locale { -namespace impl_icu { +namespace boost { namespace locale { namespace impl_icu { class uconv_converter : public util::base_converter { public: - - uconv_converter(std::string const &encoding) : - encoding_(encoding) + uconv_converter(const std::string& encoding) : encoding_(encoding) { - UErrorCode err=U_ZERO_ERROR; + 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); + 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_) @@ -47,26 +43,17 @@ namespace impl_icu { max_len_ = ucnv_getMaxCharSize(cvt_); } - ~uconv_converter() - { - ucnv_close(cvt_); - } + ~uconv_converter() { ucnv_close(cvt_); } - bool is_thread_safe() const BOOST_OVERRIDE - { - return false; - } + bool is_thread_safe() const override { return false; } - uconv_converter *clone() const BOOST_OVERRIDE - { - return new uconv_converter(encoding_); - } + uconv_converter* clone() const override { return new uconv_converter(encoding_); } - uint32_t to_unicode(char const *&begin,char const *end) BOOST_OVERRIDE + uint32_t to_unicode(const char*& begin, const char* end) override { - UErrorCode err=U_ZERO_ERROR; - char const *tmp = begin; - UChar32 c=ucnv_getNextUChar(cvt_,&tmp,end,&err); + 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) { return incomplete; @@ -79,24 +66,23 @@ namespace impl_icu { return c; } - uint32_t from_unicode(uint32_t u,char *begin,char const *end) BOOST_OVERRIDE + uint32_t from_unicode(uint32_t u, char* begin, const char* end) override { - UChar code_point[2]={0}; + UChar code_point[2] = {0}; int len; - if(u<=0xFFFF) { - if(0xD800 <=u && u<= 0xDFFF) // No surrogates + if(u <= 0xFFFF) { + if(0xD800 <= u && u <= 0xDFFF) // No surrogates return illegal; - code_point[0]=u; - len=1; - } - else { - u-=0x10000; - code_point[0]=0xD800 | (u>>10); - code_point[1]=0xDC00 | (u & 0x3FF); - len=2; + code_point[0] = u; + len = 1; + } else { + u -= 0x10000; + code_point[0] = 0xD800 | (u >> 10); + code_point[1] = 0xDC00 | (u & 0x3FF); + len = 2; } - UErrorCode err=U_ZERO_ERROR; - int olen = ucnv_fromUChars(cvt_,begin,end-begin,code_point,len,&err); + UErrorCode err = U_ZERO_ERROR; + int olen = ucnv_fromUChars(cvt_, begin, end - begin, code_point, len, &err); ucnv_reset(cvt_); if(err == U_BUFFER_OVERFLOW_ERROR) return incomplete; @@ -105,52 +91,39 @@ namespace impl_icu { return olen; } - int max_len() const BOOST_OVERRIDE - { - return max_len_; - } + int max_len() const override { return max_len_; } private: std::string encoding_; - UConverter *cvt_; + UConverter* cvt_; int max_len_; }; - util::base_converter *create_uconv_converter(std::string const &encoding) + std::unique_ptr<util::base_converter> create_uconv_converter(const std::string& encoding) { - hold_ptr<util::base_converter> cvt; try { - cvt.reset(new uconv_converter(encoding)); + return std::unique_ptr<util::base_converter>(new uconv_converter(encoding)); + } catch(const std::exception& /*e*/) { + return nullptr; } - catch(std::exception const &/*e*/) - { - // no encoding so we return empty pointer - } - return cvt.release(); } - std::locale create_codecvt(std::locale const &in,std::string const &encoding,character_facet_type type) + std::locale create_codecvt(const std::locale& in, const std::string& encoding, char_facet_t type) { - if(conv::impl::normalize_encoding(encoding.c_str())=="utf8") - return util::create_utf8_codecvt(in,type); + if(conv::impl::normalize_encoding(encoding.c_str()) == "utf8") + return util::create_utf8_codecvt(in, type); try { - return util::create_simple_codecvt(in,encoding,type); - } - catch(boost::locale::conv::invalid_charset_error const &) { - hold_ptr<util::base_converter> cvt; + return util::create_simple_codecvt(in, encoding, type); + } catch(const boost::locale::conv::invalid_charset_error&) { + std::unique_ptr<util::base_converter> cvt; try { - cvt.reset(create_uconv_converter(encoding)); - } - catch(std::exception const &/*e*/) - { + cvt = create_uconv_converter(encoding); + } catch(const std::exception& /*e*/) { cvt.reset(new util::base_converter()); } - return util::create_codecvt_from_pointer(in,cvt.release(),type); + return util::create_codecvt(in, std::move(cvt), type); } } -} // impl_icu -} // locale -} // boost - +}}} // namespace boost::locale::impl_icu diff --git a/contrib/restricted/boost/locale/src/boost/locale/icu/codecvt.hpp b/contrib/restricted/boost/locale/src/boost/locale/icu/codecvt.hpp index 78ee524041..02b7f1bfd0 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/icu/codecvt.hpp +++ b/contrib/restricted/boost/locale/src/boost/locale/icu/codecvt.hpp @@ -9,16 +9,13 @@ #include <boost/locale/config.hpp> #include <boost/locale/util.hpp> +#include <memory> #include <string> -namespace boost { -namespace locale { -namespace impl_icu { +namespace boost { namespace locale { namespace impl_icu { BOOST_LOCALE_DECL - util::base_converter *create_uconv_converter(std::string const &encoding); + std::unique_ptr<util::base_converter> create_uconv_converter(const std::string& encoding); -} // impl_icu -} // locale -} // boost +}}} // namespace boost::locale::impl_icu #endif 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 448de9d41a..0f66b7a8ee 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/icu/collator.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/icu/collator.cpp @@ -13,194 +13,182 @@ #include "boost/locale/icu/uconv.hpp" #include "boost/locale/shared/mo_hash.hpp" #include <boost/thread.hpp> -#include <vector> #include <limits> #include <unicode/coll.h> +#include <vector> #if BOOST_LOCALE_ICU_VERSION >= 402 -# define BOOST_LOCALE_WITH_STRINGPIECE 1 -# include <unicode/stringpiece.h> +# define BOOST_LOCALE_WITH_STRINGPIECE 1 +# include <unicode/stringpiece.h> #else -# define BOOST_LOCALE_WITH_STRINGPIECE 0 +# define BOOST_LOCALE_WITH_STRINGPIECE 0 #endif #ifdef BOOST_MSVC -#pragma warning(disable:4244) // 'argument' : conversion from 'int' -#pragma warning(disable:4267) // 'argument' : conversion from 'size_t' +# pragma warning(disable : 4244) // 'argument' : conversion from 'int' +# pragma warning(disable : 4267) // 'argument' : conversion from 'size_t' +#endif + +namespace boost { namespace locale { namespace impl_icu { + template<typename CharType> + class collate_impl : public collator<CharType> { + public: + int level_to_int(collate_level level) const + { + const auto res = static_cast<int>(level); + if(res < 0) + return 0; + if(res >= level_count) + return level_count - 1; + return res; + } + +#if BOOST_LOCALE_WITH_STRINGPIECE + int do_utf8_compare(collate_level level, + const char* b1, + const char* e1, + const char* b2, + const char* e2, + UErrorCode& status) const + { + icu::StringPiece left(b1, e1 - b1); + icu::StringPiece right(b2, e2 - b2); + return get_collator(level)->compareUTF8(left, right, status); + } #endif -namespace boost { - namespace locale { - namespace impl_icu { - template<typename CharType> - class collate_impl : public collator<CharType> - { - public: - typedef typename collator<CharType>::level_type level_type; - level_type limit(level_type level) const - { - if(level < 0) - level=collator_base::primary; - else if(level >= level_count) - level = static_cast<level_type>(level_count - 1); - return level; - } - - #if BOOST_LOCALE_WITH_STRINGPIECE - int do_utf8_compare( level_type level, - char const *b1,char const *e1, - char const *b2,char const *e2, - UErrorCode &status) const - { - icu::StringPiece left (b1,e1-b1); - icu::StringPiece right(b2,e2-b2); - return get_collator(level)->compareUTF8(left,right,status); - - } - #endif - - int do_ustring_compare( level_type level, - CharType const *b1,CharType const *e1, - CharType const *b2,CharType const *e2, - UErrorCode &status) const - { - icu::UnicodeString left=cvt_.icu(b1,e1); - icu::UnicodeString right=cvt_.icu(b2,e2); - return get_collator(level)->compare(left,right,status); - } - - int do_real_compare(level_type level, - CharType const *b1,CharType const *e1, - CharType const *b2,CharType const *e2, - UErrorCode &status) const - { - return do_ustring_compare(level,b1,e1,b2,e2,status); - } - - int do_compare(level_type level, - CharType const *b1,CharType const *e1, - CharType const *b2,CharType const *e2) const BOOST_OVERRIDE - { - UErrorCode status=U_ZERO_ERROR; - - int res = do_real_compare(level,b1,e1,b2,e2,status); - - if(U_FAILURE(status)) - throw std::runtime_error(std::string("Collation failed:") + u_errorName(status)); - if(res < 0) - return -1; - else if(res > 0) - return 1; - return 0; - } - - std::vector<uint8_t> do_basic_transform(level_type level,CharType const *b,CharType const *e) const - { - icu::UnicodeString str=cvt_.icu(b,e); - std::vector<uint8_t> tmp; - tmp.resize(str.length() + 1u); - icu::Collator *collate = get_collator(level); - const int len = collate->getSortKey(str,&tmp[0],tmp.size()); - if(len > int(tmp.size())) { - tmp.resize(len); - collate->getSortKey(str,&tmp[0],tmp.size()); - } - else - tmp.resize(len); - return tmp; - } - std::basic_string<CharType> do_transform(level_type level,CharType const *b,CharType const *e) const BOOST_OVERRIDE - { - std::vector<uint8_t> tmp = do_basic_transform(level,b,e); - return std::basic_string<CharType>(tmp.begin(),tmp.end()); - } - - long do_hash(level_type level,CharType const *b,CharType const *e) const BOOST_OVERRIDE - { - 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())); - } - - collate_impl(cdata const &d) : - cvt_(d.encoding), - locale_(d.locale), - is_utf8_(d.utf8) - { - - } - icu::Collator *get_collator(level_type ilevel) const - { - int l = limit(ilevel); - static const icu::Collator::ECollationStrength levels[level_count] = - { - icu::Collator::PRIMARY, - icu::Collator::SECONDARY, - icu::Collator::TERTIARY, - icu::Collator::QUATERNARY, - icu::Collator::IDENTICAL - }; - - icu::Collator *col = collates_[l].get(); - if(col) - return col; - - UErrorCode status=U_ZERO_ERROR; - - collates_[l].reset(icu::Collator::createInstance(locale_,status)); - - if(U_FAILURE(status)) - throw std::runtime_error(std::string("Creation of collate failed:") + u_errorName(status)); - - collates_[l]->setStrength(levels[l]); - return collates_[l].get(); - } - - private: - static const int level_count = 5; - icu_std_converter<CharType> cvt_; - icu::Locale locale_; - mutable boost::thread_specific_ptr<icu::Collator> collates_[level_count]; - bool is_utf8_; - }; - - - #if BOOST_LOCALE_WITH_STRINGPIECE - template<> - int collate_impl<char>::do_real_compare( - level_type level, - char const *b1,char const *e1, - char const *b2,char const *e2, - UErrorCode &status) const - { - if(is_utf8_) - return do_utf8_compare(level,b1,e1,b2,e2,status); - else - return do_ustring_compare(level,b1,e1,b2,e2,status); - } - #endif - - std::locale create_collate(std::locale const &in,cdata const &cd,character_facet_type type) - { - switch(type) { - case char_facet: - return std::locale(in,new collate_impl<char>(cd)); - case wchar_t_facet: - return std::locale(in,new collate_impl<wchar_t>(cd)); - #ifdef BOOST_LOCALE_ENABLE_CHAR16_T - case char16_t_facet: - return std::locale(in,new collate_impl<char16_t>(cd)); - #endif - #ifdef BOOST_LOCALE_ENABLE_CHAR32_T - case char32_t_facet: - return std::locale(in,new collate_impl<char32_t>(cd)); - #endif - default: - return in; - } - } - - } /// impl_icu - - } // locale -} // boost + int do_ustring_compare(collate_level level, + const CharType* b1, + const CharType* e1, + const CharType* b2, + const CharType* e2, + UErrorCode& status) const + { + icu::UnicodeString left = cvt_.icu(b1, e1); + icu::UnicodeString right = cvt_.icu(b2, e2); + return get_collator(level)->compare(left, right, status); + } + + int do_real_compare(collate_level level, + const CharType* b1, + const CharType* e1, + const CharType* b2, + const CharType* e2, + UErrorCode& status) const + { + return do_ustring_compare(level, b1, e1, b2, e2, status); + } + + int do_compare(collate_level level, + const CharType* b1, + const CharType* e1, + const CharType* b2, + const CharType* e2) const override + { + UErrorCode status = U_ZERO_ERROR; + + int res = do_real_compare(level, b1, e1, b2, e2, status); + + if(U_FAILURE(status)) + throw std::runtime_error(std::string("Collation failed:") + u_errorName(status)); + if(res < 0) + return -1; + else if(res > 0) + return 1; + return 0; + } + + std::vector<uint8_t> do_basic_transform(collate_level level, const CharType* b, const CharType* e) const + { + icu::UnicodeString str = cvt_.icu(b, e); + std::vector<uint8_t> tmp; + tmp.resize(str.length() + 1u); + icu::Collator* collate = get_collator(level); + const int len = collate->getSortKey(str, &tmp[0], tmp.size()); + if(len > int(tmp.size())) { + tmp.resize(len); + collate->getSortKey(str, &tmp[0], tmp.size()); + } else + tmp.resize(len); + return tmp; + } + std::basic_string<CharType> + do_transform(collate_level level, const CharType* b, const CharType* e) const override + { + std::vector<uint8_t> tmp = do_basic_transform(level, b, e); + return std::basic_string<CharType>(tmp.begin(), tmp.end()); + } + + long do_hash(collate_level level, const CharType* b, const CharType* e) const override + { + 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())); + } + + collate_impl(const cdata& d) : cvt_(d.encoding), locale_(d.locale), is_utf8_(d.utf8) {} + + icu::Collator* get_collator(collate_level level) const + { + const int lvl_idx = level_to_int(level); + constexpr icu::Collator::ECollationStrength levels[level_count] = {icu::Collator::PRIMARY, + icu::Collator::SECONDARY, + icu::Collator::TERTIARY, + icu::Collator::QUATERNARY, + icu::Collator::IDENTICAL}; + + icu::Collator* col = collates_[lvl_idx].get(); + if(col) + return col; + + UErrorCode status = U_ZERO_ERROR; + + collates_[lvl_idx].reset(icu::Collator::createInstance(locale_, status)); + + if(U_FAILURE(status)) + throw std::runtime_error(std::string("Creation of collate failed:") + u_errorName(status)); + + collates_[lvl_idx]->setStrength(levels[lvl_idx]); + return collates_[lvl_idx].get(); + } + + private: + static constexpr int level_count = static_cast<int>(collate_level::identical) + 1; + icu_std_converter<CharType> cvt_; + icu::Locale locale_; + mutable boost::thread_specific_ptr<icu::Collator> collates_[level_count]; + bool is_utf8_; + }; + +#if BOOST_LOCALE_WITH_STRINGPIECE + template<> + int collate_impl<char>::do_real_compare(collate_level level, + const char* b1, + const char* e1, + const char* b2, + const char* e2, + UErrorCode& status) const + { + if(is_utf8_) + return do_utf8_compare(level, b1, e1, b2, e2, status); + else + return do_ustring_compare(level, b1, e1, b2, e2, status); + } +#endif + + std::locale create_collate(const std::locale& in, const cdata& cd, char_facet_t type) + { + switch(type) { + case char_facet_t::nochar: break; + case char_facet_t::char_f: return std::locale(in, new collate_impl<char>(cd)); + case char_facet_t::wchar_f: return std::locale(in, new collate_impl<wchar_t>(cd)); +#ifdef BOOST_LOCALE_ENABLE_CHAR16_T + case char_facet_t::char16_f: return std::locale(in, new collate_impl<char16_t>(cd)); +#endif +#ifdef BOOST_LOCALE_ENABLE_CHAR32_T + case char_facet_t::char32_f: return std::locale(in, new collate_impl<char32_t>(cd)); +#endif + } + return in; + } +}}} // namespace boost::locale::impl_icu 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 7577e0b935..fdfdd99264 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/icu/conversion.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/icu/conversion.cpp @@ -10,50 +10,37 @@ #include "boost/locale/icu/cdata.hpp" #include "boost/locale/icu/icu_util.hpp" #include "boost/locale/icu/uconv.hpp" - +#include <limits> +#include <unicode/locid.h> #include <unicode/normlzr.h> #include <unicode/ustring.h> -#include <unicode/locid.h> -#include <unicode/uversion.h> #if BOOST_LOCALE_ICU_VERSION >= 308 -#include <unicode/ucasemap.h> -#define BOOST_LOCALE_WITH_CASEMAP +# include <unicode/ucasemap.h> +# define BOOST_LOCALE_WITH_CASEMAP #endif #include <vector> -namespace boost { -namespace locale { -namespace impl_icu { - +namespace boost { namespace locale { namespace impl_icu { namespace { - void normalize_string(icu::UnicodeString &str,int flags) + void normalize_string(icu::UnicodeString& str, int flags) { - UErrorCode code=U_ZERO_ERROR; - UNormalizationMode mode=UNORM_DEFAULT; + UErrorCode code = U_ZERO_ERROR; + UNormalizationMode mode = UNORM_DEFAULT; switch(flags) { - case norm_nfd: - mode=UNORM_NFD; - break; - case norm_nfc: - mode=UNORM_NFC; - break; - case norm_nfkd: - mode=UNORM_NFKD; - break; - case norm_nfkc: - mode=UNORM_NFKC; - break; + case norm_nfd: mode = UNORM_NFD; break; + case norm_nfc: mode = UNORM_NFC; break; + case norm_nfkd: mode = UNORM_NFKD; break; + case norm_nfkc: mode = UNORM_NFKC; break; } icu::UnicodeString tmp; - icu::Normalizer::normalize(str,mode,0,tmp,code); + icu::Normalizer::normalize(str, mode, 0, tmp, code); check_and_throw_icu_error(code); - str=tmp; + str = tmp; } - } - + } // namespace template<typename CharType> class converter_impl : public converter<CharType> { @@ -61,34 +48,21 @@ namespace impl_icu { typedef CharType char_type; typedef std::basic_string<char_type> string_type; - converter_impl(cdata const &d) : - locale_(d.locale), - encoding_(d.encoding) - { - } + converter_impl(const cdata& d) : locale_(d.locale), encoding_(d.encoding) {} - string_type convert(converter_base::conversion_type how, char_type const* begin, char_type const* end, int flags = 0) const BOOST_OVERRIDE + string_type convert(converter_base::conversion_type how, + const char_type* begin, + const char_type* end, + int flags = 0) const override { icu_std_converter<char_type> cvt(encoding_); - icu::UnicodeString str=cvt.icu(begin,end); + 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::case_folding: - str.foldCase(); - break; - default: - ; + 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::case_folding: str.foldCase(); break; } return cvt.std(str); } @@ -98,79 +72,90 @@ namespace impl_icu { std::string encoding_; }; // converter_impl - #ifdef BOOST_LOCALE_WITH_CASEMAP +#ifdef BOOST_LOCALE_WITH_CASEMAP + template<typename T> + struct get_casemap_size_type; + + template<typename TRes, typename TCaseMap, typename TSize> + struct get_casemap_size_type<TRes (*)(TCaseMap*, char*, TSize, const char*, TSize, UErrorCode*)> { + using type = TSize; + }; + class raii_casemap { - raii_casemap(raii_casemap const &); - void operator = (raii_casemap const&); public: - raii_casemap(std::string const &locale_id) : - map_(0) + raii_casemap(const raii_casemap&) = delete; + void operator=(const raii_casemap&) = delete; + + raii_casemap(const std::string& locale_id) : map_(0) { - UErrorCode err=U_ZERO_ERROR; - map_ = ucasemap_open(locale_id.c_str(),0,&err); + UErrorCode err = U_ZERO_ERROR; + map_ = ucasemap_open(locale_id.c_str(), 0, &err); check_and_throw_icu_error(err); if(!map_) throw std::runtime_error("Failed to create UCaseMap"); } template<typename Conv> - std::string convert(Conv func,char const *begin,char const *end) const + std::string convert(Conv func, const char* begin, const char* end) const { - std::vector<char> buf((end-begin)*11/10+1); - UErrorCode err=U_ZERO_ERROR; - int size = func(map_,&buf.front(),buf.size(),begin,end-begin,&err); - if(err == U_BUFFER_OVERFLOW_ERROR) { - err = U_ZERO_ERROR; - buf.resize(size+1); - size = func(map_,&buf.front(),buf.size(),begin,end-begin,&err); - } - check_and_throw_icu_error(err); - return std::string(&buf.front(),size); - } - ~raii_casemap() - { - ucasemap_close(map_); + using size_type = typename get_casemap_size_type<Conv>::type; + if((end - begin) >= std::numeric_limits<std::ptrdiff_t>::max() / 11) + throw std::range_error("String to long to be converted by ICU"); + const auto max_converted_size = (end - begin) * 11 / 10 + 1; + if(max_converted_size >= std::numeric_limits<size_type>::max()) + throw std::range_error("String to long to be converted by ICU"); + std::vector<char> buf(max_converted_size); + UErrorCode err = U_ZERO_ERROR; + auto size = func(map_, + &buf.front(), + static_cast<size_type>(buf.size()), + begin, + static_cast<size_type>(end - begin), + &err); + if(err == U_BUFFER_OVERFLOW_ERROR) { + err = U_ZERO_ERROR; + buf.resize(size + 1); + size = func(map_, + &buf.front(), + 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); } + ~raii_casemap() { ucasemap_close(map_); } + private: - UCaseMap *map_; + UCaseMap* map_; }; class utf8_converter_impl : public converter<char> { public: + utf8_converter_impl(const cdata& d) : locale_id_(d.locale.getName()), map_(locale_id_) {} - utf8_converter_impl(cdata const &d) : - locale_id_(d.locale.getName()), - map_(locale_id_) - { - } - - std::string convert(converter_base::conversion_type how,char const *begin,char const *end,int flags = 0) const BOOST_OVERRIDE + std::string + convert(converter_base::conversion_type how, const char* begin, const char* end, int flags = 0) const override { - - if(how == converter_base::normalization) { - icu_std_converter<char> cvt("UTF-8"); - icu::UnicodeString str=cvt.icu(begin,end); - normalize_string(str,flags); - return cvt.std(str); - } - - switch(how) - { - case converter_base::upper_case: - return map_.convert(ucasemap_utf8ToUpper,begin,end); - case converter_base::lower_case: - return map_.convert(ucasemap_utf8ToLower,begin,end); - case converter_base::title_case: - { + switch(how) { + case converter_base::upper_case: return map_.convert(ucasemap_utf8ToUpper, begin, end); + case converter_base::lower_case: return map_.convert(ucasemap_utf8ToLower, begin, end); + case converter_base::title_case: { // Non-const method, so need to create a separate map raii_casemap map(locale_id_); - return map.convert(ucasemap_utf8ToTitle,begin,end); + return map.convert(ucasemap_utf8ToTitle, begin, end); + } + case converter_base::case_folding: return map_.convert(ucasemap_utf8FoldCase, begin, end); + case converter_base::normalization: { + icu_std_converter<char> cvt("UTF-8"); + icu::UnicodeString str = cvt.icu(begin, end); + normalize_string(str, flags); + return cvt.std(str); } - case converter_base::case_folding: - return map_.convert(ucasemap_utf8FoldCase,begin,end); - default: - return std::string(begin,end-begin); } + return std::string(begin, end - begin); } + private: std::string locale_id_; raii_casemap map_; @@ -178,32 +163,25 @@ namespace impl_icu { #endif // BOOST_LOCALE_WITH_CASEMAP - std::locale create_convert(std::locale const &in,cdata const &cd,character_facet_type type) + std::locale create_convert(const std::locale& in, const cdata& cd, char_facet_t type) { switch(type) { - case char_facet: - #ifdef BOOST_LOCALE_WITH_CASEMAP - if(cd.utf8) - return std::locale(in,new utf8_converter_impl(cd)); - #endif - return std::locale(in,new converter_impl<char>(cd)); - case wchar_t_facet: - return std::locale(in,new converter_impl<wchar_t>(cd)); - #ifdef BOOST_LOCALE_ENABLE_CHAR16_T - case char16_t_facet: - return std::locale(in,new converter_impl<char16_t>(cd)); - #endif - #ifdef BOOST_LOCALE_ENABLE_CHAR32_T - case char32_t_facet: - return std::locale(in,new converter_impl<char32_t>(cd)); - #endif - default: - return in; + case char_facet_t::nochar: break; + case char_facet_t::char_f: +#ifdef BOOST_LOCALE_WITH_CASEMAP + if(cd.utf8) + return std::locale(in, new utf8_converter_impl(cd)); +#endif + return std::locale(in, new converter_impl<char>(cd)); + case char_facet_t::wchar_f: return std::locale(in, new converter_impl<wchar_t>(cd)); +#ifdef BOOST_LOCALE_ENABLE_CHAR16_T + case char_facet_t::char16_f: return std::locale(in, new converter_impl<char16_t>(cd)); +#endif +#ifdef BOOST_LOCALE_ENABLE_CHAR32_T + case char_facet_t::char32_f: return std::locale(in, new converter_impl<char32_t>(cd)); +#endif } + return in; } - -} // impl_icu -} // locale -} // boost - +}}} // namespace boost::locale::impl_icu 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 b53fda940e..c8303cdea5 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 @@ -1,5 +1,6 @@ // // Copyright (c) 2009-2011 Artyom Beilis (Tonkikh) +// Copyright (c) 2021-2022 Alexander Grund // // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt @@ -16,17 +17,14 @@ #include "boost/locale/icu/uconv.hpp" #include <boost/thread.hpp> #include <cmath> -#include <iostream> #include <memory> #include <unicode/calendar.h> #include <unicode/gregocal.h> #include <unicode/utypes.h> -namespace boost { -namespace locale { -namespace impl_icu { +namespace boost { namespace locale { namespace impl_icu { - static void check_and_throw_dt(UErrorCode &e) + static void check_and_throw_dt(UErrorCode& e) { if(U_FAILURE(e)) { throw date_time_error(u_errorName(e)); @@ -39,215 +37,178 @@ namespace impl_icu { using namespace period::marks; switch(f) { - case era: return UCAL_ERA; - case year: return UCAL_YEAR; - case extended_year: return UCAL_EXTENDED_YEAR; - case month: return UCAL_MONTH; - case day: return UCAL_DATE; - case day_of_year: return UCAL_DAY_OF_YEAR; - case day_of_week: return UCAL_DAY_OF_WEEK; - case day_of_week_in_month: return UCAL_DAY_OF_WEEK_IN_MONTH; - case day_of_week_local: return UCAL_DOW_LOCAL; - case hour: return UCAL_HOUR_OF_DAY; - case hour_12: return UCAL_HOUR; - case am_pm: return UCAL_AM_PM; - case minute: return UCAL_MINUTE; - case second: return UCAL_SECOND; - case week_of_year: return UCAL_WEEK_OF_YEAR; - case week_of_month: return UCAL_WEEK_OF_MONTH; - default: - throw std::invalid_argument("Invalid date_time period type"); - } + case era: return UCAL_ERA; + case year: return UCAL_YEAR; + case extended_year: return UCAL_EXTENDED_YEAR; + case month: return UCAL_MONTH; + case day: return UCAL_DATE; + case day_of_year: return UCAL_DAY_OF_YEAR; + case day_of_week: return UCAL_DAY_OF_WEEK; + case day_of_week_in_month: return UCAL_DAY_OF_WEEK_IN_MONTH; + case day_of_week_local: return UCAL_DOW_LOCAL; + case hour: return UCAL_HOUR_OF_DAY; + case hour_12: return UCAL_HOUR; + case am_pm: return UCAL_AM_PM; + case minute: return UCAL_MINUTE; + case second: return UCAL_SECOND; + case week_of_year: return UCAL_WEEK_OF_YEAR; + case week_of_month: return UCAL_WEEK_OF_MONTH; + case first_day_of_week: + case invalid: break; + } + throw std::invalid_argument("Invalid date_time period type"); } - class calendar_impl : public abstract_calendar { public: - - calendar_impl(cdata const &dat) + calendar_impl(const cdata& dat) { - UErrorCode err=U_ZERO_ERROR; - calendar_.reset(icu::Calendar::createInstance(dat.locale,err)); + UErrorCode err = U_ZERO_ERROR; + calendar_.reset(icu::Calendar::createInstance(dat.locale, err)); check_and_throw_dt(err); - #if BOOST_LOCALE_ICU_VERSION < 402 +#if BOOST_LOCALE_ICU_VERSION < 402 // workaround old/invalid data, it should be 4 in general calendar_->setMinimalDaysInFirstWeek(4); - #endif +#endif encoding_ = dat.encoding; } - calendar_impl(calendar_impl const &other) + calendar_impl(const calendar_impl& other) { calendar_.reset(other.calendar_->clone()); encoding_ = other.encoding_; } - calendar_impl *clone() const BOOST_OVERRIDE + calendar_impl* clone() const override { return new calendar_impl(*this); } - void set_value(period::marks::period_mark p,int value) BOOST_OVERRIDE + void set_value(period::marks::period_mark p, int value) override { - calendar_->set(to_icu(p),int32_t(value)); + calendar_->set(to_icu(p), int32_t(value)); } - int get_value(period::marks::period_mark p,value_type type) const BOOST_OVERRIDE + int get_value(period::marks::period_mark p, value_type type) const override { - UErrorCode err=U_ZERO_ERROR; - int v=0; - if(p==period::marks::first_day_of_week) { + UErrorCode err = U_ZERO_ERROR; + int v = 0; + if(p == period::marks::first_day_of_week) { guard l(lock_); - v=calendar_->getFirstDayOfWeek(err); - } - else { - UCalendarDateFields uper=to_icu(p); + v = calendar_->getFirstDayOfWeek(err); + } else { + UCalendarDateFields uper = 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(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; } } check_and_throw_dt(err); return v; } - void set_time(posix_time const &p) BOOST_OVERRIDE + void set_time(const posix_time& p) override { double utime = p.seconds * 1000.0 + p.nanoseconds / 1000000.0; - UErrorCode code=U_ZERO_ERROR; - calendar_->setTime(utime,code); + UErrorCode code = U_ZERO_ERROR; + calendar_->setTime(utime, code); check_and_throw_dt(code); } - void normalize() BOOST_OVERRIDE + void normalize() override { // Can't call complete() explicitly (protected) - // calling get wich calls complete - UErrorCode code=U_ZERO_ERROR; - calendar_->get(UCAL_YEAR,code); + // calling get which calls complete + UErrorCode code = U_ZERO_ERROR; + calendar_->get(UCAL_YEAR, code); check_and_throw_dt(code); } - posix_time get_time() const BOOST_OVERRIDE + posix_time get_time() const override { - - UErrorCode code=U_ZERO_ERROR; - double rtime = 0; + const double timeMs = get_time_ms(); + posix_time res; + res.seconds = static_cast<int64_t>(std::floor(timeMs / 1e3)); + const double remainTimeMs = std::fmod(timeMs, 1e3); // = timeMs - seconds * 1000 + constexpr uint32_t ns_in_s = static_cast<uint32_t>(1000) * 1000 * 1000; + res.nanoseconds = std::min(static_cast<uint32_t>(remainTimeMs * 1e6), ns_in_s - 1u); + return res; + } + double get_time_ms() const override + { + UErrorCode code = U_ZERO_ERROR; + double result; { guard l(lock_); - rtime = calendar_->getTime(code); + result = calendar_->getTime(code); } check_and_throw_dt(code); - rtime/=1000.0; - double secs = floor(rtime); - posix_time res; - res.seconds = static_cast<int64_t>(secs); - res.nanoseconds = static_cast<uint32_t>((rtime - secs) / 1e9); - if(res.nanoseconds > 999999999) - res.nanoseconds = 999999999; - return res; + return result; } - void set_option(calendar_option_type opt,int /*v*/) BOOST_OVERRIDE + void set_option(calendar_option_type opt, int /*v*/) override { switch(opt) { - 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"); - default: - ; + 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"); } } - int get_option(calendar_option_type opt) const BOOST_OVERRIDE + int get_option(calendar_option_type opt) const override { switch(opt) { - case is_gregorian: - return dynamic_cast<icu::GregorianCalendar const *>(calendar_.get())!=0; - case is_dst: - { + case is_gregorian: return icu_cast<const icu::GregorianCalendar>(calendar_.get()) != 0; + case is_dst: { guard l(lock_); UErrorCode err = U_ZERO_ERROR; - bool res = ( calendar_->inDaylightTime(err) != 0 ); + bool res = (calendar_->inDaylightTime(err) != 0); check_and_throw_dt(err); return res; } - default: - return 0; } + return 0; } - void adjust_value(period::marks::period_mark p,update_type u,int difference) BOOST_OVERRIDE + void adjust_value(period::marks::period_mark p, update_type u, int difference) override { - UErrorCode err=U_ZERO_ERROR; + UErrorCode err = U_ZERO_ERROR; switch(u) { - case move: - calendar_->add(to_icu(p),difference,err); - break; - case roll: - calendar_->roll(to_icu(p),difference,err); - break; + case move: calendar_->add(to_icu(p), difference, err); break; + case roll: calendar_->roll(to_icu(p), difference, err); break; } check_and_throw_dt(err); } - int difference(abstract_calendar const *other_ptr, period::marks::period_mark m) const BOOST_OVERRIDE + int difference(const abstract_calendar& other, period::marks::period_mark m) const override { - UErrorCode err=U_ZERO_ERROR; - double other_time = 0; - // + UErrorCode err = U_ZERO_ERROR; + 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()); - calendar_impl const *other_cal=dynamic_cast<calendar_impl const *>(other_ptr); - if(other_cal){ - guard l(other_cal->lock_); - other_time = other_cal->calendar_->getTime(err); - check_and_throw_dt(err); - } - else { - posix_time o_time = other_ptr->get_time(); - other_time = o_time.seconds * 1000.0 + o_time.nanoseconds / 1000000.0; - } - - int diff = self->fieldDifference(other_time,to_icu(m),err); + int diff = self->fieldDifference(other_time_ms, to_icu(m), err); check_and_throw_dt(err); return diff; } - void set_timezone(std::string const &tz) BOOST_OVERRIDE + void set_timezone(const std::string& tz) override { calendar_->adoptTimeZone(get_time_zone(tz)); } - std::string get_timezone() const BOOST_OVERRIDE + std::string get_timezone() const override { icu::UnicodeString tz; calendar_->getTimeZone().getID(tz); icu_std_converter<char> cvt(encoding_); return cvt.std(tz); } - bool same(abstract_calendar const *other) const BOOST_OVERRIDE + bool same(const abstract_calendar* other) const override { - calendar_impl const *oc=dynamic_cast<calendar_impl const *>(other); + const calendar_impl* oc = dynamic_cast<const calendar_impl*>(other); if(!oc) return false; - return calendar_->isEquivalentTo(*oc->calendar_)!=0; + return calendar_->isEquivalentTo(*oc->calendar_) != 0; } private: @@ -257,30 +218,18 @@ namespace impl_icu { hold_ptr<icu::Calendar> calendar_; }; - class icu_calendar_facet : public calendar_facet { + class icu_calendar_facet : public calendar_facet { public: - icu_calendar_facet(cdata const &d,size_t refs = 0) : - calendar_facet(refs), - data_(d) - { - } - abstract_calendar *create_calendar() const BOOST_OVERRIDE - { - return new calendar_impl(data_); - } + icu_calendar_facet(const cdata& d, size_t refs = 0) : calendar_facet(refs), data_(d) {} + abstract_calendar* create_calendar() const override { return new calendar_impl(data_); } + private: cdata data_; }; - std::locale create_calendar(std::locale const &in,cdata const &d) + std::locale create_calendar(const std::locale& in, const cdata& d) { - return std::locale(in,new icu_calendar_facet(d)); + return std::locale(in, new icu_calendar_facet(d)); } -} // impl_icu -} // locale -} // boost - - - - +}}} // namespace boost::locale::impl_icu 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 24a7e918ad..7fe2a3b70a 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/icu/formatter.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/icu/formatter.cpp @@ -1,249 +1,192 @@ // // Copyright (c) 2009-2011 Artyom Beilis (Tonkikh) +// Copyright (c) 2021-2022 Alexander Grund // // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt #define BOOST_LOCALE_SOURCE -#include <boost/locale/formatting.hpp> #include "boost/locale/icu/formatter.hpp" +#include <boost/locale/formatting.hpp> #include <boost/locale/info.hpp> -#include "boost/locale/icu/uconv.hpp" -#include "boost/locale/icu/predefined_formatters.hpp" +#include "boost/locale/icu/formatters_cache.hpp" +#include "boost/locale/icu/icu_util.hpp" #include "boost/locale/icu/time_zone.hpp" -#include <boost/core/ignore_unused.hpp> - +#include "boost/locale/icu/uconv.hpp" +#include <limits> +#include <memory> +#include <unicode/datefmt.h> +#include <unicode/decimfmt.h> #include <unicode/numfmt.h> #include <unicode/rbnf.h> -#include <unicode/datefmt.h> #include <unicode/smpdtfmt.h> -#include <unicode/decimfmt.h> -#include <limits> -#include <iostream> #ifdef BOOST_MSVC -# pragma warning(disable : 4244) // lose data +# pragma warning(disable : 4244) // lose data #endif -namespace boost { -namespace locale { - namespace impl_icu { - - - std::locale::id icu_formatters_cache::id; - - namespace { - struct init { init() { ignore_unused(std::has_facet<icu_formatters_cache>(std::locale::classic())); } } instance; - } - - - template<typename CharType> - class number_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 BOOST_OVERRIDE - { - icu::UnicodeString tmp; - icu_fmt_->format(value,tmp); - code_points=tmp.countChar32(); - return cvt_.std(tmp); - } - string_type format(int64_t value,size_t &code_points) const BOOST_OVERRIDE - { - icu::UnicodeString tmp; - icu_fmt_->format(static_cast< ::int64_t>(value),tmp); - code_points=tmp.countChar32(); - return cvt_.std(tmp); - } - - string_type format(int32_t value,size_t &code_points) const BOOST_OVERRIDE - { - icu::UnicodeString tmp; - #ifdef __SUNPRO_CC - icu_fmt_->format(static_cast<int>(value),tmp); - #else - icu_fmt_->format(::int32_t(value),tmp); - #endif - code_points=tmp.countChar32(); - return cvt_.std(tmp); - } - - size_t parse(string_type const &str,double &value) const BOOST_OVERRIDE - { - return do_parse(str,value); - } - - size_t parse(string_type const &str,int64_t &value) const BOOST_OVERRIDE - { - return do_parse(str,value); - } - size_t parse(string_type const &str,int32_t &value) const BOOST_OVERRIDE - { - return do_parse(str,value); - } +namespace boost { namespace locale { namespace impl_icu { - number_format(icu::NumberFormat *fmt,std::string codepage) : - cvt_(codepage), - icu_fmt_(fmt) - { + namespace { + // Set the min/max fraction digits for the NumberFormat + void set_fraction_digits(icu::NumberFormat& nf, const std::ios_base::fmtflags how, std::streamsize precision) + { +#if BOOST_LOCALE_ICU_VERSION >= 5601 + // Since ICU 56.1 the integer part counts to the fraction part + if(how == std::ios_base::scientific) + precision += nf.getMaximumIntegerDigits(); +#endif + nf.setMaximumFractionDigits(precision); + if(how == std::ios_base::scientific || how == std::ios_base::fixed) { + nf.setMinimumFractionDigits(precision); + } else { + nf.setMinimumFractionDigits(0); } + } + } // namespace - private: + template<typename CharType> + class number_format : public formatter<CharType> { + public: + typedef CharType char_type; + typedef std::basic_string<CharType> string_type; - bool get_value(double &v,icu::Formattable &fmt) const - { - UErrorCode err=U_ZERO_ERROR; - v=fmt.getDouble(err); - if(U_FAILURE(err)) - return false; - return true; - } + number_format(icu::NumberFormat& fmt, std::string codepage) : cvt_(codepage), icu_fmt_(fmt) {} - bool get_value(int64_t &v,icu::Formattable &fmt) const - { - UErrorCode err=U_ZERO_ERROR; - v=fmt.getInt64(err); - if(U_FAILURE(err)) - return false; - return true; - } + string_type format(double value, size_t& code_points) const override { return do_format(value, code_points); } + string_type format(int64_t value, size_t& code_points) const override { return do_format(value, code_points); } + string_type format(int32_t value, size_t& code_points) const override { return do_format(value, code_points); } + size_t parse(const string_type& str, double& value) const override { return do_parse(str, value); } + size_t parse(const string_type& str, int64_t& value) const override { return do_parse(str, value); } + size_t parse(const string_type& str, int32_t& value) const override { return do_parse(str, value); } - bool get_value(int32_t &v,icu::Formattable &fmt) const - { - UErrorCode err=U_ZERO_ERROR; - v=fmt.getLong(err); - if(U_FAILURE(err)) - return false; - return true; - } - - template<typename ValueType> - size_t do_parse(string_type const &str,ValueType &v) const - { - icu::Formattable val; - icu::ParsePosition pp; - icu::UnicodeString tmp = cvt_.icu(str.data(),str.data()+str.size()); + private: + bool get_value(double& v, icu::Formattable& fmt) const + { + UErrorCode err = U_ZERO_ERROR; + v = fmt.getDouble(err); + if(U_FAILURE(err)) + return false; + return true; + } - icu_fmt_->parse(tmp,val,pp); + bool get_value(int64_t& v, icu::Formattable& fmt) const + { + UErrorCode err = U_ZERO_ERROR; + v = fmt.getInt64(err); + if(U_FAILURE(err)) + return false; + return true; + } - ValueType tmp_v; + bool get_value(int32_t& v, icu::Formattable& fmt) const + { + UErrorCode err = U_ZERO_ERROR; + v = fmt.getLong(err); + if(U_FAILURE(err)) + return false; + return true; + } - if(pp.getIndex() == 0 || !get_value(tmp_v,val)) - return 0; - size_t cut = cvt_.cut(tmp,str.data(),str.data()+str.size(),pp.getIndex()); - if(cut==0) - return 0; - v=tmp_v; - return cut; - } + template<typename ValueType> + string_type do_format(ValueType value, size_t& code_points) const + { + icu::UnicodeString tmp; + icu_fmt_.format(value, tmp); + code_points = tmp.countChar32(); + return cvt_.std(tmp); + } - icu_std_converter<CharType> cvt_; - icu::NumberFormat *icu_fmt_; - }; + template<typename ValueType> + size_t do_parse(const string_type& str, ValueType& v) const + { + icu::Formattable val; + icu::ParsePosition pp; + icu::UnicodeString tmp = cvt_.icu(str.data(), str.data() + str.size()); + icu_fmt_.parse(tmp, val, pp); - template<typename CharType> - class date_format : public formatter<CharType> { - public: - typedef CharType char_type; - typedef std::basic_string<CharType> string_type; + ValueType tmp_v; - string_type format(double value,size_t &code_points) const BOOST_OVERRIDE - { - return do_format(value,code_points); - } - string_type format(int64_t value,size_t &code_points) const BOOST_OVERRIDE - { - return do_format(value,code_points); - } + if(pp.getIndex() == 0 || !get_value(tmp_v, val)) + return 0; + size_t cut = cvt_.cut(tmp, str.data(), str.data() + str.size(), pp.getIndex()); + if(cut == 0) + return 0; + v = tmp_v; + return cut; + } - string_type format(int32_t value,size_t &code_points) const BOOST_OVERRIDE - { - return do_format(value,code_points); - } + icu_std_converter<CharType> cvt_; + icu::NumberFormat& icu_fmt_; + }; - size_t parse(string_type const &str,double &value) const BOOST_OVERRIDE - { - return do_parse(str,value); - } - size_t parse(string_type const &str,int64_t &value) const BOOST_OVERRIDE - { - return do_parse(str,value); - } - size_t parse(string_type const &str,int32_t &value) const BOOST_OVERRIDE - { - return do_parse(str,value); - } + template<typename CharType> + class date_format : public formatter<CharType> { + public: + typedef CharType char_type; + typedef std::basic_string<CharType> string_type; - date_format(icu::DateFormat *fmt,bool transfer_owneship,std::string codepage) : - cvt_(codepage) - { - if(transfer_owneship) { - aicu_fmt_.reset(fmt); - icu_fmt_ = aicu_fmt_.get(); - } - else { - icu_fmt_ = fmt; - } - } + string_type format(double value, size_t& code_points) const override { return do_format(value, code_points); } + string_type format(int64_t value, size_t& code_points) const override { return do_format(value, code_points); } - private: - - template<typename ValueType> - size_t do_parse(string_type const &str,ValueType &value) const - { - icu::ParsePosition pp; - icu::UnicodeString tmp = cvt_.icu(str.data(),str.data() + str.size()); - - UDate udate = icu_fmt_->parse(tmp,pp); - if(pp.getIndex() == 0) - return 0; - double date = udate / 1000.0; - typedef std::numeric_limits<ValueType> limits_type; - if(date > limits_type::max() || date < limits_type::min()) - return 0; - size_t cut = cvt_.cut(tmp,str.data(),str.data()+str.size(),pp.getIndex()); - if(cut==0) - return 0; - value=static_cast<ValueType>(date); - return cut; + string_type format(int32_t value, size_t& code_points) const override { return do_format(value, code_points); } - } + size_t parse(const string_type& str, double& value) const override { return do_parse(str, value); } + size_t parse(const string_type& str, int64_t& value) const override { return do_parse(str, value); } + size_t parse(const string_type& str, int32_t& value) const override { return do_parse(str, value); } - string_type do_format(double value,size_t &codepoints) const - { - UDate date = value * 1000.0; /// UDate is time_t in miliseconds - icu::UnicodeString tmp; - icu_fmt_->format(date,tmp); - codepoints=tmp.countChar32(); - return cvt_.std(tmp); - } + date_format(icu::DateFormat& fmt, const std::string& encoding) : cvt_(encoding), icu_fmt_(fmt) {} + date_format(std::unique_ptr<icu::DateFormat> fmt, const std::string& encoding) : + cvt_(encoding), icu_fmt_holder_(std::move(fmt)), icu_fmt_(*icu_fmt_holder_) + {} - icu_std_converter<CharType> cvt_; - hold_ptr<icu::DateFormat> aicu_fmt_; - icu::DateFormat *icu_fmt_; - }; + private: + template<typename ValueType> + size_t do_parse(const string_type& str, ValueType& value) const + { + icu::ParsePosition pp; + icu::UnicodeString tmp = cvt_.icu(str.data(), str.data() + str.size()); + + UDate udate = icu_fmt_.parse(tmp, pp); + if(pp.getIndex() == 0) + return 0; + double date = udate / 1000.0; + typedef std::numeric_limits<ValueType> limits_type; + // Explicit cast to double to avoid warnings changing value (e.g. for INT64_MAX -> double) + if(date > static_cast<double>(limits_type::max()) || date < static_cast<double>(limits_type::min())) + return 0; + size_t cut = cvt_.cut(tmp, str.data(), str.data() + str.size(), pp.getIndex()); + if(cut == 0) + return 0; + // Handle the edge case where the double is slightly out of range and hence the cast would be UB + // by rounding to the min/max values + if(date == static_cast<double>(limits_type::max())) + value = limits_type::max(); + else if(date == static_cast<double>(limits_type::min())) + value = limits_type::min(); + else + value = static_cast<ValueType>(date); + return cut; + } - icu::UnicodeString strftime_to_icu_full(icu::DateFormat *dfin,char const *alt) + string_type do_format(double value, size_t& codepoints) const { - hold_ptr<icu::DateFormat> df(dfin); - icu::SimpleDateFormat *sdf=dynamic_cast<icu::SimpleDateFormat *>(df.get()); + UDate date = value * 1000.0; /// UDate is time_t in milliseconds icu::UnicodeString tmp; - if(sdf) { - sdf->toPattern(tmp); - } - else { - tmp=alt; - } - return tmp; - + icu_fmt_.format(date, tmp); + codepoints = tmp.countChar32(); + return cvt_.std(tmp); } - icu::UnicodeString strftime_to_icu_symbol(char c,icu::Locale const &locale,icu_formatters_cache const *cache=0) - { - switch(c) { + icu_std_converter<CharType> cvt_; + std::unique_ptr<icu::DateFormat> icu_fmt_holder_; + icu::DateFormat& icu_fmt_; + }; + + icu::UnicodeString strftime_symbol_to_icu(const char c, const formatters_cache& cache) + { + switch(c) { case 'a': // Abbr Weekday return "EE"; case 'A': // Full Weekday @@ -252,18 +195,10 @@ namespace locale { return "MMM"; case 'B': // Full Month return "MMMM"; - case 'c': // DateTile Full - { - if(cache) - return cache->date_time_format_[1][1]; - return strftime_to_icu_full( - icu::DateFormat::createDateTimeInstance(icu::DateFormat::kFull,icu::DateFormat::kFull,locale), - "yyyy-MM-dd HH:mm:ss" - ); - } + case 'c': // DateTime + return cache.default_date_time_format(); // not supported by ICU ;( // case 'C': // Century -> 1980 -> 19 - // retur case 'd': // Day of Month [01,31] return "dd"; case 'D': // %m/%d/%y @@ -296,29 +231,15 @@ namespace locale { return "\t"; case 'T': // %H:%M:%S return "HH:mm:ss"; -/* case 'u': // weekday 1,7 1=Monday - case 'U': // week number of year [00,53] Sunday first - case 'V': // week number of year [01,53] Moday first - case 'w': // weekday 0,7 0=Sunday - case 'W': // week number of year [00,53] Moday first, */ + /* case 'u': // weekday 1,7 1=Monday + case 'U': // week number of year [00,53] Sunday first + case 'V': // week number of year [01,53] Monday first + case 'w': // weekday 0,7 0=Sunday + case 'W': // week number of year [00,53] Monday first, */ case 'x': // Date - { - if(cache) - return cache->date_format_[1]; - return strftime_to_icu_full( - icu::DateFormat::createDateInstance(icu::DateFormat::kMedium,locale), - "yyyy-MM-dd" - ); - } + return cache.default_date_format(); case 'X': // Time - { - if(cache) - return cache->time_format_[1]; - return strftime_to_icu_full( - icu::DateFormat::createTimeInstance(icu::DateFormat::kMedium,locale), - "HH:mm:ss" - ); - } + return cache.default_time_format(); case 'y': // Year [00-99] return "yy"; case 'Y': // Year 1998 @@ -327,283 +248,213 @@ namespace locale { return "vvvv"; case '%': // % return "%"; - default: - return ""; - } + default: return ""; } + } - icu::UnicodeString strftime_to_icu(icu::UnicodeString const &ftime,icu::Locale const &locale) - { - unsigned len=ftime.length(); - icu::UnicodeString result; - bool escaped=false; - for(unsigned i=0;i<len;i++) { - UChar c=ftime[i]; - if(c=='%') { + icu::UnicodeString strftime_to_icu(const icu::UnicodeString& ftime, const formatters_cache& cache) + { + const unsigned len = ftime.length(); + icu::UnicodeString result; + bool escaped = false; + for(unsigned i = 0; i < len; i++) { + UChar c = ftime[i]; + if(c == '%') { + i++; + c = ftime[i]; + if(c == 'E' || c == 'O') { i++; - c=ftime[i]; - if(c=='E' || c=='O') { - i++; - c=ftime[i]; - } - if(escaped) { - result+="'"; - escaped=false; - } - result+=strftime_to_icu_symbol(c,locale); + c = ftime[i]; } - else if(c=='\'') { - result+="''"; + if(escaped) { + result += "'"; + escaped = false; } - else { - if(!escaped) { - result+="'"; - escaped=true; - } - result+=c; + result += strftime_symbol_to_icu(c, cache); + } else if(c == '\'') { + result += "''"; + } else { + if(!escaped) { + result += "'"; + escaped = true; } + result += c; } - if(escaped) - result+="'"; - return result; } + if(escaped) + result += "'"; + return result; + } - template<typename CharType> - formatter<CharType> *generate_formatter( - std::ios_base &ios, - icu::Locale const &locale, - std::string const &encoding) - { + format_len time_flags_to_len(const uint64_t time_flags) + { + switch(time_flags) { using namespace boost::locale::flags; + case time_short: return format_len::Short; + case time_medium: return format_len::Medium; + case time_long: return format_len::Long; + case time_full: return format_len::Full; + default: return format_len::Medium; + } + } + format_len date_flags_to_len(const uint64_t date_flags) + { + switch(date_flags) { + using namespace boost::locale::flags; + case date_short: return format_len::Short; + case date_medium: return format_len::Medium; + case date_long: return format_len::Long; + case date_full: return format_len::Full; + default: return format_len::Medium; + } + } + icu::DateFormat::EStyle time_flags_to_icu_len(const uint64_t time_flags) + { + switch(time_flags) { + using namespace boost::locale::flags; + case time_short: return icu::DateFormat::kShort; + case time_medium: return icu::DateFormat::kMedium; + case time_long: return icu::DateFormat::kLong; + case time_full: return icu::DateFormat::kFull; + case time_default: + default: return icu::DateFormat::kDefault; + } + } + icu::DateFormat::EStyle date_flags_to_icu_len(const uint64_t date_flags) + { + switch(date_flags) { + using namespace boost::locale::flags; + case date_short: return icu::DateFormat::kShort; + case date_medium: return icu::DateFormat::kMedium; + case date_long: return icu::DateFormat::kLong; + case date_full: return icu::DateFormat::kFull; + case date_default: + default: return icu::DateFormat::kDefault; + } + } - hold_ptr<formatter<CharType> > fmt; - ios_info &info=ios_info::get(ios); - uint64_t disp = info.display_flags(); - - icu_formatters_cache const &cache = std::use_facet<icu_formatters_cache>(ios.getloc()); - - - if(disp == posix) - return fmt.release(); - - UErrorCode err=U_ZERO_ERROR; - - switch(disp) { - case number: - { - std::ios_base::fmtflags how = (ios.flags() & std::ios_base::floatfield); - icu::NumberFormat *nf = 0; - - if(how == std::ios_base::scientific) - nf = cache.number_format(icu_formatters_cache::fmt_sci); - else - nf = cache.number_format(icu_formatters_cache::fmt_number); - - nf->setMaximumFractionDigits(ios.precision()); - if(how == std::ios_base::scientific || how == std::ios_base::fixed ) { - nf->setMinimumFractionDigits(ios.precision()); - } - else { - nf->setMinimumFractionDigits(0); - } - fmt.reset(new number_format<CharType>(nf,encoding)); - } - break; - case currency: - { - icu::NumberFormat *nf; - - uint64_t curr = info.currency_flags(); - - if(curr == currency_default || curr == currency_national) - nf = cache.number_format(icu_formatters_cache::fmt_curr_nat); - else - nf = cache.number_format(icu_formatters_cache::fmt_curr_iso); + template<typename CharType> + std::unique_ptr<formatter<CharType>> + formatter<CharType>::create(std::ios_base& ios, const icu::Locale& locale, const std::string& encoding) + { + using ptr_type = std::unique_ptr<formatter<CharType>>; - fmt.reset(new number_format<CharType>(nf,encoding)); - } - break; - case percent: - { - icu::NumberFormat *nf = cache.number_format(icu_formatters_cache::fmt_per); - nf->setMaximumFractionDigits(ios.precision()); - std::ios_base::fmtflags how = (ios.flags() & std::ios_base::floatfield); - if(how == std::ios_base::scientific || how == std::ios_base::fixed ) { - nf->setMinimumFractionDigits(ios.precision()); - } - else { - nf->setMinimumFractionDigits(0); - } - fmt.reset(new number_format<CharType>(nf,encoding)); + const ios_info& info = ios_info::get(ios); + const formatters_cache& cache = std::use_facet<formatters_cache>(ios.getloc()); - } - break; + const uint64_t disp = info.display_flags(); + switch(disp) { + using namespace boost::locale::flags; + case posix: + BOOST_ASSERT_MSG(false, "Shouldn't try to create a posix formatter"); // LCOV_EXCL_LINE + break; // LCOV_EXCL_LINE + case number: { + const std::ios_base::fmtflags how = (ios.flags() & std::ios_base::floatfield); + icu::NumberFormat& nf = + cache.number_format((how == std::ios_base::scientific) ? num_fmt_type::sci : num_fmt_type::number); + set_fraction_digits(nf, how, ios.precision()); + return ptr_type(new number_format<CharType>(nf, encoding)); + } + case currency: { + icu::NumberFormat& nf = cache.number_format( + (info.currency_flags() == currency_iso) ? num_fmt_type::curr_iso : num_fmt_type::curr_nat); + return ptr_type(new number_format<CharType>(nf, encoding)); + } + case percent: { + icu::NumberFormat& nf = cache.number_format(num_fmt_type::percent); + set_fraction_digits(nf, ios.flags() & std::ios_base::floatfield, ios.precision()); + return ptr_type(new number_format<CharType>(nf, encoding)); + } case spellout: - fmt.reset(new number_format<CharType>(cache.number_format(icu_formatters_cache::fmt_spell),encoding)); - break; + return ptr_type(new number_format<CharType>(cache.number_format(num_fmt_type::spell), encoding)); case ordinal: - fmt.reset(new number_format<CharType>(cache.number_format(icu_formatters_cache::fmt_ord),encoding)); - break; + return ptr_type(new number_format<CharType>(cache.number_format(num_fmt_type::ordinal), encoding)); case date: case time: case datetime: - case strftime: + case strftime: { + using namespace flags; + std::unique_ptr<icu::DateFormat> new_df; + icu::DateFormat* df = 0; + // try to use cached first { - using namespace flags; - hold_ptr<icu::DateFormat> adf; - icu::DateFormat *df = 0; - icu::SimpleDateFormat *sdf = cache.date_formatter(); - // try to use cached first + icu::SimpleDateFormat* sdf = cache.date_formatter(); if(sdf) { - int tmf=info.time_flags(); - switch(tmf) { - case time_short: - tmf=0; - break; - case time_long: - tmf=2; - break; - case time_full: - tmf=3; - break; - case time_default: - case time_medium: - default: - tmf=1; - } - int dtf=info.date_flags(); - switch(dtf) { - case date_short: - dtf=0; - break; - case date_long: - dtf=2; - break; - case date_full: - dtf=3; - break; - case date_default: - case date_medium: - default: - dtf=1; - } - icu::UnicodeString pattern; switch(disp) { - case date: - pattern = cache.date_format_[dtf]; - break; - case time: - pattern = cache.time_format_[tmf]; - break; - case datetime: - pattern = cache.date_time_format_[dtf][tmf]; - break; - case strftime: - { - if( !cache.date_format_[1].isEmpty() - && !cache.time_format_[1].isEmpty() - && !cache.date_time_format_[1][1].isEmpty()) - { - icu_std_converter<CharType> cvt_(encoding); - std::basic_string<CharType> const &f=info.date_time_pattern<CharType>(); - pattern = strftime_to_icu(cvt_.icu(f.c_str(),f.c_str()+f.size()),locale); - } - } - break; + case date: pattern = cache.date_format(date_flags_to_len(info.date_flags())); break; + case time: pattern = cache.time_format(time_flags_to_len(info.time_flags())); break; + case datetime: + pattern = cache.date_time_format(date_flags_to_len(info.date_flags()), + time_flags_to_len(info.time_flags())); + break; + case strftime: { + icu_std_converter<CharType> cvt_(encoding); + 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; } if(!pattern.isEmpty()) { sdf->applyPattern(pattern); df = sdf; - sdf = 0; } - sdf = 0; } + } - if(!df) { - icu::DateFormat::EStyle dstyle = icu::DateFormat::kDefault; - icu::DateFormat::EStyle tstyle = icu::DateFormat::kDefault; - - switch(info.time_flags()) { - case time_short: tstyle=icu::DateFormat::kShort; break; - case time_medium: tstyle=icu::DateFormat::kMedium; break; - case time_long: tstyle=icu::DateFormat::kLong; break; - case time_full: tstyle=icu::DateFormat::kFull; break; - } - switch(info.date_flags()) { - case date_short: dstyle=icu::DateFormat::kShort; break; - case date_medium: dstyle=icu::DateFormat::kMedium; break; - case date_long: dstyle=icu::DateFormat::kLong; break; - case date_full: dstyle=icu::DateFormat::kFull; break; - } - - if(disp==date) - adf.reset(icu::DateFormat::createDateInstance(dstyle,locale)); - else if(disp==time) - adf.reset(icu::DateFormat::createTimeInstance(tstyle,locale)); - else if(disp==datetime) - adf.reset(icu::DateFormat::createDateTimeInstance(dstyle,tstyle,locale)); - else {// strftime + if(!df) { + switch(disp) { + case date: + new_df.reset( + icu::DateFormat::createDateInstance(date_flags_to_icu_len(info.date_flags()), locale)); + break; + case time: + new_df.reset( + icu::DateFormat::createTimeInstance(time_flags_to_icu_len(info.time_flags()), locale)); + break; + case datetime: + new_df.reset( + icu::DateFormat::createDateTimeInstance(date_flags_to_icu_len(info.date_flags()), + time_flags_to_icu_len(info.time_flags()), + locale)); + break; + case strftime: { icu_std_converter<CharType> cvt_(encoding); - std::basic_string<CharType> const &f=info.date_time_pattern<CharType>(); - icu::UnicodeString pattern = strftime_to_icu(cvt_.icu(f.data(),f.data()+f.size()),locale); - adf.reset(new icu::SimpleDateFormat(pattern,locale,err)); - } - if(U_FAILURE(err)) - return fmt.release(); - df = adf.get(); + 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; + new_df.reset(new icu::SimpleDateFormat(pattern, locale, err)); + if(U_FAILURE(err)) + return nullptr; + } break; } - - df->adoptTimeZone(get_time_zone(info.time_zone())); - - // Depending if we own formatter or not - if(adf.get()) - fmt.reset(new date_format<CharType>(adf.release(),true,encoding)); - else - fmt.reset(new date_format<CharType>(df,false,encoding)); + df = new_df.get(); + BOOST_ASSERT_MSG(df, "Failed to create date/time formatter"); } - break; - } - - return fmt.release(); - } - - - - template<> - formatter<char> *formatter<char>::create(std::ios_base &ios,icu::Locale const &l,std::string const &e) - { - return generate_formatter<char>(ios,l,e); - } - template<> - formatter<wchar_t> *formatter<wchar_t>::create(std::ios_base &ios,icu::Locale const &l,std::string const &e) - { - return generate_formatter<wchar_t>(ios,l,e); - } - - - #ifdef BOOST_LOCALE_ENABLE_CHAR16_T - template<> - formatter<char16_t> *formatter<char16_t>::create(std::ios_base &ios,icu::Locale const &l,std::string const &e) - { - return generate_formatter<char16_t>(ios,l,e); - } + df->adoptTimeZone(get_time_zone(info.time_zone())); - #endif + // Depending if we own formatter or not + if(new_df) + return ptr_type(new date_format<CharType>(std::move(new_df), encoding)); + else + return ptr_type(new date_format<CharType>(*df, encoding)); + } break; + } - #ifdef BOOST_LOCALE_ENABLE_CHAR32_T - template<> - formatter<char32_t> *formatter<char32_t>::create(std::ios_base &ios,icu::Locale const &l,std::string const &e) - { - return generate_formatter<char32_t>(ios,l,e); + return nullptr; // LCOV_EXCL_LINE } - #endif + template class formatter<char>; + template class formatter<wchar_t>; -} // impl_icu +#ifdef BOOST_LOCALE_ENABLE_CHAR16_T + template class formatter<char16_t>; +#endif -} // locale -} // boost +#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 e502916b02..cc55e76e2e 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/icu/formatter.hpp +++ b/contrib/restricted/boost/locale/src/boost/locale/icu/formatter.hpp @@ -9,72 +9,53 @@ #include <boost/locale/config.hpp> #include <boost/cstdint.hpp> -#include <string> #include <memory> +#include <string> #include <unicode/locid.h> -namespace boost { -namespace locale { -namespace impl_icu { - - /// - /// \brief Special base polymorphic class that is used as a character type independent base for all formatter classes - /// +namespace boost { namespace locale { namespace impl_icu { + /// \brief Special base polymorphic class that is used as a character type independent base for all formatter + /// classes class base_formatter { public: - virtual ~base_formatter() {} + virtual ~base_formatter() = default; }; - /// /// \brief A class that is used for formatting numbers, currency and dates/times - /// 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 - /// - virtual string_type format(double value,size_t &code_points) const = 0; - /// + virtual string_type format(double value, size_t& code_points) const = 0; /// Format the value and return the number of Unicode code points - /// - virtual string_type format(int64_t value,size_t &code_points) const = 0; - /// + virtual string_type format(int64_t value, size_t& code_points) const = 0; /// Format the value and return the number of Unicode code points - /// - virtual string_type format(int32_t value,size_t &code_points) const = 0; + virtual string_type format(int32_t value, size_t& code_points) const = 0; - /// /// Parse the string and return the number of used characters. If it returns 0 /// then parsing failed. - /// - virtual size_t parse(string_type const &str,double &value) const = 0; - /// + virtual size_t parse(const string_type& str, double& value) const = 0; /// Parse the string and return the number of used characters. If it returns 0 /// then parsing failed. - /// - virtual size_t parse(string_type const &str,int64_t &value) const = 0; - /// + virtual size_t parse(const string_type& str, int64_t& value) const = 0; /// Parse the string and return the number of used characters. If it returns 0 /// then parsing failed. - /// - virtual size_t parse(string_type const &str,int32_t &value) const = 0; + virtual size_t parse(const string_type& str, int32_t& value) const = 0; - /// /// Get formatter for the current state of ios_base -- flags and locale, /// NULL may be returned if an invalid combination of flags is provided or this type - /// of formatting is not supported by locale. See: create + /// of formatting is not supported by locale. /// /// Note: formatter is cached. If \a ios is not changed (no flags or locale changed) /// the formatter would remain the same. Otherwise it would be rebuild and cached /// for future use. It is useful for saving time for generation /// of multiple values with same locale. /// - /// For example, this code: + /// For example this code will create a new spelling formatter only once: /// /// \code /// std::cout << as::spellout; @@ -82,43 +63,11 @@ namespace impl_icu { /// std::cout << i << std::endl; /// \endcode /// - /// Would create a new spelling formatter only once. /// - static formatter *create(std::ios_base &ios,icu::Locale const &l,std::string const &enc); + static std::unique_ptr<formatter> + create(std::ios_base& ios, const icu::Locale& locale, const std::string& encoding); }; // class formatter - /// - /// Specialization for real implementation - /// - template<> - formatter<char> *formatter<char>::create(std::ios_base &ios,icu::Locale const &l,std::string const &enc); - - /// - /// Specialization for real implementation - /// - template<> - formatter<wchar_t> *formatter<wchar_t>::create(std::ios_base &ios,icu::Locale const &l,std::string const &e); - - #ifdef BOOST_LOCALE_ENABLE_CHAR16_T - /// - /// Specialization for real implementation - /// - template<> - formatter<char16_t> *formatter<char16_t>::create(std::ios_base &ios,icu::Locale const &l,std::string const &e); - #endif - - #ifdef BOOST_LOCALE_ENABLE_CHAR32_T - /// - /// Specialization for real implementation - /// - template<> - formatter<char32_t> *formatter<char32_t>::create(std::ios_base &ios,icu::Locale const &l,std::string const &e); - #endif - -} // namespace impl_icu -} // namespace locale -} // namespace boost - - +}}} // namespace boost::locale::impl_icu #endif diff --git a/contrib/restricted/boost/locale/src/boost/locale/icu/formatters_cache.cpp b/contrib/restricted/boost/locale/src/boost/locale/icu/formatters_cache.cpp new file mode 100644 index 0000000000..c9a8c46347 --- /dev/null +++ b/contrib/restricted/boost/locale/src/boost/locale/icu/formatters_cache.cpp @@ -0,0 +1,143 @@ +// +// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh) +// Copyright (c) 2021-2022 Alexander Grund +// +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include "boost/locale/icu/formatters_cache.hpp" +#include <boost/assert.hpp> +#include <boost/core/ignore_unused.hpp> +#include <memory> +#include <type_traits> +#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/numfmt.h> +#include <unicode/rbnf.h> +#include <unicode/smpdtfmt.h> +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + +namespace boost { namespace locale { namespace impl_icu { + + std::locale::id formatters_cache::id; + + namespace { + + struct init { + init() { ignore_unused(std::has_facet<formatters_cache>(std::locale::classic())); } + } instance; + + void get_icu_pattern(std::unique_ptr<icu::DateFormat> fmt, icu::UnicodeString& out_str) + { + icu::SimpleDateFormat* sfmt = icu_cast<icu::SimpleDateFormat>(fmt.get()); + if(sfmt) + sfmt->toPattern(out_str); + else + out_str.remove(); // LCOV_EXCL_LINE + } + void get_icu_pattern(icu::DateFormat* fmt, icu::UnicodeString& out_str) + { + return get_icu_pattern(std::unique_ptr<icu::DateFormat>(fmt), out_str); + } + } // namespace + + formatters_cache::formatters_cache(const icu::Locale& locale) : locale_(locale) + { +#define BOOST_LOCALE_ARRAY_SIZE(T) std::extent<typename std::remove_reference<decltype(T)>::type>::value + constexpr icu::DateFormat::EStyle styles[]{icu::DateFormat::kShort, + icu::DateFormat::kMedium, + icu::DateFormat::kLong, + icu::DateFormat::kFull}; + constexpr int num_styles = BOOST_LOCALE_ARRAY_SIZE(styles); + + static_assert(num_styles == BOOST_LOCALE_ARRAY_SIZE(date_format_), "!"); + for(int i = 0; i < num_styles; i++) + get_icu_pattern(icu::DateFormat::createDateInstance(styles[i], locale), date_format_[i]); + + static_assert(num_styles == BOOST_LOCALE_ARRAY_SIZE(time_format_), "!"); + for(int i = 0; i < num_styles; i++) + get_icu_pattern(icu::DateFormat::createTimeInstance(styles[i], locale), time_format_[i]); + + static_assert(num_styles == BOOST_LOCALE_ARRAY_SIZE(date_time_format_), "!"); + static_assert(num_styles == BOOST_LOCALE_ARRAY_SIZE(date_time_format_[0]), "!"); + for(int i = 0; i < num_styles; i++) { + for(int j = 0; j < num_styles; j++) { + get_icu_pattern(icu::DateFormat::createDateTimeInstance(styles[i], styles[j], locale), + date_time_format_[i][j]); + } + } +#undef BOOST_LOCALE_ARRAY_SIZE + + const auto get_str_or = [](const icu::UnicodeString& str, const char* default_str) { + return str.isEmpty() ? default_str : str; + }; + default_date_format_ = get_str_or(date_format(format_len::Medium), "yyyy-MM-dd"); + default_time_format_ = get_str_or(time_format(format_len::Medium), "HH:mm:ss"); + default_date_time_format_ = + get_str_or(date_time_format(format_len::Full, format_len::Full), "yyyy-MM-dd HH:mm:ss"); + } + + icu::NumberFormat* formatters_cache::create_number_format(num_fmt_type type, UErrorCode& err) const + { + switch(type) { + case num_fmt_type::number: return icu::NumberFormat::createInstance(locale_, err); break; + case num_fmt_type::sci: return icu::NumberFormat::createScientificInstance(locale_, err); break; +#if BOOST_LOCALE_ICU_VERSION >= 408 + case num_fmt_type::curr_nat: return icu::NumberFormat::createInstance(locale_, UNUM_CURRENCY, err); break; + case num_fmt_type::curr_iso: + return icu::NumberFormat::createInstance(locale_, UNUM_CURRENCY_ISO, err); + break; +#elif BOOST_LOCALE_ICU_VERSION >= 402 + case num_fmt_type::curr_nat: + return icu::NumberFormat::createInstance(locale_, icu::NumberFormat::kCurrencyStyle, err); + break; + case num_fmt_type::curr_iso: + return icu::NumberFormat::createInstance(locale_, icu::NumberFormat::kIsoCurrencyStyle, err); + break; +#else + case num_fmt_type::curr_nat: + case num_fmt_type::curr_iso: return icu::NumberFormat::createCurrencyInstance(locale_, err); break; +#endif + case num_fmt_type::percent: return icu::NumberFormat::createPercentInstance(locale_, err); break; + case num_fmt_type::spell: return new icu::RuleBasedNumberFormat(icu::URBNF_SPELLOUT, locale_, err); break; + case num_fmt_type::ordinal: return new icu::RuleBasedNumberFormat(icu::URBNF_ORDINAL, locale_, err); break; + } + throw std::logic_error("locale::internal error should not get there"); // LCOV_EXCL_LINE + } + + icu::NumberFormat& formatters_cache::number_format(num_fmt_type type) const + { + icu::NumberFormat* result = number_format_[int(type)].get(); + if(!result) { + UErrorCode err = U_ZERO_ERROR; + std::unique_ptr<icu::NumberFormat> new_ptr(create_number_format(type, err)); + check_and_throw_icu_error(err, "Failed to create a formatter"); + result = new_ptr.get(); + BOOST_ASSERT(result); + number_format_[int(type)].reset(new_ptr.release()); + } + return *result; + } + + icu::SimpleDateFormat* formatters_cache::date_formatter() const + { + icu::SimpleDateFormat* result = date_formatter_.get(); + if(!result) { + std::unique_ptr<icu::DateFormat> fmt( + icu::DateFormat::createDateTimeInstance(icu::DateFormat::kMedium, icu::DateFormat::kMedium, locale_)); + + result = icu_cast<icu::SimpleDateFormat>(fmt.get()); + if(result) { + fmt.release(); + date_formatter_.reset(result); + } + } + return result; + } + +}}} // namespace boost::locale::impl_icu diff --git a/contrib/restricted/boost/locale/src/boost/locale/icu/formatters_cache.hpp b/contrib/restricted/boost/locale/src/boost/locale/icu/formatters_cache.hpp new file mode 100644 index 0000000000..d0e4978d55 --- /dev/null +++ b/contrib/restricted/boost/locale/src/boost/locale/icu/formatters_cache.hpp @@ -0,0 +1,78 @@ +// +// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh) +// Copyright (c) 2021-2022 Alexander Grund +// +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_LOCALE_PREDEFINED_FORMATTERS_HPP_INCLUDED +#define BOOST_LOCALE_PREDEFINED_FORMATTERS_HPP_INCLUDED + +#include <boost/locale/config.hpp> +#include "boost/locale/icu/icu_util.hpp" +#include <boost/thread/tss.hpp> +#include <locale> + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4251) // "identifier" : class "type" needs to have dll-interface... +#endif +#include <unicode/locid.h> +#include <unicode/numfmt.h> +#include <unicode/smpdtfmt.h> +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + +namespace boost { namespace locale { namespace impl_icu { + + enum class format_len { + Short, + Medium, + Long, + Full, + }; + + enum class num_fmt_type { number, sci, curr_nat, curr_iso, percent, spell, ordinal }; + + class formatters_cache : public std::locale::facet { + public: + static std::locale::id id; + + formatters_cache(const icu::Locale& locale); + + icu::NumberFormat& number_format(num_fmt_type type) const; + + const icu::UnicodeString& date_format(format_len f) const { return date_format_[int(f)]; } + + const icu::UnicodeString& time_format(format_len f) const { return time_format_[int(f)]; } + + const icu::UnicodeString& date_time_format(format_len d, format_len t) const + { + return date_time_format_[int(d)][int(t)]; + } + + const icu::UnicodeString& default_date_format() const { return default_date_format_; } + const icu::UnicodeString& default_time_format() const { return default_time_format_; } + const icu::UnicodeString& default_date_time_format() const { return default_date_time_format_; } + + icu::SimpleDateFormat* date_formatter() const; + + private: + icu::NumberFormat* create_number_format(num_fmt_type type, UErrorCode& err) const; + + static constexpr auto num_fmt_type_count = static_cast<unsigned>(num_fmt_type::ordinal) + 1; + static constexpr auto format_len_count = static_cast<unsigned>(format_len::Full) + 1; + + mutable boost::thread_specific_ptr<icu::NumberFormat> number_format_[num_fmt_type_count]; + icu::UnicodeString date_format_[format_len_count]; + icu::UnicodeString time_format_[format_len_count]; + icu::UnicodeString date_time_format_[format_len_count][format_len_count]; + icu::UnicodeString default_date_format_, default_time_format_, default_date_time_format_; + mutable boost::thread_specific_ptr<icu::SimpleDateFormat> date_formatter_; + icu::Locale locale_; + }; + +}}} // namespace boost::locale::impl_icu + +#endif 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 133d547dd7..a0da62b4a9 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 @@ -5,56 +5,41 @@ // https://www.boost.org/LICENSE_1_0.txt #define BOOST_LOCALE_SOURCE -#include <boost/locale/localization_backend.hpp> +#include "boost/locale/icu/icu_backend.hpp" #include <boost/locale/gnu_gettext.hpp> +#include <boost/locale/localization_backend.hpp> #include <boost/locale/util.hpp> #include "boost/locale/icu/all_generator.hpp" #include "boost/locale/icu/cdata.hpp" -#include "boost/locale/icu/icu_backend.hpp" #include "boost/locale/util/locale_data.hpp" #include <algorithm> #include <iterator> #include <unicode/ucnv.h> -namespace boost { -namespace locale { -namespace impl_icu { +namespace boost { namespace locale { namespace impl_icu { class icu_localization_backend : public localization_backend { public: - icu_localization_backend() : - invalid_(true), - use_ansi_encoding_(false) - { - } - icu_localization_backend(icu_localization_backend const &other) : - localization_backend(), - paths_(other.paths_), - domains_(other.domains_), - locale_id_(other.locale_id_), - invalid_(true), - use_ansi_encoding_(other.use_ansi_encoding_) - { - } - icu_localization_backend *clone() const BOOST_OVERRIDE - { - return new icu_localization_backend(*this); - } + icu_localization_backend() : invalid_(true), use_ansi_encoding_(false) {} + icu_localization_backend(const icu_localization_backend& other) : + localization_backend(), paths_(other.paths_), domains_(other.domains_), locale_id_(other.locale_id_), + invalid_(true), use_ansi_encoding_(other.use_ansi_encoding_) + {} + icu_localization_backend* clone() const override { return new icu_localization_backend(*this); } - void set_option(std::string const &name,std::string const &value) BOOST_OVERRIDE + void set_option(const std::string& name, const std::string& value) override { invalid_ = true; - if(name=="locale") + if(name == "locale") locale_id_ = value; - else if(name=="message_path") + else if(name == "message_path") paths_.push_back(value); - else if(name=="message_application") + else if(name == "message_application") domains_.push_back(value); - else if(name=="use_ansi_encoding") + else if(name == "use_ansi_encoding") use_ansi_encoding_ = value == "true"; - } - void clear_options() BOOST_OVERRIDE + void clear_options() override { invalid_ = true; use_ansi_encoding_ = false; @@ -70,7 +55,7 @@ namespace impl_icu { invalid_ = false; real_id_ = locale_id_; if(real_id_.empty()) { - bool utf8 = ! use_ansi_encoding_; + bool utf8 = !use_ansi_encoding_; real_id_ = util::get_system_locale(utf8); } @@ -85,62 +70,51 @@ namespace impl_icu { variant_ = d.variant; } - std::locale install(std::locale const &base, - locale_category_type category, - character_facet_type type = nochar_facet) BOOST_OVERRIDE + std::locale install(const std::locale& base, category_t category, char_facet_t type) override { prepare_data(); switch(category) { - case convert_facet: - return create_convert(base,data_,type); - case collation_facet: - return create_collate(base,data_,type); - case formatting_facet: - return create_formatting(base,data_,type); - case parsing_facet: - return create_parsing(base,data_,type); - case codepage_facet: - return create_codecvt(base,data_.encoding,type); - case message_facet: - { + case category_t::convert: return create_convert(base, data_, type); + case category_t::collation: return create_collate(base, data_, type); + case category_t::formatting: return create_formatting(base, data_, type); + case category_t::parsing: return create_parsing(base, data_, type); + case category_t::codepage: return create_codecvt(base, data_.encoding, type); + case category_t::message: { gnu_gettext::messages_info minf; minf.language = language_; minf.country = country_; minf.variant = variant_; minf.encoding = data_.encoding; - std::copy(domains_.begin(),domains_.end(),std::back_inserter<gnu_gettext::messages_info::domains_type>(minf.domains)); + std::copy(domains_.begin(), + domains_.end(), + std::back_inserter<gnu_gettext::messages_info::domains_type>(minf.domains)); minf.paths = paths_; switch(type) { - case char_facet: - return std::locale(base,gnu_gettext::create_messages_facet<char>(minf)); - case wchar_t_facet: - return std::locale(base,gnu_gettext::create_messages_facet<wchar_t>(minf)); - #ifdef BOOST_LOCALE_ENABLE_CHAR16_T - case char16_t_facet: - return std::locale(base,gnu_gettext::create_messages_facet<char16_t>(minf)); - #endif - #ifdef BOOST_LOCALE_ENABLE_CHAR32_T - case char32_t_facet: - return std::locale(base,gnu_gettext::create_messages_facet<char32_t>(minf)); - #endif - default: - return base; + case char_facet_t::nochar: break; + case char_facet_t::char_f: + return std::locale(base, gnu_gettext::create_messages_facet<char>(minf)); + case char_facet_t::wchar_f: + return std::locale(base, gnu_gettext::create_messages_facet<wchar_t>(minf)); +#ifdef BOOST_LOCALE_ENABLE_CHAR16_T + case char_facet_t::char16_f: + return std::locale(base, gnu_gettext::create_messages_facet<char16_t>(minf)); +#endif +#ifdef BOOST_LOCALE_ENABLE_CHAR32_T + case char_facet_t::char32_f: + return std::locale(base, gnu_gettext::create_messages_facet<char32_t>(minf)); +#endif } + return base; } - case boundary_facet: - return create_boundary(base,data_,type); - case calendar_facet: - return create_calendar(base,data_); - case information_facet: - return util::create_info(base,real_id_); - default: - return base; + case category_t::boundary: return create_boundary(base, data_, type); + case category_t::calendar: return create_calendar(base, data_); + case category_t::information: return util::create_info(base, real_id_); } + return base; } private: - std::vector<std::string> paths_; std::vector<std::string> domains_; std::string locale_id_; @@ -154,11 +128,9 @@ namespace impl_icu { bool use_ansi_encoding_; }; - localization_backend *create_localization_backend() + localization_backend* create_localization_backend() { return new icu_localization_backend(); } -} // impl icu -} // locale -} // boost +}}} // 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 ceb381b6dc..3dc2ca53ea 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 @@ -9,13 +9,10 @@ #include <boost/locale/config.hpp> -namespace boost { - namespace locale { - class localization_backend; - namespace impl_icu { - localization_backend *create_localization_backend(); - } // impl_icu - } // locale -} // boost +namespace boost { namespace locale { + class localization_backend; + namespace impl_icu { + 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 ba50473c12..871e3f8488 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 @@ -1,5 +1,6 @@ // // Copyright (c) 2009-2011 Artyom Beilis (Tonkikh) +// Copyright (c) 2021-2022 Alexander Grund // // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt @@ -9,30 +10,40 @@ #include <boost/locale/config.hpp> #ifdef BOOST_HAS_STDINT_H -#include <stdint.h> // Avoid ICU defining e.g. INT8_MIN causing macro redefinition warnings +# include <stdint.h> // Avoid ICU defining e.g. INT8_MIN causing macro redefinition warnings #endif +#include <stdexcept> +#include <string> #include <unicode/utypes.h> #include <unicode/uversion.h> -#include <stdexcept> #define BOOST_LOCALE_ICU_VERSION (U_ICU_VERSION_MAJOR_NUM * 100 + U_ICU_VERSION_MINOR_NUM) -namespace boost { -namespace locale { -namespace impl_icu { +namespace boost { namespace locale { namespace impl_icu { - inline void throw_icu_error(UErrorCode err) + inline void throw_icu_error(UErrorCode err, std::string desc) // LCOV_EXCL_LINE { - throw std::runtime_error(u_errorName(err)); + if(!desc.empty()) // LCOV_EXCL_LINE + desc += ": "; // LCOV_EXCL_LINE + throw std::runtime_error(desc + u_errorName(err)); // LCOV_EXCL_LINE } - inline void check_and_throw_icu_error(UErrorCode err) + inline void check_and_throw_icu_error(UErrorCode err, const char* desc = "") { if(U_FAILURE(err)) - throw_icu_error(err); + throw_icu_error(err, desc); // LCOV_EXCL_LINE + } + + /// Cast a pointer to an ICU object to a pointer to TargetType + /// using RTTI or ICUs "poor man's RTTI" to make it work with e.g. libc++ and hidden visibility + template<class TargetType, class SourceType> + TargetType* icu_cast(SourceType* p) + { + TargetType* result = dynamic_cast<TargetType*>(p); + if(!result && p && p->getDynamicClassID() == TargetType::getStaticClassID()) + result = static_cast<TargetType*>(p); + return result; } -} // impl -} // locale -} // boost +}}} // namespace boost::locale::impl_icu #endif 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 1671345b29..571a241abc 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/icu/numeric.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/icu/numeric.cpp @@ -6,420 +6,363 @@ #define BOOST_LOCALE_SOURCE #include <boost/locale/formatting.hpp> -#include <boost/locale/hold_ptr.hpp> #include "boost/locale/icu/all_generator.hpp" #include "boost/locale/icu/cdata.hpp" #include "boost/locale/icu/formatter.hpp" -#include "boost/locale/icu/predefined_formatters.hpp" +#include "boost/locale/icu/formatters_cache.hpp" #include <algorithm> #include <ios> #include <limits> #include <locale> #include <string> +#include <type_traits> + +namespace boost { namespace locale { namespace impl_icu { + + namespace detail { + template<typename T, bool integer = std::numeric_limits<T>::is_integer> + struct icu_format_type; + + template<typename T> + struct icu_format_type<T, true> { + // ICU supports 32 and 64 bit ints, use the former as long as it fits, else the latter + typedef typename std::conditional<std::numeric_limits<T>::digits <= 31, int32_t, int64_t>::type type; + }; + template<typename T> + struct icu_format_type<T, false> { + // Only float type ICU supports is double + typedef double type; + }; + + // ICU does not support uint64_t values so fall back to the parent/std formatting + // if the number is to large to fit into an int64_t + template<typename T, + bool BigUInt = !std::numeric_limits<T>::is_signed && std::numeric_limits<T>::is_integer + && (sizeof(T) >= sizeof(uint64_t))> + struct use_parent_traits { + static bool use(T /*v*/) { return false; } + }; + template<typename T> + struct use_parent_traits<T, true> { + static bool use(T v) { return v > static_cast<T>(std::numeric_limits<int64_t>::max()); } + }; + + template<typename ValueType> + static bool use_parent(std::ios_base& ios, ValueType v) + { + const uint64_t flg = ios_info::get(ios).display_flags(); + if(flg == flags::posix) + return true; + if(use_parent_traits<ValueType>::use(v)) + return true; + + if(!std::numeric_limits<ValueType>::is_integer) + return false; -namespace boost { -namespace locale { -namespace impl_icu { - -namespace details { - template<typename V,int n=std::numeric_limits<V>::digits,bool integer=std::numeric_limits<V>::is_integer> - struct cast_traits; - - template<typename v> - struct cast_traits<v,7,true> { - typedef int32_t cast_type; - }; - template<typename v> - struct cast_traits<v,8,true> { - typedef int32_t cast_type; - }; - - template<typename v> - struct cast_traits<v,15,true> { - typedef int32_t cast_type; - }; - template<typename v> - struct cast_traits<v,16,true> { - typedef int32_t cast_type; - }; - template<typename v> - struct cast_traits<v,31,true> { - typedef int32_t cast_type; - }; - template<typename v> - struct cast_traits<v,32,true> { - typedef int64_t cast_type; - }; - template<typename v> - struct cast_traits<v,63,true> { - typedef int64_t cast_type; - }; - template<typename v> - struct cast_traits<v,64,true> { - typedef int64_t cast_type; - }; - template<typename V,int u> - struct cast_traits<V,u,false> { - typedef double cast_type; - }; - - // ICU does not support uint64_t values so fallback - // to POSIX formatting - template< typename V, - bool Sig=std::numeric_limits<V>::is_signed, - bool Int=std::numeric_limits<V>::is_integer, - bool Big=(sizeof(V) >= 8) - > - struct use_parent_traits - { - static bool use(V /*v*/) { return false; } - }; - template<typename V> - struct use_parent_traits<V,false,true,true> - { - static bool use(V v) { return static_cast<int64_t>(v) < 0; } - }; - -} - - - -class num_base { -protected: - - template<typename ValueType> - static bool use_parent(std::ios_base &ios,ValueType v) - { - uint64_t flg = ios_info::get(ios).display_flags(); - if(flg == flags::posix) - return true; - if(details::use_parent_traits<ValueType>::use(v)) - return true; - - if(!std::numeric_limits<ValueType>::is_integer) + if(flg == flags::number && (ios.flags() & std::ios_base::basefield) != std::ios_base::dec) { + return true; + } return false; - - if(flg == flags::number && (ios.flags() & std::ios_base::basefield) != std::ios_base::dec) { - return true; } - return false; - } -}; - - -template<typename CharType> -class num_format : public std::num_put<CharType>, protected num_base -{ -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; - typedef hold_ptr<formatter_type> formatter_ptr; - - num_format(cdata const &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 BOOST_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 BOOST_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 BOOST_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 BOOST_OVERRIDE - { - return do_real_put(out,ios,fill,val); - } - - #ifndef BOOST_NO_LONG_LONG - iter_type do_put (iter_type out, std::ios_base &ios, char_type fill, long long val) const BOOST_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 BOOST_OVERRIDE - { - return do_real_put(out,ios,fill,val); - } - #endif - - -private: - - - - template<typename ValueType> - iter_type do_real_put (iter_type out, std::ios_base &ios, char_type fill, ValueType val) const - { - if(use_parent<ValueType>(ios,val)) - return std::num_put<char_type>::do_put(out,ios,fill,val); - - formatter_ptr formatter(formatter_type::create(ios,loc_,enc_)); - - if(formatter.get() == 0) - return std::num_put<char_type>::do_put(out,ios,fill,val); - - size_t code_points; - typedef typename details::cast_traits<ValueType>::cast_type cast_type; - string_type const &str = formatter->format(static_cast<cast_type>(val),code_points); - std::streamsize on_left=0,on_right = 0,points = code_points; - if(points < ios.width()) { - std::streamsize n = ios.width() - points; - - std::ios_base::fmtflags flags = ios.flags() & std::ios_base::adjustfield; - - // - // We do not really know internal point, so we assume that it does not - // exist. So according to the standard field should be right aligned - // - if(flags != std::ios_base::left) - on_left = n; - on_right = n - on_left; + } // namespace detail + + template<typename CharType> + class num_format : public std::num_put<CharType> { + 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 + { + return do_real_put(out, ios, fill, val); } - while(on_left > 0) { - *out++ = fill; - on_left--; + iter_type do_put(iter_type out, std::ios_base& ios, char_type fill, unsigned long val) const override + { + return do_real_put(out, ios, fill, val); } - std::copy(str.begin(),str.end(),out); - while(on_right > 0) { - *out++ = fill; - on_right--; + iter_type do_put(iter_type out, std::ios_base& ios, char_type 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 + { + return do_real_put(out, ios, fill, val); } - ios.width(0); - return out; - - } - - icu::Locale loc_; - std::string enc_; - -}; /// num_format - - -template<typename CharType> -class num_parse : public std::num_get<CharType>, protected num_base -{ -public: - num_parse(cdata const &d,size_t refs = 0) : - std::num_get<CharType>(refs), - loc_(d.locale), - enc_(d.encoding) - { - } -protected: - typedef typename std::num_get<CharType>::iter_type iter_type; - typedef std::basic_string<CharType> string_type; - typedef CharType char_type; - typedef formatter<CharType> formatter_type; - typedef hold_ptr<formatter_type> formatter_ptr; - typedef std::basic_istream<CharType> stream_type; - - iter_type do_get(iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,long &val) const BOOST_OVERRIDE - { - return do_real_get(in,end,ios,err,val); - } - - iter_type do_get(iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,unsigned short &val) const BOOST_OVERRIDE - { - return do_real_get(in,end,ios,err,val); - } - - iter_type do_get(iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,unsigned int &val) const BOOST_OVERRIDE - { - return do_real_get(in,end,ios,err,val); - } - - iter_type do_get(iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,unsigned long &val) const BOOST_OVERRIDE - { - return do_real_get(in,end,ios,err,val); - } - - iter_type do_get(iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,float &val) const BOOST_OVERRIDE - { - return do_real_get(in,end,ios,err,val); - } - - iter_type do_get(iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,double &val) const BOOST_OVERRIDE - { - return do_real_get(in,end,ios,err,val); - } - iter_type do_get (iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,long double &val) const BOOST_OVERRIDE - { - return do_real_get(in,end,ios,err,val); - } + iter_type do_put(iter_type out, std::ios_base& ios, char_type 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 + { + return do_real_put(out, ios, fill, val); + } - #ifndef BOOST_NO_LONG_LONG - iter_type do_get (iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,long long &val) const BOOST_OVERRIDE - { - return do_real_get(in,end,ios,err,val); - } + private: + template<typename ValueType> + iter_type do_real_put(iter_type out, std::ios_base& ios, char_type fill, ValueType val) const + { + if(detail::use_parent(ios, val)) + return std::num_put<char_type>::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); + + size_t code_points; + typedef typename detail::icu_format_type<ValueType>::type icu_type; + const string_type& str = formatter->format(static_cast<icu_type>(val), code_points); + std::streamsize on_left = 0, on_right = 0, points = code_points; + if(points < ios.width()) { + std::streamsize n = ios.width() - points; + + std::ios_base::fmtflags flags = ios.flags() & std::ios_base::adjustfield; + + // We do not really know internal point, so we assume that it does not + // exist. So according to the standard field should be right aligned + if(flags != std::ios_base::left) + on_left = n; + on_right = n - on_left; + } + while(on_left > 0) { + *out++ = fill; + on_left--; + } + std::copy(str.begin(), str.end(), out); + while(on_right > 0) { + *out++ = fill; + on_right--; + } + ios.width(0); + return out; + } - iter_type do_get (iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,unsigned long long &val) const BOOST_OVERRIDE - { - return do_real_get(in,end,ios,err,val); - } + icu::Locale loc_; + std::string enc_; - #endif + }; /// num_format -private: + template<typename CharType> + class num_parse : public std::num_get<CharType> { + public: + num_parse(const cdata& d, size_t refs = 0) : std::num_get<CharType>(refs), loc_(d.locale), enc_(d.encoding) {} + 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; - // - // This is not really an efficient solution, but it works - // - template<typename ValueType> - iter_type 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 || use_parent<ValueType>(ios,0)) { - return std::num_get<CharType>::do_get(in,end,ios,err,val); + iter_type + do_get(iter_type in, iter_type end, std::ios_base& ios, std::ios_base::iostate& err, long& val) const override + { + return do_real_get(in, end, ios, err, val); } - formatter_ptr formatter(formatter_type::create(ios,loc_,enc_)); - if(formatter.get()==0) { - return std::num_get<CharType>::do_get(in,end,ios,err,val); + iter_type do_get(iter_type in, + iter_type end, + std::ios_base& ios, + std::ios_base::iostate& err, + unsigned short& val) const override + { + return do_real_get(in, end, ios, err, val); } - typedef typename details::cast_traits<ValueType>::cast_type cast_type; - string_type tmp; - tmp.reserve(64); + iter_type do_get(iter_type in, + iter_type end, + std::ios_base& ios, + std::ios_base::iostate& err, + unsigned int& val) const override + { + return do_real_get(in, end, ios, err, val); + } - CharType c; - while(in!=end && (((c=*in)<=32 && (c>0)) || c==127)) // Assuming that ASCII is a subset - ++in; + iter_type do_get(iter_type in, + iter_type end, + std::ios_base& ios, + std::ios_base::iostate& err, + unsigned long& val) const override + { + return do_real_get(in, end, ios, err, val); + } - while(tmp.size() < 4096 && in!=end && *in!='\n') { - tmp += *in++; + iter_type + do_get(iter_type in, iter_type end, std::ios_base& ios, std::ios_base::iostate& err, float& val) const override + { + return do_real_get(in, end, ios, err, val); } - cast_type value; - size_t parsed_chars; + iter_type + do_get(iter_type in, iter_type end, std::ios_base& ios, std::ios_base::iostate& err, double& val) const override + { + return do_real_get(in, end, ios, err, val); + } - if((parsed_chars = formatter->parse(tmp,value))==0 || !valid<ValueType>(value)) { - err |= std::ios_base::failbit; + iter_type do_get(iter_type in, + iter_type end, + std::ios_base& ios, + std::ios_base::iostate& err, + long double& val) const override + { + return do_real_get(in, end, ios, err, val); } - else { - val=static_cast<ValueType>(value); + + iter_type do_get(iter_type in, + iter_type end, + std::ios_base& ios, + std::ios_base::iostate& err, + long long& val) const override + { + return do_real_get(in, end, ios, err, val); } - for(size_t n=tmp.size();n>parsed_chars;n--) { - stream_ptr->putback(tmp[n-1]); + iter_type do_get(iter_type in, + iter_type end, + std::ios_base& ios, + std::ios_base::iostate& err, + unsigned long long& val) const override + { + return do_real_get(in, end, ios, err, val); } - in = iter_type(*stream_ptr); + private: + // + // This is not really an efficient solution, but it works + // + template<typename ValueType> + iter_type + 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))) { + return std::num_get<CharType>::do_get(in, end, ios, err, val); + } + + const auto formatter = formatter_type::create(ios, loc_, enc_); + if(!formatter) { + return std::num_get<CharType>::do_get(in, end, ios, err, val); + } + + string_type tmp; + tmp.reserve(64); + + CharType c; + 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') { + 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)) { + err |= std::ios_base::failbit; + } else { + val = static_cast<ValueType>(value); + } + + for(size_t n = tmp.size(); n > parsed_chars; n--) { + stream_ptr->putback(tmp[n - 1]); + } + + in = iter_type(*stream_ptr); + + if(in == end) + err |= std::ios_base::eofbit; + return in; + } - if(in==end) - err |=std::ios_base::eofbit; - return in; - } + BOOST_LOCALE_START_CONST_CONDITION + template<typename TargetType, typename SrcType> + bool is_losless_castable(SrcType v) const + { + typedef std::numeric_limits<TargetType> target_limits; + typedef std::numeric_limits<SrcType> casted_limits; + if(v < 0 && !target_limits::is_signed) + return false; -BOOST_LOCALE_START_CONST_CONDITION - template<typename ValueType,typename CastedType> - bool valid(CastedType v) const - { - typedef std::numeric_limits<ValueType> value_limits; - typedef std::numeric_limits<CastedType> casted_limits; - if(v < 0 && value_limits::is_signed == false) - return false; + constexpr TargetType max_val = target_limits::max(); - static const CastedType max_val = static_cast<CastedType>(value_limits::max()); + if(sizeof(SrcType) > sizeof(TargetType) && v > static_cast<SrcType>(max_val)) + return false; - if(sizeof(CastedType) > sizeof(ValueType) && v > max_val) - return false; + if(target_limits::is_integer == casted_limits::is_integer) + return true; - if(value_limits::is_integer == casted_limits::is_integer) { + if(target_limits::is_integer) { // and source is not + if(static_cast<SrcType>(static_cast<TargetType>(v)) != v) + return false; + } return true; } - if(value_limits::is_integer) { // and casted is not - if(static_cast<CastedType>(static_cast<ValueType>(v))!=v) - return false; - } - return true; - } -BOOST_LOCALE_END_CONST_CONDITION - - icu::Locale loc_; - std::string enc_; - -}; + BOOST_LOCALE_END_CONST_CONDITION + icu::Locale loc_; + std::string enc_; + }; -template<typename CharType> -std::locale install_formatting_facets(std::locale const &in,cdata const &cd) -{ - std::locale tmp=std::locale(in,new num_format<CharType>(cd)); - if(!std::has_facet<icu_formatters_cache>(in)) { - tmp=std::locale(tmp,new icu_formatters_cache(cd.locale)); + template<typename CharType> + 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)) { + tmp = std::locale(tmp, new formatters_cache(cd.locale)); + } + return tmp; } - return tmp; -} - -template<typename CharType> -std::locale install_parsing_facets(std::locale const &in,cdata const &cd) -{ - std::locale tmp=std::locale(in,new num_parse<CharType>(cd)); - if(!std::has_facet<icu_formatters_cache>(in)) { - tmp=std::locale(tmp,new icu_formatters_cache(cd.locale)); + + template<typename CharType> + 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)) { + tmp = std::locale(tmp, new formatters_cache(cd.locale)); + } + return tmp; } - return tmp; -} -std::locale create_formatting(std::locale const &in,cdata const &cd,character_facet_type type) -{ + std::locale create_formatting(const std::locale& in, const cdata& cd, char_facet_t type) + { switch(type) { - case char_facet: - return install_formatting_facets<char>(in,cd); - case wchar_t_facet: - return install_formatting_facets<wchar_t>(in,cd); - #ifdef BOOST_LOCALE_ENABLE_CHAR16_T - case char16_t_facet: - return install_formatting_facets<char16_t>(in,cd); - #endif - #ifdef BOOST_LOCALE_ENABLE_CHAR32_T - case char32_t_facet: - return install_formatting_facets<char32_t>(in,cd); - #endif - default: - return in; + case char_facet_t::nochar: break; + case char_facet_t::char_f: return install_formatting_facets<char>(in, cd); + case char_facet_t::wchar_f: return install_formatting_facets<wchar_t>(in, cd); +#ifdef BOOST_LOCALE_ENABLE_CHAR16_T + case char_facet_t::char16_f: return install_formatting_facets<char16_t>(in, cd); +#endif +#ifdef BOOST_LOCALE_ENABLE_CHAR32_T + case char_facet_t::char32_f: return install_formatting_facets<char32_t>(in, cd); +#endif } -} + return in; + } -std::locale create_parsing(std::locale const &in,cdata const &cd,character_facet_type type) -{ + std::locale create_parsing(const std::locale& in, const cdata& cd, char_facet_t type) + { switch(type) { - case char_facet: - return install_parsing_facets<char>(in,cd); - case wchar_t_facet: - return install_parsing_facets<wchar_t>(in,cd); - #ifdef BOOST_LOCALE_ENABLE_CHAR16_T - case char16_t_facet: - return install_parsing_facets<char16_t>(in,cd); - #endif - #ifdef BOOST_LOCALE_ENABLE_CHAR32_T - case char32_t_facet: - return install_parsing_facets<char32_t>(in,cd); - #endif - default: - return in; + case char_facet_t::nochar: break; + case char_facet_t::char_f: return install_parsing_facets<char>(in, cd); + case char_facet_t::wchar_f: return install_parsing_facets<wchar_t>(in, cd); +#ifdef BOOST_LOCALE_ENABLE_CHAR16_T + case char_facet_t::char16_f: return install_parsing_facets<char16_t>(in, cd); +#endif +#ifdef BOOST_LOCALE_ENABLE_CHAR32_T + case char_facet_t::char32_f: return install_parsing_facets<char32_t>(in, cd); +#endif } -} - - -} // impl_icu + return in; + } -} // locale -} //boost +}}} // namespace boost::locale::impl_icu // boostinspect:nominmax diff --git a/contrib/restricted/boost/locale/src/boost/locale/icu/predefined_formatters.hpp b/contrib/restricted/boost/locale/src/boost/locale/icu/predefined_formatters.hpp deleted file mode 100644 index bbadafc27b..0000000000 --- a/contrib/restricted/boost/locale/src/boost/locale/icu/predefined_formatters.hpp +++ /dev/null @@ -1,184 +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_PREDEFINED_FORMATTERS_HPP_INCLUDED -#define BOOST_LOCALE_PREDEFINED_FORMATTERS_HPP_INCLUDED - -#include <boost/locale/config.hpp> -#include <boost/locale/hold_ptr.hpp> -#include "boost/locale/icu/icu_util.hpp" -#include <boost/cstdint.hpp> -#include <boost/thread.hpp> -#include <string> -#include <memory> - -#include <unicode/locid.h> -#include <unicode/numfmt.h> -#include <unicode/rbnf.h> -#include <unicode/datefmt.h> -#include <unicode/smpdtfmt.h> -#include <unicode/decimfmt.h> - -namespace boost { -namespace locale { - namespace impl_icu { - - class icu_formatters_cache : public std::locale::facet { - public: - - static std::locale::id id; - - icu_formatters_cache(icu::Locale const &locale) : - locale_(locale) - { - - static const icu::DateFormat::EStyle styles[4] = { - icu::DateFormat::kShort, - icu::DateFormat::kMedium, - icu::DateFormat::kLong, - icu::DateFormat::kFull - }; - - - for(int i=0;i<4;i++) { - hold_ptr<icu::DateFormat> fmt(icu::DateFormat::createDateInstance(styles[i],locale)); - icu::SimpleDateFormat *sfmt = dynamic_cast<icu::SimpleDateFormat*>(fmt.get()); - if(sfmt) { - sfmt->toPattern(date_format_[i]); - } - } - - for(int i=0;i<4;i++) { - hold_ptr<icu::DateFormat> fmt(icu::DateFormat::createTimeInstance(styles[i],locale)); - icu::SimpleDateFormat *sfmt = dynamic_cast<icu::SimpleDateFormat*>(fmt.get()); - if(sfmt) { - sfmt->toPattern(time_format_[i]); - } - } - - for(int i=0;i<4;i++) { - for(int j=0;j<4;j++) { - hold_ptr<icu::DateFormat> fmt( - icu::DateFormat::createDateTimeInstance(styles[i],styles[j],locale)); - icu::SimpleDateFormat *sfmt = dynamic_cast<icu::SimpleDateFormat*>(fmt.get()); - if(sfmt) { - sfmt->toPattern(date_time_format_[i][j]); - } - } - } - - - } - - typedef enum { - fmt_number, - fmt_sci, - fmt_curr_nat, - fmt_curr_iso, - fmt_per, - fmt_spell, - fmt_ord, - fmt_count - } fmt_type; - - icu::NumberFormat *number_format(fmt_type type) const - { - icu::NumberFormat *ptr = number_format_[type].get(); - if(ptr) - return ptr; - UErrorCode err=U_ZERO_ERROR; - hold_ptr<icu::NumberFormat> ap; - - switch(type) { - case fmt_number: - ap.reset(icu::NumberFormat::createInstance(locale_,err)); - break; - case fmt_sci: - ap.reset(icu::NumberFormat::createScientificInstance(locale_,err)); - break; -#if BOOST_LOCALE_ICU_VERSION >= 408 - case fmt_curr_nat: - ap.reset(icu::NumberFormat::createInstance(locale_,UNUM_CURRENCY,err)); - break; - case fmt_curr_iso: - ap.reset(icu::NumberFormat::createInstance(locale_,UNUM_CURRENCY_ISO,err)); - break; -#elif BOOST_LOCALE_ICU_VERSION >= 402 - case fmt_curr_nat: - ap.reset(icu::NumberFormat::createInstance(locale_,icu::NumberFormat::kCurrencyStyle,err)); - break; - case fmt_curr_iso: - ap.reset(icu::NumberFormat::createInstance(locale_,icu::NumberFormat::kIsoCurrencyStyle,err)); - break; -#else - case fmt_curr_nat: - case fmt_curr_iso: - ap.reset(icu::NumberFormat::createCurrencyInstance(locale_,err)); - break; -#endif - case fmt_per: - ap.reset(icu::NumberFormat::createPercentInstance(locale_,err)); - break; - case fmt_spell: - ap.reset(new icu::RuleBasedNumberFormat(icu::URBNF_SPELLOUT,locale_,err)); - break; - case fmt_ord: - ap.reset(new icu::RuleBasedNumberFormat(icu::URBNF_ORDINAL,locale_,err)); - break; - default: - throw std::runtime_error("locale::internal error should not get there"); - } - - test(err); - ptr = ap.get(); - number_format_[type].reset(ap.release()); - return ptr; - } - - void test(UErrorCode err) const - { - if(U_FAILURE(err)) - throw std::runtime_error("Failed to create a formatter"); - } - - icu::UnicodeString date_format_[4]; - icu::UnicodeString time_format_[4]; - icu::UnicodeString date_time_format_[4][4]; - - icu::SimpleDateFormat *date_formatter() const - { - icu::SimpleDateFormat *p=date_formatter_.get(); - if(p) - return p; - - hold_ptr<icu::DateFormat> fmt(icu::DateFormat::createDateTimeInstance( - icu::DateFormat::kMedium, - icu::DateFormat::kMedium, - locale_)); - - if(dynamic_cast<icu::SimpleDateFormat *>(fmt.get())) { - p = static_cast<icu::SimpleDateFormat *>(fmt.release()); - date_formatter_.reset(p); - } - return p; - } - - private: - - mutable boost::thread_specific_ptr<icu::NumberFormat> number_format_[fmt_count]; - mutable boost::thread_specific_ptr<icu::SimpleDateFormat> date_formatter_; - icu::Locale locale_; - }; - - - - } // namespace impl_icu -} // namespace locale -} // namespace boost - - - -#endif 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 a31bf13660..8457866405 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 @@ -6,8 +6,8 @@ #define BOOST_LOCALE_SOURCE #include "boost/locale/icu/time_zone.hpp" -#include "boost/locale/icu/icu_util.hpp" #include <boost/locale/hold_ptr.hpp> +#include "boost/locale/icu/icu_util.hpp" #include <boost/predef/os.h> // @@ -21,220 +21,198 @@ // #if BOOST_LOCALE_ICU_VERSION >= 400 && BOOST_LOCALE_ICU_VERSION <= 406 \ - && (BOOST_LOCALE_ICU_VERSION != 404 || U_ICU_VERSION_PATCHLEVEL_NUM >= 3) -# if BOOST_OS_LINUX || BOOST_OS_BSD_FREE || defined(__APPLE__) -# define BOOST_LOCALE_WORKAROUND_ICU_BUG -# endif + && (BOOST_LOCALE_ICU_VERSION != 404 || U_ICU_VERSION_PATCHLEVEL_NUM >= 3) +# if BOOST_OS_LINUX || BOOST_OS_BSD_FREE || defined(__APPLE__) +# define BOOST_LOCALE_WORKAROUND_ICU_BUG +# endif #endif #ifdef BOOST_LOCALE_WORKAROUND_ICU_BUG -#include <cstring> -#include <dirent.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <fstream> -#include <pthread.h> -#include <memory> +# include <cstring> +# include <dirent.h> +# include <fstream> +# include <memory> +# include <pthread.h> +# include <sys/stat.h> +# include <sys/types.h> +# include <unistd.h> #endif +namespace boost { namespace locale { namespace impl_icu { -namespace boost { - namespace locale { - namespace impl_icu { +#ifndef BOOST_LOCALE_WORKAROUND_ICU_BUG - #ifndef BOOST_LOCALE_WORKAROUND_ICU_BUG + // This is normal behavior - // This is normal behavior + icu::TimeZone* get_time_zone(const std::string& time_zone) + { + if(time_zone.empty()) { + return icu::TimeZone::createDefault(); + } else { + icu::TimeZone* icu_tz = icu::TimeZone::createTimeZone(time_zone.c_str()); + return icu_tz; + } + } - icu::TimeZone *get_time_zone(std::string const &time_zone) - { +#else - if(time_zone.empty()) { - return icu::TimeZone::createDefault(); - } - else { - return icu::TimeZone::createTimeZone(time_zone.c_str()); - } - } + // This is a workaround for an ICU timezone detection bug. + // It is \b very ICU specific and should not be used + // in general. It is also designed to work only on + // specific patforms: Linux, BSD and Apple, where this bug may actually + // occur + namespace { - #else - - // - // This is a workaround for an ICU timezone detection bug. - // It is \b very ICU specific and should not be used - // in general. It is also designed to work only on - // specific patforms: Linux, BSD and Apple, where this bug may actually - // occur - // - namespace { - - // Under BSD, Linux and Mac OS X dirent has normal size - // so no issues with readdir_r - - class directory { - public: - directory(char const *name) : d(0),read_result(0) - { - d=opendir(name); - if(!d) - return; - } - ~directory() - { - if(d) - closedir(d); - } - bool is_open() - { - return d; - } - char const *next() - { - if(d && readdir_r(d,&de,&read_result)==0 && read_result!=0) - return de.d_name; - return 0; - } - private: - DIR *d; - struct dirent de; - struct dirent *read_result; - }; - - bool files_equal(std::string const &left,std::string const &right) - { - char l[256],r[256]; - std::ifstream ls(left.c_str()); - if(!ls) - return false; - std::ifstream rs(right.c_str()); - if(!rs) - return false; - do { - ls.read(l,sizeof(l)); - rs.read(r,sizeof(r)); - size_t n; - if((n=ls.gcount())!=size_t(rs.gcount())) - return false; - if(memcmp(l,r,n)!=0) - return false; - }while(!ls.eof() || !rs.eof()); - if(bool(ls.eof())!=bool(rs.eof())) - return false; - return true; - } - - std::string find_file_in(std::string const &ref,size_t size,std::string const &dir) - { - directory d(dir.c_str()); - if(!d.is_open()) - return std::string(); - - char const *name=0; - while((name=d.next())!=0) { - std::string file_name = name; - 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) { - if(S_ISDIR(st.st_mode)) { - std::string res = find_file_in(ref,size,path); - if(!res.empty()) - return file_name + "/" + res; - } - else { - if(size_t(st.st_size) == size && files_equal(path,ref)) { - return file_name; - } - } - } - } - return std::string(); - } + // Under BSD, Linux and Mac OS X dirent has normal size + // so no issues with readdir_r - // This actually emulates ICU's search - // algorithm... just it ignores localtime - std::string detect_correct_time_zone() - { - - char const *tz_dir = "/usr/share/zoneinfo"; - char const *tz_file = "/etc/localtime"; - - struct stat st; - if(::stat(tz_file,&st)!=0) - return std::string(); - size_t size = st.st_size; - std::string r = find_file_in(tz_file,size,tz_dir); - if(r.empty()) - return r; - if(r.compare(0,6,"posix/")==0 || r.compare(0,6,"right/",6)==0) - return r.substr(6); - return r; - } + class directory { + public: + directory(const char* name) : d(0), read_result(0) + { + d = opendir(name); + if(!d) + return; + } + ~directory() + { + if(d) + closedir(d); + } + bool is_open() { return d; } + const char* next() + { + if(d && readdir_r(d, &de, &read_result) == 0 && read_result != 0) + return de.d_name; + return 0; + } + private: + DIR* d; + struct dirent de; + struct dirent* read_result; + }; + + bool files_equal(const std::string& left, const std::string& right) + { + char l[256], r[256]; + std::ifstream ls(left.c_str()); + if(!ls) + return false; + std::ifstream rs(right.c_str()); + if(!rs) + return false; + do { + ls.read(l, sizeof(l)); + rs.read(r, sizeof(r)); + size_t n; + if((n = ls.gcount()) != size_t(rs.gcount())) + return false; + if(memcmp(l, r, n) != 0) + return false; + } while(!ls.eof() || !rs.eof()); + if(bool(ls.eof()) != bool(rs.eof())) + return false; + return true; + } - // - // Using pthread as: - // - This bug is relevant for only Linux, BSD, Mac OS X and - // pthreads are native threading API - // - The dependency on boost.thread may be removed when using - // more recent ICU versions (so TLS would not be needed) - // - // This the dependency on Boost.Thread is eliminated - // - - pthread_once_t init_tz = PTHREAD_ONCE_INIT; - std::string default_time_zone_name; - - extern "C" { - static void init_tz_proc() - { - try { - default_time_zone_name = detect_correct_time_zone(); + std::string find_file_in(const std::string& ref, size_t size, const std::string& dir) + { + directory d(dir.c_str()); + if(!d.is_open()) + return std::string(); + + const char* name = 0; + while((name = d.next()) != 0) { + std::string file_name = name; + 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) { + if(S_ISDIR(st.st_mode)) { + std::string res = find_file_in(ref, size, path); + if(!res.empty()) + return file_name + "/" + res; + } else { + if(size_t(st.st_size) == size && files_equal(path, ref)) { + return file_name; } - catch(...){} } } + } + return std::string(); + } - std::string get_time_zone_name() - { - pthread_once(&init_tz,init_tz_proc); - return default_time_zone_name; - } - + // This actually emulates ICU's search + // algorithm... just it ignores localtime + std::string detect_correct_time_zone() + { + const char* tz_dir = "/usr/share/zoneinfo"; + const char* tz_file = "/etc/localtime"; + + struct stat st; + if(::stat(tz_file, &st) != 0) + return std::string(); + size_t size = st.st_size; + std::string r = find_file_in(tz_file, size, tz_dir); + if(r.empty()) + return r; + if(r.compare(0, 6, "posix/") == 0 || r.compare(0, 6, "right/", 6) == 0) + return r.substr(6); + return r; + } - } // namespace + // Using pthread as: + // - This bug is relevant for only Linux, BSD, Mac OS X and + // pthreads are native threading API + // - The dependency on boost.thread may be removed when using + // more recent ICU versions (so TLS would not be needed) + // + // This the dependency on Boost.Thread is eliminated + + pthread_once_t init_tz = PTHREAD_ONCE_INIT; + std::string default_time_zone_name; + + extern "C" { + static void init_tz_proc() + { + try { + default_time_zone_name = detect_correct_time_zone(); + } catch(...) { + } + } + } - icu::TimeZone *get_time_zone(std::string const &time_zone) - { + std::string get_time_zone_name() + { + pthread_once(&init_tz, init_tz_proc); + return default_time_zone_name; + } - 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); - // Check if there is a bug? - if(id != icu::UnicodeString("localtime")) - return tz.release(); - // Now let's deal with the bug and run the fixed - // search loop as that of ICU - std::string real_id = get_time_zone_name(); - if(real_id.empty()) { - // if we failed fallback to ICU's time zone - return tz.release(); - } - return icu::TimeZone::createTimeZone(real_id.c_str()); - } - #endif // bug workaround + } // namespace + icu::TimeZone* get_time_zone(const std::string& time_zone) + { + 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); + // Check if there is a bug? + if(id != icu::UnicodeString("localtime")) + return tz.release(); + // Now let's deal with the bug and run the fixed + // search loop as that of ICU + std::string real_id = get_time_zone_name(); + if(real_id.empty()) { + // if we failed fallback to ICU's time zone + return tz.release(); } + return icu::TimeZone::createTimeZone(real_id.c_str()); } -} +#endif // bug workaround +}}} // namespace boost::locale::impl_icu 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 1690c8d26d..132c5dbb64 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 @@ -9,20 +9,16 @@ #include <boost/locale/config.hpp> #ifdef BOOST_HAS_STDINT_H -#include <stdint.h> // Avoid ICU defining e.g. INT8_MIN causing macro redefinition warnings +# include <stdint.h> // Avoid ICU defining e.g. INT8_MIN causing macro redefinition warnings #endif -#include <unicode/calendar.h> #include <string> +#include <unicode/timezone.h> -namespace boost { - namespace locale { - namespace impl_icu { +namespace boost { namespace locale { namespace impl_icu { - // Provides a workaround for an ICU default timezone bug and also - // handles time_zone string correctly - if empty returns default - // otherwise returns the instance created with time_zone - icu::TimeZone *get_time_zone(std::string const &time_zone); - } - } -} + // Provides a workaround for an ICU default timezone bug and also + // handles time_zone string correctly - if empty returns default + // otherwise returns the instance created with time_zone + icu::TimeZone* get_time_zone(const std::string& time_zone); +}}} // namespace boost::locale::impl_icu #endif diff --git a/contrib/restricted/boost/locale/src/boost/locale/icu/uconv.hpp b/contrib/restricted/boost/locale/src/boost/locale/icu/uconv.hpp index 555ee47ced..ac8278235b 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/icu/uconv.hpp +++ b/contrib/restricted/boost/locale/src/boost/locale/icu/uconv.hpp @@ -19,85 +19,86 @@ #include <unicode/utf16.h> #ifdef BOOST_MSVC -#pragma warning(push) -#pragma warning(disable:4244) // 'argument' : conversion from 'int' -#pragma warning(disable:4267) // 'argument' : conversion from 'size_t' +# pragma warning(push) +# pragma warning(disable : 4244) // 'argument' : conversion from 'int' +# pragma warning(disable : 4267) // 'argument' : conversion from 'size_t' #endif -namespace boost { -namespace locale { -namespace impl_icu { +namespace boost { namespace locale { namespace impl_icu { - typedef enum { - cvt_skip, - cvt_stop - } cpcvt_type; + enum class cpcvt_type { skip, stop }; - - template<typename CharType,int char_size = sizeof(CharType) > + 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; - icu_std_converter(std::string charset,cpcvt_type cv=cvt_skip); - icu::UnicodeString icu(char_type const *begin,char_type const *end) const; - string_type std(icu::UnicodeString const &str) const; - size_t cut(icu::UnicodeString const &str,char_type const *begin,char_type const *end,size_t n,size_t from_u=0,size_t from_c=0) const; + 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; }; template<typename CharType> - class icu_std_converter<CharType,1> { + class icu_std_converter<CharType, 1> { public: typedef CharType char_type; typedef std::basic_string<char_type> string_type; - - icu::UnicodeString icu_checked(char_type const *vb,char_type const *ve) const + icu::UnicodeString icu_checked(const char_type* vb, const char_type* ve) const { - return icu(vb,ve); // Already done + return icu(vb, ve); // Already done } - icu::UnicodeString icu(char_type const *vb,char_type const *ve) const + icu::UnicodeString icu(const char_type* vb, const char_type* ve) const { - char const *begin=reinterpret_cast<char const *>(vb); - char const *end=reinterpret_cast<char const *>(ve); - uconv cvt(charset_,cvt_type_); - UErrorCode err=U_ZERO_ERROR; - icu::UnicodeString tmp(begin,end-begin,cvt.cvt(),err); + 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); check_and_throw_icu_error(err); return tmp; } - string_type std(icu::UnicodeString const &str) const + string_type std(const icu::UnicodeString& str) const { - uconv cvt(charset_,cvt_type_); - return cvt.go(str.getBuffer(),str.length(),max_len_); + uconv cvt(charset_, cvt_type_); + return cvt.go(str.getBuffer(), str.length(), max_len_); } - icu_std_converter(std::string charset,cpcvt_type cvt_type = cvt_skip) : - charset_(charset), - cvt_type_(cvt_type) + 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(); + uconv cvt(charset_, cvt_type); + max_len_ = cvt.max_char_size(); } - size_t cut(icu::UnicodeString const &str,char_type const *begin,char_type const *end, - size_t n,size_t from_u=0,size_t from_char=0) 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_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); + size_t code_points = str.countChar32(from_u, n); + uconv cvt(charset_, cvt_type_); + return cvt.cut(code_points, begin + from_char, end); } - struct uconv { - uconv(uconv const &other); - void operator=(uconv const &other); - public: - uconv(std::string const &charset,cpcvt_type cvt_type=cvt_skip) + 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); + UErrorCode err = U_ZERO_ERROR; + cvt_ = ucnv_open(charset.c_str(), &err); if(!cvt_ || U_FAILURE(err)) { if(cvt_) ucnv_close(cvt_); @@ -105,49 +106,47 @@ namespace impl_icu { } try { - if(cvt_type==cvt_skip) { - ucnv_setFromUCallBack(cvt_,UCNV_FROM_U_CALLBACK_SKIP,0,0,0,&err); + 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); + 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); + } 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); + 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; } - catch(...) { ucnv_close(cvt_) ; throw; } } - int max_char_size() - { - return ucnv_getMaxCharSize(cvt_); - } + int max_char_size() { return ucnv_getMaxCharSize(cvt_); } - string_type go(UChar const *buf,int length,int max_size) + 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); + 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,char_type const *begin,char_type const *end) + size_t cut(size_t n, const char_type* begin, const char_type* end) { - char_type const *saved = begin; + const char_type* saved = begin; while(n > 0 && begin < end) { - UErrorCode err=U_ZERO_ERROR; - ucnv_getNextUChar(cvt_,&begin,end,&err); + UErrorCode err = U_ZERO_ERROR; + ucnv_getNextUChar(cvt_, &begin, end, &err); if(U_FAILURE(err)) return 0; n--; @@ -155,15 +154,12 @@ namespace impl_icu { return begin - saved; } - UConverter *cvt() { return cvt_; } + UConverter* cvt() { return cvt_; } - ~uconv() - { - ucnv_close(cvt_); - } + ~uconv() { ucnv_close(cvt_); } private: - UConverter *cvt_; + UConverter* cvt_; }; private: @@ -173,86 +169,82 @@ namespace impl_icu { }; template<typename CharType> - class icu_std_converter<CharType,2> { + class icu_std_converter<CharType, 2> { public: typedef CharType char_type; typedef std::basic_string<char_type> string_type; - - icu::UnicodeString icu_checked(char_type const *begin,char_type const *end) const + icu::UnicodeString icu_checked(const char_type* begin, const char_type* end) const { - icu::UnicodeString tmp(end-begin,0,0); // make inital capacity - while(begin!=end) { + icu::UnicodeString tmp(end - begin, 0, 0); // make inital 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 { - UChar ct=*begin++; + } else { + UChar ct = *begin++; if(!U16_IS_TRAIL(ct)) throw_if_needed(); else { - UChar32 c=U16_GET_SUPPLEMENTARY(cl,ct); + UChar32 c = U16_GET_SUPPLEMENTARY(cl, ct); tmp.append(c); } } - } - else + } else throw_if_needed(); } return tmp; } void throw_if_needed() const { - if(mode_ == cvt_stop) + if(mode_ == cpcvt_type::stop) throw conv::conversion_error(); } - icu::UnicodeString icu(char_type const *vb,char_type const *ve) const + icu::UnicodeString icu(const char_type* vb, const char_type* ve) const { - UChar const *begin=reinterpret_cast<UChar const *>(vb); - UChar const *end=reinterpret_cast<UChar const *>(ve); - icu::UnicodeString tmp(begin,end-begin); + const UChar* begin = reinterpret_cast<const UChar*>(vb); + const UChar* end = reinterpret_cast<const UChar*>(ve); + icu::UnicodeString tmp(begin, end - begin); return tmp; - } - string_type std(icu::UnicodeString const &str) const + string_type std(const icu::UnicodeString& str) const { - char_type const *ptr=reinterpret_cast<char_type const *>(str.getBuffer()); - return string_type(ptr,str.length()); + const char_type* ptr = reinterpret_cast<const char_type*>(str.getBuffer()); + return string_type(ptr, str.length()); } - size_t cut(icu::UnicodeString const &/*str*/,char_type const * /*begin*/,char_type const * /*end*/,size_t n, - size_t /*from_u*/=0,size_t /*from_c*/=0) 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 { return n; } - icu_std_converter(std::string /*charset*/,cpcvt_type mode=cvt_skip) : - mode_(mode) - { - } + icu_std_converter(std::string /*charset*/, cpcvt_type mode = cpcvt_type::skip) : mode_(mode) {} + private: cpcvt_type mode_; - }; template<typename CharType> - class icu_std_converter<CharType,4> { + class icu_std_converter<CharType, 4> { public: - typedef CharType char_type; typedef std::basic_string<char_type> string_type; - icu::UnicodeString icu_checked(char_type const *begin,char_type const *end) const + icu::UnicodeString icu_checked(const char_type* begin, const char_type* end) const { - icu::UnicodeString tmp(end-begin,0,0); // make inital capacity - while(begin!=end) { + icu::UnicodeString tmp(end - begin, 0, 0); // make inital capacity + while(begin != end) { UChar32 c = static_cast<UChar32>(*begin++); if(U_IS_UNICODE_CHAR(c)) - tmp.append(c); + tmp.append(c); else throw_if_needed(); } @@ -260,35 +252,28 @@ namespace impl_icu { } void throw_if_needed() const { - if(mode_ == cvt_stop) + if(mode_ == cpcvt_type::stop) throw conv::conversion_error(); } - icu::UnicodeString icu(char_type const *begin,char_type const *end) const + icu::UnicodeString icu(const char_type* begin, const char_type* end) const { - icu::UnicodeString tmp(end-begin,0,0); // make inital capacity - while(begin!=end) { - UChar32 c=static_cast<UChar32>(*begin++); + icu::UnicodeString tmp(end - begin, 0, 0); // make inital capacity + while(begin != end) { + UChar32 c = static_cast<UChar32>(*begin++); tmp.append(c); } return tmp; - } - string_type std(icu::UnicodeString const &str) const + string_type std(const icu::UnicodeString& str) const { string_type tmp; tmp.resize(str.length()); - UChar32 *ptr=reinterpret_cast<UChar32 *>(&tmp[0]); - - #ifdef __SUNPRO_CC - int len=0; - #else - ::int32_t len=0; - #endif - - UErrorCode code=U_ZERO_ERROR; - u_strToUTF32(ptr,tmp.size(),&len,str.getBuffer(),str.length(),&code); + UChar32* ptr = reinterpret_cast<UChar32*>(&tmp[0]); + int32_t len = 0; + UErrorCode code = U_ZERO_ERROR; + u_strToUTF32(ptr, tmp.size(), &len, str.getBuffer(), str.length(), &code); check_and_throw_icu_error(code); @@ -297,27 +282,25 @@ namespace impl_icu { return tmp; } - size_t cut(icu::UnicodeString const &str,char_type const * /*begin*/,char_type const * /*end*/,size_t n, - size_t from_u=0,size_t /*from_c*/=0) 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 { - return str.countChar32(from_u,n); + return str.countChar32(from_u, n); } - icu_std_converter(std::string /*charset*/,cpcvt_type mode=cvt_skip) : - mode_(mode) - { - } + icu_std_converter(std::string /*charset*/, cpcvt_type mode = cpcvt_type::skip) : mode_(mode) {} + private: cpcvt_type mode_; - }; -} /// impl_icu -} // locale -} // boost +}}} // namespace boost::locale::impl_icu #endif #ifdef BOOST_MSVC -#pragma warning(push) +#pragma warning(pop) #endif - diff --git a/contrib/restricted/boost/locale/src/boost/locale/posix/all_generator.hpp b/contrib/restricted/boost/locale/src/boost/locale/posix/all_generator.hpp index a89ad5746b..da4d4a82d9 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/posix/all_generator.hpp +++ b/contrib/restricted/boost/locale/src/boost/locale/posix/all_generator.hpp @@ -8,39 +8,25 @@ #define BOOST_LOCALE_IMPL_POSIX_ALL_GENERATOR_HPP #include <boost/locale/generator.hpp> -#include <boost/shared_ptr.hpp> #include <clocale> #include <locale> +#include <memory> #ifdef __APPLE__ -#include <xlocale.h> +# include <xlocale.h> #endif -namespace boost { - namespace locale { - namespace impl_posix { +namespace boost { namespace locale { namespace impl_posix { - std::locale create_convert( std::locale const &in, - boost::shared_ptr<locale_t> lc, - character_facet_type type); + std::locale create_convert(const std::locale& in, std::shared_ptr<locale_t> lc, char_facet_t type); - std::locale create_collate( std::locale const &in, - boost::shared_ptr<locale_t> lc, - character_facet_type type); + std::locale create_collate(const std::locale& in, std::shared_ptr<locale_t> lc, char_facet_t type); - std::locale create_formatting( std::locale const &in, - boost::shared_ptr<locale_t> lc, - character_facet_type type); + std::locale create_formatting(const std::locale& in, std::shared_ptr<locale_t> lc, char_facet_t type); - std::locale create_parsing( std::locale const &in, - boost::shared_ptr<locale_t> lc, - character_facet_type type); - std::locale create_codecvt( std::locale const &in, - std::string const &encoding, - character_facet_type type); + std::locale create_parsing(const std::locale& in, std::shared_ptr<locale_t> lc, char_facet_t type); + std::locale create_codecvt(const std::locale& in, const std::string& encoding, char_facet_t type); - } - } -} +}}} // namespace boost::locale::impl_posix #endif diff --git a/contrib/restricted/boost/locale/src/boost/locale/posix/codecvt.cpp b/contrib/restricted/boost/locale/src/boost/locale/posix/codecvt.cpp index 7d0a30e061..38b60e1122 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/posix/codecvt.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/posix/codecvt.cpp @@ -9,62 +9,52 @@ #include <boost/locale/encoding.hpp> #include <boost/locale/hold_ptr.hpp> #include <boost/locale/util.hpp> -#include <boost/shared_ptr.hpp> #include <algorithm> #include <cerrno> #include <stdexcept> #include <vector> -#include "boost/locale/posix/all_generator.hpp" #include "boost/locale/encoding/conv.hpp" +#include "boost/locale/posix/all_generator.hpp" #ifdef BOOST_LOCALE_WITH_ICONV -#include "boost/locale/util/iconv.hpp" +# include "boost/locale/util/iconv.hpp" #endif -namespace boost { -namespace locale { -namespace impl_posix { +namespace boost { namespace locale { namespace impl_posix { #ifdef BOOST_LOCALE_WITH_ICONV class mb2_iconv_converter : public util::base_converter { public: - - mb2_iconv_converter(std::string const &encoding) : - encoding_(encoding), - to_utf_((iconv_t)(-1)), - from_utf_((iconv_t)(-1)) + mb2_iconv_converter(const std::string& encoding) : + encoding_(encoding), to_utf_((iconv_t)(-1)), from_utf_((iconv_t)(-1)) { iconv_t d = (iconv_t)(-1); std::vector<uint32_t> first_byte_table; try { - d = iconv_open(utf32_encoding(),encoding.c_str()); + d = iconv_open(utf32_encoding(), encoding.c_str()); if(d == (iconv_t)(-1)) { throw std::runtime_error("Unsupported encoding" + encoding); } - for(unsigned c=0;c<256;c++) { - char ibuf[2] = { char(c) , 0 }; - char *in = ibuf; - size_t insize =2; - uint32_t obuf[2] = {illegal,illegal}; - char *out = reinterpret_cast<char *>(obuf); - size_t outsize = 8; - // Basic sigle codepoint conversion - call_iconv(d,&in,&insize,&out,&outsize); + for(unsigned c = 0; c < 256; c++) { + const char ibuf[2] = {char(c), 0}; + size_t insize = sizeof(ibuf); + uint32_t obuf[2] = {illegal, illegal}; + size_t outsize = sizeof(obuf); + // Basic single codepoint conversion + call_iconv(d, ibuf, &insize, reinterpret_cast<char*>(obuf), &outsize); if(insize == 0 && outsize == 0 && obuf[1] == 0) { first_byte_table.push_back(obuf[0]); continue; } // Test if this is illegal first byte or incomplete - in = ibuf; insize = 1; - out = reinterpret_cast<char *>(obuf); - outsize = 8; - call_iconv(d,0,0,0,0); - size_t res = call_iconv(d,&in,&insize,&out,&outsize); + outsize = sizeof(obuf); + call_iconv(d, nullptr, nullptr, nullptr, nullptr); + size_t res = call_iconv(d, ibuf, &insize, reinterpret_cast<char*>(obuf), &outsize); // Now if this single byte starts a sequence we add incomplete - // to know to ask that we need two bytes, othewise it may only be + // to know to ask that we need two bytes, otherwise it may only be // illegal uint32_t point; @@ -73,11 +63,9 @@ namespace impl_posix { else point = illegal; first_byte_table.push_back(point); - } - } - catch(...) { - if(d!=(iconv_t)(-1)) + } catch(...) { + if(d != (iconv_t)(-1)) iconv_close(d); throw; } @@ -86,13 +74,10 @@ namespace impl_posix { first_byte_table_->swap(first_byte_table); } - mb2_iconv_converter(mb2_iconv_converter const &other) : - first_byte_table_(other.first_byte_table_), - encoding_(other.encoding_), - to_utf_((iconv_t)(-1)), + mb2_iconv_converter(const mb2_iconv_converter& other) : + first_byte_table_(other.first_byte_table_), encoding_(other.encoding_), to_utf_((iconv_t)(-1)), from_utf_((iconv_t)(-1)) - { - } + {} ~mb2_iconv_converter() { @@ -102,17 +87,11 @@ namespace impl_posix { iconv_close(from_utf_); } - bool is_thread_safe() const BOOST_OVERRIDE - { - return false; - } + bool is_thread_safe() const override { return false; } - mb2_iconv_converter *clone() const BOOST_OVERRIDE - { - return new mb2_iconv_converter(*this); - } + mb2_iconv_converter* clone() const override { return new mb2_iconv_converter(*this); } - uint32_t to_unicode(char const *&begin,char const *end) BOOST_OVERRIDE + uint32_t to_unicode(const char*& begin, const char* end) override { if(begin == end) return incomplete; @@ -124,72 +103,69 @@ namespace impl_posix { if(index != incomplete) { begin++; return index; - } - else if(begin+1 == end) + } else if(begin + 1 == end) return incomplete; - open(to_utf_,utf32_encoding(),encoding_.c_str()); + open(to_utf_, utf32_encoding(), encoding_.c_str()); // maybe illegal or may be double byte - char inseq[3] = { static_cast<char>(seq0) , begin[1], 0}; - char *inbuf = inseq; - size_t insize = 3; - uint32_t result[2] = { illegal, illegal }; - size_t outsize = 8; - char *outbuf = reinterpret_cast<char*>(result); - call_iconv(to_utf_,&inbuf,&insize,&outbuf,&outsize); - if(outsize == 0 && insize == 0 && result[1]==0 ) { - begin+=2; + const char inseq[3] = {static_cast<char>(seq0), begin[1], 0}; + size_t insize = sizeof(inseq); + uint32_t result[2] = {illegal, illegal}; + size_t outsize = sizeof(result); + call_iconv(to_utf_, inseq, &insize, reinterpret_cast<char*>(result), &outsize); + if(outsize == 0 && insize == 0 && result[1] == 0) { + begin += 2; return result[0]; } return illegal; } - uint32_t from_unicode(uint32_t cp,char *begin,char const *end) BOOST_OVERRIDE + uint32_t from_unicode(uint32_t cp, char* begin, const char* end) override { if(cp == 0) { - if(begin!=end) { + 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(), utf32_encoding()); - uint32_t codepoints[2] = {cp,0}; - char *inbuf = reinterpret_cast<char *>(codepoints); - size_t insize = sizeof(codepoints); + const uint32_t inbuf[2] = {cp, 0}; + size_t insize = sizeof(inbuf); char outseq[3] = {0}; - char *outbuf = outseq; size_t outsize = 3; - call_iconv(from_utf_,&inbuf,&insize,&outbuf,&outsize); + call_iconv(from_utf_, reinterpret_cast<const char*>(inbuf), &insize, outseq, &outsize); if(insize != 0 || outsize > 1) return illegal; - size_t len = 2 - outsize ; + size_t len = 2 - outsize; size_t reminder = end - begin; if(reminder < len) return incomplete; - for(unsigned i=0;i<len;i++) + for(unsigned i = 0; i < len; i++) *begin++ = outseq[i]; return len; } - void open(iconv_t &d,char const *to,char const *from) + void open(iconv_t& d, const char* to, const char* from) { - if(d!=(iconv_t)(-1)) + if(d != (iconv_t)(-1)) return; - d=iconv_open(to,from); + d = iconv_open(to, from); } - static char const *utf32_encoding() + static const char* utf32_encoding() { - union { char one; uint32_t value; } test; + union { + char one; + uint32_t value; + } test; test.value = 1; if(test.one == 1) return "UTF-32LE"; @@ -197,52 +173,41 @@ namespace impl_posix { return "UTF-32BE"; } - int max_len() const BOOST_OVERRIDE - { - return 2; - } + int max_len() const override { return 2; } private: - boost::shared_ptr<std::vector<uint32_t> > first_byte_table_; + std::shared_ptr<std::vector<uint32_t>> first_byte_table_; std::string encoding_; iconv_t to_utf_; iconv_t from_utf_; }; - util::base_converter *create_iconv_converter(std::string const &encoding) + std::unique_ptr<util::base_converter> create_iconv_converter(const std::string& encoding) { - hold_ptr<util::base_converter> cvt; try { - cvt.reset(new mb2_iconv_converter(encoding)); - } - catch(std::exception const &e) { - // Nothing to do, just retrun empty cvt + return std::unique_ptr<util::base_converter>(new mb2_iconv_converter(encoding)); + } catch(const std::exception& e) { + return nullptr; } - return cvt.release(); } #else // no iconv - util::base_converter *create_iconv_converter(std::string const &/*encoding*/) + std::unique_ptr<util::base_converter> create_iconv_converter(const std::string& /*encoding*/) { - return 0; + return nullptr; } #endif - std::locale create_codecvt(std::locale const &in,std::string const &encoding,character_facet_type type) + std::locale create_codecvt(const std::locale& in, const std::string& encoding, char_facet_t type) { - if(conv::impl::normalize_encoding(encoding.c_str())=="utf8") - return util::create_utf8_codecvt(in,type); + if(conv::impl::normalize_encoding(encoding.c_str()) == "utf8") + return util::create_utf8_codecvt(in, type); try { - return util::create_simple_codecvt(in,encoding,type); - } - catch(conv::invalid_charset_error const &) { - util::base_converter *cvt = create_iconv_converter(encoding); - return util::create_codecvt_from_pointer(in,cvt,type); + return util::create_simple_codecvt(in, encoding, type); + } catch(const conv::invalid_charset_error&) { + return util::create_codecvt(in, create_iconv_converter(encoding), type); } } -} // impl_posix -} // locale -} // boost - +}}} // namespace boost::locale::impl_posix diff --git a/contrib/restricted/boost/locale/src/boost/locale/posix/codecvt.hpp b/contrib/restricted/boost/locale/src/boost/locale/posix/codecvt.hpp index 26cb91d467..3ed08b81d6 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/posix/codecvt.hpp +++ b/contrib/restricted/boost/locale/src/boost/locale/posix/codecvt.hpp @@ -12,15 +12,10 @@ #include <memory> #include <string> -namespace boost { -namespace locale { -namespace impl_posix { +namespace boost { namespace locale { namespace impl_posix { BOOST_LOCALE_DECL - util::base_converter *create_iconv_converter(std::string const &encoding); + std::unique_ptr<util::base_converter> create_iconv_converter(const std::string& encoding); -} // impl_posix -} // locale -} // boost +}}} // namespace boost::locale::impl_posix #endif - 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 30966e2ecb..8050471e50 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/posix/collate.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/posix/collate.cpp @@ -7,114 +7,93 @@ #define BOOST_LOCALE_SOURCE #include <boost/locale/generator.hpp> #if defined(__FreeBSD__) -#include <xlocale.h> +# include <xlocale.h> #endif #include <clocale> #include <cstring> +#include <ios> #include <locale> -#include <wchar.h> -#include <string> #include <stdexcept> -#include <ios> +#include <string> #include <vector> +#include <wchar.h> -#include "boost/locale/shared/mo_hash.hpp" #include "boost/locale/posix/all_generator.hpp" +#include "boost/locale/shared/mo_hash.hpp" -namespace boost { -namespace locale { -namespace impl_posix { +namespace boost { namespace locale { namespace impl_posix { -template<typename CharType> -struct coll_traits; + template<typename CharType> + struct coll_traits; -template<> -struct coll_traits<char> { - static size_t xfrm(char *out,char const *in,size_t n,locale_t l) - { - return strxfrm_l(out,in,n,l); - } - static size_t coll(char const *left,char const *right,locale_t l) - { - return strcoll_l(left,right,l); - } -}; + template<> + struct coll_traits<char> { + static size_t xfrm(char* out, const char* in, size_t n, locale_t l) { return strxfrm_l(out, in, n, l); } + static size_t coll(const char* left, const char* right, locale_t l) { return strcoll_l(left, right, l); } + }; -template<> -struct coll_traits<wchar_t> { - static size_t xfrm(wchar_t *out,wchar_t const *in,size_t n,locale_t l) - { - return wcsxfrm_l(out,in,n,l); - } - static size_t coll(wchar_t const *left,wchar_t const *right,locale_t l) - { - return wcscoll_l(left,right,l); - } -}; + template<> + struct coll_traits<wchar_t> { + static size_t xfrm(wchar_t* out, const wchar_t* in, size_t n, locale_t l) { return wcsxfrm_l(out, in, n, l); } + static size_t coll(const wchar_t* left, const wchar_t* right, locale_t l) { return wcscoll_l(left, right, l); } + }; -template<typename CharType> -class collator : public std::collate<CharType> { -public: - typedef CharType char_type; - typedef std::basic_string<char_type> string_type; - collator(boost::shared_ptr<locale_t> l,size_t refs = 0) : - std::collate<CharType>(refs), - lc_(l) - { - } + template<typename CharType> + class collator : public std::collate<CharType> { + public: + typedef CharType char_type; + typedef std::basic_string<char_type> string_type; + collator(std::shared_ptr<locale_t> l, size_t refs = 0) : std::collate<CharType>(refs), lc_(std::move(l)) {} - int do_compare(char_type const *lb,char_type const *le,char_type const *rb,char_type const *re) const BOOST_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_); - if(res < 0) - return -1; - if(res > 0) - return 1; - return 0; - } - long do_hash(char_type const *b,char_type const *e) const BOOST_OVERRIDE - { - string_type s(do_transform(b,e)); - char const *begin = reinterpret_cast<char const *>(s.c_str()); - char const *end = begin + s.size() * sizeof(char_type); - return gnu_gettext::pj_winberger_hash_function(begin,end); - } - string_type do_transform(char_type const *b,char_type const *e) const BOOST_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_); - if(n>buf.size()) { - buf.resize(n); - coll_traits<char_type>::xfrm(&buf.front(),s.c_str(),n,*lc_); + int + do_compare(const char_type* lb, const char_type* le, const char_type* rb, const char_type* 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_); + 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 + { + 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); + 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 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_); + if(n > buf.size()) { + buf.resize(n); + coll_traits<char_type>::xfrm(&buf.front(), s.c_str(), n, *lc_); + } + return string_type(&buf.front(), n); } - return string_type(&buf.front(),n); - } -private: - boost::shared_ptr<locale_t> lc_; -}; + private: + std::shared_ptr<locale_t> lc_; + }; -std::locale create_collate( std::locale const &in, - boost::shared_ptr<locale_t> lc, - character_facet_type type) -{ - switch(type) { - case char_facet: - return std::locale(in,new collator<char>(lc)); - case wchar_t_facet: - return std::locale(in,new collator<wchar_t>(lc)); - default: + std::locale create_collate(const std::locale& in, std::shared_ptr<locale_t> lc, char_facet_t type) + { + switch(type) { + case char_facet_t::nochar: break; + case char_facet_t::char_f: return std::locale(in, new collator<char>(std::move(lc))); + case char_facet_t::wchar_f: return std::locale(in, new collator<wchar_t>(std::move(lc))); +#ifdef BOOST_LOCALE_ENABLE_CHAR16_T + case char_facet_t::char16_f: return std::locale(in, new collator<char16_t>(std::move(lc))); +#endif +#ifdef BOOST_LOCALE_ENABLE_CHAR32_T + case char_facet_t::char32_f: return std::locale(in, new collator<char32_t>(std::move(lc))); +#endif + } return in; } -} - - -} // impl_std -} // locale -} //boost - - +}}} // namespace boost::locale::impl_posix 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 718c450550..6c45eb5f24 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/posix/converter.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/posix/converter.cpp @@ -6,10 +6,9 @@ #define BOOST_LOCALE_SOURCE -#include <boost/locale/generator.hpp> #include <boost/locale/conversion.hpp> #include <boost/locale/encoding.hpp> -#include <boost/shared_ptr.hpp> +#include <boost/locale/generator.hpp> #include <cctype> #include <cstring> #include <langinfo.h> @@ -17,147 +16,128 @@ #include <stdexcept> #include <wctype.h> #if defined(__FreeBSD__) -#include <xlocale.h> +# include <xlocale.h> #endif #include "boost/locale/posix/all_generator.hpp" -namespace boost { -namespace locale { -namespace impl_posix { +namespace boost { namespace locale { namespace impl_posix { -template<typename CharType> -struct case_traits; + template<typename CharType> + struct case_traits; -template<> -struct case_traits<char> { - static char lower(char c,locale_t lc) - { - return tolower_l(c,lc); - } - static char upper(char c,locale_t lc) - { - return toupper_l(c,lc); - } -}; + template<> + struct case_traits<char> { + static char lower(char c, locale_t lc) { return tolower_l(c, lc); } + static char upper(char c, locale_t lc) { return toupper_l(c, lc); } + }; -template<> -struct case_traits<wchar_t> { - static wchar_t lower(wchar_t c,locale_t lc) - { - return towlower_l(c,lc); - } - static wchar_t upper(wchar_t c,locale_t lc) - { - return towupper_l(c,lc); - } -}; + template<> + struct case_traits<wchar_t> { + static wchar_t lower(wchar_t c, locale_t lc) { return towlower_l(c, lc); } + static wchar_t upper(wchar_t c, locale_t lc) { return towupper_l(c, lc); } + }; - -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(boost::shared_ptr<locale_t> lc,size_t refs = 0) : - converter<CharType>(refs), - lc_(lc) - { - } - string_type convert(converter_base::conversion_type how,char_type const *begin,char_type const *end,int /*flags*/ = 0) const BOOST_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_); + 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(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, + 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_); + } + return res; } - 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_); + 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_); + } + return res; } - return res; + case converter_base::normalization: + case converter_base::title_case: break; } - default: - return string_type(begin,end-begin); + return string_type(begin, end - begin); } - } -private: - boost::shared_ptr<locale_t> lc_; -}; -class utf8_converter : public converter<char> { -public: - utf8_converter(boost::shared_ptr<locale_t> lc,size_t refs = 0) : - converter<char>(refs), - lc_(lc) - { - } - std::string convert(converter_base::conversion_type how,char const *begin,char const *end,int /*flags*/ = 0) const BOOST_OVERRIDE - { - switch(how) { - case upper_case: - { - std::wstring tmp = conv::to_utf<wchar_t>(begin,end,"UTF-8"); - 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"); - } + private: + std::shared_ptr<locale_t> lc_; + }; + + class utf8_converter : public converter<char> { + public: + utf8_converter(std::shared_ptr<locale_t> lc, size_t refs = 0) : converter<char>(refs), lc_(std::move(lc)) {} + std::string convert(converter_base::conversion_type how, + const char* begin, + const char* end, + int /*flags*/ = 0) const override + { + switch(how) { + case upper_case: { + std::wstring tmp = conv::to_utf<wchar_t>(begin, end, "UTF-8"); + 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"); + } - case lower_case: - case case_folding: - { - std::wstring tmp = conv::to_utf<wchar_t>(begin,end,"UTF-8"); - 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"); + case lower_case: + case case_folding: { + std::wstring tmp = conv::to_utf<wchar_t>(begin, end, "UTF-8"); + 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"); + } + case normalization: + case title_case: break; } - default: - return std::string(begin,end-begin); + return std::string(begin, end - begin); } - } -private: - boost::shared_ptr<locale_t> lc_; -}; -std::locale create_convert( std::locale const &in, - boost::shared_ptr<locale_t> lc, - character_facet_type type) -{ + private: + std::shared_ptr<locale_t> lc_; + }; + + std::locale create_convert(const std::locale& in, std::shared_ptr<locale_t> lc, char_facet_t type) + { switch(type) { - case char_facet: - { - 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") { - return std::locale(in,new utf8_converter(lc)); + 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") { + return std::locale(in, new utf8_converter(std::move(lc))); } - return std::locale(in,new std_converter<char>(lc)); + return std::locale(in, new std_converter<char>(std::move(lc))); } - case wchar_t_facet: - return std::locale(in,new std_converter<wchar_t>(lc)); - default: - return in; + case char_facet_t::wchar_f: return std::locale(in, new std_converter<wchar_t>(std::move(lc))); +#ifdef BOOST_LOCALE_ENABLE_CHAR16_T + case char_facet_t::char16_f: return std::locale(in, new std_converter<char16_t>(std::move(lc))); +#endif +#ifdef BOOST_LOCALE_ENABLE_CHAR32_T + case char_facet_t::char32_f: return std::locale(in, new std_converter<char32_t>(std::move(lc))); +#endif } -} - + return in; + } -} // namespace impl_std -} // locale -} // boost +}}} // namespace boost::locale::impl_posix 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 69d2f290ec..f1b4a5605a 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/posix/numeric.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/posix/numeric.cpp @@ -6,13 +6,12 @@ #define BOOST_LOCALE_SOURCE #if defined(__FreeBSD__) -#include <xlocale.h> +# include <xlocale.h> #endif #include <boost/locale/encoding.hpp> #include <boost/locale/formatting.hpp> #include <boost/locale/generator.hpp> #include <boost/predef/os.h> -#include <boost/shared_ptr.hpp> #include <cctype> #include <cerrno> #include <cstdlib> @@ -21,492 +20,423 @@ #include <ios> #include <langinfo.h> #include <locale> +#include <memory> #include <monetary.h> #include <sstream> #include <string> #include <vector> #include <wctype.h> -#include "boost/locale/util/numeric.hpp" #include "boost/locale/posix/all_generator.hpp" +#include "boost/locale/util/numeric.hpp" - -#if BOOST_OS_LINUX || defined(__APPLE__) -#define BOOST_LOCALE_HAVE_WCSFTIME_L -#endif - -namespace boost { -namespace locale { -namespace impl_posix { - -template<typename CharType> -class num_format : public util::base_num_format<CharType> -{ -public: - typedef typename std::num_put<CharType>::iter_type iter_type; - typedef std::basic_string<CharType> string_type; - typedef CharType char_type; - - num_format(boost::shared_ptr<locale_t> lc,size_t refs = 0) : - util::base_num_format<CharType>(refs), - lc_(lc) - { - } -protected: - - iter_type do_format_currency(bool intl,iter_type out,std::ios_base &/*ios*/,char_type /*fill*/,long double val) const BOOST_OVERRIDE - { - char buf[4]={}; - char const *format = intl ? "%i" : "%n"; - errno=0; - ssize_t n = strfmon_l(buf,sizeof(buf),*lc_,format,static_cast<double>(val)); - if(n >= 0) - 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)); +namespace boost { namespace locale { namespace impl_posix { + + template<typename CharType> + class num_format : public util::base_num_format<CharType> { + 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)) + {} + + protected: + iter_type do_format_currency(bool intl, + iter_type out, + std::ios_base& /*ios*/, + char_type /*fill*/, + long double val) const override + { + char buf[4] = {}; + const char* format = intl ? "%i" : "%n"; + errno = 0; + ssize_t n = strfmon_l(buf, sizeof(buf), *lc_, format, static_cast<double>(val)); if(n >= 0) - return write_it(out,&tmp.front(),n); - } - return out; - } - - std::ostreambuf_iterator<char> write_it(std::ostreambuf_iterator<char> out,char const *ptr,size_t n) const - { - for(size_t i=0;i<n;i++) - *out++ = *ptr++; - return out; - } + return write_it(out, buf, n); - std::ostreambuf_iterator<wchar_t> write_it(std::ostreambuf_iterator<wchar_t> out,char const *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; - } -private: + 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)); + if(n >= 0) + return write_it(out, &tmp.front(), n); + } + return out; + } - boost::shared_ptr<locale_t> lc_; + 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; + } -}; /// num_format + 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; + } + private: + std::shared_ptr<locale_t> lc_; -template<typename CharType> -struct ftime_traits; + }; /// num_format -template<> -struct ftime_traits<char> { - static std::string ftime(char const *format,const struct tm *t,locale_t lc) - { - char buf[16]; - size_t n=strftime_l(buf,sizeof(buf),format,t,lc); - if(n == 0) { - // should be big enough - // - // Note standard specifies that in case of the error - // the function returns 0, however 0 may be actually - // valid output value of for example empty format or an - // output of %p in some locales - // - // Thus we try to guess that 1024 would be enough. - std::vector<char> v(1024); - n = strftime_l(&v.front(),1024,format,t,lc); - return std::string(&v.front(),n); - } - return std::string(buf,n); - } -}; - -template<> -struct ftime_traits<wchar_t> { - static std::wstring ftime(wchar_t const *format,const struct tm *t,locale_t lc) - { - #ifdef HAVE_WCSFTIME_L - wchar_t buf[16]; - size_t n=wcsftime_l(buf,sizeof(buf)/sizeof(buf[0]),format,t,lc); + namespace { + std::string do_ftime(const char* format, const struct tm* t, locale_t lc) + { + char buf[16]; + size_t n = strftime_l(buf, sizeof(buf), format, t, lc); if(n == 0) { - // should be big enough - // - // Note standard specifies that in case of the error - // the function returns 0, however 0 may be actually - // valid output value of for example empty format or an - // output of %p in some locales + // Note standard specifies that in case of error the function returns 0, + // however 0 may be actually valid output value of for example empty format + // or an output of %p in some locales // // Thus we try to guess that 1024 would be enough. - std::vector<wchar_t> v(1024); - n = wcsftime_l(&v.front(),1024,format,t,lc); + std::vector<char> v(1024); + n = strftime_l(v.data(), 1024, format, t, lc); + return std::string(v.data(), n); } - return std::wstring(&v.front(),n); - #else - std::string enc = nl_langinfo_l(CODESET,lc); - std::string nformat = conv::from_utf<wchar_t>(format,enc); - std::string nres = ftime_traits<char>::ftime(nformat.c_str(),t,lc); - return conv::to_utf<wchar_t>(nres,enc); - #endif - } -}; - - -template<typename CharType> -class time_put_posix : public std::time_put<CharType> { -public: - time_put_posix(boost::shared_ptr<locale_t> 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; - - iter_type do_put(iter_type out,std::ios_base &/*ios*/,CharType /*fill*/,std::tm const *tm,char format,char modifier) const BOOST_OVERRIDE - { - char_type fmt[4] = { '%' , static_cast<char_type>(modifier != 0 ? modifier : format) , static_cast<char_type>(modifier == 0 ? '\0' : format) }; - string_type res = ftime_traits<char_type>::ftime(fmt,tm,*lc_); - for(unsigned i=0;i<res.size();i++) - *out++ = res[i]; - return out; - } - -private: - boost::shared_ptr<locale_t> lc_; -}; - - -template<typename CharType> -class ctype_posix; - -template<> -class ctype_posix<char> : public std::ctype<char> { -public: - - ctype_posix(boost::shared_ptr<locale_t> lc) - { - lc_ = lc; - } - - bool do_is(mask m,char c) const - { - if((m & space) && isspace_l(c,*lc_)) - return true; - if((m & print) && isprint_l(c,*lc_)) - return true; - if((m & cntrl) && iscntrl_l(c,*lc_)) - return true; - if((m & upper) && isupper_l(c,*lc_)) - return true; - if((m & lower) && islower_l(c,*lc_)) - return true; - if((m & alpha) && isalpha_l(c,*lc_)) - return true; - if((m & digit) && isdigit_l(c,*lc_)) - return true; - if((m & xdigit) && isxdigit_l(c,*lc_)) - return true; - if((m & punct) && ispunct_l(c,*lc_)) - return true; - return false; - } - char const *do_is(char const *begin,char const *end,mask *m) const - { - while(begin!=end) { - char c= *begin++; - int r=0; - if(isspace_l(c,*lc_)) - r|=space; - if(isprint_l(c,*lc_)) - r|=cntrl; - if(iscntrl_l(c,*lc_)) - r|=space; - if(isupper_l(c,*lc_)) - r|=upper; - if(islower_l(c,*lc_)) - r|=lower; - if(isalpha_l(c,*lc_)) - r|=alpha; - if(isdigit_l(c,*lc_)) - r|=digit; - if(isxdigit_l(c,*lc_)) - r|=xdigit; - if(ispunct_l(c,*lc_)) - r|=punct; - // r actually should be mask, but some standard - // libraries (like STLPort) - // do not define operator | properly so using int+cast - *m++ = static_cast<mask>(r); + return std::string(buf, n); + } + template<typename CharType> + std::basic_string<CharType> do_ftime(const CharType* format, const struct tm* t, locale_t lc) + { + const std::string encoding = nl_langinfo_l(CODESET, lc); + const std::string nformat = conv::from_utf(format, encoding); + const std::string nres = do_ftime(nformat.c_str(), t, lc); + return conv::to_utf<CharType>(nres, encoding); + } + } // namespace + + template<typename CharType> + class time_put_posix : public std::time_put<CharType> { + public: + time_put_posix(std::shared_ptr<locale_t> lc, size_t refs = 0) : + 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; + + iter_type do_put(iter_type out, + std::ios_base& /*ios*/, + CharType /*fill*/, + const std::tm* tm, + 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)}; + string_type res = do_ftime(fmt, tm, *lc_); + for(unsigned i = 0; i < res.size(); i++) + *out++ = res[i]; + return out; } - return begin; - } - char const *do_scan_is(mask m,char const *begin,char const *end) const - { - while(begin!=end) - if(do_is(m,*begin)) - return begin; - return begin; - } - char const *do_scan_not(mask m,char const *begin,char const *end) const - { - while(begin!=end) - if(!do_is(m,*begin)) - return begin; - return begin; - } - char toupper(char c) const - { - return toupper_l(c,*lc_); - } - char const *toupper(char *begin,char const *end) const - { - for(;begin!=end;begin++) - *begin = toupper_l(*begin,*lc_); - return begin; - } - char tolower(char c) const - { - return tolower_l(c,*lc_); - } - char const *tolower(char *begin,char const *end) const - { - for(;begin!=end;begin++) - *begin = tolower_l(*begin,*lc_); - return begin; - } -private: - boost::shared_ptr<locale_t> lc_; -}; - -template<> -class ctype_posix<wchar_t> : public std::ctype<wchar_t> { -public: - ctype_posix(boost::shared_ptr<locale_t> lc) - { - lc_ = lc; - } - bool do_is(mask m,wchar_t c) const - { - if((m & space) && iswspace_l(c,*lc_)) - return true; - if((m & print) && iswprint_l(c,*lc_)) - return true; - if((m & cntrl) && iswcntrl_l(c,*lc_)) - return true; - if((m & upper) && iswupper_l(c,*lc_)) - return true; - if((m & lower) && iswlower_l(c,*lc_)) - return true; - if((m & alpha) && iswalpha_l(c,*lc_)) - return true; - if((m & digit) && iswdigit_l(c,*lc_)) - return true; - if((m & xdigit) && iswxdigit_l(c,*lc_)) - return true; - if((m & punct) && iswpunct_l(c,*lc_)) - return true; - return false; - } - wchar_t const *do_is(wchar_t const *begin,wchar_t const *end,mask *m) const - { - while(begin!=end) { - wchar_t c= *begin++; - int r=0; - if(iswspace_l(c,*lc_)) - r|=space; - if(iswprint_l(c,*lc_)) - r|=cntrl; - if(iswcntrl_l(c,*lc_)) - r|=space; - if(iswupper_l(c,*lc_)) - r|=upper; - if(iswlower_l(c,*lc_)) - r|=lower; - if(iswalpha_l(c,*lc_)) - r|=alpha; - if(iswdigit_l(c,*lc_)) - r|=digit; - if(iswxdigit_l(c,*lc_)) - r|=xdigit; - if(iswpunct_l(c,*lc_)) - r|=punct; - // r actually should be mask, but some standard - // libraries (like STLPort) - // do not define operator | properly so using int+cast - *m++ = static_cast<mask>(r); + private: + std::shared_ptr<locale_t> lc_; + }; + + template<typename CharType> + class ctype_posix; + + template<> + class ctype_posix<char> : public std::ctype<char> { + public: + ctype_posix(std::shared_ptr<locale_t> lc) : lc_(std::move(lc)) {} + + bool do_is(mask m, char c) const + { + if((m & space) && isspace_l(c, *lc_)) + return true; + if((m & print) && isprint_l(c, *lc_)) + return true; + if((m & cntrl) && iscntrl_l(c, *lc_)) + return true; + if((m & upper) && isupper_l(c, *lc_)) + return true; + if((m & lower) && islower_l(c, *lc_)) + return true; + if((m & alpha) && isalpha_l(c, *lc_)) + return true; + if((m & digit) && isdigit_l(c, *lc_)) + return true; + if((m & xdigit) && isxdigit_l(c, *lc_)) + return true; + if((m & punct) && ispunct_l(c, *lc_)) + return true; + return false; + } + const char* do_is(const char* begin, const char* end, mask* m) const + { + while(begin != end) { + char c = *begin++; + int r = 0; + if(isspace_l(c, *lc_)) + r |= space; + if(isprint_l(c, *lc_)) + r |= cntrl; + if(iscntrl_l(c, *lc_)) + r |= space; + if(isupper_l(c, *lc_)) + r |= upper; + if(islower_l(c, *lc_)) + r |= lower; + if(isalpha_l(c, *lc_)) + r |= alpha; + if(isdigit_l(c, *lc_)) + r |= digit; + if(isxdigit_l(c, *lc_)) + r |= xdigit; + if(ispunct_l(c, *lc_)) + r |= punct; + // r actually should be mask, but some standard + // libraries (like STLPort) + // do not define operator | properly so using int+cast + *m++ = static_cast<mask>(r); + } + return begin; + } + const char* do_scan_is(mask m, const char* begin, const char* end) const + { + while(begin != end) + if(do_is(m, *begin)) + return begin; + return begin; + } + const char* do_scan_not(mask m, const char* begin, const char* end) const + { + while(begin != end) + if(!do_is(m, *begin)) + return begin; + return begin; + } + char toupper(char c) const { return toupper_l(c, *lc_); } + const char* toupper(char* begin, const char* end) const + { + for(; begin != end; begin++) + *begin = toupper_l(*begin, *lc_); + return begin; + } + char tolower(char c) const { return tolower_l(c, *lc_); } + const char* tolower(char* begin, const char* end) const + { + for(; begin != end; begin++) + *begin = tolower_l(*begin, *lc_); + return begin; } - return begin; - } - wchar_t const *do_scan_is(mask m,wchar_t const *begin,wchar_t const *end) const - { - while(begin!=end) - if(do_is(m,*begin)) - return begin; - return begin; - } - wchar_t const *do_scan_not(mask m,wchar_t const *begin,wchar_t const *end) const - { - while(begin!=end) - if(!do_is(m,*begin)) - return begin; - return begin; - } - wchar_t toupper(wchar_t c) const - { - return towupper_l(c,*lc_); - } - wchar_t const *toupper(wchar_t *begin,wchar_t const *end) const - { - for(;begin!=end;begin++) - *begin = towupper_l(*begin,*lc_); - return begin; - } - wchar_t tolower(wchar_t c) const - { - return tolower_l(c,*lc_); - } - wchar_t const *tolower(wchar_t *begin,wchar_t const *end) const - { - for(;begin!=end;begin++) - *begin = tolower_l(*begin,*lc_); - return begin; - } -private: - boost::shared_ptr<locale_t> lc_; -}; + private: + std::shared_ptr<locale_t> lc_; + }; + + template<> + class ctype_posix<wchar_t> : public std::ctype<wchar_t> { + public: + ctype_posix(std::shared_ptr<locale_t> lc) : lc_(std::move(lc)) {} + + bool do_is(mask m, wchar_t c) const + { + if((m & space) && iswspace_l(c, *lc_)) + return true; + if((m & print) && iswprint_l(c, *lc_)) + return true; + if((m & cntrl) && iswcntrl_l(c, *lc_)) + return true; + if((m & upper) && iswupper_l(c, *lc_)) + return true; + if((m & lower) && iswlower_l(c, *lc_)) + return true; + if((m & alpha) && iswalpha_l(c, *lc_)) + return true; + if((m & digit) && iswdigit_l(c, *lc_)) + return true; + if((m & xdigit) && iswxdigit_l(c, *lc_)) + return true; + if((m & punct) && iswpunct_l(c, *lc_)) + return true; + return false; + } + const wchar_t* do_is(const wchar_t* begin, const wchar_t* end, mask* m) const + { + while(begin != end) { + wchar_t c = *begin++; + int r = 0; + if(iswspace_l(c, *lc_)) + r |= space; + if(iswprint_l(c, *lc_)) + r |= cntrl; + if(iswcntrl_l(c, *lc_)) + r |= space; + if(iswupper_l(c, *lc_)) + r |= upper; + if(iswlower_l(c, *lc_)) + r |= lower; + if(iswalpha_l(c, *lc_)) + r |= alpha; + if(iswdigit_l(c, *lc_)) + r |= digit; + if(iswxdigit_l(c, *lc_)) + r |= xdigit; + if(iswpunct_l(c, *lc_)) + r |= punct; + // r actually should be mask, but some standard + // libraries (like STLPort) + // do not define operator | properly so using int+cast + *m++ = static_cast<mask>(r); + } + return begin; + } + const wchar_t* do_scan_is(mask m, const wchar_t* begin, const wchar_t* end) const + { + while(begin != end) + if(do_is(m, *begin)) + return begin; + return begin; + } + const wchar_t* do_scan_not(mask m, const wchar_t* begin, const wchar_t* end) const + { + while(begin != end) + if(!do_is(m, *begin)) + return begin; + return begin; + } + wchar_t toupper(wchar_t c) const { return towupper_l(c, *lc_); } + const wchar_t* toupper(wchar_t* begin, const wchar_t* end) const + { + for(; begin != end; begin++) + *begin = towupper_l(*begin, *lc_); + return begin; + } + wchar_t tolower(wchar_t c) const { return tolower_l(c, *lc_); } + const wchar_t* tolower(wchar_t* begin, const wchar_t* end) const + { + for(; begin != end; begin++) + *begin = tolower_l(*begin, *lc_); + return begin; + } + private: + std::shared_ptr<locale_t> lc_; + }; + + struct basic_numpunct { + std::string grouping; + std::string thousands_sep; + std::string decimal_point; + basic_numpunct() : decimal_point(".") {} + basic_numpunct(locale_t lc) + { +#if defined(__APPLE__) || defined(__FreeBSD__) + lconv* cv = localeconv_l(lc); + grouping = cv->grouping; + thousands_sep = cv->thousands_sep; + decimal_point = cv->decimal_point; +#else + thousands_sep = nl_langinfo_l(THOUSEP, lc); + decimal_point = nl_langinfo_l(RADIXCHAR, lc); +# ifdef GROUPING + grouping = nl_langinfo_l(GROUPING, lc); +# endif +#endif + } + }; + + template<typename CharType> + class num_punct_posix : public std::numpunct<CharType> { + public: + typedef std::basic_string<CharType> string_type; + num_punct_posix(locale_t lc, size_t refs = 0) : std::numpunct<CharType>(refs) + { + basic_numpunct np(lc); + to_str(np.thousands_sep, thousands_sep_, lc); + to_str(np.decimal_point, decimal_point_, lc); + grouping_ = np.grouping; + if(thousands_sep_.size() > 1) + grouping_ = std::string(); + if(decimal_point_.size() > 1) + decimal_point_ = CharType('.'); + } + void to_str(std::string& s1, std::string& s2, locale_t /*lc*/) { s2.swap(s1); } + void to_str(std::string& s1, std::wstring& s2, locale_t lc) + { + s2 = conv::to_utf<wchar_t>(s1, nl_langinfo_l(CODESET, lc)); + } + 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_; } + string_type do_truename() const override + { + static const char t[] = "true"; + return string_type(t, t + sizeof(t) - 1); + } + string_type do_falsename() const override + { + static const char t[] = "false"; + return string_type(t, t + sizeof(t) - 1); + } + private: + string_type decimal_point_; + string_type thousands_sep_; + std::string grouping_; + }; -struct basic_numpunct { - std::string grouping; - std::string thousands_sep; - std::string decimal_point; - basic_numpunct() : - decimal_point(".") - { - } - basic_numpunct(locale_t lc) + template<typename CharType> + std::locale create_formatting_impl(const std::locale& in, std::shared_ptr<locale_t> lc) { - #if defined(__APPLE__) || defined(__FreeBSD__) - lconv *cv = localeconv_l(lc); - grouping = cv->grouping; - thousands_sep = cv->thousands_sep; - decimal_point = cv->decimal_point; - #else - thousands_sep = nl_langinfo_l(THOUSEP,lc); - decimal_point = nl_langinfo_l(RADIXCHAR,lc); - #ifdef GROUPING - grouping = nl_langinfo_l(GROUPING,lc); - #endif - #endif + std::locale tmp = std::locale(in, new num_punct_posix<CharType>(*lc)); + tmp = std::locale(tmp, new ctype_posix<CharType>(lc)); + tmp = std::locale(tmp, new time_put_posix<CharType>(lc)); + tmp = std::locale(tmp, new num_format<CharType>(std::move(lc))); + return tmp; } -}; -template<typename CharType> -class num_punct_posix : public std::numpunct<CharType> { -public: - typedef std::basic_string<CharType> string_type; - num_punct_posix(locale_t lc,size_t refs = 0) : - std::numpunct<CharType>(refs) - { - basic_numpunct np(lc); - to_str(np.thousands_sep,thousands_sep_,lc); - to_str(np.decimal_point,decimal_point_,lc); - grouping_ = np.grouping; - if(thousands_sep_.size() > 1) - grouping_ = std::string(); - if(decimal_point_.size() > 1) - decimal_point_ = CharType('.'); - } - void to_str(std::string &s1,std::string &s2,locale_t /*lc*/) - { - s2.swap(s1); - } - void to_str(std::string &s1,std::wstring &s2,locale_t lc) - { - s2=conv::to_utf<wchar_t>(s1,nl_langinfo_l(CODESET,lc)); - } - CharType do_decimal_point() const BOOST_OVERRIDE - { - return *decimal_point_.c_str(); - } - CharType do_thousands_sep() const BOOST_OVERRIDE - { - return *thousands_sep_.c_str(); - } - std::string do_grouping() const BOOST_OVERRIDE - { - return grouping_; - } - string_type do_truename() const BOOST_OVERRIDE - { - static const char t[]="true"; - return string_type(t,t+sizeof(t)-1); - } - string_type do_falsename() const BOOST_OVERRIDE + template<typename CharType> + std::locale create_parsing_impl(const std::locale& in, std::shared_ptr<locale_t> lc) { - static const char t[]="false"; - return string_type(t,t+sizeof(t)-1); + std::locale tmp = std::locale(in, new num_punct_posix<CharType>(*lc)); + tmp = std::locale(tmp, new ctype_posix<CharType>(std::move(lc))); + tmp = std::locale(tmp, new util::base_num_parse<CharType>()); + return tmp; } -private: - string_type decimal_point_; - string_type thousands_sep_; - std::string grouping_; -}; -template<typename CharType> -std::locale create_formatting_impl(std::locale const &in,boost::shared_ptr<locale_t> lc) -{ - std::locale tmp = std::locale(in,new num_punct_posix<CharType>(*lc)); - tmp = std::locale(tmp,new ctype_posix<CharType>(lc)); - tmp = std::locale(tmp,new time_put_posix<CharType>(lc)); - tmp = std::locale(tmp,new num_format<CharType>(lc)); - return tmp; -} - -template<typename CharType> -std::locale create_parsing_impl(std::locale const &in,boost::shared_ptr<locale_t> lc) -{ - std::locale tmp = std::locale(in,new num_punct_posix<CharType>(*lc)); - tmp = std::locale(tmp,new ctype_posix<CharType>(lc)); - tmp = std::locale(tmp,new util::base_num_parse<CharType>()); - return tmp; -} - - -std::locale create_formatting( std::locale const &in, - boost::shared_ptr<locale_t> lc, - character_facet_type type) -{ + std::locale create_formatting(const std::locale& in, std::shared_ptr<locale_t> lc, char_facet_t type) + { switch(type) { - case char_facet: - return create_formatting_impl<char>(in,lc); - case wchar_t_facet: - return create_formatting_impl<wchar_t>(in,lc); - default: - return in; + case char_facet_t::nochar: break; + case char_facet_t::char_f: return create_formatting_impl<char>(in, std::move(lc)); + case char_facet_t::wchar_f: return create_formatting_impl<wchar_t>(in, std::move(lc)); +#ifdef BOOST_LOCALE_ENABLE_CHAR16_T + case char_facet_t::char16_f: return create_formatting_impl<char16_t>(in, lc); +#endif +#ifdef BOOST_LOCALE_ENABLE_CHAR32_T + case char_facet_t::char32_f: return create_formatting_impl<char32_t>(in, lc); +#endif } -} + return in; + } -std::locale create_parsing( std::locale const &in, - boost::shared_ptr<locale_t> lc, - character_facet_type type) -{ + std::locale create_parsing(const std::locale& in, std::shared_ptr<locale_t> lc, char_facet_t type) + { switch(type) { - case char_facet: - return create_parsing_impl<char>(in,lc); - case wchar_t_facet: - return create_parsing_impl<wchar_t>(in,lc); - default: - return in; + case char_facet_t::nochar: break; + case char_facet_t::char_f: return create_parsing_impl<char>(in, std::move(lc)); + case char_facet_t::wchar_f: return create_parsing_impl<wchar_t>(in, std::move(lc)); +#ifdef BOOST_LOCALE_ENABLE_CHAR16_T + case char_facet_t::char16_f: return create_parsing_impl<char16_t>(in, lc); +#endif +#ifdef BOOST_LOCALE_ENABLE_CHAR32_T + case char_facet_t::char32_f: return create_parsing_impl<char32_t>(in, lc); +#endif } -} - - - -} // impl_std -} // locale -} //boost - - + return in; + } +}}} // namespace boost::locale::impl_posix 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 68da0e1241..ef6f498830 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 @@ -6,57 +6,44 @@ #define BOOST_LOCALE_SOURCE #include "boost/locale/posix/posix_backend.hpp" -#include <boost/locale/localization_backend.hpp> #include <boost/locale/gnu_gettext.hpp> #include <boost/locale/info.hpp> +#include <boost/locale/localization_backend.hpp> #include <boost/locale/util.hpp> #include <algorithm> #include <iterator> #include <langinfo.h> #include <vector> #if defined(__FreeBSD__) -#include <xlocale.h> +# include <xlocale.h> #endif #include "boost/locale/posix/all_generator.hpp" #include "boost/locale/util/gregorian.hpp" #include "boost/locale/util/locale_data.hpp" -namespace boost { -namespace locale { -namespace impl_posix { +namespace boost { namespace locale { namespace impl_posix { class posix_localization_backend : public localization_backend { public: - posix_localization_backend() : + posix_localization_backend() : invalid_(true) {} + posix_localization_backend(const posix_localization_backend& other) : + localization_backend(), paths_(other.paths_), domains_(other.domains_), locale_id_(other.locale_id_), invalid_(true) - { - } - posix_localization_backend(posix_localization_backend const &other) : - localization_backend(), - paths_(other.paths_), - domains_(other.domains_), - locale_id_(other.locale_id_), - invalid_(true) - { - } - posix_localization_backend *clone() const BOOST_OVERRIDE - { - return new posix_localization_backend(*this); - } + {} + posix_localization_backend* clone() const override { return new posix_localization_backend(*this); } - void set_option(std::string const &name,std::string const &value) BOOST_OVERRIDE + void set_option(const std::string& name, const std::string& value) override { invalid_ = true; - if(name=="locale") + if(name == "locale") locale_id_ = value; - else if(name=="message_path") + else if(name == "message_path") paths_.push_back(value); - else if(name=="message_application") + else if(name == "message_application") domains_.push_back(value); - } - void clear_options() BOOST_OVERRIDE + void clear_options() override { invalid_ = true; locale_id_.clear(); @@ -64,7 +51,7 @@ namespace impl_posix { domains_.clear(); } - static void free_locale_by_ptr(locale_t *lc) + static void free_locale_by_ptr(locale_t* lc) { freelocale(*lc); delete lc; @@ -80,54 +67,44 @@ 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); + locale_t tmp = newlocale(LC_ALL_MASK, real_id_.c_str(), 0); if(!tmp) { - tmp=newlocale(LC_ALL_MASK,"C",0); + tmp = newlocale(LC_ALL_MASK, "C", 0); } if(!tmp) { throw std::runtime_error("newlocale failed"); } - locale_t *tmp_p = 0; + locale_t* tmp_p = 0; try { tmp_p = new locale_t(); - } - catch(...) { + } catch(...) { freelocale(tmp); throw; } *tmp_p = tmp; - lc_ = boost::shared_ptr<locale_t>(tmp_p,free_locale_by_ptr); + lc_ = std::shared_ptr<locale_t>(tmp_p, free_locale_by_ptr); } - std::locale install(std::locale const &base, - locale_category_type category, - character_facet_type type = nochar_facet) BOOST_OVERRIDE + std::locale install(const std::locale& base, category_t category, char_facet_t type) override { prepare_data(); switch(category) { - case convert_facet: - return create_convert(base,lc_,type); - case collation_facet: - return create_collate(base,lc_,type); - case formatting_facet: - return create_formatting(base,lc_,type); - case parsing_facet: - return create_parsing(base,lc_,type); - case codepage_facet: - return create_codecvt(base,nl_langinfo_l(CODESET,*lc_),type); - case calendar_facet: - { + case category_t::convert: return create_convert(base, lc_, type); + case category_t::collation: return create_collate(base, lc_, type); + case category_t::formatting: return create_formatting(base, lc_, type); + case category_t::parsing: return create_parsing(base, lc_, type); + case category_t::codepage: return create_codecvt(base, nl_langinfo_l(CODESET, *lc_), type); + case category_t::calendar: { util::locale_data inf; inf.parse(real_id_); - return util::install_gregorian_calendar(base,inf.country); + return util::install_gregorian_calendar(base, inf.country); } - case message_facet: - { + case category_t::message: { gnu_gettext::messages_info minf; util::locale_data inf; inf.parse(real_id_); @@ -135,48 +112,46 @@ namespace impl_posix { minf.country = inf.country; minf.variant = inf.variant; minf.encoding = inf.encoding; - std::copy(domains_.begin(),domains_.end(),std::back_inserter<gnu_gettext::messages_info::domains_type>(minf.domains)); + std::copy(domains_.begin(), + domains_.end(), + std::back_inserter<gnu_gettext::messages_info::domains_type>(minf.domains)); minf.paths = paths_; switch(type) { - case char_facet: - return std::locale(base,gnu_gettext::create_messages_facet<char>(minf)); - case wchar_t_facet: - return std::locale(base,gnu_gettext::create_messages_facet<wchar_t>(minf)); - #ifdef BOOST_LOCALE_ENABLE_CHAR16_T - case char16_t_facet: - return std::locale(base,gnu_gettext::create_messages_facet<char16_t>(minf)); - #endif - #ifdef BOOST_LOCALE_ENABLE_CHAR32_T - case char32_t_facet: - return std::locale(base,gnu_gettext::create_messages_facet<char32_t>(minf)); - #endif - default: - return base; + case char_facet_t::nochar: break; + case char_facet_t::char_f: + return std::locale(base, gnu_gettext::create_messages_facet<char>(minf)); + case char_facet_t::wchar_f: + return std::locale(base, gnu_gettext::create_messages_facet<wchar_t>(minf)); +#ifdef BOOST_LOCALE_ENABLE_CHAR16_T + case char_facet_t::char16_f: + return std::locale(base, gnu_gettext::create_messages_facet<char16_t>(minf)); +#endif +#ifdef BOOST_LOCALE_ENABLE_CHAR32_T + case char_facet_t::char32_f: + return std::locale(base, gnu_gettext::create_messages_facet<char32_t>(minf)); +#endif } + return base; } - case information_facet: - return util::create_info(base,real_id_); - default: - return base; + case category_t::information: return util::create_info(base, real_id_); + case category_t::boundary: break; // Not implemented } + return base; } private: - std::vector<std::string> paths_; std::vector<std::string> domains_; std::string locale_id_; std::string real_id_; bool invalid_; - boost::shared_ptr<locale_t> lc_; + std::shared_ptr<locale_t> lc_; }; - localization_backend *create_localization_backend() + localization_backend* create_localization_backend() { return new posix_localization_backend(); } -} // impl posix -} // locale -} // boost +}}} // 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 bfc46120a9..e172fe4103 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,13 +6,10 @@ #ifndef BOOST_LOCALE_IMPL_POSIX_LOCALIZATION_BACKEND_HPP #define BOOST_LOCALE_IMPL_POSIX_LOCALIZATION_BACKEND_HPP -namespace boost { - namespace locale { - class localization_backend; - namespace impl_posix { - localization_backend *create_localization_backend(); - } // impl_std - } // locale -} // boost +namespace boost { namespace locale { + class localization_backend; + namespace impl_posix { + 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 c1c347de85..e719cc3247 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 @@ -11,457 +11,415 @@ #include <boost/thread/mutex.hpp> #include <cmath> -namespace boost { -namespace locale { - -using namespace period; - -///////////////////////// -// Calendar -//////////////////////// - -calendar::calendar(std::locale const &l,std::string const &zone) : - locale_(l), - tz_(zone), - impl_(std::use_facet<calendar_facet>(l).create_calendar()) -{ - impl_->set_timezone(tz_); -} - -calendar::calendar(std::string const &zone) : - tz_(zone), - impl_(std::use_facet<calendar_facet>(std::locale()).create_calendar()) -{ - impl_->set_timezone(tz_); -} - - -calendar::calendar(std::locale const &l) : - locale_(l), - tz_(time_zone::global()), - impl_(std::use_facet<calendar_facet>(l).create_calendar()) -{ - impl_->set_timezone(tz_); -} - -calendar::calendar(std::ios_base &ios) : - locale_(ios.getloc()), - tz_(ios_info::get(ios).time_zone()), - impl_(std::use_facet<calendar_facet>(locale_).create_calendar()) -{ - impl_->set_timezone(tz_); - -} - -calendar::calendar() : - tz_(time_zone::global()), - impl_(std::use_facet<calendar_facet>(std::locale()).create_calendar()) -{ - impl_->set_timezone(tz_); -} - -calendar::~calendar() -{ -} - -calendar::calendar(calendar const &other) : - locale_(other.locale_), - tz_(other.tz_), - impl_(other.impl_->clone()) -{ -} - -calendar const &calendar::operator = (calendar const &other) -{ - if(this !=&other) { +namespace boost { namespace locale { + + using namespace period; + + ///////////////////////// + // Calendar + //////////////////////// + + calendar::calendar(const std::locale& l, const std::string& zone) : + locale_(l), tz_(zone), impl_(std::use_facet<calendar_facet>(l).create_calendar()) + { + impl_->set_timezone(tz_); + } + + calendar::calendar(const std::string& zone) : + tz_(zone), impl_(std::use_facet<calendar_facet>(std::locale()).create_calendar()) + { + impl_->set_timezone(tz_); + } + + calendar::calendar(const std::locale& l) : + locale_(l), tz_(time_zone::global()), impl_(std::use_facet<calendar_facet>(l).create_calendar()) + { + impl_->set_timezone(tz_); + } + + calendar::calendar(std::ios_base& ios) : + locale_(ios.getloc()), tz_(ios_info::get(ios).time_zone()), + impl_(std::use_facet<calendar_facet>(locale_).create_calendar()) + { + impl_->set_timezone(tz_); + } + + calendar::calendar() : + tz_(time_zone::global()), impl_(std::use_facet<calendar_facet>(std::locale()).create_calendar()) + { + impl_->set_timezone(tz_); + } + + calendar::~calendar() = default; + + calendar::calendar(const calendar& other) : locale_(other.locale_), tz_(other.tz_), impl_(other.impl_->clone()) {} + + calendar& calendar::operator=(const calendar& other) + { impl_.reset(other.impl_->clone()); locale_ = other.locale_; tz_ = other.tz_; + return *this; + } + + bool calendar::is_gregorian() const + { + return impl_->get_option(abstract_calendar::is_gregorian) != 0; + } + + std::string calendar::get_time_zone() const + { + return tz_; + } + + std::locale calendar::get_locale() const + { + return locale_; + } + + int calendar::minimum(period_type f) const + { + return impl_->get_value(f.mark(), abstract_calendar::absolute_minimum); + } + + int calendar::greatest_minimum(period_type f) const + { + return impl_->get_value(f.mark(), abstract_calendar::greatest_minimum); + } + + int calendar::maximum(period_type f) const + { + return impl_->get_value(f.mark(), abstract_calendar::absolute_maximum); + } + + int calendar::least_maximum(period_type f) const + { + return impl_->get_value(f.mark(), abstract_calendar::least_maximum); + } + + int calendar::first_day_of_week() const + { + return impl_->get_value(period::marks::first_day_of_week, abstract_calendar::current); + } + + bool calendar::operator==(const calendar& other) const + { + return impl_->same(other.impl_.get()); + } + + bool calendar::operator!=(const calendar& other) const + { + return !(*this == other); + } + + ////////////////////////////////// + // date_time + ///////////////// + + date_time::date_time() : impl_(std::use_facet<calendar_facet>(std::locale()).create_calendar()) + { + impl_->set_timezone(time_zone::global()); + } + + date_time::date_time(const date_time& other) : impl_(other.impl_->clone()) {} + + 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++) { + impl_->set_value(s[i].type.mark(), s[i].value); + } + impl_->normalize(); + } + + date_time& date_time::operator=(const date_time& other) + { + impl_.reset(other.impl_->clone()); + return *this; + } + + date_time::date_time(double t) : impl_(std::use_facet<calendar_facet>(std::locale()).create_calendar()) + { + impl_->set_timezone(time_zone::global()); + time(t); + } + + date_time::date_time(double t, const calendar& cal) : impl_(cal.impl_->clone()) + { + time(t); + } + + date_time::date_time(const calendar& cal) : impl_(cal.impl_->clone()) {} + + date_time::date_time(const date_time_period_set& s) : + impl_(std::use_facet<calendar_facet>(std::locale()).create_calendar()) + { + impl_->set_timezone(time_zone::global()); + 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++) { + impl_->set_value(s[i].type.mark(), s[i].value); + } + impl_->normalize(); } - return *this; -} - - -bool calendar::is_gregorian() const -{ - return impl_->get_option(abstract_calendar::is_gregorian)!=0; -} - -std::string calendar::get_time_zone() const -{ - return tz_; -} - -std::locale calendar::get_locale() const -{ - return locale_; -} - -int calendar::minimum(period_type f) const -{ - return impl_->get_value(f.mark(),abstract_calendar::absolute_minimum); -} - -int calendar::greatest_minimum(period_type f) const -{ - return impl_->get_value(f.mark(),abstract_calendar::greatest_minimum); -} - -int calendar::maximum(period_type f) const -{ - return impl_->get_value(f.mark(),abstract_calendar::absolute_maximum); -} - -int calendar::least_maximum(period_type f) const -{ - return impl_->get_value(f.mark(),abstract_calendar::least_maximum); -} - -int calendar::first_day_of_week() const -{ - return impl_->get_value(period::marks::first_day_of_week,abstract_calendar::current); -} - -bool calendar::operator==(calendar const &other) const -{ - return impl_->same(other.impl_.get()); -} - -bool calendar::operator!=(calendar const &other) const -{ - return !(*this==other); -} - -////////////////////////////////// -// date_time -///////////////// - -date_time::date_time() : - impl_(std::use_facet<calendar_facet>(std::locale()).create_calendar()) -{ - impl_->set_timezone(time_zone::global()); -} - -date_time::date_time(date_time const &other) -{ - impl_.reset(other.impl_->clone()); -} - -date_time::date_time(date_time const &other,date_time_period_set const &s) -{ - impl_.reset(other.impl_->clone()); - for(unsigned i=0;i<s.size();i++) { - impl_->set_value(s[i].type.mark(),s[i].value); - } - impl_->normalize(); -} - -date_time const &date_time::operator = (date_time const &other) -{ - if(this != &other) { - date_time tmp(other); - swap(tmp); - } - return *this; -} - -date_time::~date_time() -{ -} - -date_time::date_time(double t) : - impl_(std::use_facet<calendar_facet>(std::locale()).create_calendar()) -{ - impl_->set_timezone(time_zone::global()); - time(t); -} - -date_time::date_time(double t,calendar const &cal) : - impl_(cal.impl_->clone()) -{ - time(t); -} - -date_time::date_time(calendar const &cal) : - impl_(cal.impl_->clone()) -{ -} - - - -date_time::date_time(date_time_period_set const &s) : - impl_(std::use_facet<calendar_facet>(std::locale()).create_calendar()) -{ - impl_->set_timezone(time_zone::global()); - for(unsigned i=0;i<s.size();i++) { - impl_->set_value(s[i].type.mark(),s[i].value); - } - impl_->normalize(); -} -date_time::date_time(date_time_period_set const &s,calendar const &cal) : - impl_(cal.impl_->clone()) -{ - for(unsigned i=0;i<s.size();i++) { - impl_->set_value(s[i].type.mark(),s[i].value); - } - impl_->normalize(); -} - -date_time const &date_time::operator=(date_time_period_set const &s) -{ - for(unsigned i=0;i<s.size();i++) - impl_->set_value(s[i].type.mark(),s[i].value); - impl_->normalize(); - return *this; -} - -void date_time::set(period_type f,int v) -{ - impl_->set_value(f.mark(),v); - impl_->normalize(); -} - -int date_time::get(period_type f) const -{ - return impl_->get_value(f.mark(),abstract_calendar::current); -} - -date_time date_time::operator+(date_time_period const &v) const -{ - date_time tmp(*this); - tmp+=v; - return tmp; -} - -date_time date_time::operator-(date_time_period const &v) const -{ - date_time tmp(*this); - tmp-=v; - return tmp; -} - -date_time date_time::operator<<(date_time_period const &v) const -{ - date_time tmp(*this); - tmp <<= v; - return tmp; -} - -date_time date_time::operator>>(date_time_period const &v) const -{ - date_time tmp(*this); - tmp >>= v; - return tmp; -} - -date_time const &date_time::operator+=(date_time_period const &v) -{ - impl_->adjust_value(v.type.mark(),abstract_calendar::move,v.value); - return *this; -} - -date_time const &date_time::operator-=(date_time_period const &v) -{ - impl_->adjust_value(v.type.mark(),abstract_calendar::move,-v.value); - return *this; -} - -date_time const &date_time::operator<<=(date_time_period const &v) -{ - impl_->adjust_value(v.type.mark(),abstract_calendar::roll,v.value); - return *this; -} - -date_time const &date_time::operator>>=(date_time_period const &v) -{ - impl_->adjust_value(v.type.mark(),abstract_calendar::roll,-v.value); - return *this; -} - - -date_time date_time::operator+(date_time_period_set const &v) const -{ - date_time tmp(*this); - tmp+=v; - return tmp; -} - -date_time date_time::operator-(date_time_period_set const &v) const -{ - date_time tmp(*this); - tmp-=v; - return tmp; -} - -date_time date_time::operator<<(date_time_period_set const &v) const -{ - date_time tmp(*this); - tmp <<= v; - return tmp; -} - -date_time date_time::operator>>(date_time_period_set const &v) const -{ - date_time tmp(*this); - tmp >>= v; - return tmp; -} - -date_time const &date_time::operator+=(date_time_period_set const &v) -{ - for(unsigned i=0;i<v.size();i++) { - *this+=v[i]; - } - return *this; -} - -date_time const &date_time::operator-=(date_time_period_set const &v) -{ - for(unsigned i=0;i<v.size();i++) { - *this-=v[i]; - } - return *this; -} - -date_time const &date_time::operator<<=(date_time_period_set const &v) -{ - for(unsigned i=0;i<v.size();i++) { - *this <<= v[i]; - } - return *this; -} - -date_time const &date_time::operator>>=(date_time_period_set const &v) -{ - for(unsigned i=0;i<v.size();i++) { - *this >>= v[i]; - } - return *this; -} - -double date_time::time() const -{ - posix_time ptime = impl_->get_time(); - return double(ptime.seconds)+1e-9*ptime.nanoseconds; -} - -void date_time::time(double v) -{ - double dseconds = floor(v); - int64_t seconds = static_cast<int64_t>(dseconds); - double fract = v - dseconds; - int nano = static_cast<int>(fract * 1e9); - if(nano < 0) - nano = 0; - else if(nano >999999999) - nano = 999999999; - posix_time ptime; - ptime.seconds = seconds; - ptime.nanoseconds = nano; - impl_->set_time(ptime); -} - -namespace { - int compare(posix_time const &left,posix_time const &right) - { - if(left.seconds < right.seconds) - return -1; - if(left.seconds > right.seconds) - return 1; - if(left.nanoseconds < right.nanoseconds) - return -1; - if(left.nanoseconds > right.nanoseconds) - return 1; - return 0; - } -} - -bool date_time::operator==(date_time const &other) const -{ - return compare(impl_->get_time(),other.impl_->get_time()) == 0; -} - -bool date_time::operator!=(date_time const &other) const -{ - return !(*this==other); -} - -bool date_time::operator<(date_time const &other) const -{ - return compare(impl_->get_time(),other.impl_->get_time()) < 0; -} - -bool date_time::operator>=(date_time const &other) const -{ - return !(*this<other); -} - -bool date_time::operator>(date_time const &other) const -{ - return compare(impl_->get_time(),other.impl_->get_time()) > 0; -} - -bool date_time::operator<=(date_time const &other) const -{ - return !(*this>other); -} -void date_time::swap(date_time &other) -{ - impl_.swap(other.impl_); -} + date_time& date_time::operator=(const date_time_period_set& s) + { + for(unsigned i = 0; i < s.size(); i++) + impl_->set_value(s[i].type.mark(), s[i].value); + impl_->normalize(); + return *this; + } + + void date_time::set(period_type f, int v) + { + impl_->set_value(f.mark(), v); + impl_->normalize(); + } + + int date_time::get(period_type f) const + { + return impl_->get_value(f.mark(), abstract_calendar::current); + } + + date_time date_time::operator+(const date_time_period& v) const + { + date_time tmp(*this); + tmp += v; + return tmp; + } + + date_time date_time::operator-(const date_time_period& v) const + { + date_time tmp(*this); + tmp -= v; + return tmp; + } + + date_time date_time::operator<<(const date_time_period& v) const + { + date_time tmp(*this); + tmp <<= v; + return tmp; + } + + date_time date_time::operator>>(const date_time_period& v) const + { + date_time tmp(*this); + tmp >>= v; + return tmp; + } + + date_time& date_time::operator+=(const date_time_period& v) + { + impl_->adjust_value(v.type.mark(), abstract_calendar::move, v.value); + return *this; + } + + date_time& date_time::operator-=(const date_time_period& v) + { + impl_->adjust_value(v.type.mark(), abstract_calendar::move, -v.value); + return *this; + } + + date_time& date_time::operator<<=(const date_time_period& v) + { + impl_->adjust_value(v.type.mark(), abstract_calendar::roll, v.value); + return *this; + } + + date_time& date_time::operator>>=(const date_time_period& v) + { + impl_->adjust_value(v.type.mark(), abstract_calendar::roll, -v.value); + return *this; + } + + date_time date_time::operator+(const date_time_period_set& v) const + { + date_time tmp(*this); + tmp += v; + return tmp; + } + + date_time date_time::operator-(const date_time_period_set& v) const + { + date_time tmp(*this); + tmp -= v; + return tmp; + } -int date_time::difference(date_time const &other,period_type f) const -{ - return impl_->difference(other.impl_.get(),f.mark()); -} + date_time date_time::operator<<(const date_time_period_set& v) const + { + date_time tmp(*this); + tmp <<= v; + return tmp; + } + + date_time date_time::operator>>(const date_time_period_set& v) const + { + date_time tmp(*this); + tmp >>= v; + return tmp; + } -int date_time::maximum(period_type f) const -{ - return impl_->get_value(f.mark(),abstract_calendar::actual_maximum); -} + date_time& date_time::operator+=(const date_time_period_set& v) + { + 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++) { + *this -= v[i]; + } + return *this; + } + + date_time& date_time::operator<<=(const date_time_period_set& v) + { + 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++) { + *this >>= v[i]; + } + return *this; + } + + double date_time::time() const + { + return impl_->get_time_ms() / 1000.; + } -int date_time::minimum(period_type f) const -{ - return impl_->get_value(f.mark(),abstract_calendar::actual_minimum); -} + void date_time::time(double v) + { + double seconds; + const double fract_seconds = std::modf(v, &seconds); // v = seconds + fract_seconds + posix_time ptime; + ptime.seconds = static_cast<int64_t>(seconds); + int64_t nano = static_cast<int64_t>(fract_seconds * 1e9); + + constexpr int64_t ns_in_s = static_cast<int64_t>(1000) * 1000 * 1000; + if(seconds < 0 && nano != 0) { + assert(nano < 0); // Same sign + seconds -= 1; + nano = ns_in_s + nano; + } + if(nano < 0) + nano = 0; + else if(nano >= ns_in_s) + nano = ns_in_s - 1; + ptime.nanoseconds = static_cast<uint32_t>(nano); + impl_->set_time(ptime); + } -bool date_time::is_in_daylight_saving_time() const -{ - return impl_->get_option(abstract_calendar::is_dst)!=0; -} + namespace { + int compare(const posix_time& left, const posix_time& right) + { + if(left.seconds < right.seconds) + return -1; + if(left.seconds > right.seconds) + return 1; + if(left.nanoseconds < right.nanoseconds) + return -1; + if(left.nanoseconds > right.nanoseconds) + return 1; + return 0; + } + } // namespace + + bool date_time::operator==(const date_time& other) const + { + return compare(impl_->get_time(), other.impl_->get_time()) == 0; + } -namespace time_zone { - boost::mutex &tz_mutex() + bool date_time::operator!=(const date_time& other) const { - static boost::mutex m; - return m; + return !(*this == other); } - std::string &tz_id() + + bool date_time::operator<(const date_time& other) const { - static std::string id; - return id; + return compare(impl_->get_time(), other.impl_->get_time()) < 0; } - std::string global() + + bool date_time::operator>=(const date_time& other) const { - boost::unique_lock<boost::mutex> lock(tz_mutex()); - std::string id = tz_id(); - return id; + return !(*this < other); } - std::string global(std::string const &new_id) + + bool date_time::operator>(const date_time& other) const { - boost::unique_lock<boost::mutex> lock(tz_mutex()); - std::string id = tz_id(); - tz_id() = new_id; - return id; + return compare(impl_->get_time(), other.impl_->get_time()) > 0; } -} + bool date_time::operator<=(const date_time& other) const + { + return !(*this > other); + } + void date_time::swap(date_time& other) + { + impl_.swap(other.impl_); + } -} // locale -} // boost + int date_time::difference(const date_time& other, period_type f) const + { + return impl_->difference(*other.impl_.get(), f.mark()); + } + int date_time::maximum(period_type f) const + { + return impl_->get_value(f.mark(), abstract_calendar::actual_maximum); + } + int date_time::minimum(period_type f) const + { + return impl_->get_value(f.mark(), abstract_calendar::actual_minimum); + } + bool date_time::is_in_daylight_saving_time() const + { + return impl_->get_option(abstract_calendar::is_dst) != 0; + } + namespace time_zone { + boost::mutex& tz_mutex() + { + static boost::mutex m; + return m; + } + std::string& tz_id() + { + static std::string id; + return id; + } + std::string global() + { + boost::unique_lock<boost::mutex> lock(tz_mutex()); + std::string id = tz_id(); + return 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; + } + } // namespace time_zone + +}} // namespace boost::locale 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 a662e039f5..a72e13d4e3 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/shared/format.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/shared/format.cpp @@ -6,181 +6,162 @@ #define BOOST_LOCALE_SOURCE #include <boost/locale/format.hpp> -#include <boost/locale/info.hpp> #include <boost/locale/generator.hpp> +#include <boost/locale/info.hpp> #include <cstdlib> #include <iostream> #include <limits> -namespace boost { - namespace locale { - namespace details { - struct format_parser::data { - unsigned position; - std::streamsize precision; - std::ios_base::fmtflags flags; - ios_info info; - std::locale saved_locale; - bool restore_locale; - void *cookie; - void (*imbuer)(void *,std::locale const &); - }; +namespace boost { namespace locale { namespace detail { + struct format_parser::data { + unsigned position; + std::streamsize precision; + std::ios_base::fmtflags flags; + ios_info info; + std::locale saved_locale; + bool restore_locale; + void* cookie; + void (*imbuer)(void*, const std::locale&); + }; - format_parser::format_parser(std::ios_base &ios,void *cookie,void (*imbuer)(void *,std::locale const &)) : - ios_(ios), - d(new data) - { - d->position=std::numeric_limits<unsigned>::max(); - d->precision=ios.precision(); - d->flags = ios.flags(); - d->info=ios_info::get(ios); - d->saved_locale = ios.getloc(); - d->restore_locale=false; - d->cookie = cookie; - d->imbuer = imbuer; - } - - void format_parser::imbue(std::locale const &l) - { - d->imbuer(d->cookie,l); - } + format_parser::format_parser(std::ios_base& ios, void* cookie, void (*imbuer)(void*, const std::locale&)) : + ios_(ios), d(new data) + { + d->position = std::numeric_limits<unsigned>::max(); + d->precision = ios.precision(); + d->flags = ios.flags(); + d->info = ios_info::get(ios); + d->saved_locale = ios.getloc(); + d->restore_locale = false; + d->cookie = cookie; + d->imbuer = imbuer; + } - format_parser::~format_parser() - { - } + void format_parser::imbue(const std::locale& l) + { + d->imbuer(d->cookie, l); + } - void format_parser::restore() - { - ios_info::get(ios_) = d->info; - ios_.width(0); - ios_.flags(d->flags); - if(d->restore_locale) - imbue(d->saved_locale); - } + format_parser::~format_parser() = default; - unsigned format_parser::get_position() - { - return d->position; - } + void format_parser::restore() + { + ios_info::get(ios_) = d->info; + ios_.width(0); + ios_.flags(d->flags); + if(d->restore_locale) + imbue(d->saved_locale); + } - void format_parser::set_one_flag(std::string const &key,std::string const &value) - { - 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; - } + unsigned format_parser::get_position() + { + return d->position; + } - if(key=="num" || key=="number") { - as::number(ios_); + void format_parser::set_one_flag(const std::string& key, const std::string& value) + { + 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(value=="hex") - ios_.setf(std::ios_base::hex,std::ios_base::basefield); - else if(value=="oct") - ios_.setf(std::ios_base::oct,std::ios_base::basefield); - else if(value=="sci" || value=="scientific") - ios_.setf(std::ios_base::scientific,std::ios_base::floatfield); - else if(value=="fix" || value=="fixed") - ios_.setf(std::ios_base::fixed,std::ios_base::floatfield); - } - else if(key=="cur" || key=="currency") { - as::currency(ios_); - if(value=="iso") - as::currency_iso(ios_); - else if(value=="nat" || value=="national") - as::currency_national(ios_); - } - else if(key=="per" || key=="percent") { - as::percent(ios_); - } - else if(key=="date") { - as::date(ios_); - if(value=="s" || value=="short") - as::date_short(ios_); - else if(value=="m" || value=="medium") - as::date_medium(ios_); - else if(value=="l" || value=="long") - as::date_long(ios_); - else if(value=="f" || value=="full") - as::date_full(ios_); - } - else if(key=="time") { - as::time(ios_); - if(value=="s" || value=="short") - as::time_short(ios_); - else if(value=="m" || value=="medium") - as::time_medium(ios_); - else if(value=="l" || value=="long") - as::time_long(ios_); - else if(value=="f" || value=="full") - as::time_full(ios_); - } - else if(key=="dt" || key=="datetime") { - as::datetime(ios_); - if(value=="s" || value=="short") { - as::date_short(ios_); - as::time_short(ios_); - } - else if(value=="m" || value=="medium") { - as::date_medium(ios_); - as::time_medium(ios_); - } - else if(value=="l" || value=="long") { - as::date_long(ios_); - as::time_long(ios_); - } - else if(value=="f" || value=="full") { - as::date_full(ios_); - as::time_full(ios_); - } - } - else if(key=="spell" || key=="spellout") { - as::spellout(ios_); - } - else if(key=="ord" || key=="ordinal") { - as::ordinal(ios_); - } - 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); - else if(key=="gmt") - as::gmt(ios_); - else if(key=="local") - 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") { - if(!d->restore_locale) { - d->saved_locale=ios_.getloc(); - d->restore_locale=true; - } + if(key == "num" || key == "number") { + as::number(ios_); - std::string encoding=std::use_facet<info>(d->saved_locale).encoding(); - generator gen; - gen.categories(formatting_facet); + if(value == "hex") + ios_.setf(std::ios_base::hex, std::ios_base::basefield); + else if(value == "oct") + ios_.setf(std::ios_base::oct, std::ios_base::basefield); + else if(value == "sci" || value == "scientific") + ios_.setf(std::ios_base::scientific, std::ios_base::floatfield); + else if(value == "fix" || value == "fixed") + ios_.setf(std::ios_base::fixed, std::ios_base::floatfield); + } else if(key == "cur" || key == "currency") { + as::currency(ios_); + if(value == "iso") + as::currency_iso(ios_); + else if(value == "nat" || value == "national") + as::currency_national(ios_); + } else if(key == "per" || key == "percent") { + as::percent(ios_); + } else if(key == "date") { + as::date(ios_); + if(value == "s" || value == "short") + as::date_short(ios_); + else if(value == "m" || value == "medium") + as::date_medium(ios_); + else if(value == "l" || value == "long") + as::date_long(ios_); + else if(value == "f" || value == "full") + as::date_full(ios_); + } else if(key == "time") { + as::time(ios_); + if(value == "s" || value == "short") + as::time_short(ios_); + else if(value == "m" || value == "medium") + as::time_medium(ios_); + else if(value == "l" || value == "long") + as::time_long(ios_); + else if(value == "f" || value == "full") + as::time_full(ios_); + } else if(key == "dt" || key == "datetime") { + as::datetime(ios_); + if(value == "s" || value == "short") { + as::date_short(ios_); + as::time_short(ios_); + } else if(value == "m" || value == "medium") { + as::date_medium(ios_); + as::time_medium(ios_); + } else if(value == "l" || value == "long") { + as::date_long(ios_); + as::time_long(ios_); + } else if(value == "f" || value == "full") { + as::date_full(ios_); + as::time_full(ios_); + } + } else if(key == "spell" || key == "spellout") { + as::spellout(ios_); + } else if(key == "ord" || key == "ordinal") { + as::ordinal(ios_); + } 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); + else if(key == "gmt") + as::gmt(ios_); + else if(key == "local") + 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") { + if(!d->restore_locale) { + d->saved_locale = ios_.getloc(); + d->restore_locale = true; + } - std::locale new_loc; - if(value.find('.')==std::string::npos) - new_loc = gen(value + "." + encoding); - else - new_loc = gen(value); + std::string encoding = std::use_facet<info>(d->saved_locale).encoding(); + generator gen; + gen.categories(category_t::formatting); - imbue(new_loc); - } + std::locale new_loc; + if(value.find('.') == std::string::npos) + new_loc = gen(value + "." + encoding); + else + new_loc = gen(value); - } + imbue(new_loc); } } -} +}}} // namespace boost::locale::detail // boostinspect:nominmax diff --git a/contrib/restricted/boost/locale/src/boost/locale/shared/formatting.cpp b/contrib/restricted/boost/locale/src/boost/locale/shared/formatting.cpp index b44db9952d..9c30d2af80 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/shared/formatting.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/shared/formatting.cpp @@ -5,174 +5,128 @@ // https://www.boost.org/LICENSE_1_0.txt #define BOOST_LOCALE_SOURCE -#include <boost/locale/formatting.hpp> #include <boost/locale/date_time.hpp> -#include <typeinfo> -#include <algorithm> +#include <boost/locale/formatting.hpp> #include "boost/locale/shared/ios_prop.hpp" +#include <algorithm> +#include <typeinfo> -namespace boost { - namespace locale { - - ios_info::string_set::string_set() : - type(0), - size(0), - ptr(0) - { - } - ios_info::string_set::~string_set() - { - delete [] ptr; - } - ios_info::string_set::string_set(string_set const &other) - { - if(other.ptr!=0) { - ptr=new char[other.size]; - size=other.size; - type=other.type; - memcpy(ptr,other.ptr,size); - } - else { - ptr=0; - size=0; - type=0; - } - } - - void ios_info::string_set::swap(string_set &other) - { - std::swap(type,other.type); - std::swap(size,other.size); - std::swap(ptr,other.ptr); - } - - ios_info::string_set const &ios_info::string_set::operator=(string_set const &other) - { - if(this!=&other) { - string_set tmp(other); - swap(tmp); - } - return *this; - } - - struct ios_info::data {}; - - ios_info::ios_info() : - flags_(0), - domain_id_(0), - d(0) - { - time_zone_ = time_zone::global(); - } - ios_info::~ios_info() - { - } - - ios_info::ios_info(ios_info const &other) - { - flags_ = other.flags_; - domain_id_ = other.domain_id_; - time_zone_ = other.time_zone_; - datetime_ = other.datetime_; - } - - - ios_info const &ios_info::operator=(ios_info const &other) - { - if(this!=&other) { - flags_ = other.flags_; - domain_id_ = other.domain_id_; - time_zone_ = other.time_zone_; - datetime_ = other.datetime_; - } - return *this; - } - - void ios_info::display_flags(uint64_t f) - { - flags_ = (flags_ & ~uint64_t(flags::display_flags_mask)) | f; - } - void ios_info::currency_flags(uint64_t f) - { - flags_ = (flags_ & ~uint64_t(flags::currency_flags_mask)) | f; - } - void ios_info::date_flags(uint64_t f) - { - flags_ = (flags_ & ~uint64_t(flags::date_flags_mask)) | f; - } - void ios_info::time_flags(uint64_t f) - { - flags_ = (flags_ & ~uint64_t(flags::time_flags_mask)) | f; - } - - void ios_info::domain_id(int id) - { - domain_id_ = id; - } - - void ios_info::time_zone(std::string const &tz) - { - time_zone_ = tz; - } - - uint64_t ios_info::display_flags() const - { - return flags_ & flags::display_flags_mask; - } - - uint64_t ios_info::currency_flags() const - { - return flags_ & flags::currency_flags_mask; - } - - uint64_t ios_info::date_flags() const - { - return flags_ & flags::date_flags_mask; - } - - uint64_t ios_info::time_flags() const - { - return flags_ & flags::time_flags_mask; - } - - int ios_info::domain_id() const - { - return domain_id_; - } - - std::string ios_info::time_zone() const - { - return time_zone_; - } - - ios_info::string_set const &ios_info::date_time_pattern_set() const - { - return datetime_; - } - - - ios_info::string_set &ios_info::date_time_pattern_set() - { - return datetime_; - } - - ios_info &ios_info::get(std::ios_base &ios) - { - return impl::ios_prop<ios_info>::get(ios); - } - - void ios_info::on_imbue() - { - } - - namespace { - struct initializer { - initializer() { - impl::ios_prop<ios_info>::global_init(); - } - } initializer_instance; - } // namespace - - } // locale -} // boost - +namespace boost { namespace locale { + + ios_info::string_set::string_set() : type(0), size(0), ptr(0) {} + ios_info::string_set::~string_set() + { + delete[] ptr; + } + ios_info::string_set::string_set(const string_set& other) + { + if(other.ptr != 0) { + ptr = new char[other.size]; + size = other.size; + type = other.type; + memcpy(ptr, other.ptr, size); + } else { + ptr = 0; + size = 0; + type = 0; + } + } + + void ios_info::string_set::swap(string_set& other) + { + std::swap(type, other.type); + std::swap(size, other.size); + std::swap(ptr, other.ptr); + } + + ios_info::string_set& ios_info::string_set::operator=(string_set other) + { + swap(other); + return *this; + } + + ios_info::ios_info() : flags_(0), domain_id_(0), time_zone_(time_zone::global()) {} + + ios_info::~ios_info() = default; + + ios_info::ios_info(const ios_info& other) = default; + ios_info& ios_info::operator=(const ios_info& other) = default; + + void ios_info::display_flags(uint64_t f) + { + flags_ = (flags_ & ~uint64_t(flags::display_flags_mask)) | f; + } + uint64_t ios_info::display_flags() const + { + return flags_ & flags::display_flags_mask; + } + + void ios_info::currency_flags(uint64_t f) + { + flags_ = (flags_ & ~uint64_t(flags::currency_flags_mask)) | f; + } + uint64_t ios_info::currency_flags() const + { + return flags_ & flags::currency_flags_mask; + } + + void ios_info::date_flags(uint64_t f) + { + flags_ = (flags_ & ~uint64_t(flags::date_flags_mask)) | f; + } + uint64_t ios_info::date_flags() const + { + return flags_ & flags::date_flags_mask; + } + + void ios_info::time_flags(uint64_t f) + { + flags_ = (flags_ & ~uint64_t(flags::time_flags_mask)) | f; + } + uint64_t ios_info::time_flags() const + { + return flags_ & flags::time_flags_mask; + } + + void ios_info::domain_id(int id) + { + domain_id_ = id; + } + int ios_info::domain_id() const + { + return domain_id_; + } + + void ios_info::time_zone(const std::string& tz) + { + time_zone_ = tz; + } + std::string ios_info::time_zone() const + { + return time_zone_; + } + + const ios_info::string_set& ios_info::date_time_pattern_set() const + { + return datetime_; + } + + ios_info::string_set& ios_info::date_time_pattern_set() + { + return datetime_; + } + + ios_info& ios_info::get(std::ios_base& ios) + { + return impl::ios_prop<ios_info>::get(ios); + } + + void ios_info::on_imbue() {} + + namespace { + struct initializer { + initializer() { impl::ios_prop<ios_info>::global_init(); } + } initializer_instance; + } // namespace + +}} // namespace boost::locale 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 00951cf70d..047ddb407c 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/shared/generator.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/shared/generator.cpp @@ -5,186 +5,189 @@ // https://www.boost.org/LICENSE_1_0.txt #define BOOST_LOCALE_SOURCE -#include <boost/locale/generator.hpp> #include <boost/locale/encoding.hpp> +#include <boost/locale/generator.hpp> #include <boost/locale/localization_backend.hpp> -#include <boost/shared_ptr.hpp> #include <boost/thread/locks.hpp> #include <boost/thread/mutex.hpp> #include <algorithm> #include <map> #include <vector> -namespace boost { - namespace locale { - struct generator::data { - data(localization_backend_manager const &mgr) : - cats(all_categories), - chars(all_characters), - caching_enabled(false), - use_ansi_encoding(false), - backend_manager(mgr) - { +namespace boost { namespace locale { + struct generator::data { + data(const localization_backend_manager& mgr) : + cats(all_categories), chars(all_characters), caching_enabled(false), use_ansi_encoding(false), + backend_manager(mgr) + {} + + typedef std::map<std::string, std::locale> cached_type; + mutable cached_type cached; + mutable boost::mutex cached_lock; + + category_t cats; + char_facet_t chars; + + bool caching_enabled; + bool use_ansi_encoding; + + std::vector<std::string> paths; + std::vector<std::string> domains; + + std::map<std::string, std::vector<std::string>> options; + + localization_backend_manager backend_manager; + }; + + generator::generator(const localization_backend_manager& mgr) : d(new generator::data(mgr)) {} + generator::generator() : d(new generator::data(localization_backend_manager::global())) {} + generator::~generator() = default; + + category_t generator::categories() const + { + return d->cats; + } + void generator::categories(category_t t) + { + d->cats = t; + } + + void generator::characters(char_facet_t t) + { + d->chars = t; + } + + char_facet_t generator::characters() const + { + return d->chars; + } + + void generator::add_messages_domain(const std::string& domain) + { + if(std::find(d->domains.begin(), d->domains.end(), domain) == d->domains.end()) + d->domains.push_back(domain); + } + + 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()) { + d->domains.erase(p); + } + d->domains.insert(d->domains.begin(), domain); + } + + void generator::clear_domains() + { + d->domains.clear(); + } + void generator::add_messages_path(const std::string& path) + { + d->paths.push_back(path); + } + void generator::clear_paths() + { + d->paths.clear(); + } + void generator::clear_cache() + { + d->cached.clear(); + } + + std::locale generator::generate(const std::string& id) const + { + std::locale base = std::locale::classic(); + + return generate(base, id); + } + + std::locale generator::generate(const std::locale& base, const std::string& id) const + { + 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()) { + return p->second; } - - typedef std::map<std::string,std::locale> cached_type; - mutable cached_type cached; - mutable boost::mutex cached_lock; - - locale_category_type cats; - character_facet_type chars; - - bool caching_enabled; - bool use_ansi_encoding; - - std::vector<std::string> paths; - std::vector<std::string> domains; - - std::map<std::string,std::vector<std::string> > options; - - localization_backend_manager backend_manager; - - }; - - generator::generator(localization_backend_manager const &mgr) : - d(new generator::data(mgr)) - { - } - generator::generator() : - d(new generator::data(localization_backend_manager::global())) - { - } - generator::~generator() - { - } - - locale_category_type generator::categories() const - { - return d->cats; - } - void generator::categories(locale_category_type t) - { - d->cats=t; - } - - void generator::characters(character_facet_type t) - { - d->chars=t; } + hold_ptr<localization_backend> backend(d->backend_manager.create()); + set_all_options(*backend, id); - character_facet_type generator::characters() const - { - return d->chars; - } + std::locale result = base; + category_t facets = d->cats; + char_facet_t chars = d->chars; - void generator::add_messages_domain(std::string const &domain) - { - if(std::find(d->domains.begin(),d->domains.end(),domain) == d->domains.end()) - d->domains.push_back(domain); - } - - void generator::set_default_messages_domain(std::string const &domain) - { - std::vector<std::string>::iterator p; - if((p=std::find(d->domains.begin(),d->domains.end(),domain)) != d->domains.end()) { - d->domains.erase(p); + for(category_t facet = per_character_facet_first; facet <= per_character_facet_last; ++facet) { + if(!(facets & facet)) + continue; + for(char_facet_t ch = character_facet_first; ch <= character_facet_last; ++ch) { + if(ch & chars) + result = backend->install(result, facet, ch); } - d->domains.insert(d->domains.begin(),domain); } - - void generator::clear_domains() - { - d->domains.clear(); + for(category_t facet = non_character_facet_first; facet <= non_character_facet_last; ++facet) { + if(facets & facet) + result = backend->install(result, facet, char_facet_t::nochar); } - void generator::add_messages_path(std::string const &path) - { - d->paths.push_back(path); - } - void generator::clear_paths() - { - d->paths.clear(); - } - void generator::clear_cache() - { - d->cached.clear(); - } - - std::locale generator::generate(std::string const &id) const - { - std::locale base=std::locale::classic(); - - return generate(base,id); - } - - std::locale generator::generate(std::locale const &base,std::string const &id) const - { - 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()) { - return p->second; - } - } - hold_ptr<localization_backend> backend(d->backend_manager.create()); - set_all_options(*backend,id); - - std::locale result = base; - locale_category_type facets = d->cats; - character_facet_type chars = d->chars; - - for(locale_category_type facet = per_character_facet_first; facet <= per_character_facet_last && facet!=0; facet <<=1) { - if(!(facets & facet)) - continue; - for(character_facet_type ch = character_first_facet ; ch<=character_last_facet;ch <<=1) { - if(!(ch & chars)) - continue; - result = backend->install(result,facet,ch); - } - } - for(locale_category_type facet = non_character_facet_first; facet <= non_character_facet_last && facet!=0; facet <<=1) { - if(!(facets & facet)) - continue; - result = backend->install(result,facet); - } - 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()) { - d->cached[id] = result; - } + 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()) { + d->cached[id] = result; } - return result; } - - bool generator::use_ansi_encoding() const - { - return d->use_ansi_encoding; - } - - void generator::use_ansi_encoding(bool v) - { - d->use_ansi_encoding = v; - } - - bool generator::locale_cache_enabled() const - { - return d->caching_enabled; - } - void generator::locale_cache_enabled(bool enabled) - { - d->caching_enabled = enabled; - } - - void generator::set_all_options(localization_backend& backend,std::string const &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]); - } - - } // locale -} // boost + return result; + } + + bool generator::use_ansi_encoding() const + { + return d->use_ansi_encoding; + } + + void generator::use_ansi_encoding(bool v) + { + d->use_ansi_encoding = v; + } + + bool generator::locale_cache_enabled() const + { + return d->caching_enabled; + } + void generator::locale_cache_enabled(bool enabled) + { + d->caching_enabled = enabled; + } + + 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]); + } + + // Sanity check + + static_assert((char_facet_t::char_f | char_facet_t::wchar_f) & char_facet_t::char_f, "!"); + static_assert((char_facet_t::char_f | char_facet_t::wchar_f) & char_facet_t::wchar_f, "!"); + static_assert(!((all_characters ^ char_facet_t::wchar_f) & char_facet_t::wchar_f), "!"); + + static_assert((category_t::calendar | category_t::convert) & category_t::calendar, "!"); + static_assert((category_t::calendar | category_t::convert) & category_t::convert, "!"); + static_assert(!((all_categories ^ category_t::calendar) & category_t::calendar), "!"); + +#ifndef BOOST_NO_CXX14_CONSTEXPR + template<typename T> + constexpr T inc_enum(T v) + { + return ++v; + } + static_assert(inc_enum(char_facet_t::nochar) == char_facet_t::char_f, "!"); + static_assert(inc_enum(char_facet_t::char_f) == char_facet_t::wchar_f, "!"); + static_assert(inc_enum(category_t::convert) == category_t::collation, "!"); +#endif + +}} // namespace boost::locale 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 b41d041c7c..312b9474a9 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/shared/ids.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/shared/ids.cpp @@ -11,95 +11,99 @@ #include <boost/locale/date_time_facet.hpp> #include <boost/locale/info.hpp> #include <boost/locale/message.hpp> - #include <boost/core/ignore_unused.hpp> -namespace boost { - namespace locale { - - std::locale::id info::id; - // Make sure we have the VTable here (Export/Import issues) - info::~info() {} - std::locale::id calendar_facet::id; - - std::locale::id converter<char>::id; - converter<char>::~converter() {} - std::locale::id base_message_format<char>::id; - - std::locale::id converter<wchar_t>::id; - converter<wchar_t>::~converter() {} - std::locale::id base_message_format<wchar_t>::id; - - #ifdef BOOST_LOCALE_ENABLE_CHAR16_T - - std::locale::id converter<char16_t>::id; - converter<char16_t>::~converter() {} - std::locale::id base_message_format<char16_t>::id; - - #endif - - #ifdef BOOST_LOCALE_ENABLE_CHAR32_T - - std::locale::id converter<char32_t>::id; - converter<char32_t>::~converter() {} - std::locale::id base_message_format<char32_t>::id; - - #endif - - namespace boundary { - - std::locale::id boundary_indexing<char>::id; - boundary_indexing<char>::~boundary_indexing() {} - - std::locale::id boundary_indexing<wchar_t>::id; - boundary_indexing<wchar_t>::~boundary_indexing() {} - - #ifdef BOOST_LOCALE_ENABLE_CHAR16_T - std::locale::id boundary_indexing<char16_t>::id; - boundary_indexing<char16_t>::~boundary_indexing() {} - #endif - - #ifdef BOOST_LOCALE_ENABLE_CHAR32_T - std::locale::id boundary_indexing<char32_t>::id; - boundary_indexing<char32_t>::~boundary_indexing() {} - #endif - } - - namespace { - // Initialize each facet once to avoid issues where doing so - // in a multithreaded 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 - - init_facet<info>(l); - init_facet<calendar_facet>(l); - } - template<typename Char> - void init_by(const std::locale& l) - { - init_facet<boundary::boundary_indexing<Char> >(l); - init_facet<converter<Char> >(l); - init_facet<message_format<Char> >(l); - } - template<typename Facet> - void init_facet(const std::locale& l) - { - // Use the facet to initialize e.g. their std::locale::id - ignore_unused(std::has_facet<Facet>(l)); - } - } facet_initializer; - } - - } -} - +namespace boost { namespace locale { + + std::locale::id info::id; + // Make sure we have the VTable here (Export/Import issues) + info::~info() = default; + + std::locale::id calendar_facet::id; + calendar_facet::~calendar_facet() = default; + + 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 + + namespace { + // Initialize each facet once to avoid issues where doing so + // in a multithreaded 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 + + init_facet<info>(l); + init_facet<calendar_facet>(l); + } + template<typename Char> + void init_by(const std::locale& l) + { + init_facet<boundary::boundary_indexing<Char>>(l); + init_facet<converter<Char>>(l); + init_facet<message_format<Char>>(l); + } + template<typename Facet> + void init_facet(const std::locale& l) + { + // Use the facet to initialize e.g. their std::locale::id + ignore_unused(std::has_facet<Facet>(l)); + } + } facet_initializer; + } // namespace + +}} // namespace boost::locale diff --git a/contrib/restricted/boost/locale/src/boost/locale/shared/ios_prop.hpp b/contrib/restricted/boost/locale/src/boost/locale/shared/ios_prop.hpp index efb61904be..d8256592f7 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/shared/ios_prop.hpp +++ b/contrib/restricted/boost/locale/src/boost/locale/shared/ios_prop.hpp @@ -1,104 +1,65 @@ // // Copyright (c) 2009-2011 Artyom Beilis (Tonkikh) +// Copyright (c) 2022 Alexander Grund // // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt #ifndef BOOST_SRC_LOCALE_IOS_PROP_HPP #define BOOST_SRC_LOCALE_IOS_PROP_HPP -#include <ios> - -namespace boost { - namespace locale { - namespace impl { - - template<typename Property> - class ios_prop { - public: - static void set(Property const &prop,std::ios_base &ios) - { - int id=get_id(); - if(ios.pword(id)==0) { - ios.pword(id) = new Property(prop); - ios.register_callback(callback,id); - } - else if(ios.pword(id)==invalid) { - ios.pword(id) = new Property(prop); - } - else { - *static_cast<Property *>(ios.pword(id))=prop; - } - } - static Property &get(std::ios_base &ios) - { - int id=get_id(); - if(!has(ios)) - set(Property(),ios); - return *static_cast<Property *>(ios.pword(id)); - } +#include <boost/locale/config.hpp> +#include <boost/assert.hpp> +#include <ios> - static bool has(std::ios_base &ios) - { - int id=get_id(); - if(ios.pword(id)==0 || ios.pword(id)==invalid) - return false; - return true; - } +namespace boost { namespace locale { namespace impl { - static void unset(std::ios_base &ios) - { - if(has(ios)) { - int id=get_id(); - Property *p=static_cast<Property *>(ios.pword(id)); - delete p; - ios.pword(id)=invalid; - } - } - static void global_init() - { - get_id(); - } - private: - static void * const invalid; + template<typename Property> + class BOOST_SYMBOL_VISIBLE ios_prop { + public: + static Property& get(std::ios_base& ios) + { + Property* result = get_impl(ios); + return result ? *result : create(ios); + } - static void callback(std::ios_base::event ev,std::ios_base &ios,int id) - { - switch(ev) { - case std::ios_base::erase_event: - if(!has(ios)) - break; - delete reinterpret_cast<Property *>(ios.pword(id)); - break; - case std::ios_base::copyfmt_event: - if(ios.pword(id)==invalid || ios.pword(id)==0) - break; - ios.pword(id)=new Property(*reinterpret_cast<Property *>(ios.pword(id))); - break; - case std::ios_base::imbue_event: - if(ios.pword(id)==invalid || ios.pword(id)==0) - break; - reinterpret_cast<Property *>(ios.pword(id))->on_imbue(); - break; + static void global_init() { get_id(); } - default: ; - } - } - static int get_id() - { - static int id = std::ios_base::xalloc(); - return id; - } - }; + private: + static Property* get_impl(std::ios_base& ios) { return static_cast<Property*>(ios.pword(get_id())); } - template<typename Property> - void * const ios_prop<Property>::invalid = (void *)(-1); + static Property& create(std::ios_base& ios) + { + BOOST_ASSERT_MSG(!get_impl(ios), "Called create while the property already exists"); + const int id = get_id(); + ios.register_callback(callback, id); + Property* value = new Property(); + ios.pword(id) = value; + return *value; } - } -} + static void callback(std::ios_base::event ev, std::ios_base& ios, int id) + { + Property* prop = get_impl(ios); + if(!prop) + return; + switch(ev) { + case std::ios_base::erase_event: + delete prop; + ios.pword(id) = nullptr; + break; + case std::ios_base::copyfmt_event: ios.pword(id) = new Property(*prop); break; + case std::ios_base::imbue_event: prop->on_imbue(); break; + default: break; + } + } + static int get_id() + { + static int id = std::ios_base::xalloc(); + return id; + } + }; +}}} // namespace boost::locale::impl #endif - - 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 f2a80d248b..c697175acb 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 @@ -5,279 +5,246 @@ // https://www.boost.org/LICENSE_1_0.txt #define BOOST_LOCALE_SOURCE -#include <boost/locale/localization_backend.hpp> #include <boost/locale/hold_ptr.hpp> -#include <boost/shared_ptr.hpp> +#include <boost/locale/localization_backend.hpp> #include <boost/thread/locks.hpp> #include <boost/thread/mutex.hpp> +#include <memory> #include <vector> #ifdef BOOST_LOCALE_WITH_ICU -#include "boost/locale/icu/icu_backend.hpp" +# include "boost/locale/icu/icu_backend.hpp" #endif #ifndef BOOST_LOCALE_NO_POSIX_BACKEND -#include "boost/locale/posix/posix_backend.hpp" +# include "boost/locale/posix/posix_backend.hpp" #endif #ifndef BOOST_LOCALE_NO_STD_BACKEND -#include "boost/locale/std/std_backend.hpp" +# include "boost/locale/std/std_backend.hpp" #endif #ifndef BOOST_LOCALE_NO_WINAPI_BACKEND -#include "boost/locale/win32/win_backend.hpp" +# include "boost/locale/win32/win_backend.hpp" #endif -namespace boost { - namespace locale { - class localization_backend_manager::impl { - void operator = (impl const &); - public: - impl(impl const &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); - } - } - impl() : - default_backends_(32,-1) - { - } +namespace boost { namespace locale { + localization_backend::~localization_backend() = default; - localization_backend *create() const - { - std::vector<boost::shared_ptr<localization_backend> > backends; - for(unsigned i=0;i<all_backends_.size();i++) - backends.push_back(all_backends_[i].second); - return new actual_backend(backends,default_backends_); - } - void adopt_backend(std::string const &name,localization_backend *backend_ptr) - { - boost::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)); - } - } - - void select(std::string const &backend_name,locale_category_type 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; - for(unsigned flag = 1,i=0;i<default_backends_.size();flag <<=1,i++) { - if(category & flag) { - default_backends_[i]=id; - } - } - } - - void remove_all_backends() - { - all_backends_.clear(); - for(unsigned i=0;i<default_backends_.size();i++) { - default_backends_[i]=-1; - } - } - std::vector<std::string> get_all_backends() const + 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) { - 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); - } - return res; + all_backends_type::value_type v; + v.first = p->first; + v.second.reset(p->second->clone()); + all_backends_.push_back(v); } - - private: - class actual_backend : public localization_backend { - public: - actual_backend(std::vector<boost::shared_ptr<localization_backend> > const &backends,std::vector<int> const &index): - index_(index) - { - backends_.resize(backends.size()); - for(unsigned i=0;i<backends.size();i++) { - backends_[i].reset(backends[i]->clone()); - } - } - actual_backend *clone() const BOOST_OVERRIDE - { - return new actual_backend(backends_,index_); - } - void set_option(std::string const &name,std::string const &value) BOOST_OVERRIDE - { - for(unsigned i=0;i<backends_.size();i++) - backends_[i]->set_option(name,value); - } - void clear_options() BOOST_OVERRIDE - { - for(unsigned i=0;i<backends_.size();i++) - backends_[i]->clear_options(); - } - std::locale install(std::locale const &l,locale_category_type category,character_facet_type type = nochar_facet) BOOST_OVERRIDE - { - int id; - unsigned v; - for(v=1,id=0;v!=0;v <<= 1,id++) { - if(category == v) - break; - } - if(v==0) - return l; - if(unsigned(id) >= index_.size()) - return l; - if(index_[id]==-1) - return l; - return backends_[index_[id]]->install(l,category,type); - } - private: - std::vector<boost::shared_ptr<localization_backend> > backends_; - std::vector<int> index_; - }; - - typedef std::vector<std::pair<std::string,boost::shared_ptr<localization_backend> > > all_backends_type; - all_backends_type all_backends_; - std::vector<int> default_backends_; - }; - - - - localization_backend_manager::localization_backend_manager() : - pimpl_(new impl()) - { } + impl() : default_backends_(32, -1) {} - localization_backend_manager::~localization_backend_manager() - { - } + impl& operator=(const impl&) = delete; - localization_backend_manager::localization_backend_manager(localization_backend_manager const &other) : - pimpl_(new impl(*other.pimpl_)) + 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); + return new actual_backend(backends, default_backends_); } - - localization_backend_manager const &localization_backend_manager::operator = (localization_backend_manager const &other) + void adopt_backend(const std::string& name, localization_backend* backend_ptr) { - if(this!=&other) { - pimpl_.reset(new impl(*other.pimpl_)); + 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)); } - return *this; } - - #if BOOST_LOCALE_USE_AUTO_PTR - std::auto_ptr<localization_backend> localization_backend_manager::get() const + void select(const std::string& backend_name, category_t category = all_categories) { - std::auto_ptr<localization_backend> r(pimpl_->create()); - return r; - } - void localization_backend_manager::add_backend(std::string const &name,std::auto_ptr<localization_backend> backend) - { - pimpl_->adopt_backend(name,backend.release()); - } - #endif - #ifndef BOOST_NO_CXX11_SMART_PTR - std::unique_ptr<localization_backend> localization_backend_manager::get_unique_ptr() const - { - std::unique_ptr<localization_backend> r(pimpl_->create()); - return r; - } - void localization_backend_manager::add_backend(std::string const &name,std::unique_ptr<localization_backend> backend) - { - pimpl_->adopt_backend(name,backend.release()); - } - #endif - localization_backend *localization_backend_manager::create() const - { - return pimpl_->create(); - } - void localization_backend_manager::adopt_backend(std::string const &name,localization_backend *backend) - { - pimpl_->adopt_backend(name,backend); + 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; + } + } } - - void localization_backend_manager::remove_all_backends() - { - pimpl_->remove_all_backends(); - } - std::vector<std::string> localization_backend_manager::get_all_backends() const + void remove_all_backends() { - return pimpl_->get_all_backends(); + all_backends_.clear(); + for(unsigned i = 0; i < default_backends_.size(); i++) { + default_backends_[i] = -1; + } } - void localization_backend_manager::select(std::string const &backend_name,locale_category_type category) + std::vector<std::string> get_all_backends() const { - pimpl_->select(backend_name,category); + 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); + } + return res; } - namespace { - // prevent initialization order fiasco - boost::mutex &localization_backend_manager_mutex() + private: + class actual_backend : public localization_backend { + public: + actual_backend(const std::vector<std::shared_ptr<localization_backend>>& backends, + const std::vector<int>& index) : + index_(index) { - static boost::mutex the_mutex; - return the_mutex; + backends_.resize(backends.size()); + for(unsigned i = 0; i < backends.size(); i++) { + backends_[i].reset(backends[i]->clone()); + } } - // prevent initialization order fiasco - localization_backend_manager &localization_backend_manager_global() + actual_backend* clone() const override { return new actual_backend(backends_, index_); } + void set_option(const std::string& name, const std::string& value) override { - static localization_backend_manager the_manager; - return the_manager; + for(unsigned i = 0; i < backends_.size(); i++) + backends_[i]->set_option(name, value); } - - struct init { - init() { - localization_backend_manager mgr; - #ifdef BOOST_LOCALE_WITH_ICU - mgr.adopt_backend("icu",impl_icu::create_localization_backend()); - #endif - - #ifndef BOOST_LOCALE_NO_POSIX_BACKEND - mgr.adopt_backend("posix",impl_posix::create_localization_backend()); - #endif - - #ifndef BOOST_LOCALE_NO_WINAPI_BACKEND - mgr.adopt_backend("winapi",impl_win::create_localization_backend()); - #endif - - #ifndef BOOST_LOCALE_NO_STD_BACKEND - mgr.adopt_backend("std",impl_std::create_localization_backend()); - #endif - - localization_backend_manager::global(mgr); + void clear_options() override + { + for(unsigned i = 0; i < backends_.size(); i++) + backends_[i]->clear_options(); + } + std::locale install(const std::locale& l, category_t category, char_facet_t type) override + { + unsigned id = 0; + for(category_t v = category_first; v != category; ++v, ++id) { + if(v == category_last) + return l; } - } do_init; - } + if(id >= index_.size() || index_[id] == -1) + return l; + return backends_[index_[id]]->install(l, category, type); + } - localization_backend_manager localization_backend_manager::global() + private: + std::vector<std::shared_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<int> default_backends_; + }; + + localization_backend_manager::localization_backend_manager() : pimpl_(new impl()) {} + + localization_backend_manager::~localization_backend_manager() = default; + + localization_backend_manager::localization_backend_manager(const localization_backend_manager& other) : + pimpl_(new impl(*other.pimpl_)) + {} + + localization_backend_manager& localization_backend_manager::operator=(const localization_backend_manager& other) + { + pimpl_.reset(new impl(*other.pimpl_)); + return *this; + } + + std::unique_ptr<localization_backend> localization_backend_manager::get() 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); + } + + void localization_backend_manager::remove_all_backends() + { + pimpl_->remove_all_backends(); + } + std::vector<std::string> localization_backend_manager::get_all_backends() const + { + return pimpl_->get_all_backends(); + } + void localization_backend_manager::select(const std::string& backend_name, category_t category) + { + pimpl_->select(backend_name, category); + } + + namespace { + // prevent initialization order fiasco + boost::mutex& localization_backend_manager_mutex() { - boost::unique_lock<boost::mutex> lock(localization_backend_manager_mutex()); - localization_backend_manager mgr = localization_backend_manager_global(); - return mgr; + static boost::mutex the_mutex; + return the_mutex; } - localization_backend_manager localization_backend_manager::global(localization_backend_manager const &in) + // prevent initialization order fiasco + 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(); - localization_backend_manager_global() = in; - return mgr; + static localization_backend_manager the_manager; + return the_manager; } + struct init { + init() + { + localization_backend_manager mgr; +#ifdef BOOST_LOCALE_WITH_ICU + mgr.adopt_backend("icu", impl_icu::create_localization_backend()); +#endif + +#ifndef BOOST_LOCALE_NO_POSIX_BACKEND + mgr.adopt_backend("posix", impl_posix::create_localization_backend()); +#endif +#ifndef BOOST_LOCALE_NO_WINAPI_BACKEND + mgr.adopt_backend("winapi", impl_win::create_localization_backend()); +#endif - } // locale -} // boost +#ifndef BOOST_LOCALE_NO_STD_BACKEND + mgr.adopt_backend("std", impl_std::create_localization_backend()); +#endif + + localization_backend_manager::global(mgr); + } + } do_init; + } // 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; + } + 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; + } + +}} // 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 51ef9188f4..1fb4c6a915 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/shared/message.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/shared/message.cpp @@ -10,769 +10,690 @@ // Need _wfopen which is an extension on MinGW but not on MinGW-w64 // So remove the strict-mode define on (only) MinGW before including anything #if defined(__MINGW32__) && defined(__STRICT_ANSI__) -#include <_mingw.h> -#ifndef __MINGW64_VERSION_MAJOR -#undef __STRICT_ANSI__ +# include <_mingw.h> +# ifndef __MINGW64_VERSION_MAJOR +# undef __STRICT_ANSI__ +# endif #endif -#endif - -#include <boost/locale/message.hpp> #include <boost/locale/encoding.hpp> #include <boost/locale/gnu_gettext.hpp> #include <boost/locale/hold_ptr.hpp> -#include <boost/shared_ptr.hpp> -#include <boost/unordered_map.hpp> +#include <boost/locale/message.hpp> +#include <boost/locale/util/string.hpp> +#include "boost/locale/shared/mo_hash.hpp" +#include "boost/locale/shared/mo_lambda.hpp" #include <boost/version.hpp> #include <algorithm> #include <cstdio> #include <cstring> #include <iostream> #include <map> +#include <memory> +#include <unordered_map> #include <vector> -#include "boost/locale/shared/mo_hash.hpp" -#include "boost/locale/shared/mo_lambda.hpp" - -#ifdef BOOST_MSVC -# pragma warning(disable : 4996) -#endif - -namespace boost { - namespace locale { - namespace gnu_gettext { - - class c_file { - c_file(c_file const &); - void operator=(c_file const &); - public: - - FILE *file; - - c_file() : - file(0) - { - } - ~c_file() - { - close(); - } - - void close() - { - if(file) { - fclose(file); - file=0; - } - } - - #if defined(BOOST_WINDOWS) +namespace boost { namespace locale { namespace gnu_gettext { - bool open(std::string const &file_name,std::string const &encoding) - { - close(); + class c_file { + c_file(const c_file&); + void operator=(const c_file&); - // - // 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 - // + public: + FILE* file; - std::wstring wfile_name = conv::to_utf<wchar_t>(file_name,encoding); - file = _wfopen(wfile_name.c_str(),L"rb"); + c_file() : file(0) {} + ~c_file() { close(); } - return file!=0; - } + void close() + { + if(file) { + fclose(file); + file = 0; + } + } - #else // POSIX systems do not have all this Wide API crap, as native codepages are UTF-8 +#if defined(BOOST_WINDOWS) - // We do not use encoding as we use native file name encoding + bool open(const std::string& file_name, const std::string& encoding) + { + close(); - bool open(std::string const &file_name,std::string const &/* encoding */) - { - close(); + // 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 - file = fopen(file_name.c_str(),"rb"); + std::wstring wfile_name = conv::to_utf<wchar_t>(file_name, encoding); + file = _wfopen(wfile_name.c_str(), L"rb"); - return file!=0; - } + return file != 0; + } - #endif +#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 - class mo_file { - public: - typedef std::pair<char const *,char const *> pair_type; + bool open(const std::string& file_name, const std::string& /* encoding */) + { + close(); - mo_file(std::vector<char> &file) : - native_byteorder_(true), - size_(0) - { - load_file(file); - init(); - } + file = fopen(file_name.c_str(), "rb"); - mo_file(FILE *file) : - native_byteorder_(true), - size_(0) - { - load_file(file); - init(); - } + return file != 0; + } - pair_type find(char const *context_in,char const *key_in) const - { - pair_type null_pair((char const *)0,(char const *)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; - 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); - hkey %= hash_size_; - uint32_t orig=hkey; - - - do { - uint32_t idx = get(hash_offset_ + 4*hkey); - /// Not found - if(idx == 0) - return null_pair; - /// If equal values return translation - if(key_equals(key(idx-1),context_in,key_in)) - return value(idx-1); - /// Rehash - hkey=(hkey + incr) % hash_size_; - } while(hkey!=orig); +#endif + }; + + class mo_file { + public: + typedef std::pair<const char*, const char*> pair_type; + + mo_file(std::vector<char>& file) : native_byteorder_(true), size_(0) + { + load_file(file); + init(); + } + + mo_file(FILE* file) : native_byteorder_(true), size_(0) + { + load_file(file); + init(); + } + + pair_type 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; + 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); + hkey %= hash_size_; + uint32_t orig = hkey; + + do { + uint32_t idx = get(hash_offset_ + 4 * hkey); + /// Not found + if(idx == 0) return null_pair; - } - - static bool key_equals(char const *real_key,char const *cntx,char const *key) - { - if(cntx == 0) - 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) - 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; - } - } - - char const *key(int id) const - { - uint32_t off = get(keys_offset_ + id*8 + 4); - return data_ + off; - } - - pair_type value(int 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_) - throw std::runtime_error("Bad mo-file format"); - return pair_type(&data_[off],&data_[off]+len); - } - - bool has_hash() const - { - return hash_size_ != 0; - } - - size_t size() const - { - return size_; - } - - 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 ingnore 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) { - throw std::runtime_error("Bad mo-file format"); - } - memcpy(&tmp,data_ + offset,4); - convert(tmp); - return tmp; - } - - void convert(uint32_t &v) const - { - if(native_byteorder_) - return; - v = ((v & 0xFF) << 24) - | ((v & 0xFF00) << 8) - | ((v & 0xFF0000) >> 8) - | ((v & 0xFF000000) >> 24); - } - - uint32_t keys_offset_; - uint32_t translations_offset_; - uint32_t hash_size_; - uint32_t hash_offset_; - - char const *data_; - size_t file_size_; - std::vector<char> vdata_; - bool native_byteorder_; - size_t size_; - }; - - template<typename CharType> - struct mo_file_use_traits { - static const bool in_use = false; - typedef CharType char_type; - typedef std::pair<char_type const *,char_type const *> pair_type; - static pair_type use(mo_file const &/*mo*/,char_type const * /*context*/,char_type const * /*key*/) - { - return pair_type((char_type const *)(0),(char_type const *)(0)); - } - }; - - template<> - struct mo_file_use_traits<char> { - static const bool in_use = true; - typedef char char_type; - typedef std::pair<char_type const *,char_type const *> pair_type; - static pair_type use(mo_file const &mo,char const *context,char const *key) - { - return mo.find(context,key); - } - }; - - template<typename CharType> - class converter { - public: - converter(std::string /*out_enc*/,std::string in_enc) : - in_(in_enc) - { - } - - std::basic_string<CharType> operator()(char const *begin,char const *end) - { - return conv::to_utf<CharType>(begin,end,in_,conv::stop); - } - - private: - std::string in_; - }; - - template<> - class converter<char> { - public: - converter(std::string out_enc,std::string in_enc) : - out_(out_enc), - in_(in_enc) - { - } - - std::string operator()(char const *begin,char const *end) - { - return conv::between(begin,end,out_,in_,conv::stop); - } - - private: - std::string out_,in_; - }; - - template<typename CharType> - struct message_key { - typedef CharType char_type; - typedef std::basic_string<char_type> string_type; - - - message_key(string_type const &c = string_type()) : - c_context_(0), - c_key_(0) - { - size_t pos = c.find(char_type(4)); - if(pos == string_type::npos) { - key_ = c; - } - else { - context_ = c.substr(0,pos); - key_ = c.substr(pos+1); - } - } - message_key(char_type const *c,char_type const *k) : - c_key_(k) - { - static const char_type empty = 0; - if(c!=0) - c_context_ = c; - else - c_context_ = ∅ - } - bool operator < (message_key const &other) const - { - int cc = compare(context(),other.context()); - if(cc != 0) - return cc < 0; - return compare(key(),other.key()) < 0; - } - bool operator==(message_key const &other) const - { - return compare(context(),other.context()) == 0 - && compare(key(),other.key())==0; - } - bool operator!=(message_key const &other) const - { - return !(*this==other); - } - char_type const *context() const - { - if(c_context_) - return c_context_; - return context_.c_str(); - } - char_type const *key() const - { - if(c_key_) - return c_key_; - return key_.c_str(); - } - private: - static int compare(char_type const *l,char_type const *r) - { - typedef std::char_traits<char_type> traits_type; - for(;;) { - char_type cl = *l++; - char_type cr = *r++; - if(cl == 0 && cr == 0) - return 0; - if(traits_type::lt(cl,cr)) - return -1; - if(traits_type::lt(cr,cl)) - return 1; - } - } - string_type context_; - string_type key_; - char_type const *c_context_; - char_type const *c_key_; - }; - - template<typename CharType> - struct hash_function { - size_t operator()(message_key<CharType> const &msg) const - { - pj_winberger_hash::state_type state = pj_winberger_hash::initial_state; - CharType const *p = msg.context(); - if(*p != 0) { - CharType const *e = p; - while(*e) - e++; - state = pj_winberger_hash::update_state(state, - reinterpret_cast<char const *>(p), - reinterpret_cast<char const *>(e)); - state = pj_winberger_hash::update_state(state,'\4'); - } - p = msg.key(); - CharType const *e = p; - while(*e) - e++; - state = pj_winberger_hash::update_state(state, - reinterpret_cast<char const *>(p), - reinterpret_cast<char const *>(e)); - return state; - } - }; - - - // By default for wide types the conversion is not requiredyy - template<typename CharType> - CharType const *runtime_conversion(CharType const *msg, - std::basic_string<CharType> &/*buffer*/, - bool /*do_conversion*/, - std::string const &/*locale_encoding*/, - std::string const &/*key_encoding*/) - { - return msg; + /// If equal values return translation + if(key_equals(key(idx - 1), context_in, key_in)) + return value(idx - 1); + /// Rehash + hkey = (hkey + incr) % hash_size_; + } while(hkey != orig); + return null_pair; + } + + static bool key_equals(const char* real_key, const char* cntx, const char* key) + { + if(cntx == 0) + 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) + 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; } - - // But still need to specialize for char - template<> - char const *runtime_conversion( char const *msg, - std::string &buffer, - bool do_conversion, - std::string const &locale_encoding, - std::string const &key_encoding) - { - if(!do_conversion) - return msg; - if(details::is_us_ascii_string(msg)) - return msg; - std::string tmp = conv::between(msg,locale_encoding,key_encoding,conv::skip); - buffer.swap(tmp); - return buffer.c_str(); + } + + const char* key(int id) const + { + uint32_t off = get(keys_offset_ + id * 8 + 4); + return data_ + off; + } + + pair_type value(int 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_) + throw std::runtime_error("Bad mo-file format"); + return pair_type(&data_[off], &data_[off] + len); + } + + bool has_hash() const { return hash_size_ != 0; } + + size_t size() const { return size_; } + + 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 ingnore 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"); } - - 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 boost::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; - public: - - typedef std::pair<CharType const *,CharType const *> pair_type; - - char_type const *get(int domain_id,char_type const *context,char_type const *in_id) const BOOST_OVERRIDE - { - return get_string(domain_id,context,in_id).first; - } - - char_type const *get(int domain_id,char_type const *context,char_type const *single_id,int n) const BOOST_OVERRIDE - { - pair_type ptr = get_string(domain_id,context,single_id); - if(!ptr.first) - return 0; - int form=0; - if(plural_forms_.at(domain_id)) - form = (*plural_forms_[domain_id])(n); - else - form = n == 1 ? 0 : 1; // Fallback to english plural form - - CharType const *p=ptr.first; - for(int i=0;p < ptr.second && i<form;i++) { - p=std::find(p,ptr.second,0); - if(p==ptr.second) - return 0; - ++p; - } - if(p>=ptr.second) - return 0; - return p; - } - - int domain(std::string const &domain) const BOOST_OVERRIDE - { - domains_map_type::const_iterator p=domains_.find(domain); - if(p==domains_.end()) - return -1; - return p->second; - } - - mo_message(messages_info const &inf) - { - 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; - std::vector<messages_info::domain> const &domains = inf.domains; - std::vector<std::string> const &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()); - - - 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); - } - } - } - } - - char_type const *convert(char_type const *msg,string_type &buffer) const BOOST_OVERRIDE - { - return runtime_conversion<char_type>(msg,buffer,key_conversion_required_,locale_encoding_,key_encoding_); - } - - private: - int compare_encodings(std::string const &left,std::string const &right) - { - return convert_encoding_name(left).compare(convert_encoding_name(right)); - } - - std::string convert_encoding_name(std::string const &in) - { - std::string result; - for(unsigned i=0;i<in.size();i++) { - char c=in[i]; - if('A' <= c && c<='Z') - c=c-'A' + 'a'; - else if(('a' <= c && c<='z') || ('0' <= c && c<='9')) - ; - else - continue; - result+=c; - } - return result; - } - - - bool load_file( std::string const &file_name, - std::string const &locale_encoding, - std::string const &key_encoding, - int idx, - messages_info::callback_type const &callback) - { - locale_encoding_ = locale_encoding; - key_encoding_ = key_encoding; - - key_conversion_required_ = sizeof(CharType) == 1 - && compare_encodings(locale_encoding,key_encoding)!=0; - - boost::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) - return false; - mo.reset(new mo_file(the_file.file)); - } - - std::string plural = extract(mo->value(0).first,"plural=","\r\n;"); - - std::string mo_encoding = extract(mo->value(0).first,"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());; - } - - if( mo_useable_directly(mo_encoding,*mo) ) - { - mo_catalogs_[idx]=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++) { - char const *ckey = mo->key(i); - string_type skey = cvt_key(ckey,ckey+strlen(ckey)); - key_type key(skey); - - mo_file::pair_type tmp = mo->value(i); - string_type value = cvt_value(tmp.first,tmp.second); - catalogs_[idx][key].swap(value); - } - } - return true; - - } - - // Check if the mo file as-is is useful - // 1. It is char and not wide character - // 2. The locale encoding and mo encoding is same - // 3. The source strings encoding and mo encoding is same or all - // mo key strings are US-ASCII - bool mo_useable_directly( std::string const &mo_encoding, - mo_file const &mo) - { -BOOST_LOCALE_START_CONST_CONDITION - if(sizeof(CharType) != 1) - return false; -BOOST_LOCALE_END_CONST_CONDITION - if(!mo.has_hash()) - return false; - if(compare_encodings(mo_encoding,locale_encoding_)!=0) - return false; - if(compare_encodings(mo_encoding,key_encoding_)==0) { - return true; - } - for(unsigned i=0;i<mo.size();i++) { - if(!details::is_us_ascii_string(mo.key(i))) { - return false; - } + 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) { + throw std::runtime_error("Bad mo-file format"); + } + memcpy(&tmp, data_ + offset, 4); + convert(tmp); + return tmp; + } + + void convert(uint32_t& v) const + { + if(native_byteorder_) + return; + v = ((v & 0xFF) << 24) | ((v & 0xFF00) << 8) | ((v & 0xFF0000) >> 8) | ((v & 0xFF000000) >> 24); + } + + uint32_t keys_offset_; + uint32_t translations_offset_; + uint32_t hash_size_; + uint32_t hash_offset_; + + const char* data_; + size_t file_size_; + std::vector<char> vdata_; + bool native_byteorder_; + size_t size_; + }; + + 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*/) + { + return pair_type((const char_type*)(0), (const char_type*)(0)); + } + }; + + 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); } + }; + + template<typename CharType> + class converter { + public: + converter(std::string /*out_enc*/, std::string in_enc) : in_(in_enc) {} + + std::basic_string<CharType> operator()(const char* begin, const char* end) + { + return conv::to_utf<CharType>(begin, end, in_, conv::stop); + } + + private: + std::string in_; + }; + + template<> + class converter<char> { + 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); + } + + private: + std::string out_, in_; + }; + + template<typename CharType> + struct message_key { + typedef CharType char_type; + typedef std::basic_string<char_type> string_type; + + message_key(const string_type& c = string_type()) : c_context_(0), c_key_(0) + { + size_t pos = c.find(char_type(4)); + if(pos == string_type::npos) { + key_ = c; + } else { + context_ = c.substr(0, pos); + key_ = c.substr(pos + 1); + } + } + message_key(const char_type* c, const char_type* k) : c_key_(k) + { + static const char_type empty = 0; + if(c != 0) + c_context_ = c; + else + c_context_ = ∅ + } + bool operator<(const message_key& other) const + { + int cc = compare(context(), other.context()); + if(cc != 0) + return cc < 0; + return compare(key(), other.key()) < 0; + } + bool operator==(const message_key& other) const + { + 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 + { + if(c_context_) + return c_context_; + return context_.c_str(); + } + const char_type* key() const + { + if(c_key_) + return c_key_; + return key_.c_str(); + } + + private: + static int compare(const char_type* l, const char_type* r) + { + typedef std::char_traits<char_type> traits_type; + for(;;) { + char_type cl = *l++; + char_type cr = *r++; + if(cl == 0 && cr == 0) + return 0; + if(traits_type::lt(cl, cr)) + return -1; + if(traits_type::lt(cr, cl)) + return 1; + } + } + string_type context_; + string_type key_; + const char_type* c_context_; + const char_type* c_key_; + }; + + template<typename CharType> + struct hash_function { + size_t operator()(const message_key<CharType>& msg) const + { + pj_winberger_hash::state_type state = pj_winberger_hash::initial_state; + const CharType* p = msg.context(); + if(*p != 0) { + const CharType* e = util::str_end(p); + state = pj_winberger_hash::update_state(state, + reinterpret_cast<const char*>(p), + reinterpret_cast<const char*>(e)); + state = pj_winberger_hash::update_state(state, '\4'); + } + p = msg.key(); + const CharType* e = util::str_end(p); + state = pj_winberger_hash::update_state(state, + reinterpret_cast<const char*>(p), + reinterpret_cast<const char*>(e)); + return state; + } + }; + + // By default for wide types the conversion is not required + template<typename CharType> + const CharType* runtime_conversion(const CharType* msg, + std::basic_string<CharType>& /*buffer*/, + bool /*do_conversion*/, + const std::string& /*locale_encoding*/, + const std::string& /*key_encoding*/) + { + return msg; + } + + // But still need to specialize for char + template<> + const char* runtime_conversion(const char* msg, + std::string& buffer, + bool do_conversion, + const std::string& locale_encoding, + const std::string& key_encoding) + { + if(!do_conversion) + 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); + 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; + + public: + typedef std::pair<const CharType*, const CharType*> pair_type; + + const char_type* get(int domain_id, const char_type* context, const char_type* in_id) const override + { + return get_string(domain_id, context, in_id).first; + } + + const char_type* get(int domain_id, const char_type* context, const char_type* single_id, int n) const override + { + pair_type ptr = get_string(domain_id, context, single_id); + if(!ptr.first) + return nullptr; + int form = 0; + if(plural_forms_.at(domain_id)) + form = (*plural_forms_[domain_id])(n); + else + form = 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) + return nullptr; + ++p; + } + if(p >= ptr.second) + return nullptr; + return p; + } + + int domain(const std::string& domain) const override + { + domains_map_type::const_iterator p = domains_.find(domain); + if(p == domains_.end()) + return -1; + return p->second; + } + + 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()); + + 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); } - return true; } + } + } + + const char_type* convert(const char_type* msg, string_type& buffer) const override + { + return runtime_conversion<char_type>(msg, + buffer, + key_conversion_required_, + locale_encoding_, + key_encoding_); + } + + private: + int compare_encodings(const std::string& left, const std::string& right) + { + return convert_encoding_name(left).compare(convert_encoding_name(right)); + } + + std::string convert_encoding_name(const std::string& in) + { + std::string result; + for(unsigned i = 0; i < in.size(); i++) { + char c = in[i]; + if('A' <= c && c <= 'Z') + c = c - 'A' + 'a'; + else if(('a' <= c && c <= 'z') || ('0' <= c && c <= '9')) + ; + else + continue; + result += c; + } + return result; + } + + bool load_file(const std::string& file_name, + const std::string& locale_encoding, + const std::string& key_encoding, + int idx, + const messages_info::callback_type& callback) + { + locale_encoding_ = locale_encoding; + key_encoding_ = key_encoding; + + key_conversion_required_ = sizeof(CharType) == 1 && compare_encodings(locale_encoding, key_encoding) != 0; + + 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) + return false; + mo.reset(new mo_file(the_file.file)); + } + std::string plural = extract(mo->value(0).first, "plural=", "\r\n;"); + std::string mo_encoding = extract(mo->value(0).first, "charset=", " \r\n;"); - static std::string extract(std::string const &meta,std::string const &key,char const *separator) - { - size_t pos=meta.find(key); - if(pos == std::string::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); - } - + 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()); + if(mo_useable_directly(mo_encoding, *mo)) + mo_catalogs_[idx] = 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); - pair_type get_string(int domain_id,char_type const *context,char_type const *in_id) const - { - pair_type null_pair((CharType const *)0,(CharType const *)0); - if(domain_id < 0 || size_t(domain_id) >= catalogs_.size()) - return null_pair; -BOOST_LOCALE_START_CONST_CONDITION - if(mo_file_use_traits<char_type>::in_use && mo_catalogs_[domain_id]) { -BOOST_LOCALE_END_CONST_CONDITION - return mo_file_use_traits<char_type>::use(*mo_catalogs_[domain_id],context,in_id); - } - else { - key_type key(context,in_id); - catalog_type const &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()); - } + mo_file::pair_type tmp = mo->value(i); + string_type value = cvt_value(tmp.first, tmp.second); + catalogs_[idx][key].swap(value); } - - catalogs_set_type catalogs_; - std::vector<boost::shared_ptr<mo_file> > mo_catalogs_; - std::vector<boost::shared_ptr<lambda::plural> > plural_forms_; - domains_map_type domains_; - - std::string locale_encoding_; - std::string key_encoding_; - bool key_conversion_required_; - }; - - template<> - message_format<char> *create_messages_facet(messages_info const &info) - { - return new mo_message<char>(info); } - - template<> - message_format<wchar_t> *create_messages_facet(messages_info const &info) - { - return new mo_message<wchar_t>(info); + return true; + } + + // Check if the mo file as-is is useful + // 1. It is char and not wide character + // 2. The locale encoding and mo encoding is same + // 3. The source strings encoding and mo encoding is same or all + // mo key strings are US-ASCII + bool mo_useable_directly(const std::string& mo_encoding, const mo_file& mo) + { + BOOST_LOCALE_START_CONST_CONDITION + if(sizeof(CharType) != 1) + return false; + BOOST_LOCALE_END_CONST_CONDITION + if(!mo.has_hash()) + return false; + if(compare_encodings(mo_encoding, locale_encoding_) != 0) + return false; + if(compare_encodings(mo_encoding, key_encoding_) == 0) { + return true; } - - #ifdef BOOST_LOCALE_ENABLE_CHAR16_T - - template<> - message_format<char16_t> *create_messages_facet(messages_info const &info) - { - return new mo_message<char16_t>(info); + for(unsigned i = 0; i < mo.size(); i++) { + if(!detail::is_us_ascii_string(mo.key(i))) { + return false; + } } - #endif - - #ifdef BOOST_LOCALE_ENABLE_CHAR32_T - - template<> - message_format<char32_t> *create_messages_facet(messages_info const &info) - { - return new mo_message<char32_t>(info); + return true; + } + + static std::string extract(const std::string& meta, const std::string& key, const char* separator) + { + size_t pos = meta.find(key); + if(pos == std::string::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); + } + + pair_type get_string(int domain_id, const char_type* context, const char_type* 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; + BOOST_LOCALE_START_CONST_CONDITION + if(mo_file_use_traits<char_type>::in_use && mo_catalogs_[domain_id]) { + BOOST_LOCALE_END_CONST_CONDITION + return mo_file_use_traits<char_type>::use(*mo_catalogs_[domain_id], 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()); } - #endif - + } + + 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::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) + { + return new mo_message<char16_t>(info); + } +#endif - } /// gnu_gettext +#ifdef BOOST_LOCALE_ENABLE_CHAR32_T - } // locale -} // boost + template<> + message_format<char32_t>* create_messages_facet(const messages_info& info) + { + return new mo_message<char32_t>(info); + } +#endif +}}} // 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 5be7d16592..ad417641f9 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 @@ -6,53 +6,46 @@ #include <boost/cstdint.hpp> -namespace boost { - namespace locale { - namespace gnu_gettext { +namespace boost { namespace locale { namespace gnu_gettext { - struct pj_winberger_hash { + struct pj_winberger_hash { + typedef uint32_t state_type; - typedef uint32_t state_type; + static constexpr state_type initial_state = 0; - static const state_type initial_state = 0; - - static state_type update_state(state_type value,char c) - { - value = (value << 4) + static_cast<unsigned char>(c); - uint32_t high = (value & 0xF0000000U); - if(high!=0) - value = (value ^ (high >> 24)) ^ high; - return value; - } - static state_type update_state(state_type value,char const *ptr) - { - while(*ptr) - value = update_state(value,*ptr++); - return value; - } - static state_type update_state(state_type value,char const *begin,char const *end) - { - while(begin!=end) - value = update_state(value,*begin++); - return value; - } - }; - - inline pj_winberger_hash::state_type pj_winberger_hash_function(char const *ptr) - { - pj_winberger_hash::state_type state = pj_winberger_hash::initial_state; - state = pj_winberger_hash::update_state(state,ptr); - return state; - } - - inline pj_winberger_hash::state_type pj_winberger_hash_function(char const *begin,char const *end) - { - pj_winberger_hash::state_type state = pj_winberger_hash::initial_state; - state = pj_winberger_hash::update_state(state,begin,end); - return state; - } + static state_type update_state(state_type value, char c) + { + value = (value << 4) + static_cast<unsigned char>(c); + uint32_t high = (value & 0xF0000000U); + if(high != 0) + value = (value ^ (high >> 24)) ^ high; + return value; } - } -} + static state_type update_state(state_type value, const char* ptr) + { + while(*ptr) + value = update_state(value, *ptr++); + return value; + } + static state_type update_state(state_type value, const char* begin, const char* end) + { + while(begin != end) + value = update_state(value, *begin++); + return value; + } + }; + inline pj_winberger_hash::state_type pj_winberger_hash_function(const char* ptr) + { + pj_winberger_hash::state_type state = pj_winberger_hash::initial_state; + state = pj_winberger_hash::update_state(state, ptr); + return state; + } + inline pj_winberger_hash::state_type pj_winberger_hash_function(const char* begin, const char* end) + { + pj_winberger_hash::state_type state = pj_winberger_hash::initial_state; + state = pj_winberger_hash::update_state(state, begin, end); + return state; + } +}}} // namespace boost::locale::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 fb3a783156..90d0c232cb 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 @@ -5,409 +5,369 @@ // https://www.boost.org/LICENSE_1_0.txt #include "boost/locale/shared/mo_lambda.hpp" -#include <cstring> #include <cstdlib> +#include <cstring> #ifdef BOOST_MSVC -#pragma warning(disable:4512) //assignment operator could not be generated +# pragma warning(disable : 4512) // assignment operator could not be generated #endif -namespace boost { -namespace locale { -namespace gnu_gettext { -namespace lambda { +namespace boost { namespace locale { namespace gnu_gettext { namespace lambda { -namespace { // anon - struct identity : public plural { - int operator()(int n) const BOOST_OVERRIDE - { - return n; + namespace { // anon + struct identity : public plural { + int operator()(int n) const override { return n; }; + identity* clone() const override { return new identity(); } }; - identity *clone() const BOOST_OVERRIDE - { - return new identity(); - } - }; - struct unary : public plural - { - unary(plural_ptr ptr) : - op1(ptr) - { - } - protected: - plural_ptr op1; - }; + struct unary : public plural { + unary(plural_ptr ptr) : op1(ptr) {} + protected: + plural_ptr op1; + }; - struct binary : public plural - { - binary(plural_ptr p1,plural_ptr p2) : - op1(p1), - op2(p2) - { - } - protected: - plural_ptr op1,op2; - }; + struct binary : public plural { + binary(plural_ptr p1, plural_ptr p2) : op1(p1), op2(p2) {} - struct number : public plural - { - number(int v) : - val(v) - { - } - int operator()(int /*n*/) const BOOST_OVERRIDE - { - return val; - } - number *clone() const BOOST_OVERRIDE - { - return new number(val); - } + protected: + plural_ptr op1, op2; + }; - private: - int val; - }; + 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); } - #define UNOP(name,oper) \ - struct name: public unary { \ - name(plural_ptr op) : unary(op) \ - { \ - }; \ - int operator()(int n) const BOOST_OVERRIDE \ - { \ - return oper (*op1)(n); \ - } \ - name *clone() const BOOST_OVERRIDE \ - { \ - plural_ptr op1_copy(op1->clone()); \ - return new name(op1_copy); \ - } \ - }; + private: + int val; + }; - #define BINOP(name,oper) \ - struct name : public binary \ - { \ - name(plural_ptr p1,plural_ptr p2) : \ - binary(p1,p2) \ - { \ - } \ - \ - int operator()(int n) const BOOST_OVERRIDE \ - { \ - return (*op1)(n) oper (*op2)(n); \ - } \ - name *clone() const BOOST_OVERRIDE \ - { \ - plural_ptr op1_copy(op1->clone()); \ - plural_ptr op2_copy(op2->clone()); \ - return new name(op1_copy,op2_copy); \ - } \ +#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 BINOPD(name,oper) \ - struct name : public binary { \ - name(plural_ptr p1,plural_ptr p2) : \ - binary(p1,p2) \ - { \ - } \ - int operator()(int n) const BOOST_OVERRIDE \ - { \ - int v1=(*op1)(n); \ - int v2=(*op2)(n); \ - return v2==0 ? 0 : v1 oper v2; \ - } \ - name *clone() const BOOST_OVERRIDE \ - { \ - plural_ptr op1_copy(op1->clone()); \ - plural_ptr op2_copy(op2->clone()); \ - return new name(op1_copy,op2_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); \ + } \ }; - enum { END = 0 , SHL = 256, SHR, GTE,LTE, EQ, NEQ, AND, OR, NUM, VARIABLE }; +#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); \ + } \ + }; - UNOP(l_not,!) - UNOP(minus,-) - UNOP(bin_not,~) + enum { END = 0, SHL = 256, SHR, GTE, LTE, EQ, NEQ, AND, OR, NUM, VARIABLE }; - BINOP(mul,*) - BINOPD(div,/) - BINOPD(mod,%) - static int level10[]={3,'*','/','%'}; + UNOP(l_not, !) + UNOP(minus, -) + UNOP(bin_not, ~) - BINOP(add,+) - BINOP(sub,-) - static int level9[]={2,'+','-'}; + BINOP(mul, *) + BINOPD(div, /) + BINOPD(mod, %) + static int level10[] = {3, '*', '/', '%'}; - BINOP(shl,<<) - BINOP(shr,>>) - static int level8[]={2,SHL,SHR}; + BINOP(add, +) + BINOP(sub, -) + static int level9[] = {2, '+', '-'}; - BINOP(gt,>) - BINOP(lt,<) - BINOP(gte,>=) - BINOP(lte,<=) - static int level7[]={4,'<','>',GTE,LTE}; + BINOP(shl, <<) + BINOP(shr, >>) + static int level8[] = {2, SHL, SHR}; - BINOP(eq,==) - BINOP(neq,!=) - static int level6[]={2,EQ,NEQ}; + BINOP(gt, >) + BINOP(lt, <) + BINOP(gte, >=) + BINOP(lte, <=) + static int level7[] = {4, '<', '>', GTE, LTE}; - BINOP(bin_and,&) - static int level5[]={1,'&'}; + BINOP(eq, ==) + BINOP(neq, !=) + static int level6[] = {2, EQ, NEQ}; - BINOP(bin_xor,^) - static int level4[]={1,'^'}; + BINOP(bin_and, &) + static int level5[] = {1, '&'}; - BINOP(bin_or,|) - static int level3[]={1,'|'}; + BINOP(bin_xor, ^) + static int level4[] = {1, '^'}; - BINOP(l_and,&&) - static int level2[]={1,AND}; + BINOP(bin_or, |) + static int level3[] = {1, '|'}; - 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 BOOST_OVERRIDE - { - return (*op1)(n) ? (*op2)(n) : (*op3)(n); - } - conditional *clone() const BOOST_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); - } - private: - plural_ptr op1,op2,op3; - }; + BINOP(l_and, &&) + static int level2[] = {1, AND}; + BINOP(l_or, ||) + static int level1[] = {1, OR}; - plural_ptr bin_factory(int value,plural_ptr left,plural_ptr right) - { - - 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(); - } - } - - static inline bool is_in(int v,int *p) - { - int len=*p; - p++; - while(len && *p!=v) { p++;len--; } - return len!=0; - } - - - class tokenizer { - public: - tokenizer(char const *s) { text=s; pos=0; step(); }; - int get(int *val=NULL){ - int iv=int_value; - int res=next_tocken; - step(); - if(val && res==NUM){ - *val=iv; + 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); } - return res; - }; - int next(int *val=NULL) { - if(val && next_tocken==NUM) { - *val=int_value; - return NUM; - } - return next_tocken; - } - private: - char const *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'; - } - void step() - { - while(text[pos] && is_blank(text[pos])) pos++; - char const *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++; } - } - }; - - - #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; \ - } - class parser { - public: - - parser(tokenizer &tin) : t(tin) {}; + private: + plural_ptr op1, op2, op3; + }; - plural_ptr compile() + plural_ptr bin_factory(int value, plural_ptr left, plural_ptr right) { - plural_ptr res=cond_expr(); - if(res.get() && t.next()!=END) { - return plural_ptr(); - }; - return res; + 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(); + } } - private: - - plural_ptr value_expr() + static inline bool is_in(int v, int* p) { - plural_ptr op; - if(t.next()=='(') { - t.get(); - if((op=cond_expr()).get()==0) - return plural_ptr(); - if(t.get()!=')') - return plural_ptr(); - return op; - } - else if(t.next()==NUM) { - int value; - t.get(&value); - return plural_ptr(new number(value)); + int len = *p; + p++; + while(len && *p != v) { + p++; + len--; } - else if(t.next()==VARIABLE) { - t.get(); - return plural_ptr(new identity()); - } - return plural_ptr(); - }; + return len != 0; + } - plural_ptr un_expr() - { - plural_ptr op1; - static int level_unary[]={3,'-','!','~'}; - 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(); + class tokenizer { + public: + tokenizer(const char* s) + { + text = s; + pos = 0; + 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) + { + if(val && next_tocken == NUM) { + *val = int_value; + return NUM; } + return next_tocken; } - else { - return value_expr(); + + 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'; } + 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++; + } } }; - 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(l5,l6,level5); - BINARY_EXPR(l4,l5,level4); - BINARY_EXPR(l3,l4,level3); - BINARY_EXPR(l2,l3,level2); - BINARY_EXPR(l1,l2,level1); - - plural_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) +#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; \ + } + + class parser { + public: + parser(tokenizer& tin) : t(tin){}; + + plural_ptr compile() + { + plural_ptr res = cond_expr(); + if(res.get() && t.next() != END) { return plural_ptr(); + }; + return res; } - else { - return cond; - } - return plural_ptr(new conditional(cond,case1,case2)); - } - - tokenizer &t; - }; + private: + plural_ptr value_expr() + { + plural_ptr op; + if(t.next() == '(') { + t.get(); + if((op = cond_expr()).get() == 0) + return plural_ptr(); + if(t.get() != ')') + return plural_ptr(); + return op; + } else if(t.next() == NUM) { + int value; + t.get(&value); + return plural_ptr(new number(value)); + } else if(t.next() == VARIABLE) { + t.get(); + return plural_ptr(new identity()); + } + return plural_ptr(); + }; -} // namespace anon + plural_ptr un_expr() + { + plural_ptr op1; + static int level_unary[] = {3, '-', '!', '~'}; + 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(); + } + } else { + return value_expr(); + } + }; -plural_ptr compile(char const *str) -{ - tokenizer t(str); - parser p(t); - return p.compile(); -} + 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(l5, l6, level5); + BINARY_EXPR(l4, l5, level4); + BINARY_EXPR(l3, l4, level3); + BINARY_EXPR(l2, l3, level2); + BINARY_EXPR(l1, l2, level1); + + plural_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 { + return cond; + } + return plural_ptr(new conditional(cond, case1, case2)); + } + tokenizer& t; + }; -} // lambda -} // gnu_gettext -} // locale -} // boost + } // namespace + plural_ptr compile(const char* str) + { + tokenizer t(str); + parser p(t); + return 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 96d2caf374..71ae35a174 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 @@ -8,28 +8,20 @@ #define BOOST_SRC_LOCALE_MO_LAMBDA_HPP_INCLUDED #include <boost/locale/config.hpp> -#include <boost/shared_ptr.hpp> +#include <memory> -namespace boost { - namespace locale { - namespace gnu_gettext { - namespace lambda { +namespace boost { namespace locale { namespace gnu_gettext { namespace lambda { - struct plural { + struct plural { + virtual int operator()(int n) const = 0; + virtual plural* clone() const = 0; + virtual ~plural() = default; + }; - virtual int operator()(int n) const = 0; - virtual plural *clone() const = 0; - virtual ~plural() {} - }; + typedef std::shared_ptr<plural> plural_ptr; - typedef boost::shared_ptr<plural> plural_ptr; + plural_ptr compile(const char* c_expression); - plural_ptr compile(char const *c_expression); - - } // lambda - } // gnu_gettext - } // locale -} // boost +}}}} // namespace boost::locale::gnu_gettext::lambda #endif - 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 6dc4f7d50a..81e3102974 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 @@ -11,43 +11,34 @@ #include <locale> #include <string> -namespace boost { - namespace locale { - namespace impl_std { - typedef enum { - utf8_none, - utf8_native, - utf8_native_with_wide, - utf8_from_wide - } utf8_support; - - std::locale create_convert( std::locale const &in, - std::string const &locale_name, - character_facet_type type, - utf8_support utf = utf8_none); - - std::locale create_collate( std::locale const &in, - std::string const &locale_name, - character_facet_type type, - utf8_support utf = utf8_none); - - std::locale create_formatting( std::locale const &in, - std::string const &locale_name, - character_facet_type type, - utf8_support utf = utf8_none); - - std::locale create_parsing( std::locale const &in, - std::string const &locale_name, - character_facet_type type, - utf8_support utf = utf8_none); - - std::locale create_codecvt( std::locale const &in, - std::string const &locale_name, - character_facet_type type, - utf8_support utf = utf8_none); - - } - } -} +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); + +}}} // namespace boost::locale::impl_std #endif diff --git a/contrib/restricted/boost/locale/src/boost/locale/std/codecvt.cpp b/contrib/restricted/boost/locale/src/boost/locale/std/codecvt.cpp index c20bb4af7b..4e6f9e53b5 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/std/codecvt.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/std/codecvt.cpp @@ -5,47 +5,35 @@ // https://www.boost.org/LICENSE_1_0.txt #define BOOST_LOCALE_SOURCE -#include "boost/locale/std/all_generator.hpp" #include <boost/locale/util.hpp> +#include "boost/locale/std/all_generator.hpp" #include <locale> -namespace boost { -namespace locale { -namespace impl_std { +namespace boost { namespace locale { namespace impl_std { template<typename CharType> - std::locale codecvt_bychar( std::locale const &in, - std::string const &locale_name) + 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.c_str())); } - std::locale create_codecvt( std::locale const &in, - std::string const &locale_name, - character_facet_type type, - utf8_support utf) + std::locale + create_codecvt(const std::locale& in, const std::string& locale_name, char_facet_t type, utf8_support utf) { - if(utf == utf8_from_wide) { - return util::create_utf8_codecvt(in,type); - } + if(utf == utf8_support::from_wide) + return util::create_utf8_codecvt(in, type); + switch(type) { - case char_facet: - return codecvt_bychar<char>(in,locale_name); - case wchar_t_facet: - return codecvt_bychar<wchar_t>(in,locale_name); - #if defined(BOOST_LOCALE_ENABLE_CHAR16_T) - case char16_t_facet: - return codecvt_bychar<char16_t>(in,locale_name); - #endif - #if defined(BOOST_LOCALE_ENABLE_CHAR32_T) - case char32_t_facet: - return codecvt_bychar<char32_t>(in,locale_name); - #endif - default: - return in; + case char_facet_t::nochar: break; + case char_facet_t::char_f: return codecvt_bychar<char>(in, locale_name); + case char_facet_t::wchar_f: return codecvt_bychar<wchar_t>(in, locale_name); +#if defined(BOOST_LOCALE_ENABLE_CHAR16_T) + case char_facet_t::char16_f: return codecvt_bychar<char16_t>(in, locale_name); +#endif +#if defined(BOOST_LOCALE_ENABLE_CHAR32_T) + case char_facet_t::char32_f: return codecvt_bychar<char32_t>(in, locale_name); +#endif } + return in; } -} // impl_std -} // locale -} // boost - +}}} // namespace boost::locale::impl_std 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 cf109f1731..4a41784561 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/std/collate.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/std/collate.cpp @@ -6,108 +6,88 @@ #define BOOST_LOCALE_SOURCE #include <boost/locale/encoding.hpp> +#include "boost/locale/std/all_generator.hpp" +#include <ios> #include <locale> #include <string> -#include <ios> -#include "boost/locale/std/all_generator.hpp" -namespace boost { -namespace locale { -namespace impl_std { +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(std::locale const &base,size_t refs = 0) : - std::collate<char>(refs), - base_(base) - { - } - int do_compare(char const *lb,char const *le,char const *rb,char const *re) const BOOST_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"); - return std::use_facet<wfacet>(base_).compare( l.c_str(),l.c_str()+l.size(), - r.c_str(),r.c_str()+r.size()); - } - long do_hash(char const *b,char const *e) const BOOST_OVERRIDE - { - std::wstring tmp=conv::to_utf<wchar_t>(b,e,"UTF-8"); - return std::use_facet<wfacet>(base_).hash(tmp.c_str(),tmp.c_str()+tmp.size()); - } - std::string do_transform(char const *b,char const *e) const BOOST_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()); - 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); - } + 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) {} + 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"); + return std::use_facet<wfacet>(base_).compare(l.c_str(), + l.c_str() + l.size(), + r.c_str(), + r.c_str() + r.size()); } -BOOST_LOCALE_END_CONST_CONDITION - return key; - } -private: - std::locale base_; -}; - -std::locale create_collate( std::locale const &in, - std::string const &locale_name, - character_facet_type type, - utf8_support utf) -{ - switch(type) { - case char_facet: + long do_hash(const char* b, const char* e) const override { - if(utf == utf8_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)); - } + std::wstring tmp = conv::to_utf<wchar_t>(b, e, "UTF-8"); + 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()); + std::string key; + BOOST_LOCALE_START_CONST_CONDITION + if(sizeof(wchar_t) == 2) + key.reserve(wkey.size() * 2); else - { - return std::locale(in,new std::collate_byname<char>(locale_name.c_str())); + 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); + } } + BOOST_LOCALE_END_CONST_CONDITION + return key; } - case wchar_t_facet: - return std::locale(in,new std::collate_byname<wchar_t>(locale_name.c_str())); - - #ifdef BOOST_LOCALE_ENABLE_CHAR16_T - case char16_t_facet: - return std::locale(in,new std::collate_byname<char16_t>(locale_name.c_str())); - #endif - - #ifdef BOOST_LOCALE_ENABLE_CHAR32_T - case char32_t_facet: - return std::locale(in,new std::collate_byname<char32_t>(locale_name.c_str())); - #endif - default: - return in; - } -} + private: + std::locale base_; + }; + 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())); + } + } -} // impl_std -} // locale -} //boost + case char_facet_t::wchar_f: return std::locale(in, new std::collate_byname<wchar_t>(locale_name.c_str())); +#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())); +#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())); +#endif + } + return in; + } +}}} // namespace boost::locale::impl_std 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 032d643deb..5b242f78fa 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/std/converter.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/std/converter.cpp @@ -16,128 +16,112 @@ #include "boost/locale/std/all_generator.hpp" -#ifdef BOOST_MSVC -# pragma warning(disable : 4996) -#endif - -namespace boost { -namespace locale { -namespace impl_std { +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(std::locale const &base,size_t refs = 0) : - converter<CharType>(refs), - base_(base) - { - } - string_type convert(converter_base::conversion_type how,char_type const *begin,char_type const *end,int /*flags*/ = 0) const BOOST_OVERRIDE - { - switch(how) { - case converter_base::upper_case: - case converter_base::lower_case: - case converter_base::case_folding: - { - ctype_type const &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::copy(begin,end,lbegin); - if(how == converter_base::upper_case) - ct.toupper(lbegin,lbegin+len); - else - ct.tolower(lbegin,lbegin+len); - return string_type(lbegin,len); + 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) {} + string_type convert(converter_base::conversion_type how, + const char_type* begin, + const char_type* end, + int /*flags*/ = 0) const override + { + switch(how) { + case converter_base::upper_case: + case converter_base::lower_case: + 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::copy(begin, end, lbegin); + if(how == converter_base::upper_case) + ct.toupper(lbegin, lbegin + len); + else + ct.tolower(lbegin, lbegin + len); + return string_type(lbegin, len); + } + case converter_base::normalization: + case converter_base::title_case: break; } - default: - return string_type(begin,end-begin); + return string_type(begin, end - begin); } - } -private: - std::locale base_; -}; -class utf8_converter : public converter<char> { -public: - typedef std::ctype<char> ctype_type; - typedef std::ctype<wchar_t> wctype_type; - utf8_converter(std::locale const &base,size_t refs = 0) : - converter<char>(refs), - base_(base) - { - } - std::string convert(converter_base::conversion_type how,char const *begin,char const *end,int /*flags*/ = 0) const BOOST_OVERRIDE - { - switch(how) { - case upper_case: - case lower_case: - case case_folding: - { - std::wstring tmp = conv::to_utf<wchar_t>(begin,end,"UTF-8"); - wctype_type const &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); - 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"); + private: + std::locale base_; + }; + + 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) {} + std::string convert(converter_base::conversion_type how, + const char* begin, + const char* end, + int /*flags*/ = 0) const override + { + switch(how) { + case upper_case: + case lower_case: + case case_folding: { + std::wstring tmp = conv::to_utf<wchar_t>(begin, end, "UTF-8"); + 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); + 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"); + } + case title_case: + case normalization: break; } - default: - return std::string(begin,end-begin); + return std::string(begin, end - begin); } - } -private: - std::locale base_; -}; -std::locale create_convert( std::locale const &in, - std::string const &locale_name, - character_facet_type type, - utf8_support utf) -{ + private: + std::locale base_; + }; + + std::locale + create_convert(const std::locale& in, const std::string& locale_name, char_facet_t type, utf8_support utf) + { switch(type) { - case char_facet: - { - if(utf == utf8_native_with_wide || utf == utf8_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)); + 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)); + 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 wchar_t_facet: - { - 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::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)); } - #ifdef BOOST_LOCALE_ENABLE_CHAR16_T - case char16_t_facet: - { - 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)); +#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)); } - #endif - #ifdef BOOST_LOCALE_ENABLE_CHAR32_T - case char32_t_facet: - { - 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)); +#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)); } - #endif - default: - return in; +#endif } -} - + return in; + } -} // namespace impl_std -} // locale -} // boost +}}} // namespace boost::locale::impl_std 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 f5bc534b92..91d266c22d 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/std/numeric.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/std/numeric.cpp @@ -14,441 +14,365 @@ #include <sstream> #include <string> -#include "boost/locale/util/numeric.hpp" #include "boost/locale/std/all_generator.hpp" +#include "boost/locale/util/numeric.hpp" -namespace boost { -namespace locale { -namespace impl_std { - -template<typename CharType> -class time_put_from_base : public std::time_put<CharType> { -public: - time_put_from_base(std::locale const &base, size_t refs = 0) : - std::time_put<CharType>(refs), - base_(base) - { - } - typedef typename std::time_put<CharType>::iter_type iter_type; - - iter_type do_put(iter_type out,std::ios_base &/*ios*/,CharType fill,std::tm const *tm,char format,char modifier) const BOOST_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); - } -private: - std::locale base_; -}; - -class utf8_time_put_from_wide : public std::time_put<char> { -public: - utf8_time_put_from_wide(std::locale const &base, size_t refs = 0) : - std::time_put<char>(refs), - base_(base) - { - } - iter_type do_put(iter_type out,std::ios_base &/*ios*/,char fill,std::tm const *tm,char format,char modifier = 0) const BOOST_OVERRIDE - { - std::basic_ostringstream<wchar_t> wtmps; - 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; - } -private: - std::locale base_; -}; - -class utf8_numpunct_from_wide : public std::numpunct<char> { -public: - utf8_numpunct_from_wide(std::locale const &base,size_t refs = 0) : std::numpunct<char>(refs) - { - typedef std::numpunct<wchar_t> wfacet_type; - wfacet_type const &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"); +namespace boost { namespace locale { namespace impl_std { - wchar_t tmp_decimal_point = wfacet.decimal_point(); - wchar_t tmp_thousands_sep = wfacet.thousands_sep(); - std::string tmp_grouping = wfacet.grouping(); + 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; - if( 32 <= tmp_thousands_sep && tmp_thousands_sep <=126 && - 32 <= tmp_decimal_point && tmp_decimal_point <=126) + iter_type do_put(iter_type out, + std::ios_base& /*ios*/, + CharType fill, + const std::tm* tm, + char format, + char modifier) const override { - thousands_sep_ = static_cast<char>(tmp_thousands_sep); - decimal_point_ = static_cast<char>(tmp_decimal_point); - grouping_ = tmp_grouping; + std::basic_stringstream<CharType> ss; + ss.imbue(base_); + return std::use_facet<std::time_put<CharType>>(base_).put(out, ss, fill, tm, format, modifier); } - else if(32 <= tmp_decimal_point && tmp_decimal_point <=126 && tmp_thousands_sep == 0xA0) { - // workaround common bug - substitute NBSP with ordinary space - thousands_sep_ = ' '; - decimal_point_ = static_cast<char>(tmp_decimal_point); - grouping_ = tmp_grouping; - } - else if(32 <= tmp_decimal_point && tmp_decimal_point <=126) + + private: + std::locale base_; + }; + + class utf8_time_put_from_wide : public std::time_put<char> { + public: + utf8_time_put_from_wide(const std::locale& base, size_t refs = 0) : std::time_put<char>(refs), base_(base) {} + iter_type do_put(iter_type out, + std::ios_base& /*ios*/, + char fill, + const std::tm* tm, + char format, + char modifier = 0) const override { - thousands_sep_=','; - decimal_point_ = static_cast<char>(tmp_decimal_point); - grouping_=std::string(); - } - else { - thousands_sep_ = ','; - decimal_point_ = '.'; - grouping_=std::string(); + std::basic_ostringstream<wchar_t> wtmps; + 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; } - } - char do_decimal_point() const BOOST_OVERRIDE - { - return decimal_point_; - } - char do_thousands_sep() const BOOST_OVERRIDE - { - return thousands_sep_; - } - std::string do_grouping() const BOOST_OVERRIDE - { - return grouping_; - } - std::string do_truename() const BOOST_OVERRIDE - { - return truename_; - } - std::string do_falsename() const BOOST_OVERRIDE - { - return falsename_; - } -private: - std::string truename_; - std::string falsename_; - char thousands_sep_; - char decimal_point_; - std::string grouping_; - -}; - -template<bool Intl> -class utf8_moneypunct_from_wide : public std::moneypunct<char,Intl> { -public: - utf8_moneypunct_from_wide(std::locale const &base,size_t refs = 0) : std::moneypunct<char,Intl>(refs) - { - typedef std::moneypunct<wchar_t,Intl> wfacet_type; - wfacet_type const &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"); - frac_digits_ = wfacet.frac_digits(); - pos_format_ = wfacet.pos_format(); - neg_format_ = wfacet.neg_format(); - - wchar_t tmp_decimal_point = wfacet.decimal_point(); - wchar_t tmp_thousands_sep = wfacet.thousands_sep(); - std::string tmp_grouping = wfacet.grouping(); - if( 32 <= tmp_thousands_sep && tmp_thousands_sep <=126 && - 32 <= tmp_decimal_point && tmp_decimal_point <=126) + private: + std::locale base_; + }; + + class utf8_numpunct_from_wide : public std::numpunct<char> { + public: + utf8_numpunct_from_wide(const std::locale& base, size_t refs = 0) : std::numpunct<char>(refs) { - thousands_sep_ = static_cast<char>(tmp_thousands_sep); - decimal_point_ = static_cast<char>(tmp_decimal_point); - grouping_ = tmp_grouping; - } - else if(32 <= tmp_decimal_point && tmp_decimal_point <=126 && tmp_thousands_sep == 0xA0) { - // workaround common bug - substitute NBSP with ordinary space - thousands_sep_ = ' '; - decimal_point_ = static_cast<char>(tmp_decimal_point); - grouping_ = tmp_grouping; + 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"); + + wchar_t tmp_decimal_point = wfacet.decimal_point(); + wchar_t tmp_thousands_sep = wfacet.thousands_sep(); + std::string tmp_grouping = wfacet.grouping(); + + if(32 <= tmp_thousands_sep && tmp_thousands_sep <= 126 && 32 <= tmp_decimal_point + && tmp_decimal_point <= 126) { + thousands_sep_ = static_cast<char>(tmp_thousands_sep); + decimal_point_ = static_cast<char>(tmp_decimal_point); + grouping_ = tmp_grouping; + } else if(32 <= tmp_decimal_point && tmp_decimal_point <= 126 && tmp_thousands_sep == 0xA0) { + // workaround common bug - substitute NBSP with ordinary space + thousands_sep_ = ' '; + decimal_point_ = static_cast<char>(tmp_decimal_point); + grouping_ = tmp_grouping; + } else if(32 <= tmp_decimal_point && tmp_decimal_point <= 126) { + thousands_sep_ = ','; + decimal_point_ = static_cast<char>(tmp_decimal_point); + grouping_ = std::string(); + } else { + thousands_sep_ = ','; + decimal_point_ = '.'; + grouping_ = std::string(); + } } - else if(32 <= tmp_decimal_point && tmp_decimal_point <=126) + + char do_decimal_point() const override { return decimal_point_; } + char do_thousands_sep() const override { return thousands_sep_; } + std::string do_grouping() const override { return grouping_; } + std::string do_truename() const override { return truename_; } + std::string do_falsename() const override { return falsename_; } + + private: + std::string truename_; + std::string falsename_; + char thousands_sep_; + char decimal_point_; + std::string grouping_; + }; + + template<bool Intl> + class utf8_moneypunct_from_wide : public std::moneypunct<char, Intl> { + public: + utf8_moneypunct_from_wide(const std::locale& base, size_t refs = 0) : std::moneypunct<char, Intl>(refs) { - thousands_sep_=','; - decimal_point_ = static_cast<char>(tmp_decimal_point); - grouping_=std::string(); - } - else { - thousands_sep_ = ','; - decimal_point_ = '.'; - grouping_=std::string(); + 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"); + frac_digits_ = wfacet.frac_digits(); + pos_format_ = wfacet.pos_format(); + neg_format_ = wfacet.neg_format(); + + wchar_t tmp_decimal_point = wfacet.decimal_point(); + wchar_t tmp_thousands_sep = wfacet.thousands_sep(); + std::string tmp_grouping = wfacet.grouping(); + if(32 <= tmp_thousands_sep && tmp_thousands_sep <= 126 && 32 <= tmp_decimal_point + && tmp_decimal_point <= 126) { + thousands_sep_ = static_cast<char>(tmp_thousands_sep); + decimal_point_ = static_cast<char>(tmp_decimal_point); + grouping_ = tmp_grouping; + } else if(32 <= tmp_decimal_point && tmp_decimal_point <= 126 && tmp_thousands_sep == 0xA0) { + // workaround common bug - substitute NBSP with ordinary space + thousands_sep_ = ' '; + decimal_point_ = static_cast<char>(tmp_decimal_point); + grouping_ = tmp_grouping; + } else if(32 <= tmp_decimal_point && tmp_decimal_point <= 126) { + thousands_sep_ = ','; + decimal_point_ = static_cast<char>(tmp_decimal_point); + grouping_ = std::string(); + } else { + thousands_sep_ = ','; + decimal_point_ = '.'; + grouping_ = std::string(); + } } - } - char do_decimal_point() const BOOST_OVERRIDE - { - return decimal_point_; - } + char do_decimal_point() const override { return decimal_point_; } - char do_thousands_sep() const BOOST_OVERRIDE - { - return thousands_sep_; - } + char do_thousands_sep() const override { return thousands_sep_; } - std::string do_grouping() const BOOST_OVERRIDE - { - return grouping_; - } + std::string do_grouping() const override { return grouping_; } - std::string do_curr_symbol() const BOOST_OVERRIDE - { - return curr_symbol_; - } - std::string do_positive_sign () const BOOST_OVERRIDE - { - return positive_sign_; - } - std::string do_negative_sign() const BOOST_OVERRIDE - { - return negative_sign_; - } + std::string do_curr_symbol() const override { return curr_symbol_; } + std::string do_positive_sign() const override { return positive_sign_; } + std::string do_negative_sign() const override { return negative_sign_; } - int do_frac_digits() const BOOST_OVERRIDE - { - return frac_digits_; - } + int do_frac_digits() const override { return frac_digits_; } - std::money_base::pattern do_pos_format() const BOOST_OVERRIDE - { - return pos_format_; - } + std::money_base::pattern do_pos_format() const override { return pos_format_; } - std::money_base::pattern do_neg_format() const BOOST_OVERRIDE - { - return neg_format_; - } + std::money_base::pattern do_neg_format() const override { return neg_format_; } -private: - char thousands_sep_; - char decimal_point_; - std::string grouping_; - std::string curr_symbol_; - std::string positive_sign_; - std::string negative_sign_; - int frac_digits_; - std::money_base::pattern pos_format_,neg_format_; - -}; - -class utf8_numpunct : public std::numpunct_byname<char> { -public: - typedef std::numpunct_byname<char> base_type; - utf8_numpunct(char const *name,size_t refs = 0) : - std::numpunct_byname<char>(name,refs) - { - } - char do_thousands_sep() const BOOST_OVERRIDE - { - unsigned char bs = base_type::do_thousands_sep(); - if(bs > 127) - if(bs == 0xA0) - return ' '; + private: + char thousands_sep_; + char decimal_point_; + std::string grouping_; + std::string curr_symbol_; + std::string positive_sign_; + std::string negative_sign_; + int frac_digits_; + std::money_base::pattern pos_format_, neg_format_; + }; + + 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) {} + char do_thousands_sep() const override + { + unsigned char bs = base_type::do_thousands_sep(); + if(bs > 127) + if(bs == 0xA0) + return ' '; + else + return 0; else - return 0; - else - return bs; - } - std::string do_grouping() const BOOST_OVERRIDE - { - unsigned char bs = base_type::do_thousands_sep(); - if(bs > 127 && bs != 0xA0) - return std::string(); - return base_type::do_grouping(); - } -}; - -template<bool Intl> -class utf8_moneypunct : public std::moneypunct_byname<char,Intl> { -public: - typedef std::moneypunct_byname<char,Intl> base_type; - utf8_moneypunct(char const *name,size_t refs = 0) : - std::moneypunct_byname<char,Intl>(name,refs) + return bs; + } + std::string do_grouping() const override + { + unsigned char bs = base_type::do_thousands_sep(); + if(bs > 127 && bs != 0xA0) + return std::string(); + return base_type::do_grouping(); + } + }; + + template<bool Intl> + 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) {} + char do_thousands_sep() const override + { + unsigned char bs = base_type::do_thousands_sep(); + if(bs > 127) + if(bs == 0xA0) + return ' '; + else + return 0; + else + return bs; + } + std::string do_grouping() const override + { + unsigned char bs = base_type::do_thousands_sep(); + if(bs > 127 && bs != 0xA0) + return std::string(); + return base_type::do_grouping(); + } + }; + + 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; } - char do_thousands_sep() const BOOST_OVERRIDE + + template<typename CharType> + std::locale create_basic_formatting(const std::locale& in, const std::string& locale_name) { - unsigned char bs = base_type::do_thousands_sep(); - if(bs > 127) - if(bs == 0xA0) - return ' '; - else - return 0; - else - return bs; + 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; } - std::string do_grouping() const BOOST_OVERRIDE + + std::locale + create_formatting(const std::locale& in, const std::string& locale_name, char_facet_t type, utf8_support utf) { - unsigned char bs = base_type::do_thousands_sep(); - if(bs > 127 && bs != 0xA0) - return std::string(); - return base_type::do_grouping(); - } -}; - - -template<typename CharType> -std::locale create_basic_parsing(std::locale const &in,std::string const &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; -} - -template<typename CharType> -std::locale create_basic_formatting(std::locale const &in,std::string const &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; -} - - -std::locale create_formatting( std::locale const &in, - std::string const &locale_name, - character_facet_type type, - utf8_support utf) -{ switch(type) { - case char_facet: - { - if(utf == utf8_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>()); - } - else if(utf == utf8_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>()); - } - else if(utf == utf8_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>()); - } - else - { - 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::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 wchar_t_facet: - { - std::locale tmp = create_basic_formatting<wchar_t>(in,locale_name); - tmp = std::locale(tmp,new util::base_num_format<wchar_t>()); + 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; } - #ifdef BOOST_LOCALE_ENABLE_CHAR16_T - case char16_t_facet: - { - std::locale tmp = create_basic_formatting<char16_t>(in,locale_name); - tmp = std::locale(tmp,new util::base_num_format<char16_t>()); +#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; } - #endif - #ifdef BOOST_LOCALE_ENABLE_CHAR32_T - case char32_t_facet: - { - std::locale tmp = create_basic_formatting<char32_t>(in,locale_name); - tmp = std::locale(tmp,new util::base_num_format<char32_t>()); +#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; } - #endif - default: - return in; +#endif } -} + return in; + } -std::locale create_parsing( std::locale const &in, - std::string const &locale_name, - character_facet_type type, - utf8_support utf) -{ + std::locale + create_parsing(const std::locale& in, const std::string& locale_name, char_facet_t type, utf8_support utf) + { switch(type) { - case char_facet: - { - if(utf == utf8_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>()); - } - else if(utf == utf8_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>()); - } - else if(utf == utf8_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>()); - } - else - { - 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::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 wchar_t_facet: - { - std::locale tmp = create_basic_parsing<wchar_t>(in,locale_name); - tmp = std::locale(in,new util::base_num_parse<wchar_t>()); - return tmp; - } - #ifdef BOOST_LOCALE_ENABLE_CHAR16_T - case char16_t_facet: - { - std::locale tmp = create_basic_parsing<char16_t>(in,locale_name); - tmp = std::locale(in,new util::base_num_parse<char16_t>()); - return tmp; - } - #endif - #ifdef BOOST_LOCALE_ENABLE_CHAR32_T - case char32_t_facet: - { - std::locale tmp = create_basic_parsing<char32_t>(in,locale_name); - tmp = std::locale(in,new util::base_num_parse<char32_t>()); - return tmp; - } - #endif - default: - return in; + 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; + } +#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; + } +#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; + } +#endif } -} - - -} // impl_std -} // locale -} //boost - - + return in; + } +}}} // namespace boost::locale::impl_std 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 b9599ec06a..3857c62630 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 @@ -6,64 +6,49 @@ #define BOOST_LOCALE_SOURCE #include "boost/locale/std/std_backend.hpp" -#include <boost/locale/localization_backend.hpp> #include <boost/locale/gnu_gettext.hpp> +#include <boost/locale/localization_backend.hpp> #include <boost/locale/util.hpp> #include <algorithm> #include <iterator> #include <vector> #if defined(BOOST_WINDOWS) -# ifndef NOMINMAX -# define NOMINMAX -# endif -# include <windows.h> -# include "boost/locale/encoding/conv.hpp" -# include "boost/locale/win32/lcid.hpp" +# ifndef NOMINMAX +# define NOMINMAX +# endif +# include "boost/locale/encoding/conv.hpp" +# include "boost/locale/win32/lcid.hpp" +# include <windows.h> #endif #include "boost/locale/std/all_generator.hpp" -#include "boost/locale/util/locale_data.hpp" #include "boost/locale/util/gregorian.hpp" +#include "boost/locale/util/locale_data.hpp" -namespace boost { -namespace locale { -namespace impl_std { +namespace boost { namespace locale { namespace impl_std { class std_localization_backend : public localization_backend { public: - std_localization_backend() : - invalid_(true), - use_ansi_encoding_(false) - { - } - std_localization_backend(std_localization_backend const &other) : - localization_backend(), - paths_(other.paths_), - domains_(other.domains_), - locale_id_(other.locale_id_), - invalid_(true), - use_ansi_encoding_(other.use_ansi_encoding_) - { - } - std_localization_backend *clone() const BOOST_OVERRIDE - { - return new std_localization_backend(*this); - } - - void set_option(std::string const &name,std::string const &value) BOOST_OVERRIDE + std_localization_backend() : invalid_(true), use_ansi_encoding_(false) {} + std_localization_backend(const std_localization_backend& other) : + localization_backend(), paths_(other.paths_), domains_(other.domains_), locale_id_(other.locale_id_), + invalid_(true), use_ansi_encoding_(other.use_ansi_encoding_) + {} + std_localization_backend* clone() const override { return new std_localization_backend(*this); } + + void set_option(const std::string& name, const std::string& value) override { invalid_ = true; - if(name=="locale") + if(name == "locale") locale_id_ = value; - else if(name=="message_path") + else if(name == "message_path") paths_.push_back(value); - else if(name=="message_application") + else if(name == "message_application") domains_.push_back(value); - else if(name=="use_ansi_encoding") + else if(name == "use_ansi_encoding") use_ansi_encoding_ = value == "true"; - } - void clear_options() BOOST_OVERRIDE + void clear_options() override { invalid_ = true; use_ansi_encoding_ = false; @@ -77,139 +62,133 @@ namespace impl_std { if(!invalid_) return; invalid_ = false; - std::string lid=locale_id_; + std::string lid = locale_id_; if(lid.empty()) { - bool use_utf8 = ! use_ansi_encoding_; + bool use_utf8 = !use_ansi_encoding_; lid = util::get_system_locale(use_utf8); } in_use_id_ = lid; data_.parse(lid); name_ = "C"; - utf_mode_ = utf8_none; - #if defined(BOOST_WINDOWS) - std::pair<std::string,int> wl_inf = to_windows_name(lid); - std::string win_name = wl_inf.first; - int win_codepage = wl_inf.second; - #endif +#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 if(!data_.utf8) { - if(loadable(lid)) { + if(loadable(lid)) name_ = lid; - utf_mode_ = utf8_none; - } - #if defined(BOOST_WINDOWS) +#if defined(BOOST_WINDOWS) else if(loadable(win_name) && win_codepage == conv::impl::encoding_to_windows_codepage(data_.encoding.c_str())) - { name_ = win_name; - utf_mode_ = utf8_none; - } - #endif - } - else { +#endif + utf_mode_ = utf8_support::none; + } else { if(loadable(lid)) { name_ = lid; - utf_mode_ = utf8_native_with_wide; + 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)) { +#if defined(BOOST_WINDOWS) + else if(loadable(win_name)) + { name_ = win_name; - utf_mode_ = utf8_from_wide; + utf_mode_ = utf8_support::from_wide; } - #endif +#endif + else + utf_mode_ = utf8_support::none; } } - #if defined(BOOST_WINDOWS) - std::pair<std::string,int> to_windows_name(std::string const &l) +#if defined(BOOST_WINDOWS) + std::pair<std::string, int> to_windows_name(const std::string& l) { - std::pair<std::string,int> res("C",0); + 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_lang[256] = {0}; + char win_country[256] = {0}; char win_codepage[10] = {0}; - if(GetLocaleInfoA(lcid,LOCALE_SENGLANGUAGE,win_lang,sizeof(win_lang))==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) { + 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) + if(GetLocaleInfoA(lcid, LOCALE_IDEFAULTANSICODEPAGE, win_codepage, sizeof(win_codepage)) != 0) res.second = atoi(win_codepage); return res; } - #endif +#endif bool loadable(std::string name) { try { std::locale l(name.c_str()); return true; - } - catch(std::exception const &/*e*/) { + } catch(const std::exception& /*e*/) { return false; } } - std::locale install(std::locale const &base, - locale_category_type category, - character_facet_type type = nochar_facet) BOOST_OVERRIDE + std::locale install(const std::locale& base, category_t category, char_facet_t type) override { prepare_data(); switch(category) { - case convert_facet: - return create_convert(base,name_,type,utf_mode_); - case collation_facet: - return create_collate(base,name_,type,utf_mode_); - case formatting_facet: - return create_formatting(base,name_,type,utf_mode_); - case parsing_facet: - return create_parsing(base,name_,type,utf_mode_); - case codepage_facet: - return create_codecvt(base,name_,type,utf_mode_); - case calendar_facet: - return util::install_gregorian_calendar(base,data_.country); - case message_facet: - { + case category_t::convert: return create_convert(base, name_, type, utf_mode_); + case category_t::collation: return create_collate(base, name_, type, utf_mode_); + case category_t::formatting: return create_formatting(base, name_, type, utf_mode_); + case category_t::parsing: return create_parsing(base, name_, type, utf_mode_); + case category_t::codepage: return create_codecvt(base, name_, type, utf_mode_); + case category_t::calendar: return util::install_gregorian_calendar(base, data_.country); + case category_t::message: { gnu_gettext::messages_info minf; minf.language = data_.language; minf.country = data_.country; minf.variant = data_.variant; minf.encoding = data_.encoding; - std::copy(domains_.begin(),domains_.end(),std::back_inserter<gnu_gettext::messages_info::domains_type>(minf.domains)); + std::copy(domains_.begin(), + domains_.end(), + std::back_inserter<gnu_gettext::messages_info::domains_type>(minf.domains)); minf.paths = paths_; switch(type) { - case char_facet: - return std::locale(base,gnu_gettext::create_messages_facet<char>(minf)); - case wchar_t_facet: - return std::locale(base,gnu_gettext::create_messages_facet<wchar_t>(minf)); - #ifdef BOOST_LOCALE_ENABLE_CHAR16_T - case char16_t_facet: - return std::locale(base,gnu_gettext::create_messages_facet<char16_t>(minf)); - #endif - #ifdef BOOST_LOCALE_ENABLE_CHAR32_T - case char32_t_facet: - return std::locale(base,gnu_gettext::create_messages_facet<char32_t>(minf)); - #endif - default: - return base; + case char_facet_t::nochar: break; + case char_facet_t::char_f: + return std::locale(base, gnu_gettext::create_messages_facet<char>(minf)); + case char_facet_t::wchar_f: + return std::locale(base, gnu_gettext::create_messages_facet<wchar_t>(minf)); +#ifdef BOOST_LOCALE_ENABLE_CHAR16_T + case char_facet_t::char16_f: + return std::locale(base, gnu_gettext::create_messages_facet<char16_t>(minf)); +#endif +#ifdef BOOST_LOCALE_ENABLE_CHAR32_T + case char_facet_t::char32_f: + return std::locale(base, gnu_gettext::create_messages_facet<char32_t>(minf)); +#endif } + return base; } - case information_facet: - return util::create_info(base,in_use_id_); - default: - return base; + case category_t::information: return util::create_info(base, in_use_id_); + case category_t::boundary: break; // Not implemented } + return base; } private: - std::vector<std::string> paths_; std::vector<std::string> domains_; std::string locale_id_; @@ -222,11 +201,9 @@ namespace impl_std { bool use_ansi_encoding_; }; - localization_backend *create_localization_backend() + localization_backend* create_localization_backend() { return new std_localization_backend(); } -} // impl icu -} // locale -} // boost +}}} // 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 b96a4ab156..76ddc051d0 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,13 +6,10 @@ #ifndef BOOST_LOCALE_IMPL_STD_LOCALIZATION_BACKEND_HPP #define BOOST_LOCALE_IMPL_STD_LOCALIZATION_BACKEND_HPP -namespace boost { - namespace locale { - class localization_backend; - namespace impl_std { - localization_backend *create_localization_backend(); - } // impl_std - } // locale -} // boost +namespace boost { namespace locale { + class localization_backend; + namespace impl_std { + 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 f1c91a2fef..6f544ce183 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 @@ -5,8 +5,8 @@ // https://www.boost.org/LICENSE_1_0.txt #define BOOST_LOCALE_SOURCE -#include <boost/locale/generator.hpp> #include <boost/locale/encoding.hpp> +#include <boost/locale/generator.hpp> #include <boost/locale/utf8_codecvt.hpp> #include <boost/locale/util.hpp> #include <algorithm> @@ -15,129 +15,111 @@ #include "boost/locale/encoding/conv.hpp" -//#define DEBUG_CODECVT -#ifdef DEBUG_CODECVT -#include <iostream> -#endif - #ifdef BOOST_MSVC -# pragma warning(disable : 4244 4996) // loose data +# pragma warning(disable : 4244) // loose data #endif -namespace boost { -namespace locale { -namespace util { +namespace boost { namespace locale { namespace util { - base_converter::~base_converter() {} + base_converter::~base_converter() = default; - class utf8_converter : public base_converter { + class utf8_converter : public base_converter { public: - int max_len() const BOOST_OVERRIDE - { - return 4; - } + int max_len() const override { return 4; } - utf8_converter *clone() const BOOST_OVERRIDE - { - return new utf8_converter(); - } + utf8_converter* clone() const override { return new utf8_converter(); } - bool is_thread_safe() const BOOST_OVERRIDE - { - return true; - } + bool is_thread_safe() const override { return true; } - uint32_t to_unicode(char const *&begin,char const *end) BOOST_OVERRIDE + uint32_t to_unicode(const char*& begin, const char* end) override { - char const *p=begin; + const char* p = begin; - utf::code_point c = utf::utf_traits<char>::decode(p,end); + utf::code_point c = utf::utf_traits<char>::decode(p, end); - if(c==utf::illegal) + if(c == utf::illegal) return illegal; - if(c==utf::incomplete) + if(c == utf::incomplete) return incomplete; begin = p; return c; } - uint32_t from_unicode(uint32_t u,char *begin,char const *end) BOOST_OVERRIDE + uint32_t from_unicode(uint32_t u, char* begin, const char* end) override { if(!utf::is_valid_codepoint(u)) return illegal; int width = utf::utf_traits<char>::width(u); - std::ptrdiff_t d=end-begin; + std::ptrdiff_t d = end - begin; if(d < width) return incomplete; - utf::utf_traits<char>::encode(u,begin); + utf::utf_traits<char>::encode(u, begin); return width; } }; // utf8_converter class simple_converter_impl { public: + static constexpr int hash_table_size = 1024; - static const int hash_table_size = 1024; - - simple_converter_impl(std::string const &encoding) + simple_converter_impl(const std::string& encoding) { - for(unsigned i=0;i<128;i++) - to_unicode_tbl_[i]=i; - for(unsigned i=128;i<256;i++) { - char buf[2] = { char(i) , 0 }; - uint32_t uchar=utf::illegal; + for(unsigned i = 0; i < 128; i++) + to_unicode_tbl_[i] = i; + for(unsigned i = 128; i < 256; i++) { + char buf[2] = {char(i), 0}; + uint32_t uchar = utf::illegal; try { - std::wstring const tmp = conv::to_utf<wchar_t>(buf,buf+1,encoding,conv::stop); + std::wstring const tmp = conv::to_utf<wchar_t>(buf, buf + 1, encoding, conv::stop); if(tmp.size() == 1) { uchar = tmp[0]; - } - else { + } else { uchar = utf::illegal; } - } - catch(conv::conversion_error const &/*e*/) { + } catch(const conv::conversion_error& /*e*/) { uchar = utf::illegal; } - to_unicode_tbl_[i]=uchar; + to_unicode_tbl_[i] = uchar; } - for(int i=0;i<hash_table_size;i++) - from_unicode_tbl_[i]=0; - for(unsigned i=1;i<256;i++) { - if(to_unicode_tbl_[i]!=utf::illegal) { + for(int i = 0; i < hash_table_size; i++) + from_unicode_tbl_[i] = 0; + for(unsigned i = 1; i < 256; i++) { + if(to_unicode_tbl_[i] != utf::illegal) { unsigned pos = to_unicode_tbl_[i] % hash_table_size; - while(from_unicode_tbl_[pos]!=0) + while(from_unicode_tbl_[pos] != 0) pos = (pos + 1) % hash_table_size; from_unicode_tbl_[pos] = i; } } } - uint32_t to_unicode(char const *&begin,char const *end) const + uint32_t to_unicode(const char*& begin, const char* end) const { - if(begin==end) + if(begin == end) return utf::incomplete; unsigned char c = *begin++; return to_unicode_tbl_[c]; } - uint32_t from_unicode(uint32_t u,char *begin,char const *end) const + uint32_t from_unicode(uint32_t u, char* begin, const char* end) const { - if(begin==end) + if(begin == end) return utf::incomplete; - if(u==0) { + if(u == 0) { *begin = 0; return 1; } unsigned pos = u % hash_table_size; unsigned char c; - while((c=from_unicode_tbl_[pos])!=0 && to_unicode_tbl_[c]!=u) + while((c = from_unicode_tbl_[pos]) != 0 && to_unicode_tbl_[c] != u) pos = (pos + 1) % hash_table_size; - if(c==0) - return utf::illegal; + if(c == 0) + return utf::illegal; *begin = c; return 1; } + private: uint32_t to_unicode_tbl_[256]; unsigned char from_unicode_tbl_[hash_table_size]; @@ -145,193 +127,110 @@ namespace util { class simple_converter : public base_converter { public: + simple_converter(const std::string& encoding) : cvt_(encoding) {} - simple_converter(std::string const &encoding) : - cvt_(encoding) - { - } + int max_len() const override { return 1; } - int max_len() const BOOST_OVERRIDE - { - return 1; - } + bool is_thread_safe() const override { return true; } + base_converter* clone() const override { return new simple_converter(*this); } - bool is_thread_safe() const BOOST_OVERRIDE + 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 { - return true; - } - base_converter *clone() const BOOST_OVERRIDE - { - return new simple_converter(*this); + return cvt_.from_unicode(u, begin, end); } - uint32_t to_unicode(char const *&begin,char const *end) BOOST_OVERRIDE - { - return cvt_.to_unicode(begin,end); - } - uint32_t from_unicode(uint32_t u,char *begin,char const *end) BOOST_OVERRIDE - { - return cvt_.from_unicode(u,begin,end); - } private: simple_converter_impl cvt_; }; template<typename CharType> - class simple_codecvt : public generic_codecvt<CharType,simple_codecvt<CharType> > - { + class simple_codecvt : public generic_codecvt<CharType, simple_codecvt<CharType>> { public: - - simple_codecvt(std::string const &encoding,size_t refs = 0) : - generic_codecvt<CharType,simple_codecvt<CharType> >(refs), - cvt_(encoding) - { - } + simple_codecvt(const std::string& encoding, size_t refs = 0) : + generic_codecvt<CharType, simple_codecvt<CharType>>(refs), cvt_(encoding) + {} struct state_type {}; static state_type initial_state(generic_codecvt_base::initial_convertion_state /* unused */) { return state_type(); } - static int max_encoding_length() - { - return 1; - } + static int max_encoding_length() { return 1; } - utf::code_point to_unicode(state_type &,char const *&begin,char const *end) const + utf::code_point to_unicode(state_type&, const char*& begin, const char* end) const { - return cvt_.to_unicode(begin,end); + return cvt_.to_unicode(begin, end); } - utf::code_point from_unicode(state_type &,utf::code_point u,char *begin,char const *end) const + utf::code_point from_unicode(state_type&, utf::code_point u, char* begin, const char* end) const { - return cvt_.from_unicode(u,begin,end); + return cvt_.from_unicode(u, begin, end); } + private: simple_converter_impl cvt_; - }; namespace { - char const *simple_encoding_table[] = { - "cp1250", - "cp1251", - "cp1252", - "cp1253", - "cp1254", - "cp1255", - "cp1256", - "cp1257", - "iso88591", - "iso885913", - "iso885915", - "iso88592", - "iso88593", - "iso88594", - "iso88595", - "iso88596", - "iso88597", - "iso88598", - "iso88599", - "koi8r", - "koi8u", - "usascii", - "windows1250", - "windows1251", - "windows1252", - "windows1253", - "windows1254", - "windows1255", - "windows1256", - "windows1257" - }; - - bool compare_strings(char const *l,char const *r) + const char* simple_encoding_table[] = { + "cp1250", "cp1251", "cp1252", "cp1253", "cp1254", "cp1255", + "cp1256", "cp1257", "iso88591", "iso885913", "iso885915", "iso88592", + "iso88593", "iso88594", "iso88595", "iso88596", "iso88597", "iso88598", + "iso88599", "koi8r", "koi8u", "usascii", "windows1250", "windows1251", + "windows1252", "windows1253", "windows1254", "windows1255", "windows1256", "windows1257"}; + + bool compare_strings(const char* l, const char* r) { - return strcmp(l,r) < 0; + return strcmp(l, r) < 0; } - } + } // namespace - bool check_is_simple_encoding(std::string const &encoding) + bool check_is_simple_encoding(const std::string& encoding) { std::string norm = conv::impl::normalize_encoding(encoding.c_str()); - return std::binary_search<char const **>( simple_encoding_table, - simple_encoding_table + sizeof(simple_encoding_table)/sizeof(char const *), - norm.c_str(), - compare_strings); + return std::binary_search<const char**>(simple_encoding_table, + simple_encoding_table + + sizeof(simple_encoding_table) / sizeof(const char*), + norm.c_str(), + compare_strings); } - #if BOOST_LOCALE_USE_AUTO_PTR - std::auto_ptr<base_converter> create_utf8_converter() - { - std::auto_ptr<base_converter> res(create_utf8_converter_new_ptr()); - return res; - } - std::auto_ptr<base_converter> create_simple_converter(std::string const &encoding) - { - std::auto_ptr<base_converter> res(create_simple_converter_new_ptr(encoding)); - return res; - } - std::locale create_codecvt(std::locale const &in,std::auto_ptr<base_converter> cvt,character_facet_type type) - { - return create_codecvt_from_pointer(in,cvt.release(),type); - } - #endif - #ifndef BOOST_NO_CXX11_SMART_PTR - std::unique_ptr<base_converter> create_utf8_converter_unique_ptr() - { - std::unique_ptr<base_converter> res(create_utf8_converter_new_ptr()); - return res; - } - std::unique_ptr<base_converter> create_simple_converter_unique_ptr(std::string const &encoding) + std::unique_ptr<base_converter> create_simple_converter(const std::string& encoding) { - std::unique_ptr<base_converter> res(create_simple_converter_new_ptr(encoding)); - return res; + return std::unique_ptr<base_converter>(create_simple_converter_new_ptr(encoding)); } - std::locale create_codecvt(std::locale const &in,std::unique_ptr<base_converter> cvt,character_facet_type type) - { - return create_codecvt_from_pointer(in,cvt.release(),type); - } - #endif - - base_converter *create_simple_converter_new_ptr(std::string const &encoding) + base_converter* create_simple_converter_new_ptr(const std::string& encoding) { if(check_is_simple_encoding(encoding)) return new simple_converter(encoding); return 0; } - base_converter *create_utf8_converter_new_ptr() + std::unique_ptr<base_converter> create_utf8_converter() + { + return std::unique_ptr<base_converter>(create_utf8_converter_new_ptr()); + } + + base_converter* create_utf8_converter_new_ptr() { return new utf8_converter(); } template<typename CharType> - class code_converter : public generic_codecvt<CharType,code_converter<CharType> > - { + class code_converter : public generic_codecvt<CharType, code_converter<CharType>> { public: - #ifndef BOOST_NO_CXX11_SMART_PTR typedef std::unique_ptr<base_converter> base_converter_ptr; - #define PTR_TRANS(x) std::move((x)) - #else - typedef std::auto_ptr<base_converter> base_converter_ptr; - #define PTR_TRANS(x) (x) - #endif typedef base_converter_ptr state_type; - code_converter(base_converter_ptr cvt,size_t refs = 0) : - generic_codecvt<CharType,code_converter<CharType> >(refs), - cvt_(PTR_TRANS(cvt)) + 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(); } - - int max_encoding_length() const - { - return max_len_; - } + int max_encoding_length() const { return max_len_; } base_converter_ptr initial_state(generic_codecvt_base::initial_convertion_state /* unused */) const { @@ -341,20 +240,20 @@ namespace util { return r; } - utf::code_point to_unicode(base_converter_ptr &ptr,char const *&begin,char const *end) const + utf::code_point to_unicode(base_converter_ptr& ptr, const char*& begin, const char* end) const { if(thread_safe_) - return cvt_->to_unicode(begin,end); + return cvt_->to_unicode(begin, end); else - return ptr->to_unicode(begin,end); + return ptr->to_unicode(begin, end); } - utf::code_point from_unicode(base_converter_ptr &ptr,utf::code_point u,char *begin,char const *end) const + utf::code_point from_unicode(base_converter_ptr& ptr, utf::code_point u, char* begin, const char* end) const { if(thread_safe_) - return cvt_->from_unicode(u,begin,end); + return cvt_->from_unicode(u, begin, end); else - return ptr->from_unicode(u,begin,end); + return ptr->from_unicode(u, begin, end); } private: @@ -363,87 +262,64 @@ namespace util { bool thread_safe_; }; - - std::locale create_codecvt_from_pointer(std::locale const &in,base_converter *pcvt,character_facet_type type) + std::locale create_codecvt(const std::locale& in, std::unique_ptr<base_converter> cvt, char_facet_t type) { - code_converter<char>::base_converter_ptr cvt(pcvt); - if(!cvt.get()) + if(!cvt) cvt.reset(new base_converter()); switch(type) { - case char_facet: - return std::locale(in,new code_converter<char>(PTR_TRANS(cvt))); - case wchar_t_facet: - return std::locale(in,new code_converter<wchar_t>(PTR_TRANS(cvt))); - #if defined(BOOST_LOCALE_ENABLE_CHAR16_T) - case char16_t_facet: - return std::locale(in,new code_converter<char16_t>(PTR_TRANS(cvt))); - #endif - #if defined(BOOST_LOCALE_ENABLE_CHAR32_T) - case char32_t_facet: - return std::locale(in,new code_converter<char32_t>(PTR_TRANS(cvt))); - #endif - default: - return in; + 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))); +#ifdef BOOST_LOCALE_ENABLE_CHAR16_T + case char_facet_t::char16_f: return std::locale(in, new code_converter<char16_t>(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))); +#endif } + return in; } - - /// /// Install utf8 codecvt to UTF-16 or UTF-32 into locale \a in and return /// new locale that is based on \a in and uses new facet. - /// - std::locale create_utf8_codecvt(std::locale const &in,character_facet_type type) + std::locale create_utf8_codecvt(const std::locale& in, char_facet_t type) { switch(type) { - case char_facet: - return std::locale(in,new utf8_codecvt<char>()); - case wchar_t_facet: - return std::locale(in,new utf8_codecvt<wchar_t>()); - #if defined(BOOST_LOCALE_ENABLE_CHAR16_T) - case char16_t_facet: - return std::locale(in,new utf8_codecvt<char16_t>()); - #endif - #if defined(BOOST_LOCALE_ENABLE_CHAR32_T) - case char32_t_facet: - return std::locale(in,new utf8_codecvt<char32_t>()); - #endif - default: - return in; + case char_facet_t::nochar: break; + case char_facet_t::char_f: return std::locale(in, new utf8_codecvt<char>()); + case char_facet_t::wchar_f: return std::locale(in, new utf8_codecvt<wchar_t>()); +#ifdef BOOST_LOCALE_ENABLE_CHAR16_T + case char_facet_t::char16_f: return std::locale(in, new utf8_codecvt<char16_t>()); +#endif +#ifdef BOOST_LOCALE_ENABLE_CHAR32_T + case char_facet_t::char32_f: return std::locale(in, new utf8_codecvt<char32_t>()); +#endif } + 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 chacater set is not supported or isn't single byte character + /// Throws invalid_charset_error if the character set is not supported or isn't single byte character /// set - std::locale create_simple_codecvt(std::locale const &in,std::string const &encoding,character_facet_type type) + std::locale create_simple_codecvt(const std::locale& in, const std::string& encoding, char_facet_t type) { if(!check_is_simple_encoding(encoding)) throw boost::locale::conv::invalid_charset_error("Invalid simple encoding " + encoding); switch(type) { - case char_facet: - return std::locale(in,new simple_codecvt<char>(encoding)); - case wchar_t_facet: - return std::locale(in,new simple_codecvt<wchar_t>(encoding)); - #if defined(BOOST_LOCALE_ENABLE_CHAR16_T) - case char16_t_facet: - return std::locale(in,new simple_codecvt<char16_t>(encoding)); - #endif - #if defined(BOOST_LOCALE_ENABLE_CHAR32_T) - case char32_t_facet: - return std::locale(in,new simple_codecvt<char32_t>(encoding)); - #endif - default: - return in; + case char_facet_t::nochar: break; + case char_facet_t::char_f: return std::locale(in, new simple_codecvt<char>(encoding)); + case char_facet_t::wchar_f: return std::locale(in, new simple_codecvt<wchar_t>(encoding)); +#ifdef BOOST_LOCALE_ENABLE_CHAR16_T + case char_facet_t::char16_f: return std::locale(in, new simple_codecvt<char16_t>(encoding)); +#endif +#ifdef BOOST_LOCALE_ENABLE_CHAR32_T + case char_facet_t::char32_f: return std::locale(in, new simple_codecvt<char32_t>(encoding)); +#endif } + return in; } - - -} // util -} // locale -} // boost - +}}} // namespace boost::locale::util 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 ebb4232155..92d55af57d 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 @@ -9,68 +9,56 @@ #include <cstdlib> #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) -#ifndef NOMINMAX -#define NOMINMAX -#endif -#include <windows.h> -#define BOOST_LOCALE_USE_WIN32_API -#endif - -#ifdef BOOST_MSVC -# pragma warning(disable : 4996) +# ifndef NOMINMAX +# define NOMINMAX +# endif +# include <windows.h> +# define BOOST_LOCALE_USE_WIN32_API #endif -namespace boost { - namespace locale { - namespace util { - std::string get_system_locale(bool use_utf8) - { - char const *lang = 0; - if(!lang || !*lang) - lang = getenv("LC_CTYPE"); - if(!lang || !*lang) - lang = getenv("LC_ALL"); - if(!lang || !*lang) - lang = getenv("LANG"); - #ifndef BOOST_LOCALE_USE_WIN32_API - (void)use_utf8; // not relevant for non-windows - if(!lang || !*lang) - lang = "C"; - return lang; - #else - if(lang && *lang) { - return lang; - } - char buf[10]; - if(GetLocaleInfoA(LOCALE_USER_DEFAULT,LOCALE_SISO639LANGNAME,buf,sizeof(buf))==0) - return "C"; - std::string lc_name = buf; - if(GetLocaleInfoA(LOCALE_USER_DEFAULT,LOCALE_SISO3166CTRYNAME,buf,sizeof(buf))!=0) { - lc_name += "_"; - lc_name += buf; - } - if(!use_utf8) { - if(GetLocaleInfoA(LOCALE_USER_DEFAULT,LOCALE_IDEFAULTANSICODEPAGE,buf,sizeof(buf))!=0) { - if(atoi(buf)==0) - lc_name+=".UTF-8"; - else { - lc_name +=".windows-"; - lc_name +=buf; - } - } - else { - lc_name += "UTF-8"; - } - } - else { +namespace boost { namespace locale { namespace util { + std::string get_system_locale(bool use_utf8) + { + const char* lang = 0; + if(!lang || !*lang) + lang = getenv("LC_CTYPE"); + if(!lang || !*lang) + lang = getenv("LC_ALL"); + if(!lang || !*lang) + lang = getenv("LANG"); +#ifndef BOOST_LOCALE_USE_WIN32_API + (void)use_utf8; // not relevant for non-windows + if(!lang || !*lang) + lang = "C"; + return lang; +#else + if(lang && *lang) { + return lang; + } + char buf[10]; + if(GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME, buf, sizeof(buf)) == 0) + return "C"; + std::string lc_name = buf; + if(GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SISO3166CTRYNAME, buf, sizeof(buf)) != 0) { + lc_name += "_"; + lc_name += buf; + } + if(!use_utf8) { + if(GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTANSICODEPAGE, buf, sizeof(buf)) != 0) { + if(atoi(buf) == 0) lc_name += ".UTF-8"; + else { + lc_name += ".windows-"; + lc_name += buf; } - return lc_name; - - #endif + } else { + lc_name += "UTF-8"; } - } // impl - } // locale -} // boost - + } else { + lc_name += ".UTF-8"; + } + return lc_name; +#endif + } +}}} // namespace boost::locale::util 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 d39e747978..882366b838 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/util/gregorian.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/util/gregorian.cpp @@ -6,10 +6,11 @@ #define BOOST_LOCALE_SOURCE #include "boost/locale/util/gregorian.hpp" -#include <boost/locale/date_time_facet.hpp> #include <boost/locale/date_time.hpp> +#include <boost/locale/date_time_facet.hpp> #include <boost/locale/hold_ptr.hpp> #include "boost/locale/util/timezone.hpp" +#include <boost/assert.hpp> #include <algorithm> #include <cstdlib> #include <ctime> @@ -19,13 +20,7 @@ #include <memory> #include <string> -#ifdef BOOST_MSVC -# pragma warning(disable : 4996) -#endif - -namespace boost { -namespace locale { -namespace util { +namespace boost { namespace locale { namespace util { namespace { int is_leap(int year) @@ -39,763 +34,647 @@ namespace util { return 0; } - int days_in_month(int year,int month) + int days_in_month(int year, int month) { - static const int tbl[2][12] = { - { 31,28,31,30,31,30,31,31,30,31,30,31 }, - { 31,29,31,30,31,30,31,31,30,31,30,31 } - }; + constexpr int tbl[2][12] = {{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, + {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}}; return tbl[is_leap(year)][month - 1]; } - inline int days_from_0(int year) + constexpr int days_from_0_impl(int year_m1) { - year--; - return 365 * year + (year / 400) - (year/100) + (year / 4); + return 365 * year_m1 + (year_m1 / 400) - (year_m1 / 100) + (year_m1 / 4); + } + constexpr int days_from_0(int year) + { + return days_from_0_impl(year - 1); } - int days_from_1970(int year) + constexpr int days_from_0_to_1970 = days_from_0(1970); + constexpr int days_from_1970(int year) { - static const int days_from_0_to_1970 = days_from_0(1970); return days_from_0(year) - days_from_0_to_1970; } - int days_from_1jan(int year,int month,int day) + int days_from_1jan(int year, int month, int day) { - static const int days[2][12] = { - { 0,31,59,90,120,151,181,212,243,273,304,334 }, - { 0,31,60,91,121,152,182,213,244,274,305,335 } - }; - return days[is_leap(year)][month-1] + day - 1; + constexpr int days[2][12] = {{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}, + {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335}}; + return days[is_leap(year)][month - 1] + day - 1; } - std::time_t internal_timegm(std::tm const *t) + std::time_t internal_timegm(const std::tm* t) { int year = t->tm_year + 1900; int month = t->tm_mon; if(month > 11) { - year += month/12; + year += month / 12; month %= 12; - } - else if(month < 0) { - int years_diff = (-month + 11)/12; + } else if(month < 0) { + int years_diff = (-month + 11) / 12; year -= years_diff; - month+=12 * years_diff; + month += 12 * years_diff; } month++; int day = t->tm_mday; - int day_of_year = days_from_1jan(year,month,day); + int day_of_year = days_from_1jan(year, month, day); int days_since_epoch = days_from_1970(year) + day_of_year; std::time_t seconds_in_day = 3600 * 24; - std::time_t result = seconds_in_day * days_since_epoch + 3600 * t->tm_hour + 60 * t->tm_min + t->tm_sec; + std::time_t result = seconds_in_day * days_since_epoch + 3600 * t->tm_hour + 60 * t->tm_min + t->tm_sec; return result; } - } // anon - - - + } // namespace namespace { // Locale dependent data - bool comparator(char const *left,char const *right) + bool comparator(const char* left, const char* right) { - return strcmp(left,right) < 0; + return strcmp(left, right) < 0; } - // // Ref: CLDR 1.9 common/supplemental/supplementalData.xml // // monday - default // fri - MV // sat - AE AF BH DJ DZ EG ER ET IQ IR JO KE KW LY MA OM QA SA SD SO SY TN YE - // sun - AR AS AZ BW CA CN FO GE GL GU HK IL IN JM JP KG KR LA MH MN MO MP MT NZ PH PK SG TH TT TW UM US UZ VI ZW - // + // sun - AR AS AZ BW CA CN FO GE GL GU HK IL IN JM JP KG KR LA MH MN MO MP MT NZ PH PK SG TH TT TW UM US UZ VI + // ZW - int first_day_of_week(char const *terr) { - static char const * const sat[] = { - "AE","AF","BH","DJ","DZ","EG","ER","ET","IQ","IR", - "JO","KE","KW","LY","MA","OM","QA","SA","SD","SO", - "SY","TN","YE" - }; - static char const * const sunday[] = { - "AR","AS","AZ","BW","CA","CN","FO","GE","GL","GU", - "HK","IL","IN","JM","JP","KG","KR","LA","MH","MN", - "MO","MP","MT","NZ","PH","PK","SG","TH","TT","TW", - "UM","US","UZ","VI","ZW" - }; - if(strcmp(terr,"MV") == 0) + int first_day_of_week(const char* terr) + { + constexpr const char* sat[] = {"AE", "AF", "BH", "DJ", "DZ", "EG", "ER", "ET", "IQ", "IR", "JO", "KE", + "KW", "LY", "MA", "OM", "QA", "SA", "SD", "SO", "SY", "TN", "YE"}; + constexpr const char* sunday[] = {"AR", "AS", "AZ", "BW", "CA", "CN", "FO", "GE", "GL", "GU", "HK", "IL", + "IN", "JM", "JP", "KG", "KR", "LA", "MH", "MN", "MO", "MP", "MT", "NZ", + "PH", "PK", "SG", "TH", "TT", "TW", "UM", "US", "UZ", "VI", "ZW"}; + if(strcmp(terr, "MV") == 0) return 5; // fri - if(std::binary_search<char const * const *>(sat,sat+sizeof(sat)/(sizeof(sat[0])),terr,comparator)) + if(std::binary_search<const char* const*>(sat, sat + sizeof(sat) / (sizeof(sat[0])), terr, comparator)) return 6; // sat - if(std::binary_search<char const * const *>(sunday,sunday+sizeof(sunday)/(sizeof(sunday[0])),terr,comparator)) + if(std::binary_search<const char* const*>(sunday, + sunday + sizeof(sunday) / (sizeof(sunday[0])), + terr, + comparator)) return 0; // sun // default return 1; // mon } - } + } // namespace class gregorian_calendar : public abstract_calendar { public: + gregorian_calendar(const std::string& terr) + { + first_day_of_week_ = first_day_of_week(terr.c_str()); + time_ = std::time(0); + is_local_ = true; + tzoff_ = 0; + from_time(time_); + } - gregorian_calendar(std::string const &terr) - { - first_day_of_week_ = first_day_of_week(terr.c_str()); - time_ = std::time(0); - is_local_ = true; - tzoff_ = 0; - from_time(time_); - } - - /// - /// Make a polymorphic copy of the calendar - /// - gregorian_calendar *clone() const BOOST_OVERRIDE - { - return new gregorian_calendar(*this); - } + /// Make a polymorphic copy of the calendar + gregorian_calendar* clone() const override { return new gregorian_calendar(*this); } - /// - /// Set specific \a value for period \a p, note not all values are settable. - /// - void set_value(period::marks::period_mark m,int value) BOOST_OVERRIDE - { - using namespace period::marks; - switch(m) { - case era: ///< Era i.e. AC, BC in Gregorian and Julian calendar, range [0,1] + /// Set specific \a value for period \a p, note not all values are settable. + void set_value(period::marks::period_mark m, int value) override + { + using namespace period::marks; + switch(m) { + case era: ///< Era i.e. AC, BC in Gregorian and Julian calendar, range [0,1] return; - case year: ///< Year, it is calendar specific - case extended_year: ///< Extended year for Gregorian/Julian calendars, where 1 BC == 0, 2 BC == -1. + 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 = value - 1900; break; - case month: - tm_updated_.tm_mon = value; - break; - case day: - tm_updated_.tm_mday = value; - break; - case hour: ///< 24 clock hour [0..23] + case month: tm_updated_.tm_mon = value; break; + case day: tm_updated_.tm_mday = value; break; + case hour: ///< 24 clock hour [0..23] tm_updated_.tm_hour = value; break; - case hour_12: ///< 12 clock hour [0..11] + case hour_12: ///< 12 clock hour [0..11] tm_updated_.tm_hour = tm_updated_.tm_hour / 12 * 12 + value; break; - case am_pm: ///< am or pm marker, [0..1] + case am_pm: ///< am or pm marker, [0..1] tm_updated_.tm_hour = 12 * value + tm_updated_.tm_hour % 12; break; - case minute: ///< minute [0..59] + case minute: ///< minute [0..59] tm_updated_.tm_min = value; break; - case second: - tm_updated_.tm_sec = value; - break; + case second: tm_updated_.tm_sec = value; break; case day_of_year: normalize(); tm_updated_.tm_mday += (value - (tm_updated_.tm_yday + 1)); break; - case day_of_week: ///< Day of week, starting from Sunday, [1..7] + case day_of_week: ///< Day of week, starting from Sunday, [1..7] if(value < 1) // make sure it is positive value += (-value / 7) * 7 + 7; // convert to local DOW value = (value - 1 - first_day_of_week_ + 14) % 7 + 1; BOOST_FALLTHROUGH; - case day_of_week_local: ///< Local day of week, for example in France Monday is 1, in US Sunday is 1, [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] normalize(); tm_updated_.tm_mday += (value - 1) - (tm_updated_.tm_wday - first_day_of_week_ + 7) % 7; break; - case day_of_week_in_month: ///< Original number of the day of the week in month. (1st sunday, 2nd sunday etc) - case week_of_year: ///< The week number in the year, 4 is the minimal number of days to be in month - case week_of_month: ///< The week number withing current month - { - normalize(); - int current_week = get_value(m,current); - 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 - default: - return; - } - normalized_ = false; + case day_of_week_in_month: ///< Original number of the day of the week in month. (1st sunday, 2nd sunday + ///< etc) + case week_of_year: ///< The week number in the year, 4 is the minimal number of days to be in month + case week_of_month: ///< The week number within current month + { + normalize(); + int current_week = get_value(m, current); + 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; } + normalized_ = false; + } - void normalize() BOOST_OVERRIDE - { - if(!normalized_) { - std::tm val = tm_updated_; - val.tm_isdst = -1; - val.tm_wday = -1; // indicator of error - std::time_t point = -1; - if(is_local_) { - point = std::mktime(&val); - if(point == static_cast<std::time_t>(-1)){ - #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 - if(val.tm_wday == -1) - #endif - { - throw date_time_error("boost::locale::gregorian_calendar: invalid time"); - } + void normalize() override + { + if(!normalized_) { + std::tm val = tm_updated_; + val.tm_isdst = -1; + val.tm_wday = -1; // indicator of error + std::time_t point = -1; + if(is_local_) { + point = std::mktime(&val); + if(point == static_cast<std::time_t>(-1)) { +#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 + if(val.tm_wday == -1) +#endif + { + throw date_time_error("boost::locale::gregorian_calendar: invalid time"); } } - 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) - throw date_time_error("boost::locale::gregorian_calendar time is out of range"); - val = *revert_point; - #else - if(!gmtime_r(&point,&val)) - throw date_time_error("boost::locale::gregorian_calendar invalid time"); - #endif - - } - - time_ = point - tzoff_; - tm_ = val; - tm_updated_ = val; - normalized_ = true; + } 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) + throw date_time_error("boost::locale::gregorian_calendar time is out of range"); + val = *revert_point; +#else + if(!gmtime_r(&point, &val)) + throw date_time_error("boost::locale::gregorian_calendar invalid time"); +#endif } - } - - int get_week_number(int day,int wday) const - { - /// - /// This is the number of days that are considered withing - /// period such that the week belongs there - /// - static const int days_in_full_week = 4; + time_ = point - tzoff_; + tm_ = val; + tm_updated_ = val; + normalized_ = true; + } + } - // Alaways use local week start - int current_dow = (wday - first_day_of_week_ + 7) % 7; - // Calculate local week day of Jan 1st. - int first_week_day = (current_dow + 700 - day) % 7; - // adding something big devidable by 7 - - int start_of_period_in_weeks; - if(first_week_day < days_in_full_week) { - start_of_period_in_weeks = - first_week_day; - } - 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; - return week_number_in_days / 7 + 1; + int get_week_number(int day, int wday) const + { + /// This is the number of days that are considered within + /// period such that the week belongs there + constexpr int days_in_full_week = 4; + + // Always use local week start + int current_dow = (wday - first_day_of_week_ + 7) % 7; + // Calculate local week day of Jan 1st. + int first_week_day = (current_dow + 700 - day) % 7; + // adding something big dividable by 7 + + int start_of_period_in_weeks; + if(first_week_day < days_in_full_week) { + start_of_period_in_weeks = -first_week_day; + } 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; + return week_number_in_days / 7 + 1; + } - /// - /// Get specific value for period \a p according to a value_type \a v - /// - int get_value(period::marks::period_mark m,value_type v) const BOOST_OVERRIDE - { - using namespace period::marks; - switch(m) { - case era: - return 1; + /// Get specific value for period \a p according to a value_type \a v + int get_value(period::marks::period_mark m, value_type v) const override + { + using namespace period::marks; + switch(m) { + case era: return 1; case year: case extended_year: switch(v) { - case absolute_minimum: - case greatest_minimum: - case actual_minimum: - #ifdef BOOST_WINDOWS - return 1970; // Unix epoch windows can't handle negative time_t - #else - if(sizeof(std::time_t) == 4) - return 1901; // minimal year with 32 bit time_t - else - return 1; - #endif - case absolute_maximum: - case least_maximum: - case actual_maximum: -BOOST_LOCALE_START_CONST_CONDITION - if(sizeof(std::time_t) == 4) - return 2038; // Y2K38 - maximal with 32 bit time_t - else - return std::numeric_limits<int>::max(); -BOOST_LOCALE_END_CONST_CONDITION - case current: - return tm_.tm_year + 1900; + case absolute_minimum: + case greatest_minimum: + case actual_minimum: +#ifdef BOOST_WINDOWS + return 1970; // Unix epoch windows can't handle negative time_t +#else + if(sizeof(std::time_t) == 4) + return 1901; // minimal year with 32 bit time_t + else + return 1; +#endif + case absolute_maximum: + case least_maximum: + case actual_maximum: + BOOST_LOCALE_START_CONST_CONDITION + if(sizeof(std::time_t) == 4) + return 2038; // Y2K38 - maximal with 32 bit time_t + else + return std::numeric_limits<int>::max() + / 365; // Reasonably large but we can still get the days without overflowing + BOOST_LOCALE_END_CONST_CONDITION + case current: return tm_.tm_year + 1900; }; break; case month: switch(v) { - case absolute_minimum: - case greatest_minimum: - case actual_minimum: - return 0; - case absolute_maximum: - case least_maximum: - case actual_maximum: - return 11; - case current: - return tm_.tm_mon; + case absolute_minimum: + case greatest_minimum: + case actual_minimum: return 0; + case absolute_maximum: + case least_maximum: + case actual_maximum: return 11; + case current: return tm_.tm_mon; }; break; case day: switch(v) { - case absolute_minimum: - case greatest_minimum: - case actual_minimum: - return 1; - case absolute_maximum: - return 31; - case least_maximum: - return 28; - case actual_maximum: - return days_in_month(tm_.tm_year + 1900,tm_.tm_mon + 1); - case current: - return tm_.tm_mday; + case absolute_minimum: + case greatest_minimum: + case actual_minimum: return 1; + case absolute_maximum: return 31; + case least_maximum: return 28; + case actual_maximum: return days_in_month(tm_.tm_year + 1900, tm_.tm_mon + 1); + case current: return tm_.tm_mday; }; break; - case day_of_year: ///< The number of day in year, starting from 1 + case day_of_year: ///< The number of day in year, starting from 1 switch(v) { - case absolute_minimum: - case greatest_minimum: - case actual_minimum: - return 1; - case absolute_maximum: - return 366; - case least_maximum: - return 365; - case actual_maximum: - return is_leap(tm_.tm_year + 1900) ? 366 : 365; - case current: - return tm_.tm_yday + 1; + case absolute_minimum: + case greatest_minimum: + case actual_minimum: return 1; + case absolute_maximum: return 366; + case least_maximum: return 365; + case actual_maximum: return is_leap(tm_.tm_year + 1900) ? 366 : 365; + case current: return tm_.tm_yday + 1; } break; - case day_of_week: ///< Day of week, starting from Sunday, [1..7] + case day_of_week: ///< Day of week, starting from Sunday, [1..7] switch(v) { - case absolute_minimum: - case greatest_minimum: - case actual_minimum: - return 1; - case absolute_maximum: - case least_maximum: - case actual_maximum: - return 7; - case current: - return tm_.tm_wday + 1; + case absolute_minimum: + case greatest_minimum: + case actual_minimum: return 1; + case absolute_maximum: + case least_maximum: + case actual_maximum: return 7; + case current: return tm_.tm_wday + 1; } break; - case day_of_week_local: ///< Local day of week, for example in France Monday is 1, in US Sunday is 1, [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] switch(v) { - case absolute_minimum: - case greatest_minimum: - case actual_minimum: - return 1; - case absolute_maximum: - case least_maximum: - case actual_maximum: - return 7; - case current: - return (tm_.tm_wday - first_day_of_week_ + 7) % 7 + 1; + case absolute_minimum: + case greatest_minimum: + case actual_minimum: return 1; + case absolute_maximum: + case least_maximum: + 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] + case hour: ///< 24 clock hour [0..23] switch(v) { - case absolute_minimum: - case greatest_minimum: - case actual_minimum: - return 0; - case absolute_maximum: - case least_maximum: - case actual_maximum: - return 23; - case current: - return tm_.tm_hour; + case absolute_minimum: + case greatest_minimum: + case actual_minimum: return 0; + case absolute_maximum: + case least_maximum: + case actual_maximum: return 23; + case current: return tm_.tm_hour; } break; - case hour_12: ///< 12 clock hour [0..11] + case hour_12: ///< 12 clock hour [0..11] switch(v) { - case absolute_minimum: - case greatest_minimum: - case actual_minimum: - return 0; - case absolute_maximum: - case least_maximum: - case actual_maximum: - return 11; - case current: - return tm_.tm_hour % 12; + case absolute_minimum: + case greatest_minimum: + case actual_minimum: return 0; + case absolute_maximum: + case least_maximum: + case actual_maximum: return 11; + case current: return tm_.tm_hour % 12; } break; - case am_pm: ///< am or pm marker, [0..1] + case am_pm: ///< am or pm marker, [0..1] switch(v) { - case absolute_minimum: - case greatest_minimum: - case actual_minimum: - return 0; - case absolute_maximum: - case least_maximum: - case actual_maximum: - return 1; - case current: - return tm_.tm_hour >= 12 ? 1 : 0; + case absolute_minimum: + case greatest_minimum: + case actual_minimum: return 0; + case absolute_maximum: + case least_maximum: + case actual_maximum: return 1; + case current: return tm_.tm_hour >= 12 ? 1 : 0; } break; - case minute: ///< minute [0..59] + case minute: ///< minute [0..59] switch(v) { - case absolute_minimum: - case greatest_minimum: - case actual_minimum: - return 0; - case absolute_maximum: - case least_maximum: - case actual_maximum: - return 59; - case current: - return tm_.tm_min; + case absolute_minimum: + case greatest_minimum: + case actual_minimum: return 0; + case absolute_maximum: + case least_maximum: + case actual_maximum: return 59; + case current: return tm_.tm_min; } break; - case second: ///< second [0..59] + case second: ///< second [0..59] switch(v) { - case absolute_minimum: - case greatest_minimum: - case actual_minimum: - return 0; - case absolute_maximum: - case least_maximum: - case actual_maximum: - return 59; - case current: - return tm_.tm_sec; + case absolute_minimum: + case greatest_minimum: + case actual_minimum: return 0; + case absolute_maximum: + case least_maximum: + case actual_maximum: return 59; + case current: return tm_.tm_sec; } break; - case period::marks::first_day_of_week: ///< For example Sunday in US, Monday in France + case period::marks::first_day_of_week: ///< For example Sunday in US, Monday in France return first_day_of_week_ + 1; - case week_of_year: ///< The week number in the year + case week_of_year: ///< The week number in the year switch(v) { - case absolute_minimum: - case greatest_minimum: - case actual_minimum: - return 1; - case absolute_maximum: - return 53; - case least_maximum: - return 52; - case actual_maximum: - { + case absolute_minimum: + case greatest_minimum: + case actual_minimum: return 1; + case absolute_maximum: return 53; + case least_maximum: return 52; + case actual_maximum: { int year = tm_.tm_year + 1900; int end_of_year_days = (is_leap(year) ? 366 : 365) - 1; int dow_of_end_of_year = (end_of_year_days - tm_.tm_yday + tm_.tm_wday) % 7; - return get_week_number(end_of_year_days,dow_of_end_of_year); + 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); + case current: { + int val = get_week_number(tm_.tm_yday, tm_.tm_wday); if(val < 0) return 53; return val; } } break; - case week_of_month: ///< The week number withing current month + case week_of_month: ///< The week number within current month switch(v) { - case absolute_minimum: - case greatest_minimum: - case actual_minimum: - return 1; - case absolute_maximum: - return 5; - case least_maximum: - return 4; - case actual_maximum: - { - int end_of_month_days = days_in_month(tm_.tm_year + 1900,tm_.tm_mon + 1); + case absolute_minimum: + case greatest_minimum: + case actual_minimum: return 1; + case absolute_maximum: return 5; + case least_maximum: return 4; + case actual_maximum: { + int end_of_month_days = days_in_month(tm_.tm_year + 1900, tm_.tm_mon + 1); int dow_of_end_of_month = (end_of_month_days - tm_.tm_mday + tm_.tm_wday) % 7; - return get_week_number(end_of_month_days,dow_of_end_of_month); + 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); + case current: { + int val = get_week_number(tm_.tm_mday, tm_.tm_wday); if(val < 0) return 5; return val; } } break; - case day_of_week_in_month: ///< Original number of the day of the week in month. + case day_of_week_in_month: ///< Original number of the day of the week in month. switch(v) { - case absolute_minimum: - case greatest_minimum: - case actual_minimum: - return 1; - case absolute_maximum: - return 5; - case least_maximum: - return 4; - case actual_maximum: - if(tm_.tm_mon == 1 && !is_leap(tm_.tm_year + 1900)) { - // only in february in non leap year is 28 days, the rest - // conver more then 4 weeks - return 4; - } - return 5; - case current: - return (tm_.tm_mday - 1) / 7 + 1; - default: - ; + case absolute_minimum: + case greatest_minimum: + case actual_minimum: return 1; + case absolute_maximum: return 5; + case least_maximum: return 4; + case actual_maximum: + if(tm_.tm_mon == 1 && !is_leap(tm_.tm_year + 1900)) { + // only february in non leap year is 28 days, the rest + // has more then 4 weeks + return 4; + } + return 5; + case current: return (tm_.tm_mday - 1) / 7 + 1; } - default: - ; - } - return 0; - + break; + case invalid: BOOST_ASSERT_MSG(false, "Shouldn't use 'invalid' value."); break; } + return 0; + } - /// - /// Set current time point - /// - void set_time(posix_time const &p) BOOST_OVERRIDE - { - from_time(static_cast<std::time_t>(p.seconds)); - } - posix_time get_time() const BOOST_OVERRIDE - { - posix_time pt = { time_, 0}; - return pt; - } + /// Set current time point + void set_time(const posix_time& p) override + { + from_time(static_cast<std::time_t>(p.seconds)); + } + posix_time get_time() const override + { + posix_time pt = {time_, 0}; + return pt; + } + double get_time_ms() const override + { + return time_ * 1e3; + } - /// - /// Set option for calendar, for future use - /// - void set_option(calendar_option_type opt,int /*v*/) BOOST_OVERRIDE - { - switch(opt) { - 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"); - default: - ; - } + /// Set option for calendar, for future use + void set_option(calendar_option_type opt, int /*v*/) override + { + switch(opt) { + 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"); } - /// - /// Get option for calendar, currently only check if it is Gregorian calendar - /// - int get_option(calendar_option_type opt) const BOOST_OVERRIDE - { - switch(opt) { - case is_gregorian: - return 1; - case is_dst: - return tm_.tm_isdst == 1; - default: - return 0; - }; + } + /// Get option for calendar, currently only check if it is Gregorian calendar + int get_option(calendar_option_type opt) const override + { + switch(opt) { + case is_gregorian: return 1; + case is_dst: return tm_.tm_isdst == 1; } + return 0; + } - /// - /// 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) BOOST_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; + /// 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; + 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] + 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] + case am_pm: ///< am or pm marker, [0..1] tm_updated_.tm_hour += 12 * difference; break; - case minute: ///< minute [0..59] + case minute: ///< minute [0..59] tm_updated_.tm_min += difference; break; - case second: - tm_updated_.tm_sec += difference; + 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 week_of_year: ///< The week number in the year - case week_of_month: ///< The week number withing 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; - default: - ; // Not all values are adjustable - } - normalized_ = false; - normalize(); + case era: + case period::marks::first_day_of_week: + case invalid: break; // Not adjustable and ignored } - break; - case roll: - { // roll - int cur_min = get_value(m,actual_minimum); - int cur_max = get_value(m,actual_maximum); - int max_diff = cur_max - cur_min + 1; - if(max_diff > 0) { - int value = get_value(m,current); - int addon = 0; - if(difference < 0) - addon = ((-difference/max_diff) + 1) * max_diff; - value = (value - cur_min + difference + addon) % max_diff + cur_min; - set_value(m,value); - normalize(); - } - } - default: - ; + 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(); } } + } - int get_diff(period::marks::period_mark m,int diff,gregorian_calendar const *other) const - { - if(diff == 0) - return 0; - hold_ptr<gregorian_calendar> self(clone()); - self->adjust_value(m,move,diff); - if(diff > 0){ - if(self->time_ > other->time_) - return diff - 1; - else - return diff; - } - else { - if(self->time_ < other->time_) - return diff + 1; - else - return diff; - } - } - - /// - /// Calculate the difference between this calendar and \a other in \a p units - /// - int difference(abstract_calendar const *other_cal,period::marks::period_mark m) const BOOST_OVERRIDE - { - hold_ptr<gregorian_calendar> keeper; - gregorian_calendar const *other = dynamic_cast<gregorian_calendar const *>(other_cal); - if(!other) { - keeper.reset(clone()); - keeper->set_time(other_cal->get_time()); - other = keeper.get(); - } + int get_diff(period::marks::period_mark m, int diff, const gregorian_calendar* other) const + { + if(diff == 0) + return 0; + hold_ptr<gregorian_calendar> self(clone()); + self->adjust_value(m, move, diff); + if(diff > 0) { + if(self->time_ > other->time_) + return diff - 1; + else + return diff; + } else { + if(self->time_ < other->time_) + return diff + 1; + else + return diff; + } + } + + /// Calculate the difference between this calendar and \a other in \a p units + int difference(const abstract_calendar& other_cal, period::marks::period_mark m) const override + { + hold_ptr<gregorian_calendar> keeper; + const gregorian_calendar* other = dynamic_cast<const gregorian_calendar*>(&other_cal); + if(!other) { + keeper.reset(clone()); + keeper->set_time(other_cal.get_time()); + other = keeper.get(); + } - int factor = 1; // for weeks vs days handling + int factor = 1; // for weeks vs days handling - using namespace period::marks; - switch(m) { - case era: - return 0; + using namespace period::marks; + switch(m) { + case era: return 0; case year: - case extended_year: - { - int diff = other->tm_.tm_year - tm_.tm_year; - return get_diff(period::marks::year,diff,other); - } - case month: - { - int diff = 12 * (other->tm_.tm_year - tm_.tm_year) - + other->tm_.tm_mon - tm_.tm_mon; - return get_diff(period::marks::month,diff,other); - } + case extended_year: { + int diff = other->tm_.tm_year - tm_.tm_year; + return get_diff(period::marks::year, diff, other); + } + case month: { + int diff = 12 * (other->tm_.tm_year - tm_.tm_year) + other->tm_.tm_mon - tm_.tm_mon; + return get_diff(period::marks::month, diff, other); + } case day_of_week_in_month: case week_of_month: - case week_of_year: - factor = 7; - BOOST_FALLTHROUGH; + case week_of_year: factor = 7; BOOST_FALLTHROUGH; case day: case day_of_year: 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) { - 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 day_of_week_local: { + int diff = other->tm_.tm_yday - tm_.tm_yday; + if(other->tm_.tm_year != tm_.tm_year) { + diff += days_from_0(other->tm_.tm_year + 1900) - days_from_0(tm_.tm_year + 1900); } - case am_pm: - return static_cast<int>( (other->time_ - time_) / (3600*12) ); + return get_diff(period::marks::day, diff, other) / factor; + } + case am_pm: return static_cast<int>((other->time_ - time_) / (3600 * 12)); case hour: - 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_ ); - default: - return 0; - }; + 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 } + return 0; + } - /// - /// Set time zone, empty - use system - /// - void set_timezone(std::string const &tz) BOOST_OVERRIDE - { - if(tz.empty()) { - is_local_ = true; - tzoff_ = 0; - } - else { - is_local_ = false; - tzoff_ = parse_tz(tz); - } - from_time(time_); - time_zone_name_ = tz; - } - std::string get_timezone() const BOOST_OVERRIDE - { - return time_zone_name_; + /// Set time zone, empty - use system + void set_timezone(const std::string& tz) override + { + if(tz.empty()) { + is_local_ = true; + tzoff_ = 0; + } else { + is_local_ = false; + tzoff_ = parse_tz(tz); } + from_time(time_); + time_zone_name_ = tz; + } + std::string get_timezone() const override + { + return time_zone_name_; + } - bool same(abstract_calendar const *other) const BOOST_OVERRIDE - { - gregorian_calendar const *gcal = dynamic_cast<gregorian_calendar const *>(other); - if(!gcal) - return false; - return - gcal->tzoff_ == tzoff_ - && gcal->is_local_ == is_local_ - && gcal->first_day_of_week_ == first_day_of_week_; - } + bool same(const abstract_calendar* other) const override + { + const gregorian_calendar* gcal = dynamic_cast<const gregorian_calendar*>(other); + if(!gcal) + return false; + return gcal->tzoff_ == tzoff_ && gcal->is_local_ == is_local_ + && gcal->first_day_of_week_ == first_day_of_week_; + } private: - void from_time(std::time_t point) { std::time_t real_point = point + tzoff_; - std::tm *t = 0; - #ifdef BOOST_WINDOWS + std::tm* t = 0; +#ifdef BOOST_WINDOWS // Windows uses TLS, thread safe t = is_local_ ? localtime(&real_point) : gmtime(&real_point); - #else +#else std::tm tmp_tm; - t = is_local_ ? localtime_r(&real_point,&tmp_tm) : gmtime_r(&real_point,&tmp_tm); - #endif + t = is_local_ ? localtime_r(&real_point, &tmp_tm) : gmtime_r(&real_point, &tmp_tm); +#endif if(!t) { throw date_time_error("boost::locale::gregorian_calendar: invalid time point"); } @@ -812,37 +691,27 @@ BOOST_LOCALE_END_CONST_CONDITION bool is_local_; int tzoff_; std::string time_zone_name_; - }; - abstract_calendar *create_gregorian_calendar(std::string const &terr) + abstract_calendar* create_gregorian_calendar(const std::string& terr) { return new gregorian_calendar(terr); } class gregorian_facet : public calendar_facet { public: - gregorian_facet(std::string const &terr,size_t refs = 0) : - calendar_facet(refs), - terr_(terr) - { - } - abstract_calendar *create_calendar() const BOOST_OVERRIDE - { - return create_gregorian_calendar(terr_); - } + gregorian_facet(const std::string& terr, size_t refs = 0) : calendar_facet(refs), terr_(terr) {} + abstract_calendar* create_calendar() const override { return create_gregorian_calendar(terr_); } + private: std::string terr_; }; - std::locale install_gregorian_calendar(std::locale const &in,std::string const &terr) + std::locale install_gregorian_calendar(const std::locale& in, const std::string& terr) { - return std::locale(in,new gregorian_facet(terr)); + return std::locale(in, new gregorian_facet(terr)); } - -} // util -} // locale -} //boost +}}} // namespace boost::locale::util // boostinspect:nominmax diff --git a/contrib/restricted/boost/locale/src/boost/locale/util/gregorian.hpp b/contrib/restricted/boost/locale/src/boost/locale/util/gregorian.hpp index 263964126b..e3a3a46238 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/util/gregorian.hpp +++ b/contrib/restricted/boost/locale/src/boost/locale/util/gregorian.hpp @@ -9,15 +9,10 @@ #include <locale> -namespace boost { -namespace locale { -namespace util { +namespace boost { namespace locale { namespace util { - std::locale install_gregorian_calendar(std::locale const &in,std::string const &terr); - -} // util -} // locale -} //boost + std::locale install_gregorian_calendar(const std::locale& in, const std::string& terr); +}}} // namespace boost::locale::util #endif 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 8257de7059..cca703a3f3 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/util/iconv.hpp +++ b/contrib/restricted/boost/locale/src/boost/locale/util/iconv.hpp @@ -9,48 +9,55 @@ #include <iconv.h> -namespace boost { - namespace locale { +namespace boost { namespace locale { + extern "C" { #if defined(__ICONV_F_HIDE_INVALID) && defined(__FreeBSD__) - extern "C" { - typedef size_t (*const_iconv_ptr_type)(iconv_t d,char const **in,size_t *insize,char **out,size_t *outsize,uint32_t,size_t *); - typedef size_t (*nonconst_iconv_ptr_type)(iconv_t d,char **in,size_t *insize,char **out,size_t *outsize,uint32_t,size_t *); - } - inline size_t do_iconv(const_iconv_ptr_type ptr,iconv_t d,char **in,size_t *insize,char **out,size_t *outsize) - { - char const **rin = const_cast<char const **>(in); - return ptr(d,rin,insize,out,outsize,__ICONV_F_HIDE_INVALID,0); - } - inline size_t do_iconv(nonconst_iconv_ptr_type ptr,iconv_t d,char **in,size_t *insize,char **out,size_t *outsize) - { - return ptr(d,in,insize,out,outsize,__ICONV_F_HIDE_INVALID,0); - } - inline size_t call_iconv(iconv_t d,char **in,size_t *insize,char **out,size_t *outsize) - { - char const **rin = const_cast<char const **>(in); - return do_iconv(__iconv, d, in,insize,out,outsize); - } +# define BOOST_LOCALE_ICONV_FUNC __iconv +# define BOOST_LOCALE_ICONV_FLAGS , __ICONV_F_HIDE_INVALID, 0 + + // GNU variant + typedef size_t (*const_iconv_ptr_type)(iconv_t, const char**, size_t*, char**, size_t*, uint32_t, size_t*); + // POSIX variant + typedef size_t (*nonconst_iconv_ptr_type)(iconv_t, char**, size_t*, char**, size_t*, uint32_t, size_t*); #else - extern "C" { - typedef size_t (*gnu_iconv_ptr_type)(iconv_t d,char const **in,size_t *insize,char **out,size_t *outsize); - typedef size_t (*posix_iconv_ptr_type)(iconv_t d,char **in,size_t *insize,char **out,size_t *outsize); - } - inline size_t do_iconv(gnu_iconv_ptr_type ptr,iconv_t d,char **in,size_t *insize,char **out,size_t *outsize) - { - char const **rin = const_cast<char const **>(in); - return ptr(d,rin,insize,out,outsize); - } - inline size_t do_iconv(posix_iconv_ptr_type ptr,iconv_t d,char **in,size_t *insize,char **out,size_t *outsize) - { - return ptr(d,in,insize,out,outsize); - } - inline size_t call_iconv(iconv_t d,char **in,size_t *insize,char **out,size_t *outsize) - { - return do_iconv( iconv, d, in,insize,out,outsize); - } +# define BOOST_LOCALE_ICONV_FUNC iconv +# define BOOST_LOCALE_ICONV_FLAGS + + typedef size_t (*const_iconv_ptr_type)(iconv_t, const char**, size_t*, char**, size_t*); + typedef size_t (*nonconst_iconv_ptr_type)(iconv_t, char**, size_t*, char**, size_t*); #endif + } + + inline size_t + call_iconv_impl(const_iconv_ptr_type ptr, iconv_t d, const char** in, size_t* insize, char** out, size_t* outsize) + { + return ptr(d, in, insize, out, outsize BOOST_LOCALE_ICONV_FLAGS); + } + inline size_t call_iconv_impl(nonconst_iconv_ptr_type ptr, + iconv_t d, + const char** in, + size_t* insize, + char** out, + size_t* outsize) + { + return ptr(d, const_cast<char**>(in), insize, out, outsize BOOST_LOCALE_ICONV_FLAGS); + } + + inline size_t call_iconv(iconv_t d, const char** in, size_t* insize, char** out, size_t* outsize) + { + return call_iconv_impl(BOOST_LOCALE_ICONV_FUNC, d, in, insize, out, outsize); + } - } // locale -} // boost + // Convenience overload when the adjusted in/out ptrs are not required + inline size_t call_iconv(iconv_t d, const char* in, size_t* insize, char* out, size_t* outsize) + { + return call_iconv(d, &in, insize, &out, outsize); + } + // Disambiguation + inline size_t call_iconv(iconv_t d, std::nullptr_t, std::nullptr_t, std::nullptr_t, std::nullptr_t) + { + return call_iconv_impl(BOOST_LOCALE_ICONV_FUNC, d, nullptr, nullptr, nullptr, nullptr); + } +}} // namespace boost::locale #endif diff --git a/contrib/restricted/boost/locale/src/boost/locale/util/info.cpp b/contrib/restricted/boost/locale/src/boost/locale/util/info.cpp index 853df1095c..16b93e04ea 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/util/info.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/util/info.cpp @@ -16,59 +16,39 @@ #include "boost/locale/util/locale_data.hpp" -namespace boost { -namespace locale { -namespace util { +namespace boost { namespace locale { namespace util { class simple_info : public info { public: - simple_info(std::string const &name,size_t refs = 0) : - info(refs), - name_(name) - { - d.parse(name); - } - std::string get_string_property(string_propery v) const BOOST_OVERRIDE + simple_info(const std::string& name, size_t refs = 0) : info(refs), name_(name) { d.parse(name); } + std::string get_string_property(string_propery v) const override { switch(v) { - case language_property: - return d.language; - case country_property: - return d.country; - case variant_property: - return d.variant; - case encoding_property: - return d.encoding; - case name_property: - return name_; - default: - return ""; - }; + case language_property: return d.language; + case country_property: return d.country; + case variant_property: return d.variant; + case encoding_property: return d.encoding; + case name_property: return name_; + } + return ""; } - int get_integer_property(integer_property v) const BOOST_OVERRIDE + int get_integer_property(integer_property v) const override { switch(v) { - case utf8_property: - return d.utf8; - default: - return 0; + case utf8_property: return d.utf8; } + return 0; } + private: locale_data d; std::string name_; }; - std::locale create_info(std::locale const &in,std::string const &name) + std::locale create_info(const std::locale& in, const std::string& name) { - return std::locale(in,new simple_info(name)); + return std::locale(in, new simple_info(name)); } - -} // util -} // locale -} //boost - - - +}}} // namespace boost::locale::util 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 db9f507198..fced746aae 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 @@ -9,28 +9,26 @@ #include "boost/locale/encoding/conv.hpp" #include <string> -namespace boost { -namespace locale { -namespace util { - void locale_data::parse(std::string const &locale_name) +namespace boost { namespace locale { namespace util { + void locale_data::parse(const std::string& locale_name) { language = "C"; country.clear(); variant.clear(); encoding = "us-ascii"; - utf8=false; + utf8 = false; parse_from_lang(locale_name); } - void locale_data::parse_from_lang(std::string const &locale_name) + void locale_data::parse_from_lang(const std::string& locale_name) { size_t end = locale_name.find_first_of("-_@."); - std::string tmp = locale_name.substr(0,end); + std::string tmp = locale_name.substr(0, end); if(tmp.empty()) return; - for(unsigned i=0;i<tmp.size();i++) { - if('A' <= tmp[i] && tmp[i]<='Z') - tmp[i]=tmp[i]-'A'+'a'; + for(unsigned i = 0; i < tmp.size(); i++) { + if('A' <= tmp[i] && tmp[i] <= 'Z') + tmp[i] = tmp[i] - 'A' + 'a'; else if(tmp[i] < 'a' || 'z' < tmp[i]) return; } @@ -38,26 +36,24 @@ namespace util { if(end >= locale_name.size()) return; - if(locale_name[end] == '-' || locale_name[end]=='_') { - parse_from_country(locale_name.substr(end+1)); - } - else if(locale_name[end] == '.') { - parse_from_encoding(locale_name.substr(end+1)); - } - else if(locale_name[end] == '@') { - parse_from_variant(locale_name.substr(end+1)); + if(locale_name[end] == '-' || locale_name[end] == '_') { + parse_from_country(locale_name.substr(end + 1)); + } else if(locale_name[end] == '.') { + parse_from_encoding(locale_name.substr(end + 1)); + } else if(locale_name[end] == '@') { + parse_from_variant(locale_name.substr(end + 1)); } } - void locale_data::parse_from_country(std::string const &locale_name) + void locale_data::parse_from_country(const std::string& locale_name) { size_t end = locale_name.find_first_of("@."); - std::string tmp = locale_name.substr(0,end); + std::string tmp = locale_name.substr(0, end); if(tmp.empty()) return; - for(unsigned i=0;i<tmp.size();i++) { - if('a' <= tmp[i] && tmp[i]<='z') - tmp[i]=tmp[i]-'a'+'A'; + for(unsigned i = 0; i < tmp.size(); i++) { + if('a' <= tmp[i] && tmp[i] <= 'z') + tmp[i] = tmp[i] - 'a' + 'A'; else if(tmp[i] < 'A' || 'Z' < tmp[i]) return; } @@ -67,22 +63,21 @@ namespace util { if(end >= locale_name.size()) return; else if(locale_name[end] == '.') { - parse_from_encoding(locale_name.substr(end+1)); - } - else if(locale_name[end] == '@') { - parse_from_variant(locale_name.substr(end+1)); + parse_from_encoding(locale_name.substr(end + 1)); + } else if(locale_name[end] == '@') { + parse_from_variant(locale_name.substr(end + 1)); } } - void locale_data::parse_from_encoding(std::string const &locale_name) + void locale_data::parse_from_encoding(const std::string& locale_name) { size_t end = locale_name.find_first_of('@'); - std::string tmp = locale_name.substr(0,end); + std::string tmp = locale_name.substr(0, end); if(tmp.empty()) return; - for(unsigned i=0;i<tmp.size();i++) { - if('A' <= tmp[i] && tmp[i]<='Z') - tmp[i]=tmp[i]-'A'+'a'; + for(unsigned i = 0; i < tmp.size(); i++) { + if('A' <= tmp[i] && tmp[i] <= 'Z') + tmp[i] = tmp[i] - 'A' + 'a'; } encoding = tmp; @@ -92,20 +87,17 @@ namespace util { return; if(locale_name[end] == '@') { - parse_from_variant(locale_name.substr(end+1)); + parse_from_variant(locale_name.substr(end + 1)); } } - void locale_data::parse_from_variant(std::string const &locale_name) + void locale_data::parse_from_variant(const std::string& locale_name) { variant = locale_name; - for(unsigned i=0;i<variant.size();i++) { - if('A' <= variant[i] && variant[i]<='Z') - variant[i]=variant[i]-'A'+'a'; + for(unsigned i = 0; i < variant.size(); i++) { + if('A' <= variant[i] && variant[i] <= 'Z') + variant[i] = variant[i] - 'A' + 'a'; } } -} // util -} // locale -} // boost - +}}} // namespace boost::locale::util diff --git a/contrib/restricted/boost/locale/src/boost/locale/util/locale_data.hpp b/contrib/restricted/boost/locale/src/boost/locale/util/locale_data.hpp index fbd2000bfe..2190b62050 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/util/locale_data.hpp +++ b/contrib/restricted/boost/locale/src/boost/locale/util/locale_data.hpp @@ -9,37 +9,27 @@ #include <string> -namespace boost { - namespace locale { - namespace util { - - class locale_data { - public: - locale_data() : - language("C"), - encoding("us-ascii"), - utf8(false) - { - } - - std::string language; - std::string country; - std::string variant; - std::string encoding; - bool utf8; - - void parse(std::string const &locale_name); - - private: - - void parse_from_lang(std::string const &locale_name); - void parse_from_country(std::string const &locale_name); - void parse_from_encoding(std::string const &locale_name); - void parse_from_variant(std::string const &locale_name); - }; - - } // util - } // locale -} // boost +namespace boost { namespace locale { namespace util { + + class locale_data { + public: + locale_data() : language("C"), encoding("us-ascii"), utf8(false) {} + + std::string language; + std::string country; + std::string variant; + std::string encoding; + bool utf8; + + void parse(const std::string& locale_name); + + private: + void parse_from_lang(const std::string& locale_name); + void parse_from_country(const std::string& locale_name); + void parse_from_encoding(const std::string& locale_name); + void parse_from_variant(const std::string& locale_name); + }; + +}}} // namespace boost::locale::util #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 b42ddf3b98..5b4393d694 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/util/numeric.hpp +++ b/contrib/restricted/boost/locale/src/boost/locale/util/numeric.hpp @@ -6,386 +6,378 @@ #ifndef BOOST_LOCALE_IMPL_UTIL_NUMERIC_HPP #define BOOST_LOCALE_IMPL_UTIL_NUMERIC_HPP -#include <boost/locale/info.hpp> #include <boost/locale/formatting.hpp> +#include <boost/locale/info.hpp> #include <boost/predef/os.h> -#include <ctime> #include <cstdlib> +#include <ctime> #include <ios> #include <locale> -#include <string> #include <sstream> +#include <string> #include <vector> #include "boost/locale/util/timezone.hpp" -// This is internal header so disable crappy "unsecure functions" for all -#ifdef BOOST_MSVC -# pragma warning(disable : 4996) -#endif - -namespace boost { -namespace locale { -namespace util { - -template<typename CharType> -struct formatting_size_traits { - static size_t size(std::basic_string<CharType> const &s,std::locale const &/*l*/) - { - return s.size(); - } -}; - -template<> -struct formatting_size_traits<char> { - static size_t size(std::string const &s,std::locale const &l) - { - if(!std::has_facet<info>(l)) - return s.size(); - 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 ++; +namespace boost { namespace locale { namespace util { + + template<typename CharType> + struct formatting_size_traits { + static size_t size(const std::basic_string<CharType>& s, const std::locale& /*l*/) { return s.size(); } + }; + + template<> + struct formatting_size_traits<char> { + static size_t size(const std::string& s, const std::locale& l) + { + if(!std::has_facet<info>(l)) + return s.size(); + 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 res; - } -}; - - - -template<typename CharType> -class base_num_format : public std::num_put<CharType> -{ -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 BOOST_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 BOOST_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 BOOST_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 BOOST_OVERRIDE - { - return do_real_put(out,ios,fill,val); - } - - #ifndef BOOST_NO_LONG_LONG - iter_type do_put (iter_type out, std::ios_base &ios, char_type fill, long long val) const BOOST_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 BOOST_OVERRIDE - { - return do_real_put(out,ios,fill,val); - } - #endif - - -private: - - - - template<typename ValueType> - iter_type do_real_put (iter_type out, std::ios_base &ios, char_type fill, ValueType val) const - { - typedef std::num_put<char_type> super; - - ios_info &info=ios_info::get(ios); - - switch(info.display_flags()) { - case flags::posix: - { - typedef std::basic_ostringstream<char_type> sstream_type; - sstream_type ss; - ss.imbue(std::locale::classic()); - ss.flags(ios.flags()); - ss.precision(ios.precision()); - ss.width(ios.width()); - iter_type ret_ptr = super::do_put(out,ss,fill,val); - ios.width(0); - return ret_ptr; - } - case flags::date: - return format_time(out,ios,fill,static_cast<std::time_t>(val),'x'); - case flags::time: - return format_time(out,ios,fill,static_cast<std::time_t>(val),'X'); - case flags::datetime: - return format_time(out,ios,fill,static_cast<std::time_t>(val),'c'); - case flags::strftime: - return format_time(out,ios,fill,static_cast<std::time_t>(val),info.date_time_pattern<char_type>()); - case flags::currency: - { - bool nat = info.currency_flags()==flags::currency_default - || info.currency_flags() == flags::currency_national; - bool intl = !nat; - return do_format_currency(intl,out,ios,fill,static_cast<long double>(val)); - } + }; - case flags::number: - case flags::percent: - case flags::spellout: - case flags::ordinal: - default: - return super::do_put(out,ios,fill,val); + template<typename CharType> + class base_num_format : public std::num_put<CharType> { + 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 + { + 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 + { + return do_real_put(out, ios, fill, val); } - } - - virtual iter_type do_format_currency(bool intl,iter_type out,std::ios_base &ios,char_type fill,long double val) const - { - if(intl) - return format_currency<true>(out,ios,fill,val); - else - return format_currency<false>(out,ios,fill,val); - } - - template<bool intl> - iter_type format_currency(iter_type out,std::ios_base &ios,char_type fill,long double val) const - { - std::locale loc = ios.getloc(); - int digits = std::use_facet<std::moneypunct<char_type,intl> >(loc).frac_digits(); - while(digits > 0) { - val*=10; - digits --; + iter_type do_put(iter_type out, std::ios_base& ios, char_type fill, double val) const override + { + return do_real_put(out, ios, fill, val); } - 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); - 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 - { - string_type fmt; - fmt+=char_type('%'); - fmt+=char_type(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,string_type const &format) const - { - std::string tz = ios_info::get(ios).time_zone(); - std::tm tm; - #if BOOST_OS_LINUX || BOOST_OS_BSD_FREE || defined(__APPLE__) - std::vector<char> tmp_buf(tz.c_str(),tz.c_str()+tz.size()+1); - #endif - if(tz.empty()) { - #ifdef BOOST_WINDOWS - /// Windows uses TLS - tm = *localtime(&time); - #else - localtime_r(&time,&tm); - #endif + iter_type do_put(iter_type out, std::ios_base& ios, char_type fill, long double val) const override + { + return do_real_put(out, ios, fill, val); } - else { - int gmtoff = parse_tz(tz); - time+=gmtoff; - #ifdef BOOST_WINDOWS - /// Windows uses TLS - tm = *gmtime(&time); - #else - gmtime_r(&time,&tm); - #endif - - #if BOOST_OS_LINUX || BOOST_OS_BSD_FREE || defined(__APPLE__) - // 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_gmtoff = gmtoff; + + iter_type do_put(iter_type out, std::ios_base& ios, char_type 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 + { + 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 + { + typedef std::num_put<char_type> super; + + ios_info& info = ios_info::get(ios); + + switch(info.display_flags()) { + case flags::posix: { + typedef std::basic_ostringstream<char_type> sstream_type; + sstream_type ss; + ss.imbue(std::locale::classic()); + ss.flags(ios.flags()); + ss.precision(ios.precision()); + ss.width(ios.width()); + iter_type ret_ptr = super::do_put(out, ss, fill, val); + ios.width(0); + return ret_ptr; + } + case flags::date: return format_time(out, ios, fill, static_cast<std::time_t>(val), 'x'); + case flags::time: return format_time(out, ios, fill, static_cast<std::time_t>(val), 'X'); + case flags::datetime: return format_time(out, ios, fill, static_cast<std::time_t>(val), 'c'); + case flags::strftime: + return format_time(out, + ios, + fill, + static_cast<std::time_t>(val), + info.date_time_pattern<char_type>()); + case flags::currency: { + bool nat = info.currency_flags() == flags::currency_default + || info.currency_flags() == flags::currency_national; + bool intl = !nat; + return do_format_currency(intl, out, ios, fill, static_cast<long double>(val)); + } + + case flags::number: + case flags::percent: + case flags::spellout: + case flags::ordinal: break; } - #endif + return super::do_put(out, ios, fill, val); } - std::basic_ostringstream<char_type> tmp_out; - std::use_facet<std::time_put<char_type> >(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()); - if(points < ios.width()) { - std::streamsize n = ios.width() - points; - - std::ios_base::fmtflags flags = ios.flags() & std::ios_base::adjustfield; - - // - // we do not really know internal point, so we assume that it does not - // exist. so according to the standard field should be right aligned - // - if(flags != std::ios_base::left) - on_left = n; - on_right = n - on_left; + + virtual iter_type + do_format_currency(bool intl, iter_type out, std::ios_base& ios, char_type fill, long double val) const + { + if(intl) + return format_currency<true>(out, ios, fill, val); + else + return format_currency<false>(out, ios, fill, val); } - while(on_left > 0) { - *out++ = fill; - on_left--; + + template<bool intl> + iter_type format_currency(iter_type out, std::ios_base& ios, char_type fill, long double val) const + { + std::locale loc = ios.getloc(); + int digits = std::use_facet<std::moneypunct<char_type, 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); + ios.flags(f); + return out; } - std::copy(str.begin(),str.end(),out); - while(on_right > 0) { - *out++ = fill; - on_right--; + + iter_type format_time(iter_type out, std::ios_base& ios, char_type fill, std::time_t time, char c) const + { + string_type fmt; + fmt += char_type('%'); + fmt += char_type(c); + return format_time(out, ios, fill, time, fmt); } - ios.width(0); - return out; - } - -}; /// num_format - - -template<typename CharType> -class base_num_parse : public std::num_get<CharType> -{ -public: - base_num_parse(size_t refs = 0) : - std::num_get<CharType>(refs) - { - } -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 BOOST_OVERRIDE - { - return do_real_get(in,end,ios,err,val); - } - - iter_type do_get(iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,unsigned short &val) const BOOST_OVERRIDE - { - return do_real_get(in,end,ios,err,val); - } - - iter_type do_get(iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,unsigned int &val) const BOOST_OVERRIDE - { - return do_real_get(in,end,ios,err,val); - } - - iter_type do_get(iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,unsigned long &val) const BOOST_OVERRIDE - { - return do_real_get(in,end,ios,err,val); - } - - iter_type do_get(iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,float &val) const BOOST_OVERRIDE - { - return do_real_get(in,end,ios,err,val); - } - - iter_type do_get(iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,double &val) const BOOST_OVERRIDE - { - return do_real_get(in,end,ios,err,val); - } - - iter_type do_get (iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,long double &val) const BOOST_OVERRIDE - { - return do_real_get(in,end,ios,err,val); - } - - #ifndef BOOST_NO_LONG_LONG - iter_type do_get (iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,long long &val) const BOOST_OVERRIDE - { - return do_real_get(in,end,ios,err,val); - } - - iter_type do_get (iter_type in, iter_type end, std::ios_base &ios,std::ios_base::iostate &err,unsigned long long &val) const BOOST_OVERRIDE - { - return do_real_get(in,end,ios,err,val); - } - - #endif - -private: - - template<typename ValueType> - 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; - - ios_info &info=ios_info::get(ios); - - switch(info.display_flags()) { - case flags::posix: - { - std::stringstream ss; - ss.imbue(std::locale::classic()); - ss.flags(ios.flags()); - ss.precision(ios.precision()); - return super::do_get(in,end,ss,err,val); + + iter_type format_time(iter_type out, + std::ios_base& ios, + char_type fill, + std::time_t time, + const string_type& format) const + { + std::string tz = ios_info::get(ios).time_zone(); + std::tm tm; +#if BOOST_OS_LINUX || BOOST_OS_BSD_FREE || defined(__APPLE__) + std::vector<char> tmp_buf(tz.c_str(), tz.c_str() + tz.size() + 1); +#endif + if(tz.empty()) { +#ifdef BOOST_WINDOWS + /// Windows uses TLS + tm = *localtime(&time); +#else + localtime_r(&time, &tm); +#endif + } else { + int gmtoff = parse_tz(tz); + time += gmtoff; +#ifdef BOOST_WINDOWS + /// Windows uses TLS + tm = *gmtime(&time); +#else + gmtime_r(&time, &tm); +#endif + +#if BOOST_OS_LINUX || BOOST_OS_BSD_FREE || defined(__APPLE__) + // 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_gmtoff = gmtoff; + } +#endif + } + std::basic_ostringstream<char_type> tmp_out; + std::use_facet<std::time_put<char_type>>(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()); + if(points < ios.width()) { + std::streamsize n = ios.width() - points; + + std::ios_base::fmtflags flags = ios.flags() & std::ios_base::adjustfield; + + // we do not really know internal point, so we assume that it does not + // exist. so according to the standard field should be right aligned + if(flags != std::ios_base::left) + on_left = n; + on_right = n - on_left; + } + while(on_left > 0) { + *out++ = fill; + on_left--; } - case flags::currency: - { - long double ret_val = 0; - if(info.currency_flags()==flags::currency_default || info.currency_flags() == flags::currency_national) - in = parse_currency<false>(in,end,ios,err,ret_val); - else - in = parse_currency<true>(in,end,ios,err,ret_val); - if(!(err & std::ios_base::failbit)) - val = static_cast<ValueType>(ret_val); - return in; + std::copy(str.begin(), str.end(), out); + while(on_right > 0) { + *out++ = fill; + on_right--; } + ios.width(0); + return out; + } + + }; /// num_format + + template<typename CharType> + class base_num_parse : public std::num_get<CharType> { + public: + base_num_parse(size_t refs = 0) : std::num_get<CharType>(refs) {} - // date-time parsing is not supported - // due to buggy standard - case flags::date: - case flags::time: - case flags::datetime: - case flags::strftime: - - case flags::number: - case flags::percent: - case flags::spellout: - case flags::ordinal: - default: - return super::do_get(in,end,ios,err,val); + 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 + { + return do_real_get(in, end, ios, err, val); } - } - - template<bool intl> - iter_type parse_currency(iter_type in,iter_type end,std::ios_base &ios,std::ios_base::iostate &err,long double &val) const - { - std::locale loc = ios.getloc(); - int digits = std::use_facet<std::moneypunct<char_type,intl> >(loc).frac_digits(); - long double rval; - in = std::use_facet<std::money_get<char_type> >(loc).get(in,end,intl,ios,err,rval); - if(!(err & std::ios::failbit)) { - while(digits > 0) { - rval/=10; - digits --; - } - val = rval; + + iter_type do_get(iter_type in, + iter_type end, + std::ios_base& ios, + std::ios_base::iostate& err, + unsigned short& val) const override + { + return do_real_get(in, end, ios, err, val); + } + + iter_type do_get(iter_type in, + iter_type end, + std::ios_base& ios, + std::ios_base::iostate& err, + unsigned int& val) const override + { + return do_real_get(in, end, ios, err, val); } - return in; - } + iter_type do_get(iter_type in, + iter_type end, + std::ios_base& ios, + std::ios_base::iostate& err, + unsigned long& val) const override + { + return do_real_get(in, end, ios, err, val); + } -}; + iter_type + do_get(iter_type in, iter_type end, std::ios_base& ios, std::ios_base::iostate& err, float& val) const override + { + return do_real_get(in, end, ios, err, val); + } -} // util -} // locale -} //boost + iter_type + do_get(iter_type in, iter_type end, std::ios_base& ios, std::ios_base::iostate& err, double& val) const override + { + return do_real_get(in, end, ios, err, val); + } + iter_type do_get(iter_type in, + iter_type end, + std::ios_base& ios, + std::ios_base::iostate& err, + long double& val) const override + { + return do_real_get(in, end, ios, err, val); + } + iter_type do_get(iter_type in, + iter_type end, + std::ios_base& ios, + std::ios_base::iostate& err, + long long& val) const override + { + return do_real_get(in, end, ios, err, val); + } + + iter_type do_get(iter_type in, + iter_type end, + std::ios_base& ios, + std::ios_base::iostate& err, + unsigned long long& val) const override + { + return do_real_get(in, end, ios, err, val); + } + + private: + template<typename ValueType> + 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; + + ios_info& info = ios_info::get(ios); + + switch(info.display_flags()) { + case flags::posix: { + std::stringstream ss; + ss.imbue(std::locale::classic()); + ss.flags(ios.flags()); + ss.precision(ios.precision()); + return super::do_get(in, end, ss, err, val); + } + case flags::currency: { + long double ret_val = 0; + if(info.currency_flags() == flags::currency_default + || info.currency_flags() == flags::currency_national) + in = parse_currency<false>(in, end, ios, err, ret_val); + else + in = parse_currency<true>(in, end, ios, err, ret_val); + if(!(err & std::ios_base::failbit)) + val = static_cast<ValueType>(ret_val); + return in; + } + + // date-time parsing is not supported + // due to buggy standard + case flags::date: + case flags::time: + case flags::datetime: + case flags::strftime: + + case flags::number: + case flags::percent: + case flags::spellout: + case flags::ordinal: break; + } + return super::do_get(in, end, ios, err, val); + } + + template<bool intl> + iter_type parse_currency(iter_type in, + iter_type end, + std::ios_base& ios, + std::ios_base::iostate& err, + long double& val) const + { + std::locale loc = ios.getloc(); + int digits = std::use_facet<std::moneypunct<char_type, intl>>(loc).frac_digits(); + long double rval; + in = std::use_facet<std::money_get<char_type>>(loc).get(in, end, intl, ios, err, rval); + if(!(err & std::ios::failbit)) { + while(digits > 0) { + rval /= 10; + digits--; + } + val = rval; + } + return in; + } + }; +}}} // namespace boost::locale::util #endif 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 506946b34c..684379d87b 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/util/timezone.hpp +++ b/contrib/restricted/boost/locale/src/boost/locale/util/timezone.hpp @@ -10,43 +10,38 @@ #include <cstring> #include <string> -namespace boost { -namespace locale { -namespace util { - inline int parse_tz(std::string const &tz) +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++) { + for(unsigned i = 0; i < tz.size(); i++) { if('a' <= tz[i] && tz[i] <= 'z') - ltz += tz[i]-'a' + 'A'; - else if(tz[i]==' ') + ltz += tz[i] - 'a' + 'A'; + else if(tz[i] == ' ') ; else - ltz+=tz[i]; + ltz += tz[i]; } - if(ltz.compare(0,3,"GMT")!=0 && ltz.compare(0,3,"UTC")!=0) + if(ltz.compare(0, 3, "GMT") != 0 && ltz.compare(0, 3, "UTC") != 0) return 0; - if(ltz.size()<=3) + if(ltz.size() <= 3) return 0; - char const *begin = ltz.c_str()+3; - char *end=0; - int hours = strtol(begin,&end,10); + const char* begin = ltz.c_str() + 3; + char* end = 0; + int hours = strtol(begin, &end, 10); if(end != begin) { - gmtoff+=hours * 3600; + gmtoff += hours * 3600; } - if(*end==':') { - begin=end+1; - int minutes = strtol(begin,&end,10); - if(end!=begin) - gmtoff+=minutes * 60; + if(*end == ':') { + begin = end + 1; + int minutes = strtol(begin, &end, 10); + if(end != begin) + gmtoff += minutes * 60; } return gmtoff; } -} // util -} // locale -} //boost - +}}} // namespace boost::locale::util #endif diff --git a/contrib/restricted/boost/locale/src/boost/locale/win32/all_generator.hpp b/contrib/restricted/boost/locale/src/boost/locale/win32/all_generator.hpp index 41ae83d8a6..ad1984b712 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/win32/all_generator.hpp +++ b/contrib/restricted/boost/locale/src/boost/locale/win32/all_generator.hpp @@ -10,33 +10,20 @@ #include <boost/locale/generator.hpp> #include <locale> -namespace boost { - namespace locale { - namespace impl_win { +namespace boost { namespace locale { namespace impl_win { - class winlocale; + class winlocale; - std::locale create_convert( std::locale const &in, - winlocale const &lc, - character_facet_type type); + std::locale create_convert(const std::locale& in, const winlocale& lc, char_facet_t type); - std::locale create_collate( std::locale const &in, - winlocale const &lc, - character_facet_type type); + std::locale create_collate(const std::locale& in, const winlocale& lc, char_facet_t type); - std::locale create_formatting( std::locale const &in, - winlocale const &lc, - character_facet_type type); + std::locale create_formatting(const std::locale& in, const winlocale& lc, char_facet_t type); - std::locale create_parsing( std::locale const &in, - winlocale const &lc, - character_facet_type type); + std::locale create_parsing(const std::locale& in, const winlocale& lc, char_facet_t type); - std::locale create_codecvt( std::locale const &in, - character_facet_type type); + std::locale create_codecvt(const std::locale& in, char_facet_t type); - } - } -} +}}} // namespace boost::locale::impl_win #endif diff --git a/contrib/restricted/boost/locale/src/boost/locale/win32/api.hpp b/contrib/restricted/boost/locale/src/boost/locale/win32/api.hpp index 635c415d1f..a02d347779 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/win32/api.hpp +++ b/contrib/restricted/boost/locale/src/boost/locale/win32/api.hpp @@ -7,38 +7,28 @@ #ifndef BOOST_LOCALE_IMPL_WIN32_API_HPP #define BOOST_LOCALE_IMPL_WIN32_API_HPP -#include <string> -#include <vector> -#include <sstream> +#include <ctime> #include <iomanip> #include <limits> -#include <ctime> +#include <sstream> #include <stdexcept> +#include <string> +#include <vector> #include "boost/locale/win32/lcid.hpp" #ifndef NOMINMAX -#define NOMINMAX +# define NOMINMAX #endif #ifndef UNICODE -#define UNICODE +# define UNICODE #endif #include <windows.h> -#include <boost/locale/conversion.hpp> #include <boost/locale/collator.hpp> +#include <boost/locale/conversion.hpp> -#define BOOST_LOCALE_WINDOWS_2000_API - -#if defined(_WIN32_NT) && _WIN32_NT >= 0x600 && !defined(BOOST_LOCALE_WINDOWS_2000_API) -#define BOOST_LOCALE_WINDOWS_VISTA_API -#else -#define BOOST_LOCALE_WINDOWS_2000_API -#endif - -namespace boost { -namespace locale { -namespace impl_win { +namespace boost { namespace locale { namespace impl_win { struct numeric_info { std::wstring thousands_sep; @@ -46,57 +36,36 @@ namespace impl_win { std::string grouping; }; - inline DWORD collation_level_to_flag(collator_base::level_type level) + inline DWORD collation_level_to_flag(collate_level level) { - DWORD flags; switch(level) { - case collator_base::primary: - flags = NORM_IGNORESYMBOLS | NORM_IGNORECASE | NORM_IGNORENONSPACE; - break; - case collator_base::secondary: - flags = NORM_IGNORESYMBOLS | NORM_IGNORECASE; - break; - case collator_base::tertiary: - flags = NORM_IGNORESYMBOLS; - break; - default: - flags = 0; + case collate_level::primary: return NORM_IGNORESYMBOLS | NORM_IGNORECASE | NORM_IGNORENONSPACE; + case collate_level::secondary: return NORM_IGNORESYMBOLS | NORM_IGNORECASE; + case collate_level::tertiary: return NORM_IGNORESYMBOLS; + case collate_level::quaternary: + case collate_level::identical: return 0; } - return flags; + return 0; } - - - #ifdef BOOST_LOCALE_WINDOWS_2000_API - - class winlocale{ + class winlocale { public: - winlocale() : - lcid(0) - { - } + winlocale() : lcid(0) {} - winlocale(std::string const &name) - { - lcid = locale_to_lcid(name); - } + winlocale(const std::string& name) { lcid = locale_to_lcid(name); } unsigned lcid; - bool is_c() const - { - return lcid == 0; - } + bool is_c() const { return lcid == 0; } }; - //////////////////////////////////////////////////////////////////////// /// /// Number Format /// //////////////////////////////////////////////////////////////////////// - inline numeric_info wcsnumformat_l(winlocale const &l) + inline numeric_info wcsnumformat_l(const winlocale& l) { numeric_info res; res.decimal_point = L'.'; @@ -106,58 +75,57 @@ namespace impl_win { return res; // limits according to MSDN - static const int th_size = 4; - static const int de_size = 4; - static const int gr_size = 10; + constexpr int th_size = 4; + constexpr int de_size = 4; + constexpr int gr_size = 10; - wchar_t th[th_size]={0}; - wchar_t de[de_size]={0}; - wchar_t gr[gr_size]={0}; + wchar_t th[th_size] = {0}; + wchar_t de[de_size] = {0}; + wchar_t gr[gr_size] = {0}; - if( GetLocaleInfoW(lcid,LOCALE_STHOUSAND,th,th_size)==0 - || GetLocaleInfoW(lcid,LOCALE_SDECIMAL ,de,de_size)==0 - || GetLocaleInfoW(lcid,LOCALE_SGROUPING,gr,gr_size)==0) + if(GetLocaleInfoW(lcid, LOCALE_STHOUSAND, th, th_size) == 0 + || GetLocaleInfoW(lcid, LOCALE_SDECIMAL, de, de_size) == 0 + || GetLocaleInfoW(lcid, LOCALE_SGROUPING, gr, gr_size) == 0) { return res; } res.decimal_point = de; res.thousands_sep = th; bool inf_group = false; - for(unsigned i=0;gr[i];i++) { - if(gr[i]==L';') + for(unsigned i = 0; gr[i]; i++) { + if(gr[i] == L';') continue; - if(L'1'<= gr[i] && gr[i]<=L'9') { - res.grouping += char(gr[i]-L'0'); - } - else if(gr[i]==L'0') + if(L'1' <= gr[i] && gr[i] <= L'9') { + res.grouping += char(gr[i] - L'0'); + } else if(gr[i] == L'0') inf_group = true; } if(!inf_group) { -BOOST_LOCALE_START_CONST_CONDITION + BOOST_LOCALE_START_CONST_CONDITION if(std::numeric_limits<char>::is_signed) { - res.grouping+=std::numeric_limits<char>::min(); + res.grouping += std::numeric_limits<char>::min(); + } else { + res.grouping += std::numeric_limits<char>::max(); } - else { - res.grouping+=std::numeric_limits<char>::max(); - } -BOOST_LOCALE_END_CONST_CONDITION + BOOST_LOCALE_END_CONST_CONDITION } return res; } - inline std::wstring win_map_string_l(unsigned flags,wchar_t const *begin,wchar_t const *end,winlocale const &l) + inline std::wstring win_map_string_l(unsigned flags, const wchar_t* begin, const wchar_t* end, const winlocale& l) { std::wstring res; if(end - begin > std::numeric_limits<int>::max()) throw std::length_error("String to long for int type"); - int len = LCMapStringW(l.lcid,flags,begin, static_cast<int>(end-begin),0,0); + int len = LCMapStringW(l.lcid, flags, begin, static_cast<int>(end - begin), 0, 0); if(len == 0) return res; if(len == std::numeric_limits<int>::max()) 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); + 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); return res; } @@ -167,34 +135,40 @@ BOOST_LOCALE_END_CONST_CONDITION /// //////////////////////////////////////////////////////////////////////// - - inline int wcscoll_l( collator_base::level_type level, - wchar_t const *lb,wchar_t const *le, - wchar_t const *rb,wchar_t const *re, - winlocale const &l) + inline int wcscoll_l(collate_level level, + const wchar_t* lb, + const wchar_t* le, + const wchar_t* rb, + const wchar_t* re, + const winlocale& l) { if(le - lb > std::numeric_limits<int>::max() || re - rb > std::numeric_limits<int>::max()) throw std::length_error("String to long for int type"); - return CompareStringW(l.lcid,collation_level_to_flag(level),lb,static_cast<int>(le-lb),rb,static_cast<int>(re-rb)) - 2; + const int result = CompareStringW(l.lcid, + collation_level_to_flag(level), + lb, + static_cast<int>(le - lb), + rb, + static_cast<int>(re - rb)); + return result - 2; // Subtract 2 to get the meaning of <0, ==0, and >0 } - //////////////////////////////////////////////////////////////////////// /// /// Money Format /// //////////////////////////////////////////////////////////////////////// - inline std::wstring wcsfmon_l(double value,winlocale const &l) + inline std::wstring wcsfmon_l(double value, const winlocale& l) { std::wostringstream ss; ss.imbue(std::locale::classic()); - ss << std::setprecision(std::numeric_limits<double>::digits10+1) << value; + 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); - std::vector<wchar_t> buf(len+1); - GetCurrencyFormatW(l.lcid,0,sval.c_str(),0,&buf.front(),len); + int len = GetCurrencyFormatW(l.lcid, 0, sval.c_str(), 0, 0, 0); + std::vector<wchar_t> buf(len + 1); + GetCurrencyFormatW(l.lcid, 0, sval.c_str(), 0, &buf.front(), len); return &buf.front(); } @@ -204,166 +178,147 @@ BOOST_LOCALE_END_CONST_CONDITION /// //////////////////////////////////////////////////////////////////////// - - inline std::wstring wcs_format_date_l(wchar_t const *format,SYSTEMTIME const *tm,winlocale const &l) + 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); - std::vector<wchar_t> buf(len+1); - GetDateFormatW(l.lcid,0,tm,format,&buf.front(),len); + int len = GetDateFormatW(l.lcid, 0, tm, format, 0, 0); + std::vector<wchar_t> buf(len + 1); + GetDateFormatW(l.lcid, 0, tm, format, &buf.front(), len); return &buf.front(); } - inline std::wstring wcs_format_time_l(wchar_t const *format,SYSTEMTIME const *tm,winlocale const &l) + 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); - std::vector<wchar_t> buf(len+1); - GetTimeFormatW(l.lcid,0,tm,format,&buf.front(),len); + int len = GetTimeFormatW(l.lcid, 0, tm, format, 0, 0); + std::vector<wchar_t> buf(len + 1); + GetTimeFormatW(l.lcid, 0, tm, format, &buf.front(), len); return &buf.front(); } - inline std::wstring wcsfold(wchar_t const *begin,wchar_t const *end) + inline std::wstring wcsfold(const wchar_t* begin, const wchar_t* end) { winlocale l; l.lcid = 0x0409; // en-US - return win_map_string_l(LCMAP_LOWERCASE,begin,end,l); + return win_map_string_l(LCMAP_LOWERCASE, begin, end, l); } - inline std::wstring wcsnormalize(norm_type norm,wchar_t const *begin,wchar_t const *end) + inline std::wstring wcsnormalize(norm_type norm, const wchar_t* begin, const wchar_t* end) { // We use FoldString, under Vista it actually does normalization; // under XP and below it does something similar, half job, better then nothing - unsigned flags = 0; + unsigned flags = MAP_PRECOMPOSED; switch(norm) { - case norm_nfd: - flags = MAP_COMPOSITE; - break; - case norm_nfc: - flags = MAP_PRECOMPOSED; - break; - case norm_nfkd: - flags = MAP_FOLDCZONE; - break; - case norm_nfkc: - flags = MAP_FOLDCZONE | MAP_COMPOSITE; - break; - default: - flags = MAP_PRECOMPOSED; + case norm_nfd: flags = MAP_COMPOSITE; break; + case norm_nfc: flags = MAP_PRECOMPOSED; break; + case norm_nfkd: flags = MAP_FOLDCZONE; break; + case norm_nfkc: flags = MAP_FOLDCZONE | MAP_COMPOSITE; break; } if(end - begin > std::numeric_limits<int>::max()) throw std::length_error("String to long for int type"); - int len = FoldStringW(flags,begin,static_cast<int>(end-begin),0,0); + int len = FoldStringW(flags, begin, static_cast<int>(end - begin), 0, 0); if(len == 0) return std::wstring(); 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); + 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); } - - #endif - - inline std::wstring wcsxfrm_l(collator_base::level_type level,wchar_t const *begin,wchar_t const *end,winlocale const &l) + inline std::wstring wcsxfrm_l(collate_level level, const wchar_t* begin, const wchar_t* end, const winlocale& l) { int flag = LCMAP_SORTKEY | collation_level_to_flag(level); - return win_map_string_l(flag,begin,end,l); + return win_map_string_l(flag, begin, end, l); } - inline std::wstring towupper_l(wchar_t const *begin,wchar_t const *end,winlocale const &l) + inline std::wstring towupper_l(const wchar_t* begin, const wchar_t* end, const winlocale& l) { - return win_map_string_l(LCMAP_UPPERCASE | LCMAP_LINGUISTIC_CASING,begin,end,l); + return win_map_string_l(LCMAP_UPPERCASE | LCMAP_LINGUISTIC_CASING, begin, end, l); } - inline std::wstring towlower_l(wchar_t const *begin,wchar_t const *end,winlocale const &l) + inline std::wstring towlower_l(const wchar_t* begin, const wchar_t* end, const winlocale& l) { - return win_map_string_l(LCMAP_LOWERCASE | LCMAP_LINGUISTIC_CASING,begin,end,l); + return win_map_string_l(LCMAP_LOWERCASE | LCMAP_LINGUISTIC_CASING, begin, end, l); } - inline std::wstring wcsftime_l(char c,std::tm const *tm,winlocale const &l) + inline std::wstring wcsftime_l(char c, const std::tm* tm, const winlocale& l) { - SYSTEMTIME wtm=SYSTEMTIME(); + SYSTEMTIME wtm = SYSTEMTIME(); wtm.wYear = static_cast<WORD>(tm->tm_year + 1900); - wtm.wMonth = static_cast<WORD>(tm->tm_mon+1); + wtm.wMonth = static_cast<WORD>(tm->tm_mon + 1); wtm.wDayOfWeek = static_cast<WORD>(tm->tm_wday); wtm.wDay = static_cast<WORD>(tm->tm_mday); wtm.wHour = static_cast<WORD>(tm->tm_hour); wtm.wMinute = static_cast<WORD>(tm->tm_min); wtm.wSecond = static_cast<WORD>(tm->tm_sec); switch(c) { - case 'a': // Abbr Weekday - return wcs_format_date_l(L"ddd",&wtm,l); - case 'A': // Full Weekday - return wcs_format_date_l(L"dddd",&wtm,l); - case 'b': // Abbr Month - return wcs_format_date_l(L"MMM",&wtm,l); - case 'B': // Full Month - return wcs_format_date_l(L"MMMM",&wtm,l); - case 'c': // DateTile Full - return wcs_format_date_l(0,&wtm,l) + L" " + wcs_format_time_l(0,&wtm,l); - // not supported by WIN ;( - // case 'C': // Century -> 1980 -> 19 - // retur - case 'd': // Day of Month [01,31] - return wcs_format_date_l(L"dd",&wtm,l); - case 'D': // %m/%d/%y - return wcs_format_date_l(L"MM/dd/yy",&wtm,l); - case 'e': // Day of Month [1,31] - return wcs_format_date_l(L"d",&wtm,l); - case 'h': // == b - return wcs_format_date_l(L"MMM",&wtm,l); - case 'H': // 24 clock hour 00,23 - return wcs_format_time_l(L"HH",&wtm,l); - case 'I': // 12 clock hour 01,12 - return wcs_format_time_l(L"hh",&wtm,l); - /* - case 'j': // day of year 001,366 - return "D";*/ - case 'm': // month as [01,12] - return wcs_format_date_l(L"MM",&wtm,l); - case 'M': // minute [00,59] - return wcs_format_time_l(L"mm",&wtm,l); - case 'n': // \n - return L"\n"; - case 'p': // am-pm - return wcs_format_time_l(L"tt",&wtm,l); - case 'r': // time with AM/PM %I:%M:%S %p - return wcs_format_time_l(L"hh:mm:ss tt",&wtm,l); - case 'R': // %H:%M - return wcs_format_time_l(L"HH:mm",&wtm,l); - case 'S': // second [00,61] - return wcs_format_time_l(L"ss",&wtm,l); - case 't': // \t - return L"\t"; - case 'T': // %H:%M:%S - return wcs_format_time_l(L"HH:mm:ss",&wtm,l); -/* case 'u': // weekday 1,7 1=Monday - case 'U': // week number of year [00,53] Sunday first - case 'V': // week number of year [01,53] Monday first - case 'w': // weekday 0,7 0=Sunday - case 'W': // week number of year [00,53] Monday first, */ - case 'x': // Date - return wcs_format_date_l(0,&wtm,l); - case 'X': // Time - return wcs_format_time_l(0,&wtm,l); - case 'y': // Year [00-99] - return wcs_format_date_l(L"yy",&wtm,l); - case 'Y': // Year 1998 - return wcs_format_date_l(L"yyyy",&wtm,l); - case '%': // % - return L"%"; - default: - return L""; + case 'a': // Abbr Weekday + return wcs_format_date_l(L"ddd", &wtm, l); + case 'A': // Full Weekday + return wcs_format_date_l(L"dddd", &wtm, l); + case 'b': // Abbr Month + return wcs_format_date_l(L"MMM", &wtm, l); + case 'B': // Full Month + return wcs_format_date_l(L"MMMM", &wtm, l); + case 'c': // DateTile Full + return wcs_format_date_l(0, &wtm, l) + L" " + wcs_format_time_l(0, &wtm, l); + // not supported by WIN ;( + // case 'C': // Century -> 1980 -> 19 + // retur + case 'd': // Day of Month [01,31] + return wcs_format_date_l(L"dd", &wtm, l); + case 'D': // %m/%d/%y + return wcs_format_date_l(L"MM/dd/yy", &wtm, l); + case 'e': // Day of Month [1,31] + return wcs_format_date_l(L"d", &wtm, l); + case 'h': // == b + return wcs_format_date_l(L"MMM", &wtm, l); + case 'H': // 24 clock hour 00,23 + return wcs_format_time_l(L"HH", &wtm, l); + case 'I': // 12 clock hour 01,12 + return wcs_format_time_l(L"hh", &wtm, l); + /* + case 'j': // day of year 001,366 + return "D";*/ + case 'm': // month as [01,12] + return wcs_format_date_l(L"MM", &wtm, l); + case 'M': // minute [00,59] + return wcs_format_time_l(L"mm", &wtm, l); + case 'n': // \n + return L"\n"; + case 'p': // am-pm + return wcs_format_time_l(L"tt", &wtm, l); + case 'r': // time with AM/PM %I:%M:%S %p + return wcs_format_time_l(L"hh:mm:ss tt", &wtm, l); + case 'R': // %H:%M + return wcs_format_time_l(L"HH:mm", &wtm, l); + case 'S': // second [00,61] + return wcs_format_time_l(L"ss", &wtm, l); + case 't': // \t + return L"\t"; + case 'T': // %H:%M:%S + return wcs_format_time_l(L"HH:mm:ss", &wtm, l); + /* case 'u': // weekday 1,7 1=Monday + case 'U': // week number of year [00,53] Sunday first + case 'V': // week number of year [01,53] Monday first + case 'w': // weekday 0,7 0=Sunday + case 'W': // week number of year [00,53] Monday first, */ + case 'x': // Date + return wcs_format_date_l(0, &wtm, l); + case 'X': // Time + return wcs_format_time_l(0, &wtm, l); + case 'y': // Year [00-99] + return wcs_format_date_l(L"yy", &wtm, l); + case 'Y': // Year 1998 + return wcs_format_date_l(L"yyyy", &wtm, l); + case '%': // % + return L"%"; + default: return L""; } } - - -} // win -} // locale -} // boost -#endif +}}} // namespace boost::locale::impl_win // boostinspect:nominmax +#endif 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 ad4c2bdcc8..aa8be85d71 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/win32/collate.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/win32/collate.cpp @@ -5,123 +5,118 @@ // https://www.boost.org/LICENSE_1_0.txt #define BOOST_LOCALE_SOURCE -#include <locale> -#include <string> -#include <ios> #include <boost/locale/encoding.hpp> #include <boost/locale/generator.hpp> -#include "boost/locale/win32/api.hpp" #include "boost/locale/shared/mo_hash.hpp" +#include "boost/locale/win32/api.hpp" +#include <ios> +#include <locale> +#include <string> -namespace boost { -namespace locale { -namespace impl_win { +namespace boost { namespace locale { namespace impl_win { -class utf8_collator : public collator<char> { -public: - utf8_collator(winlocale lc,size_t refs = 0) : - collator<char>(refs), - lc_(lc) - { - } - int do_compare(collator_base::level_type level,char const *lb,char const *le,char const *rb,char const *re) const BOOST_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"); - return wcscoll_l(level,l.c_str(),l.c_str()+l.size(),r.c_str(),r.c_str()+r.size(),lc_); - } - long do_hash(collator_base::level_type level,char const *b,char const *e) const BOOST_OVERRIDE - { - 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(collator_base::level_type level,char const *b,char const *e) const BOOST_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_); - 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); + class utf8_collator : public collator<char> { + public: + utf8_collator(winlocale lc, size_t refs = 0) : collator<char>(refs), lc_(lc) {} + int + do_compare(collate_level level, const char* lb, const char* le, const char* rb, const char* re) const override + { + std::wstring l = conv::to_utf<wchar_t>(lb, le, "UTF-8"); + std::wstring r = conv::to_utf<wchar_t>(rb, re, "UTF-8"); + 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); + 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_); + 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); + } } + BOOST_LOCALE_END_CONST_CONDITION + return key; } -BOOST_LOCALE_END_CONST_CONDITION - return key; - } -private: - winlocale lc_; -}; + private: + winlocale lc_; + }; -class utf16_collator : public collator<wchar_t> { -public: - typedef std::collate<wchar_t> wfacet; - utf16_collator(winlocale lc,size_t refs = 0) : - collator<wchar_t>(refs), - lc_(lc) - { - } - int do_compare(collator_base::level_type level,wchar_t const *lb,wchar_t const *le,wchar_t const *rb,wchar_t const *re) const BOOST_OVERRIDE - { - return wcscoll_l(level,lb,le,rb,re,lc_); - } - long do_hash(collator_base::level_type level,wchar_t const *b,wchar_t const *e) const BOOST_OVERRIDE - { - std::wstring key = do_transform(level,b,e); - char const *begin = reinterpret_cast<char const *>(key.c_str()); - char const *end = begin + key.size()*sizeof(wchar_t); - return gnu_gettext::pj_winberger_hash_function(begin,end); - } - std::wstring do_transform(collator_base::level_type level,wchar_t const *b,wchar_t const *e) const BOOST_OVERRIDE - { - return wcsxfrm_l(level,b,e,lc_); - } -private: - winlocale lc_; -}; - - -std::locale create_collate( std::locale const &in, - winlocale const &lc, - character_facet_type type) -{ - if(lc.is_c()) { - switch(type) { - case char_facet: - return std::locale(in,new std::collate_byname<char>("C")); - case wchar_t_facet: - return std::locale(in,new std::collate_byname<wchar_t>("C")); + class utf16_collator : public collator<wchar_t> { + public: + typedef std::collate<wchar_t> wfacet; + utf16_collator(winlocale lc, size_t refs = 0) : collator<wchar_t>(refs), lc_(lc) {} + int do_compare(collate_level level, + const wchar_t* lb, + const wchar_t* le, + const wchar_t* rb, + const wchar_t* re) const override + { + return wcscoll_l(level, lb, le, rb, re, lc_); } - } - else { - switch(type) { - case char_facet: - return std::locale(in,new utf8_collator(lc)); - case wchar_t_facet: - return std::locale(in,new utf16_collator(lc)); + long do_hash(collate_level level, const wchar_t* b, const wchar_t* e) const override + { + std::wstring key = do_transform(level, b, e); + const char* begin = reinterpret_cast<const char*>(key.c_str()); + const char* end = begin + key.size() * sizeof(wchar_t); + return gnu_gettext::pj_winberger_hash_function(begin, end); + } + std::wstring do_transform(collate_level level, const wchar_t* b, const wchar_t* e) const override + { + return wcsxfrm_l(level, b, e, lc_); } - } - return in; -} - - -} // impl_std -} // locale -} //boost + private: + winlocale lc_; + }; + std::locale create_collate(const std::locale& in, const winlocale& lc, char_facet_t type) + { + if(lc.is_c()) { + switch(type) { + case char_facet_t::nochar: break; + case char_facet_t::char_f: return std::locale(in, new std::collate_byname<char>("C")); + case char_facet_t::wchar_f: return std::locale(in, new std::collate_byname<wchar_t>("C")); +#ifdef BOOST_LOCALE_ENABLE_CHAR16_T + case char_facet_t::char16_f: return std::locale(in, new collate_byname<char16_t>("C")); +#endif +#ifdef BOOST_LOCALE_ENABLE_CHAR32_T + case char_facet_t::char32_f: return std::locale(in, new collate_byname<char32_t>("C")); +#endif + } + } else { + switch(type) { + case char_facet_t::nochar: break; + case char_facet_t::char_f: return std::locale(in, new utf8_collator(lc)); + case char_facet_t::wchar_f: return std::locale(in, new utf16_collator(lc)); +#ifdef BOOST_LOCALE_ENABLE_CHAR16_T + case char_facet_t::char16_f: break; +#endif +#ifdef BOOST_LOCALE_ENABLE_CHAR32_T + case char_facet_t::char32_f: break; +#endif + } + } + return in; + } +}}} // namespace boost::locale::impl_win 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 e11d9924da..15090bc205 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/win32/converter.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/win32/converter.cpp @@ -6,98 +6,79 @@ #define BOOST_LOCALE_SOURCE -#include <boost/locale/generator.hpp> #include <boost/locale/conversion.hpp> #include <boost/locale/encoding.hpp> +#include <boost/locale/generator.hpp> +#include "boost/locale/win32/all_generator.hpp" +#include "boost/locale/win32/api.hpp" #include <cstring> #include <locale> #include <stdexcept> -#include "boost/locale/win32/api.hpp" -#include "boost/locale/win32/all_generator.hpp" -namespace boost { -namespace locale { -namespace impl_win { +namespace boost { namespace locale { namespace impl_win { -class utf16_converter : public converter<wchar_t> -{ -public: - utf16_converter(winlocale const &lc,size_t refs = 0) : - converter<wchar_t>(refs), - lc_(lc) - { - } - std::wstring convert(converter_base::conversion_type how,wchar_t const *begin,wchar_t const *end,int flags = 0) const BOOST_OVERRIDE - { - switch(how) { - case converter_base::upper_case: - return towupper_l(begin,end,lc_); - case converter_base::lower_case: - return towlower_l(begin,end,lc_); - case converter_base::case_folding: - return wcsfold(begin,end); - case converter_base::normalization: - return wcsnormalize(static_cast<norm_type>(flags),begin,end); - default: - return std::wstring(begin,end-begin); + class utf16_converter : public converter<wchar_t> { + public: + utf16_converter(const winlocale& lc, size_t refs = 0) : converter<wchar_t>(refs), lc_(lc) {} + std::wstring convert(converter_base::conversion_type how, + const wchar_t* begin, + const wchar_t* end, + int flags = 0) const override + { + switch(how) { + case converter_base::upper_case: return towupper_l(begin, end, lc_); + case converter_base::lower_case: return towlower_l(begin, end, lc_); + case converter_base::case_folding: return wcsfold(begin, end); + case converter_base::normalization: return wcsnormalize(static_cast<norm_type>(flags), begin, end); + case converter_base::title_case: break; + } + return std::wstring(begin, end - begin); } - } -private: - winlocale lc_; -}; -class utf8_converter : public converter<char> { -public: - utf8_converter(winlocale const &lc,size_t refs = 0) : - converter<char>(refs), - lc_(lc) - { - } - std::string convert(converter_base::conversion_type how,char const *begin,char const *end,int flags = 0) const BOOST_OVERRIDE - { - std::wstring tmp = conv::to_utf<wchar_t>(begin,end,"UTF-8"); - wchar_t const *wb=tmp.c_str(); - wchar_t const *we=wb+tmp.size(); + private: + winlocale lc_; + }; - std::wstring res; + class utf8_converter : public converter<char> { + public: + utf8_converter(const winlocale& lc, size_t refs = 0) : converter<char>(refs), lc_(lc) {} + std::string + convert(converter_base::conversion_type how, const char* begin, const char* end, int flags = 0) const override + { + std::wstring tmp = conv::to_utf<wchar_t>(begin, end, "UTF-8"); + const wchar_t* wb = tmp.c_str(); + const wchar_t* we = wb + tmp.size(); - switch(how) { - case upper_case: - res = towupper_l(wb,we,lc_); - break; - case lower_case: - res = towlower_l(wb,we,lc_); - break; - case case_folding: - res = wcsfold(wb,we); - break; - case normalization: - res = wcsnormalize(static_cast<norm_type>(flags),wb,we); - break; - default: - res = tmp; // make gcc happy + std::wstring res; + + switch(how) { + case upper_case: res = towupper_l(wb, we, lc_); break; + case lower_case: res = towlower_l(wb, we, lc_); break; + case case_folding: res = wcsfold(wb, we); break; + case normalization: res = wcsnormalize(static_cast<norm_type>(flags), wb, we); break; + case title_case: break; + } + return conv::from_utf(res, "UTF-8"); } - return conv::from_utf(res,"UTF-8"); - } -private: - winlocale lc_; -}; -std::locale create_convert( std::locale const &in, - winlocale const &lc, - character_facet_type type) -{ + private: + winlocale lc_; + }; + + std::locale create_convert(const std::locale& in, const winlocale& lc, char_facet_t type) + { switch(type) { - case char_facet: - return std::locale(in,new utf8_converter(lc)); - case wchar_t_facet: - return std::locale(in,new utf16_converter(lc)); - default: - return in; + case char_facet_t::nochar: break; + case char_facet_t::char_f: return std::locale(in, new utf8_converter(lc)); + case char_facet_t::wchar_f: return std::locale(in, new utf16_converter(lc)); +#ifdef BOOST_LOCALE_ENABLE_CHAR16_T + case char_facet_t::char16_f: break; +#endif +#ifdef BOOST_LOCALE_ENABLE_CHAR32_T + case char_facet_t::char32_f: break; +#endif } -} - + return in; + } -} // namespace impl_win32 -} // locale -} // boost +}}} // namespace boost::locale::impl_win 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 733aceb2ba..f4c47a5dc4 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/win32/lcid.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/win32/lcid.cpp @@ -6,10 +6,11 @@ #define BOOST_LOCALE_SOURCE #ifndef NOMINMAX -#define NOMINMAX +# define NOMINMAX #endif #include "boost/locale/win32/lcid.hpp" +#include "boost/locale/util/locale_data.hpp" #include <boost/thread/locks.hpp> #include <boost/thread/mutex.hpp> #include <map> @@ -17,108 +18,99 @@ #include <string.h> #include <string> #include <windows.h> -#include "boost/locale/util/locale_data.hpp" -namespace boost { -namespace locale { -namespace impl_win { - -typedef std::map<std::string,unsigned> table_type; - -static table_type * volatile table = 0; - -boost::mutex &lcid_table_mutex() -{ - static boost::mutex m; - return m; -} - -table_type &real_lcid_table() -{ - static table_type real_table; - return real_table; -} - -BOOL CALLBACK proc(char *s) -{ - table_type &tbl = real_lcid_table(); - try { - std::istringstream ss; - ss.str(s); - ss >> std::hex; - - unsigned lcid ; - ss >>lcid; - if(ss.fail() || !ss.eof()) { - return FALSE; - } +namespace boost { namespace locale { namespace impl_win { - char iso_639_lang[16]; - char iso_3166_country[16]; - if(GetLocaleInfoA(lcid,LOCALE_SISO639LANGNAME,iso_639_lang,sizeof(iso_639_lang))==0) - return FALSE; - std::string lc_name = iso_639_lang; - if(GetLocaleInfoA(lcid,LOCALE_SISO3166CTRYNAME,iso_3166_country,sizeof(iso_3166_country))!=0) { - lc_name += "_"; - lc_name += iso_3166_country; - } - table_type::iterator p = tbl.find(lc_name); - if(p!=tbl.end()) { - if(p->second > lcid) - p->second = lcid; - } - else { - tbl[lc_name]=lcid; - } - } - catch(...) { - tbl.clear(); - return FALSE; - } - return TRUE; -} + typedef std::map<std::string, unsigned> table_type; + static table_type* volatile table = 0; -table_type const &get_ready_lcid_table() -{ - if(table) - return *table; - else { - boost::unique_lock<boost::mutex> lock(lcid_table_mutex()); - if(table) - return *table; - EnumSystemLocalesA(proc,LCID_INSTALLED); - table = &real_lcid_table(); - return *table; + boost::mutex& lcid_table_mutex() + { + static boost::mutex m; + return m; } -} -unsigned locale_to_lcid(std::string const &locale_name) -{ - if(locale_name.empty()) { - return LOCALE_USER_DEFAULT; + table_type& real_lcid_table() + { + static table_type real_table; + return real_table; } - boost::locale::util::locale_data d; - d.parse(locale_name); - std::string id = d.language; - if(!d.country.empty()) { - id+="_"+d.country; + BOOL CALLBACK proc(char* s) + { + table_type& tbl = real_lcid_table(); + try { + std::istringstream ss; + ss.str(s); + ss >> std::hex; + + unsigned lcid; + ss >> lcid; + if(ss.fail() || !ss.eof()) { + return FALSE; + } + + char iso_639_lang[16]; + char iso_3166_country[16]; + if(GetLocaleInfoA(lcid, LOCALE_SISO639LANGNAME, iso_639_lang, sizeof(iso_639_lang)) == 0) + return FALSE; + std::string lc_name = iso_639_lang; + if(GetLocaleInfoA(lcid, LOCALE_SISO3166CTRYNAME, iso_3166_country, sizeof(iso_3166_country)) != 0) { + lc_name += "_"; + lc_name += iso_3166_country; + } + table_type::iterator p = tbl.find(lc_name); + if(p != tbl.end()) { + if(p->second > lcid) + p->second = lcid; + } else { + tbl[lc_name] = lcid; + } + } catch(...) { + tbl.clear(); + return FALSE; + } + return TRUE; } - if(!d.variant.empty()) { - id+="@" + d.variant; + + const table_type& get_ready_lcid_table() + { + if(table) + return *table; + else { + boost::unique_lock<boost::mutex> lock(lcid_table_mutex()); + if(table) + return *table; + EnumSystemLocalesA(proc, LCID_INSTALLED); + table = &real_lcid_table(); + return *table; + } } - table_type const &tbl = get_ready_lcid_table(); - table_type::const_iterator p = tbl.find(id); + unsigned locale_to_lcid(const std::string& locale_name) + { + 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()) { + id += "_" + d.country; + } + if(!d.variant.empty()) { + id += "@" + d.variant; + } - unsigned lcid = 0; - if(p!=tbl.end()) - lcid = p->second; - return lcid; -} + 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; + } -} // impl_win -} // locale -} // boost +}}} // namespace boost::locale::impl_win diff --git a/contrib/restricted/boost/locale/src/boost/locale/win32/lcid.hpp b/contrib/restricted/boost/locale/src/boost/locale/win32/lcid.hpp index 2ec2284602..19a801d4a8 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/win32/lcid.hpp +++ b/contrib/restricted/boost/locale/src/boost/locale/win32/lcid.hpp @@ -7,17 +7,13 @@ #ifndef BOOST_LOCALE_IMPL_WIN32_LCID_HPP #define BOOST_LOCALE_IMPL_WIN32_LCID_HPP -#include <string> #include <boost/locale/config.hpp> +#include <string> -namespace boost { - namespace locale { - namespace impl_win { +namespace boost { namespace locale { namespace impl_win { - BOOST_LOCALE_DECL unsigned locale_to_lcid(std::string const &locale_name); + BOOST_LOCALE_DECL unsigned locale_to_lcid(const std::string& locale_name); - } // impl_win - } // locale -} // boost +}}} // namespace boost::locale::impl_win #endif diff --git a/contrib/restricted/boost/locale/src/boost/locale/win32/numeric.cpp b/contrib/restricted/boost/locale/src/boost/locale/win32/numeric.cpp index edf8e24781..d6725295d2 100644 --- a/contrib/restricted/boost/locale/src/boost/locale/win32/numeric.cpp +++ b/contrib/restricted/boost/locale/src/boost/locale/win32/numeric.cpp @@ -5,12 +5,12 @@ // https://www.boost.org/LICENSE_1_0.txt #define BOOST_LOCALE_SOURCE -#include "boost/locale/win32/all_generator.hpp" -#include "boost/locale/win32/api.hpp" #include "boost/locale/util/numeric.hpp" #include <boost/locale/encoding.hpp> #include <boost/locale/formatting.hpp> #include <boost/locale/generator.hpp> +#include "boost/locale/win32/all_generator.hpp" +#include "boost/locale/win32/api.hpp" #include <cctype> #include <cstdlib> #include <cstring> @@ -21,221 +21,191 @@ #include <string> #include <wctype.h> -namespace boost { -namespace locale { -namespace impl_win { +namespace boost { namespace locale { namespace impl_win { namespace { - std::ostreambuf_iterator<wchar_t> write_it(std::ostreambuf_iterator<wchar_t> out,std::wstring const &s) + 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++) + for(size_t i = 0; i < s.size(); i++) *out++ = s[i]; return out; } - std::ostreambuf_iterator<char> write_it(std::ostreambuf_iterator<char> out,std::wstring const &s) + 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++) + std::string tmp = conv::from_utf(s, "UTF-8"); + for(size_t i = 0; i < tmp.size(); i++) *out++ = tmp[i]; return out; } - } + } // namespace + + template<typename CharType> + class num_format : public util::base_num_format<CharType> { + 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) {} + + private: + iter_type do_format_currency(bool /*intl*/, + iter_type out, + std::ios_base& ios, + char_type 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(); + 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); + ios.flags(f); + return out; + } else { + std::wstring cur = wcsfmon_l(static_cast<double>(val), lc_); + return write_it(out, cur); + } + } + private: + winlocale lc_; -template<typename CharType> -class num_format : public util::base_num_format<CharType> -{ -public: - typedef typename std::num_put<CharType>::iter_type iter_type; - typedef std::basic_string<CharType> string_type; - typedef CharType char_type; + }; /// num_format - num_format(winlocale const &lc,size_t refs = 0) : - util::base_num_format<CharType>(refs), - lc_(lc) - { - } -private: + template<typename CharType> + class time_put_win : public std::time_put<CharType> { + public: + time_put_win(const winlocale& lc, size_t refs = 0) : std::time_put<CharType>(refs), lc_(lc) {} - iter_type do_format_currency(bool /*intl*/,iter_type out,std::ios_base &ios,char_type fill,long double val) const BOOST_OVERRIDE - { - if(lc_.is_c()) { - std::locale loc = ios.getloc(); - int digits = std::use_facet<std::moneypunct<char_type> >(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); - ios.flags(f); - return out; - } - else { - std::wstring cur = wcsfmon_l(static_cast<double>(val),lc_); - return write_it(out,cur); - } - } + typedef typename std::time_put<CharType>::iter_type iter_type; + typedef CharType char_type; + typedef std::basic_string<char_type> string_type; -private: - winlocale lc_; - -}; /// num_format + iter_type do_put(iter_type out, + std::ios_base& /*ios*/, + CharType /*fill*/, + const std::tm* tm, + char format, + char /*modifier*/) const override + { + return write_it(out, wcsftime_l(format, tm, lc_)); + } -template<typename CharType> -class time_put_win : public std::time_put<CharType> { -public: - time_put_win(winlocale const &lc, size_t refs = 0) : - std::time_put<CharType>(refs), - lc_(lc) - { - } + private: + winlocale lc_; + }; - typedef typename std::time_put<CharType>::iter_type iter_type; - typedef CharType char_type; - typedef std::basic_string<char_type> string_type; + template<typename CharType> + class num_punct_win : public std::numpunct<CharType> { + public: + typedef std::basic_string<CharType> string_type; + num_punct_win(const winlocale& lc, size_t refs = 0) : std::numpunct<CharType>(refs) + { + numeric_info np = wcsnumformat_l(lc); + + BOOST_LOCALE_START_CONST_CONDITION + if(sizeof(CharType) == 1 && np.thousands_sep == L"\xA0") + np.thousands_sep = L" "; + BOOST_LOCALE_END_CONST_CONDITION + + to_str(np.thousands_sep, thousands_sep_); + to_str(np.decimal_point, decimal_point_); + grouping_ = np.grouping; + if(thousands_sep_.size() > 1) + grouping_ = std::string(); + if(decimal_point_.size() > 1) + decimal_point_ = CharType('.'); + } - iter_type do_put( iter_type out, - std::ios_base &/*ios*/, - CharType /*fill*/, - std::tm const *tm, - char format, - char /*modifier*/) const BOOST_OVERRIDE - { - return write_it(out,wcsftime_l(format,tm,lc_)); - } + void to_str(std::wstring& s1, std::wstring& s2) { s2.swap(s1); } -private: - winlocale lc_; -}; + void to_str(std::wstring& s1, std::string& s2) { s2 = conv::from_utf(s1, "UTF-8"); } + 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_; } + string_type do_truename() const override + { + static const char t[] = "true"; + return string_type(t, t + sizeof(t) - 1); + } + string_type do_falsename() const override + { + static const char t[] = "false"; + return string_type(t, t + sizeof(t) - 1); + } + private: + string_type decimal_point_; + string_type thousands_sep_; + std::string grouping_; + }; -template<typename CharType> -class num_punct_win : public std::numpunct<CharType> { -public: - typedef std::basic_string<CharType> string_type; - num_punct_win(winlocale const &lc,size_t refs = 0) : - std::numpunct<CharType>(refs) + template<typename CharType> + std::locale create_formatting_impl(const std::locale& in, const winlocale& lc) { - numeric_info np = wcsnumformat_l(lc) ; - -BOOST_LOCALE_START_CONST_CONDITION - if(sizeof(CharType) == 1 && np.thousands_sep == L"\xA0") - np.thousands_sep=L" "; -BOOST_LOCALE_END_CONST_CONDITION - - to_str(np.thousands_sep,thousands_sep_); - to_str(np.decimal_point,decimal_point_); - grouping_ = np.grouping; - if(thousands_sep_.size() > 1) - grouping_ = std::string(); - if(decimal_point_.size() > 1) - decimal_point_ = CharType('.'); + if(lc.is_c()) { + std::locale tmp(in, new std::numpunct_byname<CharType>("C")); + tmp = std::locale(tmp, new std::time_put_byname<CharType>("C")); + tmp = std::locale(tmp, new num_format<CharType>(lc)); + return tmp; + } else { + std::locale tmp(in, new num_punct_win<CharType>(lc)); + tmp = std::locale(tmp, new time_put_win<CharType>(lc)); + tmp = std::locale(tmp, new num_format<CharType>(lc)); + return tmp; + } } - void to_str(std::wstring &s1,std::wstring &s2) + template<typename CharType> + std::locale create_parsing_impl(const std::locale& in, const winlocale& lc) { - s2.swap(s1); + std::numpunct<CharType>* np = 0; + if(lc.is_c()) + np = new std::numpunct_byname<CharType>("C"); + else + np = new num_punct_win<CharType>(lc); + std::locale tmp(in, np); + tmp = std::locale(tmp, new util::base_num_parse<CharType>()); + return tmp; } - void to_str(std::wstring &s1,std::string &s2) - { - s2=conv::from_utf(s1,"UTF-8"); - } - CharType do_decimal_point() const BOOST_OVERRIDE - { - return *decimal_point_.c_str(); - } - CharType do_thousands_sep() const BOOST_OVERRIDE - { - return *thousands_sep_.c_str(); - } - std::string do_grouping() const BOOST_OVERRIDE - { - return grouping_; - } - string_type do_truename() const BOOST_OVERRIDE - { - static const char t[]="true"; - return string_type(t,t+sizeof(t)-1); - } - string_type do_falsename() const BOOST_OVERRIDE + std::locale create_formatting(const std::locale& in, const winlocale& lc, char_facet_t type) { - static const char t[]="false"; - return string_type(t,t+sizeof(t)-1); - } -private: - string_type decimal_point_; - string_type thousands_sep_; - std::string grouping_; -}; - -template<typename CharType> -std::locale create_formatting_impl(std::locale const &in,winlocale const &lc) -{ - if(lc.is_c()) { - std::locale tmp(in,new std::numpunct_byname<CharType>("C")); - tmp=std::locale(tmp,new std::time_put_byname<CharType>("C")); - tmp = std::locale(tmp,new num_format<CharType>(lc)); - return tmp; - } - else { - std::locale tmp(in,new num_punct_win<CharType>(lc)); - tmp = std::locale(tmp,new time_put_win<CharType>(lc)); - tmp = std::locale(tmp,new num_format<CharType>(lc)); - return tmp; - } -} - -template<typename CharType> -std::locale create_parsing_impl(std::locale const &in,winlocale const &lc) -{ - std::numpunct<CharType> *np = 0; - if(lc.is_c()) - np = new std::numpunct_byname<CharType>("C"); - else - np = new num_punct_win<CharType>(lc); - std::locale tmp(in,np); - tmp = std::locale(tmp,new util::base_num_parse<CharType>()); - return tmp; -} - - -std::locale create_formatting( std::locale const &in, - winlocale const &lc, - character_facet_type type) -{ switch(type) { - case char_facet: - return create_formatting_impl<char>(in,lc); - case wchar_t_facet: - return create_formatting_impl<wchar_t>(in,lc); - default: - return in; + case char_facet_t::nochar: break; + case char_facet_t::char_f: return create_formatting_impl<char>(in, lc); + case char_facet_t::wchar_f: return create_formatting_impl<wchar_t>(in, lc); +#ifdef BOOST_LOCALE_ENABLE_CHAR16_T + case char_facet_t::char16_f: return create_formatting_impl<char16_t>(in, lc); +#endif +#ifdef BOOST_LOCALE_ENABLE_CHAR32_T + case char_facet_t::char32_f: return create_formatting_impl<char32_t>(in, lc); +#endif } -} + return in; + } -std::locale create_parsing( std::locale const &in, - winlocale const &lc, - character_facet_type type) -{ + std::locale create_parsing(const std::locale& in, const winlocale& lc, char_facet_t type) + { switch(type) { - case char_facet: - return create_parsing_impl<char>(in,lc); - case wchar_t_facet: - return create_parsing_impl<wchar_t>(in,lc); - default: - return in; + case char_facet_t::nochar: break; + case char_facet_t::char_f: return create_parsing_impl<char>(in, lc); + case char_facet_t::wchar_f: return create_parsing_impl<wchar_t>(in, lc); +#ifdef BOOST_LOCALE_ENABLE_CHAR16_T + case char_facet_t::char16_f: return create_parsing_impl<char16_t>(in, lc); +#endif +#ifdef BOOST_LOCALE_ENABLE_CHAR32_T + case char_facet_t::char32_f: return create_parsing_impl<char32_t>(in, lc); +#endif } -} - - - -} // impl_std -} // locale -} //boost - - + return in; + } +}}} // namespace boost::locale::impl_win 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 43b221beb9..b7aae73b84 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 @@ -5,54 +5,41 @@ // https://www.boost.org/LICENSE_1_0.txt #define BOOST_LOCALE_SOURCE -#include <boost/locale/localization_backend.hpp> +#include "boost/locale/win32/win_backend.hpp" #include <boost/locale/gnu_gettext.hpp> #include <boost/locale/info.hpp> +#include <boost/locale/localization_backend.hpp> #include <boost/locale/util.hpp> -#include "boost/locale/win32/all_generator.hpp" -#include "boost/locale/win32/win_backend.hpp" #include "boost/locale/util/gregorian.hpp" #include "boost/locale/util/locale_data.hpp" +#include "boost/locale/win32/all_generator.hpp" #include "boost/locale/win32/api.hpp" #include <algorithm> #include <iterator> #include <vector> -namespace boost { -namespace locale { -namespace impl_win { +namespace boost { namespace locale { namespace impl_win { class winapi_localization_backend : public localization_backend { public: - winapi_localization_backend() : - invalid_(true) - { - } - winapi_localization_backend(winapi_localization_backend const &other) : - localization_backend(), - paths_(other.paths_), - domains_(other.domains_), - locale_id_(other.locale_id_), + winapi_localization_backend() : invalid_(true) {} + winapi_localization_backend(const winapi_localization_backend& other) : + localization_backend(), paths_(other.paths_), domains_(other.domains_), locale_id_(other.locale_id_), invalid_(true) - { - } - winapi_localization_backend *clone() const BOOST_OVERRIDE - { - return new winapi_localization_backend(*this); - } + {} + winapi_localization_backend* clone() const override { return new winapi_localization_backend(*this); } - void set_option(std::string const &name,std::string const &value) + void set_option(const std::string& name, const std::string& value) override { invalid_ = true; - if(name=="locale") + if(name == "locale") locale_id_ = value; - else if(name=="message_path") + else if(name == "message_path") paths_.push_back(value); - else if(name=="message_application") + else if(name == "message_application") domains_.push_back(value); - } - void clear_options() + void clear_options() override { invalid_ = true; locale_id_.clear(); @@ -68,9 +55,8 @@ namespace impl_win { if(locale_id_.empty()) { real_id_ = util::get_system_locale(true); // always UTF-8 lc_ = winlocale(real_id_); - } - else { - lc_=winlocale(locale_id_); + } else { + lc_ = winlocale(locale_id_); real_id_ = locale_id_; } util::locale_data d; @@ -81,58 +67,57 @@ namespace impl_win { } } - std::locale install(std::locale const &base, - locale_category_type category, - character_facet_type type = nochar_facet) BOOST_OVERRIDE + std::locale install(const std::locale& base, category_t category, char_facet_t type) override { prepare_data(); switch(category) { - case convert_facet: - return create_convert(base,lc_,type); - case collation_facet: - return create_collate(base,lc_,type); - case formatting_facet: - return create_formatting(base,lc_,type); - case parsing_facet: - return create_parsing(base,lc_,type); - case calendar_facet: - { + case category_t::convert: return create_convert(base, lc_, type); + case category_t::collation: return create_collate(base, lc_, type); + case category_t::formatting: return create_formatting(base, lc_, type); + case category_t::parsing: return create_parsing(base, lc_, type); + case category_t::calendar: { util::locale_data inf; inf.parse(real_id_); - return util::install_gregorian_calendar(base,inf.country); + return util::install_gregorian_calendar(base, inf.country); } - case message_facet: - { + case category_t::message: { gnu_gettext::messages_info minf; - std::locale tmp=util::create_info(std::locale::classic(),real_id_); - boost::locale::info const &inf=std::use_facet<boost::locale::info>(tmp); + std::locale tmp = util::create_info(std::locale::classic(), real_id_); + const boost::locale::info& inf = std::use_facet<boost::locale::info>(tmp); minf.language = inf.language(); minf.country = inf.country(); minf.variant = inf.variant(); minf.encoding = inf.encoding(); - std::copy(domains_.begin(),domains_.end(),std::back_inserter<gnu_gettext::messages_info::domains_type>(minf.domains)); + std::copy(domains_.begin(), + domains_.end(), + std::back_inserter<gnu_gettext::messages_info::domains_type>(minf.domains)); minf.paths = paths_; switch(type) { - case char_facet: - return std::locale(base,gnu_gettext::create_messages_facet<char>(minf)); - case wchar_t_facet: - return std::locale(base,gnu_gettext::create_messages_facet<wchar_t>(minf)); - default: - return base; + case char_facet_t::nochar: break; + case char_facet_t::char_f: + return std::locale(base, gnu_gettext::create_messages_facet<char>(minf)); + case char_facet_t::wchar_f: + return std::locale(base, gnu_gettext::create_messages_facet<wchar_t>(minf)); +#ifdef BOOST_LOCALE_ENABLE_CHAR16_T + case char_facet_t::char16_f: + return std::locale(base, gnu_gettext::create_messages_facet<char16_t>(minf)); +#endif +#ifdef BOOST_LOCALE_ENABLE_CHAR32_T + case char_facet_t::char32_f: + return std::locale(base, gnu_gettext::create_messages_facet<char32_t>(minf)); +#endif } + return base; } - case information_facet: - return util::create_info(base,real_id_); - case codepage_facet: - return util::create_utf8_codecvt(base,type); - default: - return base; + case category_t::information: return util::create_info(base, real_id_); + case category_t::codepage: return util::create_utf8_codecvt(base, type); + case category_t::boundary: break; // Not implemented } + return base; } private: - std::vector<std::string> paths_; std::vector<std::string> domains_; std::string locale_id_; @@ -142,11 +127,9 @@ namespace impl_win { winlocale lc_; }; - localization_backend *create_localization_backend() + localization_backend* create_localization_backend() { return new winapi_localization_backend(); } -} // impl win -} // locale -} // boost +}}} // 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 e63d69e346..57fa5c2919 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,13 +6,10 @@ #ifndef BOOST_LOCALE_IMPL_WIN32_LOCALIZATION_BACKEND_HPP #define BOOST_LOCALE_IMPL_WIN32_LOCALIZATION_BACKEND_HPP -namespace boost { - namespace locale { - class localization_backend; - namespace impl_win { - localization_backend *create_localization_backend(); - } // impl_win - } // locale -} // boost +namespace boost { namespace locale { + class localization_backend; + namespace impl_win { + localization_backend* create_localization_backend(); + } // namespace impl_win +}} // namespace boost::locale #endif - |