update boost
This commit is contained in:
@@ -1,18 +1,16 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// 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_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
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
|
||||
@@ -1,41 +1,37 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// 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_BOUNDARY_BOUNDARY_POINT_HPP_INCLUDED
|
||||
#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.
|
||||
///
|
||||
/// \brief This class represents a boundary point in the text.
|
||||
///
|
||||
/// It represents a pair - an iterator and a rule that defines this
|
||||
/// 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()
|
||||
/// member function you can get the reason why this specific boundary point was selected.
|
||||
/// 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
|
||||
@@ -45,139 +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);
|
||||
}
|
||||
///
|
||||
/// Check if the boundary point points to same location as an iterator \a other
|
||||
///
|
||||
bool operator==(iterator_type const &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 boundary_point& other) const { return !(*this == other); }
|
||||
|
||||
/// Check if the boundary point points to same location as an iterator \a 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!=(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
|
||||
|
||||
|
||||
} // boundary
|
||||
} // locale
|
||||
} // boost
|
||||
|
||||
|
||||
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
|
||||
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
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
|
||||
|
||||
@@ -1,203 +1,83 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// 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_BOUNDARY_FACETS_HPP_INCLUDED
|
||||
#define BOOST_LOCALE_BOUNDARY_FACETS_HPP_INCLUDED
|
||||
|
||||
#include <boost/locale/config.hpp>
|
||||
#include <boost/locale/boundary/types.hpp>
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4275 4251 4231 4660)
|
||||
#endif
|
||||
#include <boost/locale/detail/facet_id.hpp>
|
||||
#include <boost/locale/detail/is_supported_char.hpp>
|
||||
#include <locale>
|
||||
#include <vector>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# 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 namespae 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;
|
||||
|
||||
/// \brief This facet generates an index for boundary analysis of a given text.
|
||||
///
|
||||
namespace boundary {
|
||||
///
|
||||
/// \addtogroup boundary
|
||||
///
|
||||
/// @{
|
||||
/// It is implemented for supported character types, at least \c char, \c wchar_t
|
||||
template<typename Char>
|
||||
class BOOST_SYMBOL_VISIBLE boundary_indexing : public std::locale::facet,
|
||||
public boost::locale::detail::facet_id<boundary_indexing<Char>> {
|
||||
BOOST_LOCALE_ASSERT_IS_SUPPORTED(Char);
|
||||
|
||||
public:
|
||||
/// Default constructor typical for facets
|
||||
boundary_indexing(size_t refs = 0) : std::locale::facet(refs) {}
|
||||
|
||||
/// 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, const Char* begin, const Char* end) const = 0;
|
||||
};
|
||||
|
||||
|
||||
///
|
||||
/// \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 beggining 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;
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
}
|
||||
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)
|
||||
{
|
||||
}
|
||||
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)
|
||||
{
|
||||
}
|
||||
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)
|
||||
{
|
||||
}
|
||||
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
|
||||
|
||||
} // locale
|
||||
} // boost
|
||||
/// @}
|
||||
} // namespace boundary
|
||||
|
||||
}} // namespace boost::locale
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(pop)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,93 +1,82 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// 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_BOUNDARY_SEGMENT_HPP_INCLUDED
|
||||
#define BOOST_LOCALE_BOUNDARY_SEGMENT_HPP_INCLUDED
|
||||
#include <boost/locale/config.hpp>
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4275 4251 4231 4660)
|
||||
#endif
|
||||
#include <locale>
|
||||
#include <string>
|
||||
|
||||
#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)
|
||||
#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());
|
||||
}
|
||||
|
||||
template<typename Left,typename Char>
|
||||
int compare_string(Left const &l,Char const *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(), r.begin(), r.end());
|
||||
}
|
||||
|
||||
template<typename Right,typename Char>
|
||||
int compare_string(Char const *begin,Right const &r)
|
||||
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(begin,end,r.begin(),r.end());
|
||||
return compare_text(l.begin(), l.end(), begin, util::str_end(begin));
|
||||
}
|
||||
|
||||
}
|
||||
template<typename Right, typename Char>
|
||||
int compare_string(const Char* begin, const Right& r)
|
||||
{
|
||||
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.
|
||||
@@ -95,389 +84,294 @@ namespace boundary {
|
||||
/// \see
|
||||
///
|
||||
/// - \ref segment_index
|
||||
/// - \ref boundary_point
|
||||
/// - \ref boundary_point_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
|
||||
///
|
||||
/// 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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/// Compare C string and segment
|
||||
template<typename CharType,typename IteratorR>
|
||||
bool operator==(CharType const *l,segment<IteratorR> const &r)
|
||||
{
|
||||
return details::compare_string(l,r) == 0;
|
||||
}
|
||||
/// Compare C string and segment
|
||||
template<typename CharType,typename IteratorR>
|
||||
bool operator!=(CharType const *l,segment<IteratorR> const &r)
|
||||
{
|
||||
return details::compare_string(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;
|
||||
}
|
||||
/// Compare C string and segment
|
||||
template<typename CharType,typename IteratorR>
|
||||
bool operator>(CharType const *l,segment<IteratorR> const &r)
|
||||
{
|
||||
return details::compare_string(l,r) > 0;
|
||||
}
|
||||
/// Compare C string and segment
|
||||
template<typename CharType,typename IteratorR>
|
||||
bool operator>=(CharType const *l,segment<IteratorR> const &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 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 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>(const CharType* l, const segment<IteratorR>& r)
|
||||
{
|
||||
return detail::compare_string(l, r) > 0;
|
||||
}
|
||||
/// Compare C string and segment
|
||||
template<typename CharType, typename IteratorR>
|
||||
bool operator>=(const CharType* l, const segment<IteratorR>& r)
|
||||
{
|
||||
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<(const segment<Iterator>& l, const CharType* r)
|
||||
{
|
||||
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>=(const segment<Iterator>& l, const CharType* r)
|
||||
{
|
||||
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>& seg)
|
||||
{
|
||||
for(Iterator p=tok.begin(),e=tok.end();p!=e;++p)
|
||||
out << *p;
|
||||
for(const auto& p : seg)
|
||||
out << p;
|
||||
return out;
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
} // boundary
|
||||
} // locale
|
||||
} // boost
|
||||
}}} // namespace boost::locale::boundary
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(pop)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
|
||||
@@ -1,136 +1,110 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// 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_BOUNDARY_TYPES_HPP_INCLUDED
|
||||
#define BOOST_LOCALE_BOUNDARY_TYPES_HPP_INCLUDED
|
||||
|
||||
#include <boost/locale/config.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <cstdint>
|
||||
|
||||
#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 {
|
||||
/// \defgroup boundary Boundary Analysis
|
||||
///
|
||||
/// \brief This namespase contains all operations required for boundary analysis of text
|
||||
/// This module contains all operations required for boundary analysis of text: character, word, like and
|
||||
/// sentence boundaries
|
||||
///
|
||||
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
|
||||
};
|
||||
/// 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;
|
||||
/// \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_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
|
||||
/// @{
|
||||
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
|
||||
/// \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
|
||||
|
||||
///@}
|
||||
/// @}
|
||||
|
||||
///
|
||||
/// \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
|
||||
/// \anchor bl_boundary_sentence_rules
|
||||
/// \name Flags that describe a type of sentence break
|
||||
///
|
||||
/// @{
|
||||
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
|
||||
|
||||
///@}
|
||||
///@}
|
||||
|
||||
///
|
||||
/// This function returns the mask that covers all variants for specific boundary type
|
||||
///
|
||||
inline rule_type boundary_rule(boundary_type t)
|
||||
{
|
||||
switch(t) {
|
||||
/// \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
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
|
||||
@@ -1,86 +1,71 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// 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_COLLATOR_HPP_INCLUDED
|
||||
#define BOOST_LOCALE_COLLATOR_HPP_INCLUDED
|
||||
|
||||
#include <boost/locale/config.hpp>
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4275 4251 4231 4660)
|
||||
#endif
|
||||
#include <locale>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4275 4251 4231 4660)
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
namespace boost { namespace locale {
|
||||
|
||||
class info;
|
||||
|
||||
///
|
||||
/// \defgroup collation Collation
|
||||
/// \defgroup collation Collation
|
||||
///
|
||||
/// This module introduces collation related classes
|
||||
///
|
||||
/// @{
|
||||
|
||||
///
|
||||
/// \brief a base class that includes collation level flags
|
||||
///
|
||||
|
||||
class 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;
|
||||
/// 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
|
||||
};
|
||||
|
||||
///
|
||||
/// \brief Collation facet.
|
||||
|
||||
class BOOST_DEPRECATED("Use collate_level") collator_base {
|
||||
public:
|
||||
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.
|
||||
///
|
||||
@@ -90,47 +75,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.
|
||||
///
|
||||
@@ -138,124 +111,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) {}
|
||||
|
||||
virtual ~collator()
|
||||
{
|
||||
}
|
||||
|
||||
///
|
||||
/// This function is used to override default collation function that does not take in account collation level.
|
||||
/// Uses primary level
|
||||
///
|
||||
virtual int do_compare( char_type const *b1,char_type const *e1,
|
||||
char_type const *b2,char_type const *e2) const
|
||||
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
|
||||
///
|
||||
virtual string_type do_transform(char_type const *b,char_type const *e) const
|
||||
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
|
||||
///
|
||||
virtual long do_hash(char_type const *b,char_type const *e) const
|
||||
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 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;
|
||||
///
|
||||
/// 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;
|
||||
|
||||
/// 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(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(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
|
||||
{
|
||||
/// Would create a map the keys of which are sorted using secondary collation level
|
||||
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)
|
||||
/// \throws std::bad_cast: \a l does not have \ref collator facet installed
|
||||
comparator(const std::locale& l = std::locale(), collate_level level = default_level) :
|
||||
locale_(l), level_(level)
|
||||
{}
|
||||
|
||||
/// Compare two strings -- equivalent to return left < right according to collation rules
|
||||
bool operator()(const std::basic_string<CharType>& left, const std::basic_string<CharType>& right) const
|
||||
{
|
||||
return std::use_facet<collator<CharType>>(locale_).compare(level_, left, right) < 0;
|
||||
}
|
||||
|
||||
///
|
||||
/// 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
|
||||
{
|
||||
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
|
||||
///
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,37 +1,87 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// 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_CONFIG_HPP_INCLUDED
|
||||
#define BOOST_LOCALE_CONFIG_HPP_INCLUDED
|
||||
|
||||
#include <boost/locale/definitions.hpp>
|
||||
#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
|
||||
#else
|
||||
# define BOOST_LOCALE_DECL
|
||||
#endif // BOOST_LOCALE_DYN_LINK
|
||||
|
||||
//
|
||||
// Automatically link to the correct build variant where possible.
|
||||
//
|
||||
// Automatically link to the correct build variant where possible.
|
||||
//
|
||||
#if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_LOCALE_NO_LIB) && !defined(BOOST_LOCALE_SOURCE)
|
||||
//
|
||||
// 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
|
||||
# include <boost/config/auto_link.hpp>
|
||||
#endif // auto-linking disabled
|
||||
|
||||
// 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))
|
||||
#else
|
||||
# define BOOST_LOCALE_START_CONST_CONDITION
|
||||
# define BOOST_LOCALE_END_CONST_CONDITION
|
||||
#endif
|
||||
|
||||
/// \cond INTERNAL
|
||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
// Internal define to check if we have access to the Win32 API
|
||||
# define BOOST_LOCALE_USE_WIN32_API 1
|
||||
#else
|
||||
# define BOOST_LOCALE_USE_WIN32_API 0
|
||||
#endif
|
||||
|
||||
// To be used to suppress false positives of UBSAN
|
||||
#if defined(__clang__) && defined(__has_attribute)
|
||||
# if __has_attribute(no_sanitize)
|
||||
# define BOOST_LOCALE_NO_SANITIZE(what) __attribute__((no_sanitize(what)))
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(BOOST_LOCALE_NO_SANITIZE)
|
||||
# define BOOST_LOCALE_NO_SANITIZE(what)
|
||||
#endif
|
||||
/// \endcond
|
||||
|
||||
#endif // boost/locale/config.hpp
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
|
||||
|
||||
@@ -1,372 +1,243 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// 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_CONVERTER_HPP_INCLUDED
|
||||
#define BOOST_LOCALE_CONVERTER_HPP_INCLUDED
|
||||
|
||||
#include <boost/locale/config.hpp>
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4275 4251 4231 4660)
|
||||
#endif
|
||||
#include <boost/locale/detail/facet_id.hpp>
|
||||
#include <boost/locale/detail/is_supported_char.hpp>
|
||||
#include <boost/locale/util/string.hpp>
|
||||
#include <locale>
|
||||
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
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; }
|
||||
#ifdef BOOST_MSVC
|
||||
# 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
|
||||
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
|
||||
};
|
||||
#else
|
||||
};
|
||||
|
||||
template<>
|
||||
class BOOST_LOCALE_DECL converter<char> : public converter_base, public std::locale::facet {
|
||||
public:
|
||||
static std::locale::id id;
|
||||
/// \brief The facet that implements text manipulation
|
||||
///
|
||||
/// It is used to perform text conversion operations defined by \ref converter_base::conversion_type.
|
||||
/// It is implemented for supported character types, at least \c char, \c wchar_t
|
||||
template<typename Char>
|
||||
class BOOST_SYMBOL_VISIBLE converter : public converter_base,
|
||||
public std::locale::facet,
|
||||
public detail::facet_id<converter<Char>> {
|
||||
BOOST_LOCALE_ASSERT_IS_SUPPORTED(Char);
|
||||
|
||||
converter(size_t refs = 0) : std::locale::facet(refs)
|
||||
{
|
||||
}
|
||||
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
|
||||
};
|
||||
public:
|
||||
/// Standard constructor
|
||||
converter(size_t refs = 0) : std::locale::facet(refs) {}
|
||||
/// Convert text in range [\a begin, \a end) according to conversion method \a how. Parameter
|
||||
/// \a flags is used for specification of normalization method like nfd, nfc etc.
|
||||
virtual std::basic_string<Char>
|
||||
convert(conversion_type how, const Char* begin, const Char* end, int flags = 0) const = 0;
|
||||
};
|
||||
|
||||
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)
|
||||
{
|
||||
}
|
||||
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
|
||||
};
|
||||
/// 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
|
||||
};
|
||||
|
||||
#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)
|
||||
{
|
||||
}
|
||||
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
|
||||
/// 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.
|
||||
///
|
||||
/// \throws std::bad_cast: \a loc does not have \ref converter facet installed
|
||||
template<typename CharType>
|
||||
std::basic_string<CharType> normalize(const CharType* begin,
|
||||
const CharType* end,
|
||||
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);
|
||||
}
|
||||
|
||||
#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)
|
||||
{
|
||||
}
|
||||
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
|
||||
/// 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.
|
||||
///
|
||||
/// \throws std::bad_cast: \a loc does not have \ref converter facet installed
|
||||
template<typename CharType>
|
||||
std::basic_string<CharType> normalize(const std::basic_string<CharType>& str,
|
||||
norm_type n = norm_default,
|
||||
const std::locale& loc = std::locale())
|
||||
{
|
||||
return normalize(str.data(), str.data() + str.size(), n, loc);
|
||||
}
|
||||
|
||||
#endif
|
||||
/// 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.
|
||||
///
|
||||
/// \throws std::bad_cast: \a loc does not have \ref converter facet installed
|
||||
template<typename CharType>
|
||||
std::basic_string<CharType>
|
||||
normalize(const CharType* str, norm_type n = norm_default, const std::locale& loc = std::locale())
|
||||
{
|
||||
return normalize(str, util::str_end(str), n, loc);
|
||||
}
|
||||
|
||||
///
|
||||
/// 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);
|
||||
}
|
||||
/// Convert a string in range [begin,end) to upper case according to locale \a loc
|
||||
///
|
||||
/// \throws std::bad_cast: \a loc does not have \ref converter facet installed
|
||||
template<typename CharType>
|
||||
std::basic_string<CharType>
|
||||
to_upper(const CharType* begin, const CharType* end, const std::locale& loc = std::locale())
|
||||
{
|
||||
return std::use_facet<converter<CharType>>(loc).convert(converter_base::upper_case, begin, end);
|
||||
}
|
||||
|
||||
///
|
||||
/// 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
|
||||
///
|
||||
/// \throws std::bad_cast: \a loc does not have \ref converter facet installed
|
||||
template<typename CharType>
|
||||
std::basic_string<CharType> to_upper(const std::basic_string<CharType>& str, const std::locale& loc = std::locale())
|
||||
{
|
||||
return to_upper(str.data(), str.data() + str.size(), loc);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////
|
||||
|
||||
///
|
||||
/// 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
|
||||
///
|
||||
/// Convert a NULL terminated string \a str to upper case according to locale \a loc
|
||||
///
|
||||
/// \throws std::bad_cast: \a loc does not have \ref converter facet installed
|
||||
template<typename CharType>
|
||||
std::basic_string<CharType> to_upper(const CharType* str, const std::locale& loc = std::locale())
|
||||
{
|
||||
return to_upper(str, util::str_end(str), loc);
|
||||
}
|
||||
|
||||
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
|
||||
///
|
||||
/// Convert a string in range [begin,end) to lower case according to locale \a loc
|
||||
///
|
||||
/// \throws std::bad_cast: \a loc does not have \ref converter facet installed
|
||||
template<typename CharType>
|
||||
std::basic_string<CharType>
|
||||
to_lower(const CharType* begin, const CharType* end, const std::locale& loc = std::locale())
|
||||
{
|
||||
return std::use_facet<converter<CharType>>(loc).convert(converter_base::lower_case, begin, end);
|
||||
}
|
||||
|
||||
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
|
||||
///
|
||||
/// Convert a string \a str to lower case according to locale \a loc
|
||||
///
|
||||
/// \throws std::bad_cast: \a loc does not have \ref converter facet installed
|
||||
template<typename CharType>
|
||||
std::basic_string<CharType> to_lower(const std::basic_string<CharType>& str, const std::locale& loc = std::locale())
|
||||
{
|
||||
return to_lower(str.data(), str.data() + str.size(), loc);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
/// Convert a NULL terminated string \a str to lower case according to locale \a loc
|
||||
///
|
||||
/// \throws std::bad_cast: \a loc does not have \ref converter facet installed
|
||||
template<typename CharType>
|
||||
std::basic_string<CharType> to_lower(const CharType* str, const std::locale& loc = std::locale())
|
||||
{
|
||||
return to_lower(str, util::str_end(str), loc);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////
|
||||
|
||||
///
|
||||
/// 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);
|
||||
}
|
||||
/// Convert a string in range [begin,end) to title case according to locale \a loc
|
||||
///
|
||||
/// \throws std::bad_cast: \a loc does not have \ref converter facet installed
|
||||
template<typename CharType>
|
||||
std::basic_string<CharType>
|
||||
to_title(const CharType* begin, const CharType* end, const std::locale& loc = std::locale())
|
||||
{
|
||||
return std::use_facet<converter<CharType>>(loc).convert(converter_base::title_case, begin, end);
|
||||
}
|
||||
|
||||
///
|
||||
///@}
|
||||
///
|
||||
} // locale
|
||||
/// Convert a string \a str to title case according to locale \a loc
|
||||
///
|
||||
/// \throws std::bad_cast: \a loc does not have \ref converter facet installed
|
||||
template<typename CharType>
|
||||
std::basic_string<CharType> to_title(const std::basic_string<CharType>& str, const std::locale& loc = std::locale())
|
||||
{
|
||||
return to_title(str.data(), str.data() + str.size(), loc);
|
||||
}
|
||||
|
||||
} // boost
|
||||
/// Convert a NULL terminated string \a str to title case according to locale \a loc
|
||||
///
|
||||
/// \throws std::bad_cast: \a loc does not have \ref converter facet installed
|
||||
template<typename CharType>
|
||||
std::basic_string<CharType> to_title(const CharType* str, const std::locale& loc = std::locale())
|
||||
{
|
||||
return to_title(str, util::str_end(str), loc);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////
|
||||
|
||||
/// Fold case of a string in range [begin,end) according to locale \a loc
|
||||
///
|
||||
/// \throws std::bad_cast: \a loc does not have \ref converter facet installed
|
||||
template<typename CharType>
|
||||
std::basic_string<CharType>
|
||||
fold_case(const CharType* begin, const CharType* end, const std::locale& loc = std::locale())
|
||||
{
|
||||
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
|
||||
///
|
||||
/// \throws std::bad_cast: \a loc does not have \ref converter facet installed
|
||||
template<typename CharType>
|
||||
std::basic_string<CharType> fold_case(const std::basic_string<CharType>& str,
|
||||
const std::locale& loc = std::locale())
|
||||
{
|
||||
return fold_case(str.data(), str.data() + str.size(), loc);
|
||||
}
|
||||
|
||||
/// Fold case of a NULL terminated string \a str according to locale \a loc
|
||||
///
|
||||
/// \throws std::bad_cast: \a loc does not have \ref converter facet installed
|
||||
template<typename CharType>
|
||||
std::basic_string<CharType> fold_case(const CharType* str, const std::locale& loc = std::locale())
|
||||
{
|
||||
return fold_case(str, util::str_end(str), loc);
|
||||
}
|
||||
|
||||
///@}
|
||||
}} // namespace boost::locale
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(pop)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
///
|
||||
/// \example conversions.cpp
|
||||
///
|
||||
/// Example of using various text conversion functions.
|
||||
@@ -374,7 +245,5 @@ namespace boost {
|
||||
/// \example wconversions.cpp
|
||||
///
|
||||
/// Example of using various text conversion functions with wide strings.
|
||||
///
|
||||
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,263 +1,185 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// 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_DATE_TIME_FACET_HPP_INCLUDED
|
||||
#define BOOST_LOCALE_DATE_TIME_FACET_HPP_INCLUDED
|
||||
|
||||
#include <boost/locale/config.hpp>
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4275 4251 4231 4660)
|
||||
#endif
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/locale/detail/facet_id.hpp>
|
||||
#include <cstdint>
|
||||
#include <locale>
|
||||
|
||||
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
|
||||
};
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4275 4251 4231 4660)
|
||||
#endif
|
||||
|
||||
} // marks
|
||||
namespace boost { namespace locale {
|
||||
|
||||
///
|
||||
/// \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_;
|
||||
}
|
||||
/// \brief Namespace that contains various types for manipulation with dates
|
||||
namespace period {
|
||||
|
||||
///
|
||||
/// 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_;
|
||||
/// \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
|
||||
};
|
||||
|
||||
///
|
||||
/// 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 abstract_calendar {
|
||||
/// 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) {}
|
||||
|
||||
///
|
||||
/// 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;
|
||||
/// Get the value of marks::period_mark it was created with.
|
||||
marks::period_mark mark() const { return mark_; }
|
||||
|
||||
///
|
||||
/// 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 p,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 p,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 p,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 p) 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()
|
||||
{
|
||||
}
|
||||
/// 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_;
|
||||
};
|
||||
|
||||
///
|
||||
/// \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)
|
||||
{
|
||||
}
|
||||
///
|
||||
/// Create a new calendar that points to current point of time.
|
||||
///
|
||||
virtual abstract_calendar *create_calendar() const = 0;
|
||||
} // namespace period
|
||||
|
||||
///
|
||||
/// Locale id (needed to work with std::locale)
|
||||
///
|
||||
static std::locale::id id;
|
||||
/// 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_SYMBOL_VISIBLE 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.
|
||||
};
|
||||
|
||||
} // locale
|
||||
} // boost
|
||||
/// 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
|
||||
};
|
||||
|
||||
/// 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.
|
||||
///
|
||||
/// 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().
|
||||
///
|
||||
/// 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(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() = default;
|
||||
};
|
||||
|
||||
/// \brief the facet that generates calendar for specific locale
|
||||
class BOOST_SYMBOL_VISIBLE calendar_facet : public std::locale::facet, public detail::facet_id<calendar_facet> {
|
||||
public:
|
||||
/// Basic constructor
|
||||
calendar_facet(size_t refs = 0) : std::locale::facet(refs) {}
|
||||
/// Create a new calendar that points to current point of time.
|
||||
virtual abstract_calendar* create_calendar() const = 0;
|
||||
};
|
||||
|
||||
}} // namespace boost::locale
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(pop)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#ifndef BOOST_LOCALE_DEFINITIONS_HPP_INCLUDED
|
||||
#define BOOST_LOCALE_DEFINITIONS_HPP_INCLUDED
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
// Support older ICU versions
|
||||
#ifndef BOOST_SYMBOL_VISIBLE
|
||||
# define BOOST_SYMBOL_VISIBLE
|
||||
#endif
|
||||
|
||||
#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
|
||||
#endif // DYN_LINK
|
||||
|
||||
#ifndef BOOST_LOCALE_DECL
|
||||
# define BOOST_LOCALE_DECL
|
||||
#endif
|
||||
|
||||
#endif // boost/locale/config.hpp
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
|
||||
58
linx64/include/boost/locale/detail/encoding.hpp
Normal file
58
linx64/include/boost/locale/detail/encoding.hpp
Normal file
@@ -0,0 +1,58 @@
|
||||
//
|
||||
// Copyright (c) 2022-2023 Alexander Grund
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#ifndef BOOST_LOCALE_DETAIL_ENCODING_HPP_INCLUDED
|
||||
#define BOOST_LOCALE_DETAIL_ENCODING_HPP_INCLUDED
|
||||
|
||||
#include <boost/locale/config.hpp>
|
||||
#include <boost/locale/encoding_errors.hpp>
|
||||
#include <boost/utility/string_view.hpp>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
/// \cond INTERNAL
|
||||
namespace boost { namespace locale { namespace conv { namespace detail {
|
||||
template<typename CharIn, typename CharOut>
|
||||
class BOOST_SYMBOL_VISIBLE charset_converter {
|
||||
public:
|
||||
using char_out_type = CharOut;
|
||||
using char_in_type = CharIn;
|
||||
using string_type = std::basic_string<CharOut>;
|
||||
|
||||
virtual ~charset_converter() = default;
|
||||
virtual string_type convert(const CharIn* begin, const CharIn* end) = 0;
|
||||
string_type convert(const boost::basic_string_view<CharIn>& text)
|
||||
{
|
||||
return convert(text.data(), text.data() + text.length());
|
||||
}
|
||||
};
|
||||
|
||||
using narrow_converter = charset_converter<char, char>;
|
||||
|
||||
template<typename CharType>
|
||||
using utf_encoder = charset_converter<char, CharType>;
|
||||
|
||||
template<typename CharType>
|
||||
using utf_decoder = charset_converter<CharType, char>;
|
||||
|
||||
enum class conv_backend { Default, IConv, ICU, WinAPI };
|
||||
|
||||
template<typename Char>
|
||||
BOOST_LOCALE_DECL std::unique_ptr<utf_encoder<Char>>
|
||||
make_utf_encoder(const std::string& charset, method_type how, conv_backend impl = conv_backend::Default);
|
||||
template<typename Char>
|
||||
BOOST_LOCALE_DECL std::unique_ptr<utf_decoder<Char>>
|
||||
make_utf_decoder(const std::string& charset, method_type how, conv_backend impl = conv_backend::Default);
|
||||
BOOST_LOCALE_DECL std::unique_ptr<narrow_converter>
|
||||
make_narrow_converter(const std::string& src_encoding,
|
||||
const std::string& target_encoding,
|
||||
method_type how,
|
||||
conv_backend impl = conv_backend::Default);
|
||||
}}}} // namespace boost::locale::conv::detail
|
||||
|
||||
/// \endcond
|
||||
|
||||
#endif
|
||||
35
linx64/include/boost/locale/detail/facet_id.hpp
Normal file
35
linx64/include/boost/locale/detail/facet_id.hpp
Normal file
@@ -0,0 +1,35 @@
|
||||
//
|
||||
// Copyright (c) 2022-2023 Alexander Grund
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#ifndef BOOST_LOCALE_DETAIL_FACET_ID_HPP_INCLUDED
|
||||
#define BOOST_LOCALE_DETAIL_FACET_ID_HPP_INCLUDED
|
||||
|
||||
#include <boost/locale/config.hpp>
|
||||
#include <locale>
|
||||
|
||||
/// \cond INTERNAL
|
||||
namespace boost { namespace locale { namespace detail {
|
||||
#if defined(__clang__)
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wundefined-var-template"
|
||||
#endif
|
||||
/// CRTP base class to hold the id required for facets
|
||||
///
|
||||
/// Required because the id needs to be defined in a CPP file and hence ex/imported for shared libraries.
|
||||
/// However the virtual classes need to be declared as BOOST_VISIBLE to combine the VTables because otherwise
|
||||
/// casts/virtual-calls might be flagged as invalid by UBSAN
|
||||
template<class Derived>
|
||||
struct BOOST_LOCALE_DECL facet_id {
|
||||
static std::locale::id id;
|
||||
};
|
||||
#if defined(__clang__)
|
||||
# pragma clang diagnostic pop
|
||||
#endif
|
||||
}}} // namespace boost::locale::detail
|
||||
|
||||
/// \endcond
|
||||
|
||||
#endif
|
||||
44
linx64/include/boost/locale/detail/is_supported_char.hpp
Normal file
44
linx64/include/boost/locale/detail/is_supported_char.hpp
Normal file
@@ -0,0 +1,44 @@
|
||||
//
|
||||
// Copyright (c) 2022-2023 Alexander Grund
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#ifndef BOOST_LOCALE_DETAIL_IS_SUPPORTED_CHAR_HPP_INCLUDED
|
||||
#define BOOST_LOCALE_DETAIL_IS_SUPPORTED_CHAR_HPP_INCLUDED
|
||||
|
||||
#include <boost/locale/config.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
/// \cond INTERNAL
|
||||
namespace boost { namespace locale { namespace detail {
|
||||
/// Trait, returns true iff the argument is a supported character type
|
||||
template<typename Char>
|
||||
struct is_supported_char : std::false_type {};
|
||||
|
||||
template<>
|
||||
struct is_supported_char<char> : std::true_type {};
|
||||
template<>
|
||||
struct is_supported_char<wchar_t> : std::true_type {};
|
||||
|
||||
#ifdef BOOST_LOCALE_ENABLE_CHAR16_T
|
||||
template<>
|
||||
struct is_supported_char<char16_t> : std::true_type {};
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_LOCALE_ENABLE_CHAR32_T
|
||||
template<>
|
||||
struct is_supported_char<char32_t> : std::true_type {};
|
||||
#endif
|
||||
|
||||
template<typename Char>
|
||||
using enable_if_is_supported_char = typename std::enable_if<is_supported_char<Char>::value>::type;
|
||||
|
||||
}}} // namespace boost::locale::detail
|
||||
|
||||
#define BOOST_LOCALE_ASSERT_IS_SUPPORTED(Char) \
|
||||
static_assert(boost::locale::detail::is_supported_char<Char>::value, "Unsupported Char type")
|
||||
|
||||
/// \endcond
|
||||
|
||||
#endif
|
||||
@@ -1,248 +1,314 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// 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_ENCODING_HPP_INCLUDED
|
||||
#define BOOST_LOCALE_ENCODING_HPP_INCLUDED
|
||||
|
||||
#include <boost/locale/config.hpp>
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4275 4251 4231 4660)
|
||||
#endif
|
||||
#include <boost/locale/info.hpp>
|
||||
#include <boost/locale/detail/encoding.hpp>
|
||||
#include <boost/locale/encoding_errors.hpp>
|
||||
#include <boost/locale/encoding_utf.hpp>
|
||||
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
|
||||
///
|
||||
/// \brief Namespace that contains all functions related to character set conversion
|
||||
///
|
||||
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
|
||||
#include <boost/locale/info.hpp>
|
||||
#include <boost/locale/util/string.hpp>
|
||||
#include <memory>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(pop)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4275 4251 4231 4660)
|
||||
#endif
|
||||
|
||||
namespace boost { namespace locale {
|
||||
|
||||
/// \brief Namespace that contains all functions related to character set conversion
|
||||
namespace conv {
|
||||
|
||||
/// \defgroup Charset conversion functions
|
||||
///
|
||||
/// @{
|
||||
|
||||
/// convert text in range [begin,end) encoded with \a charset to UTF according to policy \a how
|
||||
///
|
||||
/// \throws invalid_charset_error: Character set is not supported
|
||||
/// \throws conversion_error: Conversion failed (e.g. \a how is \c stop and any character cannot be
|
||||
/// encoded or decoded)
|
||||
template<typename CharType>
|
||||
BOOST_LOCALE_DECL std::basic_string<CharType>
|
||||
to_utf(const char* begin, const char* end, const std::string& charset, method_type how = default_method);
|
||||
|
||||
/// convert UTF text in range [begin,end) to text encoded with \a charset according to policy \a how
|
||||
///
|
||||
/// \throws invalid_charset_error: Character set is not supported
|
||||
/// \throws conversion_error: Conversion failed (e.g. \a how is \c stop and any character cannot be
|
||||
/// encoded or decoded)
|
||||
template<typename CharType>
|
||||
BOOST_LOCALE_DECL std::string from_utf(const CharType* begin,
|
||||
const CharType* end,
|
||||
const std::string& charset,
|
||||
method_type how = default_method);
|
||||
|
||||
/// convert \a text encoded with \a charset to UTF according to policy \a how
|
||||
///
|
||||
/// \throws invalid_charset_error: Character set is not supported
|
||||
/// \throws conversion_error: Conversion failed (e.g. \a how is \c stop and any character cannot be
|
||||
/// encoded or decoded)
|
||||
template<typename CharType>
|
||||
std::basic_string<CharType>
|
||||
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 text encoded with \a charset to UTF according to policy \a how
|
||||
///
|
||||
/// \throws invalid_charset_error: Character set is not supported
|
||||
/// \throws conversion_error: Conversion failed (e.g. \a how is \c stop and any character cannot be
|
||||
/// encoded or decoded)
|
||||
template<typename CharType>
|
||||
std::basic_string<CharType>
|
||||
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 text in range [begin,end) in locale encoding given by \a loc to UTF according to
|
||||
/// policy \a how
|
||||
///
|
||||
/// \throws std::bad_cast: \a loc does not have \ref info facet installed
|
||||
/// \throws invalid_charset_error: Character set is not supported
|
||||
/// \throws conversion_error: Conversion failed (e.g. \a how is \c stop and any character cannot be
|
||||
/// encoded or decoded)
|
||||
template<typename CharType>
|
||||
std::basic_string<CharType>
|
||||
to_utf(const 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 \a text in locale encoding given by \a loc to UTF according to policy \a how
|
||||
///
|
||||
/// \throws std::bad_cast: \a loc does not have \ref info facet installed
|
||||
/// \throws invalid_charset_error: Character set is not supported
|
||||
/// \throws conversion_error: Conversion failed (e.g. \a how is \c stop and any character cannot be
|
||||
/// encoded or decoded)
|
||||
template<typename CharType>
|
||||
std::basic_string<CharType>
|
||||
to_utf(const std::string& text, const std::locale& loc, method_type how = default_method)
|
||||
{
|
||||
return to_utf<CharType>(text, std::use_facet<info>(loc).encoding(), how);
|
||||
}
|
||||
|
||||
/// Convert \a text in locale encoding given by \a loc to UTF according to policy \a how
|
||||
///
|
||||
/// \throws std::bad_cast: \a loc does not have \ref info facet installed
|
||||
/// \throws invalid_charset_error: Character set is not supported
|
||||
/// \throws conversion_error: Conversion failed (e.g. \a how is \c stop and any character cannot be
|
||||
/// encoded or decoded)
|
||||
template<typename CharType>
|
||||
std::basic_string<CharType> to_utf(const char* text, const std::locale& loc, method_type how = default_method)
|
||||
{
|
||||
return to_utf<CharType>(text, std::use_facet<info>(loc).encoding(), how);
|
||||
}
|
||||
|
||||
/// convert \a text from UTF to text encoded with \a charset according to policy \a how
|
||||
///
|
||||
/// \throws invalid_charset_error: Character set is not supported
|
||||
/// \throws conversion_error: Conversion failed (e.g. \a how is \c stop and any character cannot be
|
||||
/// encoded or decoded)
|
||||
template<typename CharType>
|
||||
std::string
|
||||
from_utf(const 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 text from UTF to \a charset according to policy \a how
|
||||
///
|
||||
/// \throws invalid_charset_error: Character set is not supported
|
||||
/// \throws conversion_error: Conversion failed (e.g. \a how is \c stop and any character cannot be
|
||||
/// encoded or decoded)
|
||||
template<typename CharType>
|
||||
std::string from_utf(const CharType* text, const std::string& charset, method_type how = default_method)
|
||||
{
|
||||
return from_utf(text, util::str_end(text), charset, how);
|
||||
}
|
||||
|
||||
/// Convert UTF text in range [begin,end) to text in locale encoding given by \a loc according to policy \a how
|
||||
///
|
||||
/// \throws std::bad_cast: \a loc does not have \ref info facet installed
|
||||
/// \throws invalid_charset_error: Character set is not supported
|
||||
/// \throws conversion_error: Conversion failed (e.g. \a how is \c stop and any character cannot be
|
||||
/// encoded or decoded)
|
||||
template<typename CharType>
|
||||
std::string
|
||||
from_utf(const 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 text from UTF to locale encoding given by \a loc according to policy \a how
|
||||
///
|
||||
/// \throws std::bad_cast: \a loc does not have \ref info facet installed
|
||||
/// \throws invalid_charset_error: Character set is not supported
|
||||
/// \throws conversion_error: Conversion failed (e.g. \a how is \c stop and any character cannot be
|
||||
/// encoded or decoded)
|
||||
template<typename CharType>
|
||||
std::string
|
||||
from_utf(const std::basic_string<CharType>& text, const std::locale& loc, method_type how = default_method)
|
||||
{
|
||||
return from_utf(text, std::use_facet<info>(loc).encoding(), how);
|
||||
}
|
||||
|
||||
/// Convert \a text from UTF to locale encoding given by \a loc according to policy \a how
|
||||
///
|
||||
/// \throws std::bad_cast: \a loc does not have \ref info facet installed
|
||||
/// \throws invalid_charset_error: Character set is not supported
|
||||
/// \throws conversion_error: Conversion failed (e.g. \a how is \c stop and any character cannot be
|
||||
/// encoded or decoded)
|
||||
template<typename CharType>
|
||||
std::string from_utf(const CharType* text, const std::locale& loc, method_type how = default_method)
|
||||
{
|
||||
return from_utf(text, std::use_facet<info>(loc).encoding(), how);
|
||||
}
|
||||
|
||||
/// Convert a text in range [begin,end) to \a to_encoding from \a from_encoding according to
|
||||
/// policy \a how
|
||||
///
|
||||
/// \throws invalid_charset_error: Either character set is not supported
|
||||
/// \throws conversion_error: when the conversion fails (e.g. \a how is \c stop and any character cannot be
|
||||
/// encoded or decoded)
|
||||
BOOST_LOCALE_DECL
|
||||
std::string between(const char* begin,
|
||||
const char* end,
|
||||
const std::string& to_encoding,
|
||||
const std::string& from_encoding,
|
||||
method_type how = default_method);
|
||||
|
||||
/// Convert \a text to \a to_encoding from \a from_encoding according to
|
||||
/// policy \a how
|
||||
///
|
||||
/// \throws invalid_charset_error: Either character set is not supported
|
||||
/// \throws conversion_error: Conversion failed (e.g. \a how is \c stop and any character cannot be
|
||||
/// encoded or decoded)
|
||||
inline std::string between(const char* text,
|
||||
const std::string& to_encoding,
|
||||
const std::string& from_encoding,
|
||||
method_type how = default_method)
|
||||
{
|
||||
return between(text, util::str_end(text), to_encoding, from_encoding, how);
|
||||
}
|
||||
|
||||
/// Convert \a text to \a to_encoding from \a from_encoding according to
|
||||
/// policy \a how
|
||||
///
|
||||
/// \throws invalid_charset_error: Either character set is not supported
|
||||
/// \throws conversion_error: Conversion failed (e.g. \a how is \c stop and any character cannot be
|
||||
/// encoded or decoded)
|
||||
inline std::string between(const std::string& text,
|
||||
const std::string& to_encoding,
|
||||
const std::string& from_encoding,
|
||||
method_type how = default_method)
|
||||
{
|
||||
return between(text.c_str(), text.c_str() + text.size(), to_encoding, from_encoding, how);
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
/// Converter class to decode a narrow string using a local encoding and encode it with UTF
|
||||
template<typename CharType>
|
||||
class utf_encoder {
|
||||
std::unique_ptr<detail::utf_encoder<CharType>> impl_;
|
||||
|
||||
public:
|
||||
using char_type = CharType;
|
||||
using string_type = std::basic_string<CharType>;
|
||||
|
||||
/// Create an instance to convert text encoded with \a charset to UTF according to policy \a how
|
||||
///
|
||||
/// Note: When converting only a single text \ref to_utf is likely faster.
|
||||
/// \throws invalid_charset_error: Character set is not supported
|
||||
utf_encoder(const std::string& charset, method_type how = default_method) :
|
||||
impl_(detail::make_utf_encoder<CharType>(charset, how))
|
||||
{}
|
||||
|
||||
/// Convert text in range [begin,end) to UTF
|
||||
///
|
||||
/// \throws conversion_error: Conversion failed
|
||||
string_type convert(const char* begin, const char* end) const { return impl_->convert(begin, end); }
|
||||
/// Convert \a text to UTF
|
||||
///
|
||||
/// \throws conversion_error: Conversion failed
|
||||
string_type convert(const boost::string_view& text) const { return impl_->convert(text); }
|
||||
/// Convert \a text to UTF
|
||||
///
|
||||
/// \throws conversion_error: Conversion failed
|
||||
string_type operator()(const boost::string_view& text) const { return convert(text); }
|
||||
};
|
||||
|
||||
/// Converter class to decode an UTF string and encode it using a local encoding
|
||||
template<typename CharType>
|
||||
class utf_decoder {
|
||||
std::unique_ptr<detail::utf_decoder<CharType>> impl_;
|
||||
|
||||
public:
|
||||
using char_type = CharType;
|
||||
using stringview_type = boost::basic_string_view<CharType>;
|
||||
|
||||
/// Create an instance to convert UTF text to text encoded with \a charset according to policy \a how
|
||||
///
|
||||
/// Note: When converting only a single text \ref from_utf is likely faster.
|
||||
/// \throws invalid_charset_error: Character set is not supported
|
||||
utf_decoder(const std::string& charset, method_type how = default_method) :
|
||||
impl_(detail::make_utf_decoder<CharType>(charset, how))
|
||||
{}
|
||||
|
||||
/// Convert UTF text in range [begin,end) to local encoding
|
||||
///
|
||||
/// \throws conversion_error: Conversion failed
|
||||
std::string convert(const CharType* begin, const CharType* end) const { return impl_->convert(begin, end); }
|
||||
/// Convert \a text from UTF to local encoding
|
||||
///
|
||||
/// \throws conversion_error: Conversion failed
|
||||
std::string convert(const stringview_type& text) const { return impl_->convert(text); }
|
||||
/// Convert \a text from UTF to local encoding
|
||||
///
|
||||
/// \throws conversion_error: Conversion failed
|
||||
std::string operator()(const stringview_type& text) const { return convert(text); }
|
||||
};
|
||||
|
||||
class narrow_converter {
|
||||
std::unique_ptr<detail::narrow_converter> impl_;
|
||||
|
||||
public:
|
||||
/// Create converter to convert text from \a src_encoding to \a target_encoding according to policy \a how
|
||||
///
|
||||
/// \throws invalid_charset_error: Either character set is not supported
|
||||
narrow_converter(const std::string& src_encoding,
|
||||
const std::string& target_encoding,
|
||||
method_type how = default_method) :
|
||||
impl_(detail::make_narrow_converter(src_encoding, target_encoding, how))
|
||||
{}
|
||||
|
||||
/// Convert text in range [begin,end)
|
||||
///
|
||||
/// \throws conversion_error: Conversion failed
|
||||
std::string convert(const char* begin, const char* end) const { return impl_->convert(begin, end); }
|
||||
/// Convert \a text
|
||||
///
|
||||
/// \throws conversion_error: Conversion failed
|
||||
std::string convert(const boost::string_view& text) const { return impl_->convert(text); }
|
||||
/// Convert \a text
|
||||
///
|
||||
/// \throws conversion_error: Conversion failed
|
||||
std::string operator()(const boost::string_view& text) const { return convert(text); }
|
||||
};
|
||||
} // namespace conv
|
||||
}} // namespace boost::locale
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
|
||||
|
||||
@@ -1,75 +1,55 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// 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_ENCODING_ERRORS_HPP_INCLUDED
|
||||
#define BOOST_LOCALE_ENCODING_ERRORS_HPP_INCLUDED
|
||||
|
||||
#include <boost/locale/definitions.hpp>
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4275 4251 4231 4660)
|
||||
#endif
|
||||
#include <boost/locale/config.hpp>
|
||||
#include <stdexcept>
|
||||
|
||||
|
||||
|
||||
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
|
||||
#include <string>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(pop)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4275 4251 4231 4660)
|
||||
#endif
|
||||
|
||||
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)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
|
||||
|
||||
@@ -1,93 +1,71 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// 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_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)
|
||||
#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);
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// 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);
|
||||
}
|
||||
|
||||
|
||||
/// @}
|
||||
|
||||
} // conv
|
||||
|
||||
} // locale
|
||||
} // boost
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(pop)
|
||||
# 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
|
||||
///
|
||||
/// \throws conversion_error: Conversion failed (e.g. \a how is \c stop and any character cannot be decoded)
|
||||
template<typename CharOut, typename CharIn>
|
||||
std::basic_string<CharOut> utf_to_utf(const CharIn* begin, const CharIn* end, method_type how = default_method)
|
||||
{
|
||||
std::basic_string<CharOut> result;
|
||||
result.reserve(end - begin);
|
||||
std::back_insert_iterator<std::basic_string<CharOut>> inserter(result);
|
||||
while(begin != end) {
|
||||
const utf::code_point c = utf::utf_traits<CharIn>::decode(begin, end);
|
||||
if(c == utf::illegal || c == utf::incomplete) {
|
||||
if(how == stop)
|
||||
throw conversion_error();
|
||||
} else
|
||||
utf::utf_traits<CharOut>::encode(c, inserter);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Convert a Unicode NULL terminated string \a str other Unicode encoding
|
||||
///
|
||||
/// \throws conversion_error: Conversion failed (e.g. \a how is \c stop and any character cannot be decoded)
|
||||
template<typename CharOut, typename CharIn>
|
||||
std::basic_string<CharOut> utf_to_utf(const CharIn* str, method_type how = default_method)
|
||||
{
|
||||
return utf_to_utf<CharOut, CharIn>(str, util::str_end(str), how);
|
||||
}
|
||||
|
||||
/// Convert a Unicode string \a str other Unicode encoding
|
||||
///
|
||||
/// \throws conversion_error: Conversion failed (e.g. \a how is \c stop and any character cannot be decoded)
|
||||
template<typename CharOut, typename CharIn>
|
||||
std::basic_string<CharOut> utf_to_utf(const std::basic_string<CharIn>& str, method_type how = default_method)
|
||||
{
|
||||
return utf_to_utf<CharOut, CharIn>(str.c_str(), str.c_str() + str.size(), how);
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
}}} // namespace boost::locale::conv
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
|
||||
|
||||
@@ -1,507 +1,445 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
// Copyright (c) 2021-2023 Alexander Grund
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#ifndef BOOST_LOCALE_FORMAT_HPP_INCLUDED
|
||||
#define BOOST_LOCALE_FORMAT_HPP_INCLUDED
|
||||
|
||||
#include <boost/locale/config.hpp>
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4275 4251 4231 4660)
|
||||
#endif
|
||||
#include <boost/locale/message.hpp>
|
||||
#include <boost/locale/formatting.hpp>
|
||||
#include <boost/locale/hold_ptr.hpp>
|
||||
|
||||
#include <boost/locale/message.hpp>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4275 4251 4231 4660)
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
|
||||
///
|
||||
/// \defgroup format Format
|
||||
///
|
||||
/// This module provides printf like functionality integrated into iostreams and suitable for localization
|
||||
///
|
||||
/// @{
|
||||
///
|
||||
namespace boost { namespace locale {
|
||||
|
||||
/// \cond INTERNAL
|
||||
namespace details {
|
||||
/// \defgroup format Format
|
||||
///
|
||||
/// This module provides printf like functionality integrated into iostreams and suitable for localization
|
||||
///
|
||||
/// @{
|
||||
|
||||
/// \cond INTERNAL
|
||||
namespace detail {
|
||||
|
||||
template<typename CharType>
|
||||
struct formattible {
|
||||
typedef std::basic_ostream<CharType> stream_type;
|
||||
typedef void (*writer_type)(stream_type& output, const void* ptr);
|
||||
|
||||
formattible() noexcept : pointer_(nullptr), writer_(&formattible::void_write) {}
|
||||
|
||||
formattible(const formattible&) noexcept = default;
|
||||
formattible(formattible&&) noexcept = default;
|
||||
formattible& operator=(const formattible&) noexcept = default;
|
||||
formattible& operator=(formattible&&) noexcept = default;
|
||||
|
||||
template<typename Type>
|
||||
explicit formattible(const Type& value) noexcept
|
||||
{
|
||||
pointer_ = static_cast<const void*>(&value);
|
||||
writer_ = &write<Type>;
|
||||
}
|
||||
|
||||
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, const void* /*ptr*/)
|
||||
{
|
||||
CharType empty_string[1] = {0};
|
||||
output << empty_string;
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
static void write(stream_type& output, const void* ptr)
|
||||
{
|
||||
output << *static_cast<const Type*>(ptr);
|
||||
}
|
||||
|
||||
const void* pointer_;
|
||||
writer_type writer_;
|
||||
}; // formattible
|
||||
|
||||
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();
|
||||
|
||||
void set_one_flag(const std::string& key, const std::string& value);
|
||||
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
||||
formattible(formattible const &other) :
|
||||
pointer_(other.pointer_),
|
||||
writer_(other.writer_)
|
||||
{
|
||||
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();
|
||||
|
||||
formattible const &operator=(formattible const &other)
|
||||
{
|
||||
if(this != &other) {
|
||||
pointer_=other.pointer_;
|
||||
writer_=other.writer_;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
formattible(Type const &value)
|
||||
{
|
||||
pointer_ = static_cast<void const *>(&value);
|
||||
writer_ = &write<Type>;
|
||||
}
|
||||
private:
|
||||
void imbue(const std::locale&);
|
||||
|
||||
template<typename Type>
|
||||
formattible const &operator=(Type const &other)
|
||||
{
|
||||
*this = formattible(other);
|
||||
return *this;
|
||||
}
|
||||
std::ios_base& ios_;
|
||||
struct data;
|
||||
hold_ptr<data> d;
|
||||
};
|
||||
|
||||
friend stream_type &operator<<(stream_type &out,formattible const &fmt)
|
||||
{
|
||||
fmt.writer_(out,fmt.pointer_);
|
||||
return out;
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
private:
|
||||
static void void_write(stream_type &output,void const * /*ptr*/)
|
||||
{
|
||||
CharType empty_string[1]={0};
|
||||
output<<empty_string;
|
||||
}
|
||||
/// \endcond
|
||||
|
||||
template<typename Type>
|
||||
static void write(stream_type &output,void const *ptr)
|
||||
{
|
||||
output << *static_cast<Type const *>(ptr);
|
||||
}
|
||||
|
||||
void const *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();
|
||||
|
||||
unsigned get_position();
|
||||
|
||||
void set_one_flag(std::string const &key,std::string const &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);
|
||||
}
|
||||
}
|
||||
void restore();
|
||||
private:
|
||||
void imbue(std::locale const &);
|
||||
format_parser(format_parser const &);
|
||||
void operator=(format_parser const &);
|
||||
|
||||
std::ios_base &ios_;
|
||||
struct data;
|
||||
hold_ptr<data> d;
|
||||
};
|
||||
|
||||
}
|
||||
/// \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 silently ignored.
|
||||
/// This protects against a translator crashing the program in an unexpected location.
|
||||
template<typename CharType>
|
||||
class basic_format {
|
||||
int throw_if_params_bound() const;
|
||||
|
||||
public:
|
||||
typedef CharType char_type; ///< Underlying character type
|
||||
typedef basic_message<char_type> message_type; ///< The translation message type
|
||||
/// \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_((other.throw_if_params_bound(), std::move(other.message_))), format_(std::move(other.format_)),
|
||||
translate_(other.translate_), parameters_count_(0)
|
||||
{}
|
||||
basic_format& operator=(basic_format&& other)
|
||||
{
|
||||
other.throw_if_params_bound();
|
||||
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
|
||||
/// 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
|
||||
/// cout << format("Hello {1}, you are {2} years old") % name % age << endl;
|
||||
/// 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
|
||||
///
|
||||
/// 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
|
||||
/// 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
|
||||
/// 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
|
||||
/// 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
|
||||
/// 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 {
|
||||
template<typename Formattible>
|
||||
basic_format& operator%(const Formattible& 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);
|
||||
}
|
||||
|
||||
private:
|
||||
class format_guard {
|
||||
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)
|
||||
format_guard(detail::format_parser& fmt) : fmt_(fmt), restored_(false) {}
|
||||
void restore()
|
||||
{
|
||||
if(restored_)
|
||||
return;
|
||||
fmt_.restore();
|
||||
restored_ = true;
|
||||
}
|
||||
///
|
||||
/// 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)
|
||||
~format_guard()
|
||||
{
|
||||
// clang-format off
|
||||
try { restore(); } catch(...) {}
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
///
|
||||
/// 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(std::locale const &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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
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(...) {
|
||||
}
|
||||
}
|
||||
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='\'';
|
||||
void format_output(stream_type& out, const string_type& sformat) const
|
||||
{
|
||||
constexpr char_type obrk = '{';
|
||||
constexpr char_type cbrk = '}';
|
||||
constexpr char_type eq = '=';
|
||||
constexpr char_type comma = ',';
|
||||
constexpr 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;
|
||||
}
|
||||
else {
|
||||
out<<format[pos];
|
||||
const size_t size = sformat.size();
|
||||
const CharType* format = sformat.c_str();
|
||||
for(size_t pos = 0; format[pos];) {
|
||||
if(format[pos] != obrk) {
|
||||
if(format[pos] == cbrk && format[pos + 1] == cbrk) {
|
||||
out << cbrk;
|
||||
pos += 2;
|
||||
} else {
|
||||
out << format[pos];
|
||||
pos++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
pos++;
|
||||
if(format[pos] == obrk) {
|
||||
out << obrk;
|
||||
continue;
|
||||
}
|
||||
|
||||
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(char_type c = format[pos]; !(c == 0 || c == comma || c == eq || c == cbrk); c = format[++pos]) {
|
||||
key += static_cast<char>(c);
|
||||
}
|
||||
|
||||
if(format[pos] == eq) {
|
||||
pos++;
|
||||
if(format[pos] == quote) {
|
||||
pos++;
|
||||
}
|
||||
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) {
|
||||
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(format[pos]==comma) {
|
||||
pos++;
|
||||
continue;
|
||||
}
|
||||
else if(format[pos]==cbrk) {
|
||||
if(use_svalue)
|
||||
fmt.set_one_flag(key, svalue);
|
||||
else
|
||||
fmt.set_flag_with_str(key, value);
|
||||
|
||||
if(format[pos] == comma)
|
||||
pos++;
|
||||
else {
|
||||
if(format[pos] == cbrk) {
|
||||
unsigned position = fmt.get_position();
|
||||
out << get(position);
|
||||
guard.restore();
|
||||
pos++;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
guard.restore();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// 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)
|
||||
{
|
||||
fmt.write(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
void add(const formattible_type& param)
|
||||
{
|
||||
if(parameters_count_ >= base_params_)
|
||||
ext_params_.push_back(param);
|
||||
else
|
||||
parameters_[parameters_count_] = param;
|
||||
parameters_count_++;
|
||||
}
|
||||
|
||||
///
|
||||
/// Definition of char based format
|
||||
///
|
||||
typedef basic_format<char> format;
|
||||
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];
|
||||
}
|
||||
|
||||
///
|
||||
/// Definition of wchar_t based format
|
||||
///
|
||||
typedef basic_format<wchar_t> wformat;
|
||||
static void imbue_locale(void* ptr, const std::locale& l) { static_cast<stream_type*>(ptr)->imbue(l); }
|
||||
|
||||
#ifdef BOOST_LOCALE_ENABLE_CHAR16_T
|
||||
///
|
||||
/// Definition of char16_t based format
|
||||
///
|
||||
typedef basic_format<char16_t> u16format;
|
||||
#endif
|
||||
static constexpr unsigned base_params_ = 8;
|
||||
|
||||
#ifdef BOOST_LOCALE_ENABLE_CHAR32_T
|
||||
///
|
||||
/// Definition of char32_t based format
|
||||
///
|
||||
typedef basic_format<char32_t> u32format;
|
||||
#endif
|
||||
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, 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_LOCALE_ENABLE_CHAR32_T
|
||||
/// Definition of char32_t based format
|
||||
typedef basic_format<char32_t> u32format;
|
||||
#endif
|
||||
|
||||
template<typename CharType>
|
||||
int basic_format<CharType>::throw_if_params_bound() const
|
||||
{
|
||||
if(parameters_count_)
|
||||
throw std::invalid_argument("Can't move a basic_format with bound parameters");
|
||||
return 0;
|
||||
}
|
||||
/// @}
|
||||
}} // namespace boost::locale
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(pop)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
///
|
||||
/// \example hello.cpp
|
||||
///
|
||||
/// Basic example of using various functions provided by this library
|
||||
@@ -509,8 +447,5 @@ namespace boost {
|
||||
/// \example whello.cpp
|
||||
///
|
||||
/// Basic example of using various functions with wide strings provided by this library
|
||||
///
|
||||
///
|
||||
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,236 +1,236 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// 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_GENERATOR_HPP
|
||||
#define BOOST_LOCALE_GENERATOR_HPP
|
||||
#include <boost/locale/config.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4275 4251 4231 4660)
|
||||
#endif
|
||||
#include <string>
|
||||
|
||||
#include <boost/locale/hold_ptr.hpp>
|
||||
#include <cstdint>
|
||||
#include <locale>
|
||||
#include <memory>
|
||||
#include <boost/locale/hold_ptr.hpp>
|
||||
#include <string>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4275 4251 4231 4660)
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
template<typename Type>
|
||||
class shared_ptr;
|
||||
///
|
||||
/// \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
|
||||
///
|
||||
/// \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 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
|
||||
///
|
||||
namespace locale {
|
||||
/// 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;
|
||||
|
||||
class localization_backend;
|
||||
class localization_backend_manager;
|
||||
/// 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);
|
||||
|
||||
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
|
||||
/// \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.
|
||||
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&);
|
||||
|
||||
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
|
||||
|
||||
typedef uint32_t character_facet_type; ///<type that specifies the character type that locales can be generated for
|
||||
~generator();
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
/// 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;
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
|
||||
static const uint32_t all_categories = 0xFFFFFFFFu; ///< Generate all of them
|
||||
|
||||
typedef uint32_t locale_category_type; ///< a type used for more fine grained generation of facets
|
||||
/// 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.
|
||||
///
|
||||
/// \brief the major class used for locale generation
|
||||
/// 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.
|
||||
///
|
||||
/// 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.
|
||||
/// 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 BOOST_LOCALE_DECL generator {
|
||||
public:
|
||||
/// 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);
|
||||
|
||||
///
|
||||
/// Create new generator using global localization_backend_manager
|
||||
///
|
||||
generator();
|
||||
///
|
||||
/// Create new generator using specific localization_backend_manager
|
||||
///
|
||||
generator(localization_backend_manager const &);
|
||||
/// Remove all added domains from the list
|
||||
void clear_domains();
|
||||
|
||||
~generator();
|
||||
/// 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);
|
||||
|
||||
///
|
||||
/// 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;
|
||||
/// Remove all added paths
|
||||
void clear_paths();
|
||||
|
||||
///
|
||||
/// 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 cached locales
|
||||
void clear_cache();
|
||||
|
||||
///
|
||||
/// Remove all added domains from the list
|
||||
///
|
||||
void clear_domains();
|
||||
/// Turn locale caching ON
|
||||
void locale_cache_enabled(bool on);
|
||||
|
||||
///
|
||||
/// 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);
|
||||
/// Get locale cache option
|
||||
bool locale_cache_enabled() const;
|
||||
|
||||
///
|
||||
/// Remove all added paths
|
||||
///
|
||||
void clear_paths();
|
||||
/// Check if by default ANSI encoding is selected or UTF-8 onces. The default is false.
|
||||
bool use_ansi_encoding() const;
|
||||
|
||||
///
|
||||
/// Remove all cached locales
|
||||
///
|
||||
void clear_cache();
|
||||
/// 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);
|
||||
|
||||
///
|
||||
/// Turn locale caching ON
|
||||
///
|
||||
void locale_cache_enabled(bool on);
|
||||
/// 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); }
|
||||
|
||||
///
|
||||
/// Get locale cache option
|
||||
///
|
||||
bool locale_cache_enabled() const;
|
||||
private:
|
||||
void set_all_options(localization_backend& backend, const std::string& id) const;
|
||||
|
||||
///
|
||||
/// Check if by default ANSI encoding is selected or UTF-8 onces. The default is false.
|
||||
///
|
||||
bool use_ansi_encoding() const;
|
||||
generator(const generator&);
|
||||
void operator=(const generator&);
|
||||
|
||||
///
|
||||
/// 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(shared_ptr<localization_backend> backend,std::string const &id) const;
|
||||
|
||||
generator(generator const &);
|
||||
void operator=(generator const &);
|
||||
|
||||
struct data;
|
||||
hold_ptr<data> d;
|
||||
};
|
||||
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
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,167 +1,124 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// 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_LOCLAE_GNU_GETTEXT_HPP
|
||||
#define BOOST_LOCLAE_GNU_GETTEXT_HPP
|
||||
|
||||
#include <boost/locale/detail/is_supported_char.hpp>
|
||||
#include <boost/locale/message.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <functional>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
#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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
///
|
||||
/// Check whether two objects are equivalent, only names are compared, encoding is ignored
|
||||
///
|
||||
bool operator==(domain const &other) const
|
||||
{
|
||||
return name==other.name;
|
||||
}
|
||||
///
|
||||
/// Check whether two objects are distinct, only names are compared, encoding is ignored
|
||||
///
|
||||
bool operator!=(domain const &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 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(messages_info const &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_CHAR32_T
|
||||
template<>
|
||||
BOOST_LOCALE_DECL message_format<char32_t> *create_messages_facet(messages_info const &info);
|
||||
#endif
|
||||
|
||||
/// \endcond
|
||||
|
||||
} // gnu_gettext
|
||||
|
||||
/// @}
|
||||
|
||||
} // locale
|
||||
} // boost
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4251) // "identifier" : class "type" needs to have dll-interface...
|
||||
#endif
|
||||
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
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 BOOST_LOCALE_DECL messages_info {
|
||||
messages_info() : language("C"), locale_category("LC_MESSAGES") {}
|
||||
|
||||
std::string language; ///< The language we load the catalog for, like "ru", "en", "de"
|
||||
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() = 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)
|
||||
{
|
||||
const 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 an error occurs during file read it should throw an exception.
|
||||
///
|
||||
/// \note The user should support only the encodings the locales are created for. So if the user
|
||||
/// uses only one encoding or the file system is encoding agnostic, he may ignore the \a encoding parameter.
|
||||
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;
|
||||
|
||||
/// Get paths to folders which may contain catalog files
|
||||
std::vector<std::string> get_catalog_paths() const;
|
||||
|
||||
private:
|
||||
/// Get a list of folder names for the language, country and variant
|
||||
std::vector<std::string> get_lang_folders() const;
|
||||
};
|
||||
|
||||
/// Create a message_format facet using GNU Gettext catalogs. It uses \a info structure to get
|
||||
/// information about where to read them from and uses it for character set conversion (if needed)
|
||||
template<typename CharType, class = boost::locale::detail::enable_if_is_supported_char<CharType>>
|
||||
BOOST_LOCALE_DECL message_format<CharType>* create_messages_facet(const messages_info& info);
|
||||
|
||||
} // namespace gnu_gettext
|
||||
|
||||
/// @}
|
||||
|
||||
}} // namespace boost::locale
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,93 +1,87 @@
|
||||
//
|
||||
// Copyright (c) 2010 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Copyright (c) 2010 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#ifndef BOOST_LOCALE_HOLD_PTR_H
|
||||
#define BOOST_LOCALE_HOLD_PTR_H
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
///
|
||||
/// \brief a smart pointer similar to std::auto_ptr but it is non-copyable and the
|
||||
#include <boost/locale/config.hpp>
|
||||
#include <boost/core/exchange.hpp>
|
||||
|
||||
namespace boost { namespace locale {
|
||||
/// \brief a smart pointer similar to std::unique_ptr but the
|
||||
/// 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_(exchange(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_; }
|
||||
///
|
||||
/// Get a mutable pointer to the object
|
||||
///
|
||||
T *get() { return ptr_; }
|
||||
T const* get() const { return ptr_; }
|
||||
/// Get a mutable pointer to the object
|
||||
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_; }
|
||||
///
|
||||
/// Get a mutable pointer to the object
|
||||
///
|
||||
T *operator->() { return ptr_; }
|
||||
T const* operator->() const { return ptr_; }
|
||||
/// Get a mutable pointer to the object
|
||||
T* operator->() { return ptr_; }
|
||||
|
||||
///
|
||||
/// Transfer an ownership on the pointer to user
|
||||
///
|
||||
T *release() { T *tmp=ptr_; ptr_=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) noexcept
|
||||
{
|
||||
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
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
|
||||
@@ -1,125 +1,71 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// 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_INFO_HPP_INCLUDED
|
||||
#define BOOST_LOCALE_INFO_HPP_INCLUDED
|
||||
|
||||
#include <boost/locale/config.hpp>
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4275 4251 4231 4660)
|
||||
#endif
|
||||
#include <boost/locale/detail/facet_id.hpp>
|
||||
#include <locale>
|
||||
#include <string>
|
||||
|
||||
|
||||
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:
|
||||
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
|
||||
};
|
||||
|
||||
|
||||
///
|
||||
/// 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);
|
||||
}
|
||||
|
||||
///
|
||||
/// 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; }
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4275 4251 4231 4660)
|
||||
#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;
|
||||
|
||||
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_SYMBOL_VISIBLE info : public std::locale::facet, public detail::facet_id<info> {
|
||||
public:
|
||||
/// 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); }
|
||||
|
||||
/// 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; }
|
||||
|
||||
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
|
||||
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
|
||||
@@ -1,187 +1,129 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// 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_LOCALIZATION_BACKEND_HPP
|
||||
#define BOOST_LOCALE_LOCALIZATION_BACKEND_HPP
|
||||
#include <boost/locale/config.hpp>
|
||||
|
||||
#include <boost/locale/generator.hpp>
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4275 4251 4231 4660)
|
||||
#endif
|
||||
#include <string>
|
||||
#include <locale>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <boost/locale/hold_ptr.hpp>
|
||||
|
||||
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.
|
||||
///
|
||||
|
||||
class localization_backend {
|
||||
localization_backend(localization_backend const &);
|
||||
void operator=(localization_backend const &);
|
||||
public:
|
||||
|
||||
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;
|
||||
|
||||
///
|
||||
/// 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;
|
||||
|
||||
}; // 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(localization_backend_manager const &);
|
||||
///
|
||||
/// Assign localization_backend_manager
|
||||
///
|
||||
localization_backend_manager const &operator=(localization_backend_manager const &);
|
||||
|
||||
///
|
||||
/// Destructor
|
||||
///
|
||||
~localization_backend_manager();
|
||||
|
||||
#if !defined(BOOST_LOCALE_HIDE_AUTO_PTR) && !defined(BOOST_NO_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
|
||||
|
||||
#include <locale>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(pop)
|
||||
# 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 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&);
|
||||
/// Move construct localization_backend_manager
|
||||
localization_backend_manager(localization_backend_manager&&) noexcept;
|
||||
/// Move assign localization_backend_manager
|
||||
localization_backend_manager& operator=(localization_backend_manager&&) noexcept;
|
||||
|
||||
/// Destructor
|
||||
~localization_backend_manager();
|
||||
|
||||
/// Create new localization backend according to current settings. Ownership is passed to caller
|
||||
std::unique_ptr<localization_backend> create() const;
|
||||
|
||||
BOOST_DEPRECATED("This function is deprecated, use 'create()' instead")
|
||||
std::unique_ptr<localization_backend> get() const { return create(); } // LCOV_EXCL_LINE
|
||||
BOOST_DEPRECATED("This function is deprecated, use 'create()' instead")
|
||||
std::unique_ptr<localization_backend> get_unique_ptr() const { return create(); } // LCOV_EXCL_LINE
|
||||
|
||||
/// Add new backend to the manager, each backend should be uniquely defined by its name.
|
||||
///
|
||||
/// This library provides: "icu", "posix", "winapi" and "std" backends.
|
||||
void add_backend(const std::string& name, std::unique_ptr<localization_backend> backend);
|
||||
|
||||
// clang-format off
|
||||
BOOST_DEPRECATED("This function is deprecated, use 'add_backend' instead")
|
||||
void adopt_backend(const std::string& name, localization_backend* backend) { add_backend(name, std::unique_ptr<localization_backend>(backend)); } // LCOV_EXCL_LINE
|
||||
// clang-format on
|
||||
|
||||
/// Clear backend
|
||||
void remove_all_backends();
|
||||
|
||||
/// 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.
|
||||
///
|
||||
/// 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();
|
||||
|
||||
private:
|
||||
class impl;
|
||||
hold_ptr<impl> pimpl_;
|
||||
};
|
||||
|
||||
}} // namespace boost::locale
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,54 +1,40 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// 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_TIME_ZONE_HPP_INCLUDED
|
||||
#define BOOST_LOCALE_TIME_ZONE_HPP_INCLUDED
|
||||
|
||||
#include <boost/locale/config.hpp>
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4275 4251 4231 4660)
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4275 4251 4231 4660)
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace locale {
|
||||
///
|
||||
/// \addtogroup date_time
|
||||
///
|
||||
/// @{
|
||||
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);
|
||||
}
|
||||
/// \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
|
||||
|
||||
/// @}
|
||||
/// @}
|
||||
|
||||
} // locale
|
||||
} // boost
|
||||
}} // namespace boost::locale
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(pop)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
|
||||
@@ -1,460 +1,371 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// 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_UTF_HPP_INCLUDED
|
||||
#define BOOST_LOCALE_UTF_HPP_INCLUDED
|
||||
|
||||
#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
|
||||
#include <boost/locale/config.hpp>
|
||||
#include <cstdint>
|
||||
|
||||
namespace boost { namespace locale {
|
||||
/// \brief Namespace that holds basic operations on UTF encoded sequences
|
||||
///
|
||||
/// \brief The integral type that can hold a Unicode code point
|
||||
///
|
||||
typedef uint32_t code_point;
|
||||
/// 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
|
||||
using code_point = uint32_t;
|
||||
|
||||
///
|
||||
/// \brief Special constant that defines illegal code point
|
||||
///
|
||||
static const code_point illegal = 0xFFFFFFFFu;
|
||||
/// \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 Special constant that defines incomplete code point
|
||||
///
|
||||
static const code_point incomplete = 0xFFFFFFFEu;
|
||||
/// Either a length/size or an error (illegal/incomplete)
|
||||
using len_or_error = code_point;
|
||||
|
||||
///
|
||||
/// \brief the function checks if \a v is a valid code point
|
||||
///
|
||||
inline bool is_valid_codepoint(code_point v)
|
||||
{
|
||||
if(v>0x10FFFF)
|
||||
return false;
|
||||
if(0xD800 <=v && v<= 0xDFFF) // surragates
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
unsigned char lead = *p++;
|
||||
|
||||
// First byte is fully validated here
|
||||
int trail_size = trail_length(lead);
|
||||
|
||||
if(BOOST_LOCALE_UNLIKELY(trail_size < 0))
|
||||
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_LOCALE_UNLIKELY(p==e))
|
||||
return incomplete;
|
||||
tmp = *p++;
|
||||
if (!is_trail(tmp))
|
||||
return illegal;
|
||||
c = (c << 6) | ( tmp & 0x3F);
|
||||
case 2:
|
||||
if(BOOST_LOCALE_UNLIKELY(p==e))
|
||||
return incomplete;
|
||||
tmp = *p++;
|
||||
if (!is_trail(tmp))
|
||||
return illegal;
|
||||
c = (c << 6) | ( tmp & 0x3F);
|
||||
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;
|
||||
|
||||
// make sure it is the most compact representation
|
||||
if(BOOST_LOCALE_UNLIKELY(width(c)!=trail_size + 1))
|
||||
return illegal;
|
||||
|
||||
return c;
|
||||
|
||||
}
|
||||
|
||||
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);
|
||||
case 2:
|
||||
c = (c << 6) | ( static_cast<unsigned char>(*p++) & 0x3F);
|
||||
case 1:
|
||||
c = (c << 6) | ( static_cast<unsigned char>(*p++) & 0x3F);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
|
||||
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_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);
|
||||
}
|
||||
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;
|
||||
}
|
||||
}; // 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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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);
|
||||
}
|
||||
else {
|
||||
u -= 0x10000;
|
||||
*out++ = static_cast<char_type>(0xD800 | (u>>10));
|
||||
*out++ = static_cast<char_type>(0xDC00 | (u & 0x3FF));
|
||||
}
|
||||
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*/)
|
||||
/// \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;
|
||||
}
|
||||
|
||||
template<typename It>
|
||||
static code_point decode_valid(It ¤t)
|
||||
{
|
||||
return *current++;
|
||||
}
|
||||
#ifdef BOOST_LOCALE_DOXYGEN
|
||||
|
||||
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;
|
||||
}
|
||||
/// \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;
|
||||
|
||||
}; // utf32
|
||||
/// 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);
|
||||
|
||||
#endif
|
||||
/// 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);
|
||||
|
||||
} // utf
|
||||
} // locale
|
||||
} // boost
|
||||
/// 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 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;
|
||||
}
|
||||
|
||||
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_UNLIKELY(p == e))
|
||||
return incomplete;
|
||||
|
||||
unsigned char lead = *p++;
|
||||
|
||||
// First byte is fully validated here
|
||||
int trail_size = trail_length(lead);
|
||||
|
||||
if(BOOST_UNLIKELY(trail_size < 0))
|
||||
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_UNLIKELY(width(c) != trail_size + 1))
|
||||
return illegal;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
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_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);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}; // 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;
|
||||
}
|
||||
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& 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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}; // 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& current)
|
||||
{
|
||||
return *current++;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
} // namespace utf
|
||||
}} // namespace boost::locale
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,69 +1,56 @@
|
||||
//
|
||||
// Copyright (c) 2015 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Copyright (c) 2015 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#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/cstdint.hpp>
|
||||
#include <boost/locale/utf.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <cstdint>
|
||||
#include <locale>
|
||||
|
||||
namespace boost {
|
||||
namespace 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 {};
|
||||
/// \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)
|
||||
{
|
||||
}
|
||||
utf8_codecvt(size_t refs = 0) : generic_codecvt<CharType, utf8_codecvt<CharType>>(refs) {}
|
||||
|
||||
static int max_encoding_length()
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
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;
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
};
|
||||
static utf::len_or_error from_unicode(state_type&, utf::code_point u, char* begin, const char* end)
|
||||
{
|
||||
BOOST_ASSERT(utf::is_valid_codepoint(u));
|
||||
const auto width = utf::utf_traits<char>::width(u);
|
||||
if(width > end - begin)
|
||||
return utf::incomplete;
|
||||
utf::utf_traits<char>::encode(u, begin);
|
||||
return width;
|
||||
}
|
||||
};
|
||||
|
||||
} // locale
|
||||
} // namespace boost
|
||||
}} // namespace boost::locale
|
||||
|
||||
#endif
|
||||
///
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
|
||||
@@ -1,286 +1,210 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
// Copyright (c) 2022-2023 Alexander Grund
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#ifndef BOOST_LOCALE_UTIL_HPP
|
||||
#define BOOST_LOCALE_UTIL_HPP
|
||||
#include <locale>
|
||||
#include <typeinfo>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/locale/utf.hpp>
|
||||
|
||||
#include <boost/locale/generator.hpp>
|
||||
#include <boost/locale/utf.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <cstdint>
|
||||
#include <locale>
|
||||
#include <memory>
|
||||
#include <typeinfo>
|
||||
|
||||
#include <vector>
|
||||
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);
|
||||
namespace boost { namespace locale {
|
||||
/// \brief This namespace provides various utility function useful for Boost.Locale's backends
|
||||
/// implementations
|
||||
namespace util {
|
||||
|
||||
///
|
||||
/// \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);
|
||||
/// \brief Return default system locale name in POSIX format.
|
||||
///
|
||||
/// This function tries to detect the locale using LC_ALL, LC_CTYPE and LANG environment
|
||||
/// variables in this order and if all of them are unset, on POSIX platforms it returns "C".
|
||||
/// On Windows additionally to the above environment variables, this function
|
||||
/// tries to create the locale name from ISO-639 and ISO-3166 country codes defined
|
||||
/// for the users default locale.
|
||||
/// If \a use_utf8_on_windows is true it sets the encoding to UTF-8,
|
||||
/// otherwise, if the system locale supports ANSI codepages it defines the ANSI encoding, e.g. windows-1252,
|
||||
/// otherwise (if ANSI codepage is not available) it uses UTF-8 encoding.
|
||||
BOOST_LOCALE_DECL
|
||||
std::string get_system_locale(bool use_utf8_on_windows = false);
|
||||
|
||||
/// \brief Installs information facet to locale \a 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 character 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 base_converter {
|
||||
public:
|
||||
/// \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 utf::code_point illegal = utf::illegal;
|
||||
|
||||
///
|
||||
/// 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 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 utf::code_point incomplete = utf::incomplete;
|
||||
|
||||
///
|
||||
/// 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
|
||||
{
|
||||
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();
|
||||
}
|
||||
virtual ~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(char const *&begin,char const *end)
|
||||
{
|
||||
if(begin == end)
|
||||
return incomplete;
|
||||
unsigned char cp = *begin;
|
||||
if(cp <= 0x7F) {
|
||||
begin++;
|
||||
return cp;
|
||||
/// 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();
|
||||
}
|
||||
return illegal;
|
||||
}
|
||||
///
|
||||
/// 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,char const *end)
|
||||
{
|
||||
if(begin==end)
|
||||
return incomplete;
|
||||
if(u >= 0x80)
|
||||
/// 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 utf::code_point 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;
|
||||
*begin = static_cast<char>(u);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/// 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 utf::len_or_error from_unicode(utf::code_point u, char* begin, const char* end)
|
||||
{
|
||||
if(begin == end)
|
||||
return incomplete;
|
||||
if(u >= 0x80)
|
||||
return illegal;
|
||||
*begin = static_cast<char>(u);
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
/// 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();
|
||||
|
||||
BOOST_DEPRECATED("This function is deprecated, use 'create_utf8_converter()'")
|
||||
inline std::unique_ptr<base_converter> create_utf8_converter_unique_ptr()
|
||||
{
|
||||
return create_utf8_converter();
|
||||
}
|
||||
};
|
||||
|
||||
#if !defined(BOOST_LOCALE_HIDE_AUTO_PTR) && !defined(BOOST_NO_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);
|
||||
/// 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.
|
||||
/// 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)
|
||||
{
|
||||
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.
|
||||
///
|
||||
/// 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
|
||||
/// 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(const std::locale& in, std::unique_ptr<base_converter> cvt, char_facet_t type);
|
||||
|
||||
#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);
|
||||
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)
|
||||
{
|
||||
return create_codecvt(in, std::unique_ptr<base_converter>(cvt), type);
|
||||
}
|
||||
|
||||
///
|
||||
/// 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
|
||||
BOOST_DEPRECATED("This function is deprecated, use 'create_utf8_converter()'")
|
||||
BOOST_LOCALE_DECL base_converter* create_utf8_converter_new_ptr();
|
||||
|
||||
///
|
||||
/// This function creates a \a base_converter that can be used for conversion between 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);
|
||||
BOOST_DEPRECATED("This function is deprecated, use 'create_simple_converter()'")
|
||||
BOOST_LOCALE_DECL base_converter* create_simple_converter_new_ptr(const std::string& encoding);
|
||||
|
||||
///
|
||||
/// Install 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);
|
||||
/// 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);
|
||||
|
||||
///
|
||||
/// 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);
|
||||
|
||||
///
|
||||
/// 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: Character set is not supported or isn't a single
|
||||
/// byte character set
|
||||
BOOST_LOCALE_DECL
|
||||
std::locale create_simple_codecvt(const std::locale& in, const std::string& encoding, char_facet_t type);
|
||||
} // namespace util
|
||||
}} // namespace boost::locale
|
||||
|
||||
#endif
|
||||
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
||||
|
||||
78
linx64/include/boost/locale/util/locale_data.hpp
Normal file
78
linx64/include/boost/locale/util/locale_data.hpp
Normal file
@@ -0,0 +1,78 @@
|
||||
//
|
||||
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
||||
// Copyright (c) 2023 Alexander Grund
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#ifndef BOOST_LOCALE_UTIL_LOCALE_DATA_HPP
|
||||
#define BOOST_LOCALE_UTIL_LOCALE_DATA_HPP
|
||||
|
||||
#include <boost/locale/config.hpp>
|
||||
#include <string>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4251)
|
||||
#endif
|
||||
|
||||
namespace boost { namespace locale { namespace util {
|
||||
|
||||
/// Holder and parser for locale names/identifiers
|
||||
class BOOST_LOCALE_DECL locale_data {
|
||||
std::string language_;
|
||||
std::string country_;
|
||||
std::string encoding_;
|
||||
std::string variant_;
|
||||
bool utf8_;
|
||||
|
||||
public:
|
||||
/// Default to C locale with US-ASCII encoding
|
||||
locale_data();
|
||||
/// Construct from the parsed locale \see \ref parse
|
||||
///
|
||||
/// \throws std::invalid_argument: parsing failed
|
||||
explicit locale_data(const std::string& locale_name);
|
||||
|
||||
/// Return language (usually 2 lowercase letters, i.e. ISO-639 or 'C')
|
||||
const std::string& language() const { return language_; }
|
||||
/// Return country (usually 2 uppercase letters, i.e. ISO-3166)
|
||||
const std::string& country() const { return country_; }
|
||||
/// Return encoding/codeset, e.g. ISO8859-1 or UTF-8
|
||||
const std::string& encoding() const { return encoding_; }
|
||||
/// Set encoding, will be made uppercase by default as-if it was parsed
|
||||
/// Returns \c *this for chaining
|
||||
locale_data& encoding(std::string new_encoding, bool uppercase = true);
|
||||
/// Return variant/modifier, e.g. euro or stroke
|
||||
const std::string& variant() const { return variant_; }
|
||||
/// Return iff the encoding is UTF-8
|
||||
bool is_utf8() const { return utf8_; }
|
||||
|
||||
/// Parse a locale identifier of the form `[language[_territory][.codeset][@modifier]]`
|
||||
///
|
||||
/// Allows a dash as the delimiter: `[language-territory]`
|
||||
/// Return true if the identifier is valid:
|
||||
/// - `language` is given and consists of ASCII letters
|
||||
/// - `territory`, if given, consists of ASCII letters
|
||||
/// - Any field started by a delimiter (`_`, `-`, `.`, `@`) is not empty
|
||||
/// Otherwise parsing is aborted. Valid values already parsed stay set, other are defaulted.
|
||||
bool parse(const std::string& locale_name);
|
||||
|
||||
/// Get a representation in the form `[language[_territory][.codeset][@modifier]]`
|
||||
/// codeset is omitted if it is US-ASCII
|
||||
std::string to_string() const;
|
||||
|
||||
private:
|
||||
void reset();
|
||||
bool parse_from_lang(const std::string& input);
|
||||
bool parse_from_country(const std::string& input);
|
||||
bool parse_from_encoding(const std::string& input);
|
||||
bool parse_from_variant(const std::string& input);
|
||||
};
|
||||
|
||||
}}} // namespace boost::locale::util
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
#endif
|
||||
46
linx64/include/boost/locale/util/string.hpp
Normal file
46
linx64/include/boost/locale/util/string.hpp
Normal file
@@ -0,0 +1,46 @@
|
||||
//
|
||||
// Copyright (c) 2022-2023 Alexander Grund
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#ifndef BOOST_LOCALE_UTIL_STRING_HPP
|
||||
#define BOOST_LOCALE_UTIL_STRING_HPP
|
||||
|
||||
#include <boost/locale/config.hpp>
|
||||
#include <limits>
|
||||
|
||||
namespace boost { namespace locale { namespace util {
|
||||
/// Return the end of a C-string, i.e. the pointer to the trailing NULL byte
|
||||
template<typename Char>
|
||||
Char* str_end(Char* str)
|
||||
{
|
||||
while(*str)
|
||||
++str;
|
||||
return str;
|
||||
}
|
||||
|
||||
inline constexpr bool is_upper_ascii(const char c)
|
||||
{
|
||||
return 'A' <= c && c <= 'Z';
|
||||
}
|
||||
|
||||
inline constexpr bool is_lower_ascii(const char c)
|
||||
{
|
||||
return 'a' <= c && c <= 'z';
|
||||
}
|
||||
|
||||
inline constexpr bool is_numeric_ascii(const char c)
|
||||
{
|
||||
return '0' <= c && c <= '9';
|
||||
}
|
||||
|
||||
/// Cast an unsigned char to a (possibly signed) char avoiding implementation defined behavior
|
||||
constexpr char to_char(unsigned char c)
|
||||
{
|
||||
return static_cast<char>((c - std::numeric_limits<char>::min()) + std::numeric_limits<char>::min());
|
||||
}
|
||||
|
||||
}}} // namespace boost::locale::util
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user