mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-12-04 09:14:04 +08:00
P0482R5 char8_t: Standard library support
gcc/cp: 2019-02-19 Tom Honermann <tom@honermann.net> * name-lookup.c (get_std_name_hint): Added u8string as a name hint. libstdc++: 2019-02-19 Tom Honermann <tom@honermann.net> P0482R5 char8_t: Standard library support * config/abi/pre/gnu-versioned-namespace.ver (CXXABI_2.0): Add typeinfo symbols for char8_t. * config/abi/pre/gnu.ver: Add CXXABI_1.3.12. (GLIBCXX_3.4.26): Add symbols for specializations of numeric_limits and codecvt that involve char8_t. (CXXABI_1.3.12): Add typeinfo symbols for char8_t. * include/bits/atomic_base.h: Add atomic_char8_t. * include/bits/basic_string.h: Add std::hash<u8string> and operator""s(const char8_t*, size_t). * include/bits/c++config: Define _GLIBCXX_USE_CHAR8_T and __cpp_lib_char8_t. * include/bits/char_traits.h: Add char_traits<char8_t>. * include/bits/codecvt.h: Add codecvt<char16_t, char8_t, mbstate_t>, codecvt<char32_t, char8_t, mbstate_t>, codecvt_byname<char16_t, char8_t, mbstate_t>, and codecvt_byname<char32_t, char8_t, mbstate_t>. * include/bits/cpp_type_traits.h: Add __is_integer<char8_t> to recognize char8_t as an integral type. * include/bits/fs_path.h: (path::__is_encoded_char): Recognize char8_t. (path::u8string): Return std::u8string when char8_t support is enabled. (path::generic_u8string): Likewise. (path::_S_convert): Handle conversion from char8_t input. (path::_S_str_convert): Likewise. * include/bits/functional_hash.h: Add hash<char8_t>. * include/bits/locale_conv.h (__str_codecvt_out): Add overloads for char8_t. * include/bits/locale_facets.h (_GLIBCXX_NUM_UNICODE_FACETS): Bump for new char8_t specializations. * include/bits/localefwd.h: Add missing declarations of codecvt<char16_t, char, mbstate_t> and codecvt<char32_t, char, mbstate_t>. Add char8_t declarations codecvt<char16_t, char8_t, mbstate_t> and codecvt<char32_t, char8_t, mbstate_t>. * include/bits/postypes.h: Add u8streampos * include/bits/stringfwd.h: Add declarations of char_traits<char8_t> and u8string. * include/c_global/cstddef: Add __byte_operand<char8_t>. * include/experimental/bits/fs_path.h (path::__is_encoded_char): Recognize char8_t. (path::u8string): Return std::u8string when char8_t support is enabled. (path::generic_u8string): Likewise. (path::_S_convert): Handle conversion from char8_t input. (path::_S_str_convert): Likewise. * include/experimental/string: Add u8string. * include/experimental/string_view: Add u8string_view, hash<experimental::u8string_view>, and operator""sv(const char8_t*, size_t). * include/std/atomic: Add atomic<char8_t> and atomic_char8_t. * include/std/charconv (__is_int_to_chars_type): Recognize char8_t as a character type. * include/std/limits: Add numeric_limits<char8_t>. * include/std/string_view: Add u8string_view, hash<experimental::u8string_view>, and operator""sv(const char8_t*, size_t). * include/std/type_traits: Add __is_integral_helper<char8_t>, __make_unsigned<char8_t>, and __make_signed<char8_t>. * libsupc++/atomic_lockfree_defines.h: Define ATOMIC_CHAR8_T_LOCK_FREE. * src/c++11/Makefile.am: Compile with -fchar8_t when compiling codecvt.cc and limits.cc so that char8_t specializations of numeric_limits and codecvt and emitted. * src/c++11/Makefile.in: Likewise. * src/c++11/codecvt.cc: Define members of codecvt<char16_t, char8_t, mbstate_t>, codecvt<char32_t, char8_t, mbstate_t>, codecvt_byname<char16_t, char8_t, mbstate_t>, and codecvt_byname<char32_t, char8_t, mbstate_t>. * src/c++11/limits.cc: Define members of numeric_limits<char8_t>. * src/c++98/Makefile.am: Compile with -fchar8_t when compiling locale_init.cc and localename.cc. * src/c++98/Makefile.in: Likewise. * src/c++98/locale_init.cc: Add initialization for the codecvt<char16_t, char8_t, mbstate_t> and codecvt<char32_t, char8_t, mbstate_t> facets. * src/c++98/localename.cc: Likewise. * testsuite/util/testsuite_abi.cc: Validate ABI bump. From-SVN: r269004
This commit is contained in:
parent
e8b3c1bc3b
commit
c124af936b
@ -1,3 +1,7 @@
|
||||
2019-02-19 Tom Honermann <tom@honermann.net>
|
||||
|
||||
* name-lookup.c (get_std_name_hint): Added u8string as a name hint.
|
||||
|
||||
2019-02-18 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/89336 - multiple stores in constexpr stmt.
|
||||
|
@ -5765,6 +5765,7 @@ get_std_name_hint (const char *name)
|
||||
{"basic_string", "<string>", cxx98},
|
||||
{"string", "<string>", cxx98},
|
||||
{"wstring", "<string>", cxx98},
|
||||
{"u8string", "<string>", cxx2a},
|
||||
{"u16string", "<string>", cxx11},
|
||||
{"u32string", "<string>", cxx11},
|
||||
/* <string_view>. */
|
||||
|
@ -1,3 +1,88 @@
|
||||
2019-02-19 Tom Honermann <tom@honermann.net>
|
||||
|
||||
P0482R5 char8_t: Standard library support
|
||||
* config/abi/pre/gnu-versioned-namespace.ver (CXXABI_2.0): Add
|
||||
typeinfo symbols for char8_t.
|
||||
* config/abi/pre/gnu.ver: Add CXXABI_1.3.12.
|
||||
(GLIBCXX_3.4.26): Add symbols for specializations of
|
||||
numeric_limits and codecvt that involve char8_t.
|
||||
(CXXABI_1.3.12): Add typeinfo symbols for char8_t.
|
||||
* include/bits/atomic_base.h: Add atomic_char8_t.
|
||||
* include/bits/basic_string.h: Add std::hash<u8string> and
|
||||
operator""s(const char8_t*, size_t).
|
||||
* include/bits/c++config: Define _GLIBCXX_USE_CHAR8_T and
|
||||
__cpp_lib_char8_t.
|
||||
* include/bits/char_traits.h: Add char_traits<char8_t>.
|
||||
* include/bits/codecvt.h: Add
|
||||
codecvt<char16_t, char8_t, mbstate_t>,
|
||||
codecvt<char32_t, char8_t, mbstate_t>,
|
||||
codecvt_byname<char16_t, char8_t, mbstate_t>, and
|
||||
codecvt_byname<char32_t, char8_t, mbstate_t>.
|
||||
* include/bits/cpp_type_traits.h: Add __is_integer<char8_t> to
|
||||
recognize char8_t as an integral type.
|
||||
* include/bits/fs_path.h: (path::__is_encoded_char): Recognize
|
||||
char8_t.
|
||||
(path::u8string): Return std::u8string when char8_t support is
|
||||
enabled.
|
||||
(path::generic_u8string): Likewise.
|
||||
(path::_S_convert): Handle conversion from char8_t input.
|
||||
(path::_S_str_convert): Likewise.
|
||||
* include/bits/functional_hash.h: Add hash<char8_t>.
|
||||
* include/bits/locale_conv.h (__str_codecvt_out): Add overloads for
|
||||
char8_t.
|
||||
* include/bits/locale_facets.h (_GLIBCXX_NUM_UNICODE_FACETS): Bump
|
||||
for new char8_t specializations.
|
||||
* include/bits/localefwd.h: Add missing declarations of
|
||||
codecvt<char16_t, char, mbstate_t> and
|
||||
codecvt<char32_t, char, mbstate_t>. Add char8_t declarations
|
||||
codecvt<char16_t, char8_t, mbstate_t> and
|
||||
codecvt<char32_t, char8_t, mbstate_t>.
|
||||
* include/bits/postypes.h: Add u8streampos
|
||||
* include/bits/stringfwd.h: Add declarations of
|
||||
char_traits<char8_t> and u8string.
|
||||
* include/c_global/cstddef: Add __byte_operand<char8_t>.
|
||||
* include/experimental/bits/fs_path.h (path::__is_encoded_char):
|
||||
Recognize char8_t.
|
||||
(path::u8string): Return std::u8string when char8_t support is
|
||||
enabled.
|
||||
(path::generic_u8string): Likewise.
|
||||
(path::_S_convert): Handle conversion from char8_t input.
|
||||
(path::_S_str_convert): Likewise.
|
||||
* include/experimental/string: Add u8string.
|
||||
* include/experimental/string_view: Add u8string_view,
|
||||
hash<experimental::u8string_view>, and
|
||||
operator""sv(const char8_t*, size_t).
|
||||
* include/std/atomic: Add atomic<char8_t> and atomic_char8_t.
|
||||
* include/std/charconv (__is_int_to_chars_type): Recognize char8_t
|
||||
as a character type.
|
||||
* include/std/limits: Add numeric_limits<char8_t>.
|
||||
* include/std/string_view: Add u8string_view,
|
||||
hash<experimental::u8string_view>, and
|
||||
operator""sv(const char8_t*, size_t).
|
||||
* include/std/type_traits: Add __is_integral_helper<char8_t>,
|
||||
__make_unsigned<char8_t>, and __make_signed<char8_t>.
|
||||
* libsupc++/atomic_lockfree_defines.h: Define
|
||||
ATOMIC_CHAR8_T_LOCK_FREE.
|
||||
* src/c++11/Makefile.am: Compile with -fchar8_t when compiling
|
||||
codecvt.cc and limits.cc so that char8_t specializations of
|
||||
numeric_limits and codecvt and emitted.
|
||||
* src/c++11/Makefile.in: Likewise.
|
||||
* src/c++11/codecvt.cc: Define members of
|
||||
codecvt<char16_t, char8_t, mbstate_t>,
|
||||
codecvt<char32_t, char8_t, mbstate_t>,
|
||||
codecvt_byname<char16_t, char8_t, mbstate_t>, and
|
||||
codecvt_byname<char32_t, char8_t, mbstate_t>.
|
||||
* src/c++11/limits.cc: Define members of
|
||||
numeric_limits<char8_t>.
|
||||
* src/c++98/Makefile.am: Compile with -fchar8_t when compiling
|
||||
locale_init.cc and localename.cc.
|
||||
* src/c++98/Makefile.in: Likewise.
|
||||
* src/c++98/locale_init.cc: Add initialization for the
|
||||
codecvt<char16_t, char8_t, mbstate_t> and
|
||||
codecvt<char32_t, char8_t, mbstate_t> facets.
|
||||
* src/c++98/localename.cc: Likewise.
|
||||
* testsuite/util/testsuite_abi.cc: Validate ABI bump.
|
||||
|
||||
2019-02-18 Wilco Dijkstra <wdijkstr@arm.com>
|
||||
|
||||
* 27_io/filesystem/operations/all.cc: Add dg-require-filesystem-ts.
|
||||
|
@ -301,6 +301,11 @@ CXXABI_2.0 {
|
||||
_ZTSN10__cxxabiv120__si_class_type_infoE;
|
||||
_ZTSN10__cxxabiv121__vmi_class_type_infoE;
|
||||
|
||||
# typeinfo for char8_t
|
||||
_ZTIDu;
|
||||
_ZTIPDu;
|
||||
_ZTIPKDu;
|
||||
|
||||
# typeinfo for char16_t and char32_t
|
||||
_ZTIDs;
|
||||
_ZTIPDs;
|
||||
|
@ -2244,6 +2244,17 @@ GLIBCXX_3.4.26 {
|
||||
# _Sp_make_shared_tag::_S_eq
|
||||
_ZNSt19_Sp_make_shared_tag5_S_eqERKSt9type_info;
|
||||
|
||||
# numeric_limits<char8_t>
|
||||
_ZNSt14numeric_limitsIDuE[5-9]*;
|
||||
_ZNSt14numeric_limitsIDuE1[0-7][hirt]*;
|
||||
_ZNSt14numeric_limitsIDuE1[0-7]mi*;
|
||||
_ZNSt14numeric_limitsIDuE1[0-7]max_e*;
|
||||
|
||||
# codecvt<char16_t, char8_t, mbstate_t>, codecvt<char32_t, char8_t, mbstate_t>
|
||||
_ZNKSt7codecvtID[is]Du*;
|
||||
_ZNSt7codecvtID[is]Du*;
|
||||
_ZT[ISV]St7codecvtID[is]Du*E;
|
||||
|
||||
} GLIBCXX_3.4.25;
|
||||
|
||||
# Symbols in the support library (libsupc++) have their own tag.
|
||||
@ -2535,6 +2546,15 @@ CXXABI_1.3.11 {
|
||||
|
||||
} CXXABI_1.3.10;
|
||||
|
||||
CXXABI_1.3.12 {
|
||||
|
||||
# typeinfo for char8_t
|
||||
_ZTIDu;
|
||||
_ZTIPDu;
|
||||
_ZTIPKDu;
|
||||
|
||||
} CXXABI_1.3.11;
|
||||
|
||||
# Symbols in the support library (libsupc++) supporting transactional memory.
|
||||
CXXABI_TM_1 {
|
||||
|
||||
|
@ -227,6 +227,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
// atomic_ulong unsigned long
|
||||
// atomic_llong long long
|
||||
// atomic_ullong unsigned long long
|
||||
// atomic_char8_t char8_t
|
||||
// atomic_char16_t char16_t
|
||||
// atomic_char32_t char32_t
|
||||
// atomic_wchar_t wchar_t
|
||||
|
@ -6753,6 +6753,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
#endif
|
||||
#endif /* _GLIBCXX_COMPATIBILITY_CXX0X */
|
||||
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
/// std::hash specialization for u8string.
|
||||
template<>
|
||||
struct hash<u8string>
|
||||
: public __hash_base<size_t, u8string>
|
||||
{
|
||||
size_t
|
||||
operator()(const u8string& __s) const noexcept
|
||||
{ return std::_Hash_impl::hash(__s.data(),
|
||||
__s.length() * sizeof(char8_t)); }
|
||||
};
|
||||
|
||||
template<>
|
||||
struct __is_fast_hash<hash<u8string>> : std::false_type
|
||||
{ };
|
||||
#endif
|
||||
|
||||
/// std::hash specialization for u16string.
|
||||
template<>
|
||||
struct hash<u16string>
|
||||
@ -6805,6 +6822,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
{ return basic_string<wchar_t>{__str, __len}; }
|
||||
#endif
|
||||
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
_GLIBCXX_DEFAULT_ABI_TAG
|
||||
inline basic_string<char8_t>
|
||||
operator""s(const char8_t* __str, size_t __len)
|
||||
{ return basic_string<char8_t>{__str, __len}; }
|
||||
#endif
|
||||
|
||||
_GLIBCXX_DEFAULT_ABI_TAG
|
||||
inline basic_string<char16_t>
|
||||
operator""s(const char16_t* __str, size_t __len)
|
||||
|
@ -625,6 +625,17 @@ namespace std
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// Unless explicitly specified, enable char8_t extensions only if the core
|
||||
// language char8_t feature macro is defined.
|
||||
#ifndef _GLIBCXX_USE_CHAR8_T
|
||||
# ifdef __cpp_char8_t
|
||||
# define _GLIBCXX_USE_CHAR8_T 1
|
||||
# endif
|
||||
#endif
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
# define __cpp_lib_char8_t 201811
|
||||
#endif
|
||||
|
||||
/* Define if __float128 is supported on this host. */
|
||||
#if defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__)
|
||||
#define _GLIBCXX_USE_FLOAT128
|
||||
|
@ -507,6 +507,115 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
};
|
||||
#endif //_GLIBCXX_USE_WCHAR_T
|
||||
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
template<>
|
||||
struct char_traits<char8_t>
|
||||
{
|
||||
typedef char8_t char_type;
|
||||
typedef unsigned int int_type;
|
||||
typedef u8streampos pos_type;
|
||||
typedef streamoff off_type;
|
||||
typedef mbstate_t state_type;
|
||||
|
||||
static _GLIBCXX17_CONSTEXPR void
|
||||
assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
|
||||
{ __c1 = __c2; }
|
||||
|
||||
static _GLIBCXX_CONSTEXPR bool
|
||||
eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
|
||||
{ return __c1 == __c2; }
|
||||
|
||||
static _GLIBCXX_CONSTEXPR bool
|
||||
lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
|
||||
{ return __c1 < __c2; }
|
||||
|
||||
static _GLIBCXX17_CONSTEXPR int
|
||||
compare(const char_type* __s1, const char_type* __s2, size_t __n)
|
||||
{
|
||||
#if __cplusplus > 201402
|
||||
if (__builtin_constant_p(__n)
|
||||
&& __constant_char_array_p(__s1, __n)
|
||||
&& __constant_char_array_p(__s2, __n))
|
||||
return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n);
|
||||
#endif
|
||||
if (__n == 0)
|
||||
return 0;
|
||||
return __builtin_memcmp(__s1, __s2, __n);
|
||||
}
|
||||
|
||||
static _GLIBCXX17_CONSTEXPR size_t
|
||||
length(const char_type* __s)
|
||||
{
|
||||
#if __cplusplus > 201402
|
||||
if (__constant_string_p(__s))
|
||||
return __gnu_cxx::char_traits<char_type>::length(__s);
|
||||
#endif
|
||||
size_t __i = 0;
|
||||
while (!eq(__s[__i], char_type()))
|
||||
++__i;
|
||||
return __i;
|
||||
}
|
||||
|
||||
static _GLIBCXX17_CONSTEXPR const char_type*
|
||||
find(const char_type* __s, size_t __n, const char_type& __a)
|
||||
{
|
||||
#if __cplusplus > 201402
|
||||
if (__builtin_constant_p(__n)
|
||||
&& __builtin_constant_p(__a)
|
||||
&& __constant_char_array_p(__s, __n))
|
||||
return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
|
||||
#endif
|
||||
if (__n == 0)
|
||||
return 0;
|
||||
return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n));
|
||||
}
|
||||
|
||||
static char_type*
|
||||
move(char_type* __s1, const char_type* __s2, size_t __n)
|
||||
{
|
||||
if (__n == 0)
|
||||
return __s1;
|
||||
return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n));
|
||||
}
|
||||
|
||||
static char_type*
|
||||
copy(char_type* __s1, const char_type* __s2, size_t __n)
|
||||
{
|
||||
if (__n == 0)
|
||||
return __s1;
|
||||
return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n));
|
||||
}
|
||||
|
||||
static char_type*
|
||||
assign(char_type* __s, size_t __n, char_type __a)
|
||||
{
|
||||
if (__n == 0)
|
||||
return __s;
|
||||
return static_cast<char_type*>(__builtin_memset(__s, __a, __n));
|
||||
}
|
||||
|
||||
static _GLIBCXX_CONSTEXPR char_type
|
||||
to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
|
||||
{ return char_type(__c); }
|
||||
|
||||
static _GLIBCXX_CONSTEXPR int_type
|
||||
to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
|
||||
{ return int_type(__c); }
|
||||
|
||||
static _GLIBCXX_CONSTEXPR bool
|
||||
eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
|
||||
{ return __c1 == __c2; }
|
||||
|
||||
static _GLIBCXX_CONSTEXPR int_type
|
||||
eof() _GLIBCXX_NOEXCEPT
|
||||
{ return static_cast<int_type>(-1); }
|
||||
|
||||
static _GLIBCXX_CONSTEXPR int_type
|
||||
not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
|
||||
{ return eq_int_type(__c, eof()) ? 0 : __c; }
|
||||
};
|
||||
#endif //_GLIBCXX_USE_CHAR8_T
|
||||
|
||||
_GLIBCXX_END_NAMESPACE_VERSION
|
||||
} // namespace
|
||||
|
||||
|
@ -573,6 +573,122 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
do_max_length() const throw();
|
||||
};
|
||||
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
/** @brief Class codecvt<char16_t, char8_t, mbstate_t> specialization.
|
||||
*
|
||||
* Converts between UTF-16 and UTF-8.
|
||||
*/
|
||||
template<>
|
||||
class codecvt<char16_t, char8_t, mbstate_t>
|
||||
: public __codecvt_abstract_base<char16_t, char8_t, mbstate_t>
|
||||
{
|
||||
public:
|
||||
// Types:
|
||||
typedef char16_t intern_type;
|
||||
typedef char8_t extern_type;
|
||||
typedef mbstate_t state_type;
|
||||
|
||||
public:
|
||||
static locale::id id;
|
||||
|
||||
explicit
|
||||
codecvt(size_t __refs = 0)
|
||||
: __codecvt_abstract_base<char16_t, char8_t, mbstate_t>(__refs) { }
|
||||
|
||||
protected:
|
||||
virtual
|
||||
~codecvt();
|
||||
|
||||
virtual result
|
||||
do_out(state_type& __state, const intern_type* __from,
|
||||
const intern_type* __from_end, const intern_type*& __from_next,
|
||||
extern_type* __to, extern_type* __to_end,
|
||||
extern_type*& __to_next) const;
|
||||
|
||||
virtual result
|
||||
do_unshift(state_type& __state,
|
||||
extern_type* __to, extern_type* __to_end,
|
||||
extern_type*& __to_next) const;
|
||||
|
||||
virtual result
|
||||
do_in(state_type& __state,
|
||||
const extern_type* __from, const extern_type* __from_end,
|
||||
const extern_type*& __from_next,
|
||||
intern_type* __to, intern_type* __to_end,
|
||||
intern_type*& __to_next) const;
|
||||
|
||||
virtual
|
||||
int do_encoding() const throw();
|
||||
|
||||
virtual
|
||||
bool do_always_noconv() const throw();
|
||||
|
||||
virtual
|
||||
int do_length(state_type&, const extern_type* __from,
|
||||
const extern_type* __end, size_t __max) const;
|
||||
|
||||
virtual int
|
||||
do_max_length() const throw();
|
||||
};
|
||||
|
||||
/** @brief Class codecvt<char32_t, char8_t, mbstate_t> specialization.
|
||||
*
|
||||
* Converts between UTF-32 and UTF-8.
|
||||
*/
|
||||
template<>
|
||||
class codecvt<char32_t, char8_t, mbstate_t>
|
||||
: public __codecvt_abstract_base<char32_t, char8_t, mbstate_t>
|
||||
{
|
||||
public:
|
||||
// Types:
|
||||
typedef char32_t intern_type;
|
||||
typedef char8_t extern_type;
|
||||
typedef mbstate_t state_type;
|
||||
|
||||
public:
|
||||
static locale::id id;
|
||||
|
||||
explicit
|
||||
codecvt(size_t __refs = 0)
|
||||
: __codecvt_abstract_base<char32_t, char8_t, mbstate_t>(__refs) { }
|
||||
|
||||
protected:
|
||||
virtual
|
||||
~codecvt();
|
||||
|
||||
virtual result
|
||||
do_out(state_type& __state, const intern_type* __from,
|
||||
const intern_type* __from_end, const intern_type*& __from_next,
|
||||
extern_type* __to, extern_type* __to_end,
|
||||
extern_type*& __to_next) const;
|
||||
|
||||
virtual result
|
||||
do_unshift(state_type& __state,
|
||||
extern_type* __to, extern_type* __to_end,
|
||||
extern_type*& __to_next) const;
|
||||
|
||||
virtual result
|
||||
do_in(state_type& __state,
|
||||
const extern_type* __from, const extern_type* __from_end,
|
||||
const extern_type*& __from_next,
|
||||
intern_type* __to, intern_type* __to_end,
|
||||
intern_type*& __to_next) const;
|
||||
|
||||
virtual
|
||||
int do_encoding() const throw();
|
||||
|
||||
virtual
|
||||
bool do_always_noconv() const throw();
|
||||
|
||||
virtual
|
||||
int do_length(state_type&, const extern_type* __from,
|
||||
const extern_type* __end, size_t __max) const;
|
||||
|
||||
virtual int
|
||||
do_max_length() const throw();
|
||||
};
|
||||
#endif // _GLIBCXX_USE_CHAR8_T
|
||||
|
||||
#endif // C++11
|
||||
|
||||
/// class codecvt_byname [22.2.1.6].
|
||||
@ -639,6 +755,45 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
virtual
|
||||
~codecvt_byname() { }
|
||||
};
|
||||
|
||||
#if defined(_GLIBCXX_USE_CHAR8_T)
|
||||
template<>
|
||||
class codecvt_byname<char16_t, char8_t, mbstate_t>
|
||||
: public codecvt<char16_t, char8_t, mbstate_t>
|
||||
{
|
||||
public:
|
||||
explicit
|
||||
codecvt_byname(const char* __s, size_t __refs = 0)
|
||||
: codecvt<char16_t, char8_t, mbstate_t>(__refs) { }
|
||||
|
||||
explicit
|
||||
codecvt_byname(const string& __s, size_t __refs = 0)
|
||||
: codecvt_byname(__s.c_str(), __refs) { }
|
||||
|
||||
protected:
|
||||
virtual
|
||||
~codecvt_byname() { }
|
||||
};
|
||||
|
||||
template<>
|
||||
class codecvt_byname<char32_t, char8_t, mbstate_t>
|
||||
: public codecvt<char32_t, char8_t, mbstate_t>
|
||||
{
|
||||
public:
|
||||
explicit
|
||||
codecvt_byname(const char* __s, size_t __refs = 0)
|
||||
: codecvt<char32_t, char8_t, mbstate_t>(__refs) { }
|
||||
|
||||
explicit
|
||||
codecvt_byname(const string& __s, size_t __refs = 0)
|
||||
: codecvt_byname(__s.c_str(), __refs) { }
|
||||
|
||||
protected:
|
||||
virtual
|
||||
~codecvt_byname() { }
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif // C++11
|
||||
|
||||
// Inhibit implicit instantiations for required instantiations,
|
||||
@ -669,6 +824,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
#if __cplusplus >= 201103L
|
||||
extern template class codecvt_byname<char16_t, char, mbstate_t>;
|
||||
extern template class codecvt_byname<char32_t, char, mbstate_t>;
|
||||
|
||||
#if defined(_GLIBCXX_USE_CHAR8_T)
|
||||
extern template class codecvt_byname<char16_t, char8_t, mbstate_t>;
|
||||
extern template class codecvt_byname<char32_t, char8_t, mbstate_t>;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -48,7 +48,7 @@
|
||||
// so function return values won't work: We need compile-time entities.
|
||||
// We're left with types and constant integral expressions.
|
||||
// Secondly, from the point of view of ease of use, type-based compile-time
|
||||
// information is -not- *that* convenient. On has to write lots of
|
||||
// information is -not- *that* convenient. One has to write lots of
|
||||
// overloaded functions and to hope that the compiler will select the right
|
||||
// one. As a net effect, the overall structure isn't very clear at first
|
||||
// glance.
|
||||
@ -171,6 +171,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
};
|
||||
# endif
|
||||
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
template<>
|
||||
struct __is_integer<char8_t>
|
||||
{
|
||||
enum { __value = 1 };
|
||||
typedef __true_type __type;
|
||||
};
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
template<>
|
||||
struct __is_integer<char16_t>
|
||||
|
@ -69,8 +69,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
|
||||
{
|
||||
template<typename _CharT, typename _Ch = remove_const_t<_CharT>>
|
||||
using __is_encoded_char
|
||||
= __or_<is_same<_Ch, char>, is_same<_Ch, wchar_t>,
|
||||
is_same<_Ch, char16_t>, is_same<_Ch, char32_t>>;
|
||||
= __or_<is_same<_Ch, char>,
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
is_same<_Ch, char8_t>,
|
||||
#endif
|
||||
is_same<_Ch, wchar_t>,
|
||||
is_same<_Ch, char16_t>,
|
||||
is_same<_Ch, char32_t>>;
|
||||
|
||||
template<typename _Iter,
|
||||
typename _Iter_traits = std::iterator_traits<_Iter>>
|
||||
@ -320,7 +325,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
|
||||
#if _GLIBCXX_USE_WCHAR_T
|
||||
std::wstring wstring() const;
|
||||
#endif
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
__attribute__((__abi_tag__("__u8")))
|
||||
std::u8string u8string() const;
|
||||
#else
|
||||
std::string u8string() const;
|
||||
#endif // _GLIBCXX_USE_CHAR8_T
|
||||
std::u16string u16string() const;
|
||||
std::u32string u32string() const;
|
||||
|
||||
@ -334,7 +344,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
|
||||
#if _GLIBCXX_USE_WCHAR_T
|
||||
std::wstring generic_wstring() const;
|
||||
#endif
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
__attribute__((__abi_tag__("__u8")))
|
||||
std::u8string generic_u8string() const;
|
||||
#else
|
||||
std::string generic_u8string() const;
|
||||
#endif // _GLIBCXX_USE_CHAR8_T
|
||||
std::u16string generic_u16string() const;
|
||||
std::u32string generic_u32string() const;
|
||||
|
||||
@ -735,10 +750,22 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
|
||||
static string_type
|
||||
_S_convert(const _CharT* __f, const _CharT* __l)
|
||||
{
|
||||
std::codecvt_utf8<_CharT> __cvt;
|
||||
std::string __str;
|
||||
if (__str_codecvt_out(__f, __l, __str, __cvt))
|
||||
return __str;
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
if constexpr (is_same_v<_CharT, char8_t>)
|
||||
{
|
||||
string_type __str(__f, __l);
|
||||
return __str;
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
std::codecvt_utf8<_CharT> __cvt;
|
||||
std::string __str;
|
||||
if (__str_codecvt_out(__f, __l, __str, __cvt))
|
||||
return __str;
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
}
|
||||
#endif
|
||||
_GLIBCXX_THROW_OR_ABORT(filesystem_error(
|
||||
"Cannot convert character sequence",
|
||||
std::make_error_code(errc::illegal_byte_sequence)));
|
||||
@ -938,6 +965,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
|
||||
{
|
||||
if constexpr (is_same_v<_CharT, char>)
|
||||
return __u8str;
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
else if constexpr (is_same_v<_CharT, char8_t>)
|
||||
{
|
||||
const char* __f = __u8str.data();
|
||||
const char* __l = __f + __u8str.size();
|
||||
_WString __wstr(__f, __l);
|
||||
return __wstr;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
_WString __wstr;
|
||||
@ -950,10 +986,22 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
|
||||
}
|
||||
}
|
||||
#else
|
||||
codecvt_utf8<_CharT> __cvt;
|
||||
basic_string<_CharT, _Traits, _Allocator> __wstr{__a};
|
||||
if (__str_codecvt_in(__first, __last, __wstr, __cvt))
|
||||
return __wstr;
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
if constexpr (is_same_v<_CharT, char8_t>)
|
||||
{
|
||||
basic_string<_CharT, _Traits, _Allocator> __wstr{__first, __last, __a};
|
||||
return __wstr;
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
codecvt_utf8<_CharT> __cvt;
|
||||
basic_string<_CharT, _Traits, _Allocator> __wstr{__a};
|
||||
if (__str_codecvt_in(__first, __last, __wstr, __cvt))
|
||||
return __wstr;
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
_GLIBCXX_THROW_OR_ABORT(filesystem_error(
|
||||
"Cannot convert character sequence",
|
||||
@ -978,6 +1026,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
|
||||
path::wstring() const { return string<wchar_t>(); }
|
||||
#endif
|
||||
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
inline std::u8string
|
||||
path::u8string() const { return string<char8_t>(); }
|
||||
#else
|
||||
inline std::string
|
||||
path::u8string() const
|
||||
{
|
||||
@ -996,6 +1048,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
|
||||
return _M_pathname;
|
||||
#endif
|
||||
}
|
||||
#endif // _GLIBCXX_USE_CHAR8_T
|
||||
|
||||
inline std::u16string
|
||||
path::u16string() const { return string<char16_t>(); }
|
||||
@ -1045,9 +1098,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
|
||||
{ return generic_string<wchar_t>(); }
|
||||
#endif
|
||||
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
inline std::u8string
|
||||
path::generic_u8string() const
|
||||
{ return generic_string<char8_t>(); }
|
||||
#else
|
||||
inline std::string
|
||||
path::generic_u8string() const
|
||||
{ return generic_string(); }
|
||||
#endif
|
||||
|
||||
inline std::u16string
|
||||
path::generic_u16string() const
|
||||
|
@ -135,6 +135,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
/// Explicit specialization for wchar_t.
|
||||
_Cxx_hashtable_define_trivial_hash(wchar_t)
|
||||
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
/// Explicit specialization for char8_t.
|
||||
_Cxx_hashtable_define_trivial_hash(char8_t)
|
||||
#endif
|
||||
|
||||
/// Explicit specialization for char16_t.
|
||||
_Cxx_hashtable_define_trivial_hash(char16_t)
|
||||
|
||||
|
@ -158,6 +158,39 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
return __str_codecvt_out(__first, __last, __outstr, __cvt, __state, __n);
|
||||
}
|
||||
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
|
||||
// Convert wide character string to narrow.
|
||||
template<typename _CharT, typename _Traits, typename _Alloc, typename _State>
|
||||
inline bool
|
||||
__str_codecvt_out(const _CharT* __first, const _CharT* __last,
|
||||
basic_string<char8_t, _Traits, _Alloc>& __outstr,
|
||||
const codecvt<_CharT, char8_t, _State>& __cvt,
|
||||
_State& __state, size_t& __count)
|
||||
{
|
||||
using _Codecvt = codecvt<_CharT, char8_t, _State>;
|
||||
using _ConvFn
|
||||
= codecvt_base::result
|
||||
(_Codecvt::*)(_State&, const _CharT*, const _CharT*, const _CharT*&,
|
||||
char8_t*, char8_t*, char8_t*&) const;
|
||||
_ConvFn __fn = &codecvt<_CharT, char8_t, _State>::out;
|
||||
return __do_str_codecvt(__first, __last, __outstr, __cvt, __state,
|
||||
__count, __fn);
|
||||
}
|
||||
|
||||
template<typename _CharT, typename _Traits, typename _Alloc, typename _State>
|
||||
inline bool
|
||||
__str_codecvt_out(const _CharT* __first, const _CharT* __last,
|
||||
basic_string<char8_t, _Traits, _Alloc>& __outstr,
|
||||
const codecvt<_CharT, char8_t, _State>& __cvt)
|
||||
{
|
||||
_State __state = {};
|
||||
size_t __n;
|
||||
return __str_codecvt_out(__first, __last, __outstr, __cvt, __state, __n);
|
||||
}
|
||||
|
||||
#endif // _GLIBCXX_USE_CHAR8_T
|
||||
|
||||
#ifdef _GLIBCXX_USE_WCHAR_T
|
||||
|
||||
_GLIBCXX_BEGIN_NAMESPACE_CXX11
|
||||
|
@ -59,7 +59,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
# define _GLIBCXX_NUM_FACETS 14
|
||||
# define _GLIBCXX_NUM_CXX11_FACETS 8
|
||||
#endif
|
||||
#define _GLIBCXX_NUM_UNICODE_FACETS 2
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
# define _GLIBCXX_NUM_UNICODE_FACETS 4
|
||||
#else
|
||||
# define _GLIBCXX_NUM_UNICODE_FACETS 2
|
||||
#endif
|
||||
|
||||
// Convert string to numeric value of type _Tp and store results.
|
||||
// NB: This is specialized for all required types, there is no
|
||||
|
@ -139,6 +139,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
template<> class codecvt<char, char, mbstate_t>;
|
||||
#ifdef _GLIBCXX_USE_WCHAR_T
|
||||
template<> class codecvt<wchar_t, char, mbstate_t>;
|
||||
#endif
|
||||
#if __cplusplus >= 201103L
|
||||
template<> class codecvt<char16_t, char, mbstate_t>;
|
||||
template<> class codecvt<char32_t, char, mbstate_t>;
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
template<> class codecvt<char16_t, char8_t, mbstate_t>;
|
||||
template<> class codecvt<char32_t, char8_t, mbstate_t>;
|
||||
#endif
|
||||
#endif
|
||||
template<typename _InternT, typename _ExternT, typename _StateT>
|
||||
class codecvt_byname;
|
||||
|
@ -235,6 +235,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
/// File position for wchar_t streams.
|
||||
typedef fpos<mbstate_t> wstreampos;
|
||||
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
/// File position for char8_t streams.
|
||||
typedef fpos<mbstate_t> u8streampos;
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
/// File position for char16_t streams.
|
||||
typedef fpos<mbstate_t> u16streampos;
|
||||
|
@ -58,6 +58,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
template<> struct char_traits<wchar_t>;
|
||||
#endif
|
||||
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
template<> struct char_traits<char8_t>;
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
template<> struct char_traits<char16_t>;
|
||||
template<> struct char_traits<char32_t>;
|
||||
@ -79,6 +83,11 @@ _GLIBCXX_END_NAMESPACE_CXX11
|
||||
typedef basic_string<wchar_t> wstring;
|
||||
#endif
|
||||
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
/// A string of @c char8_t
|
||||
typedef basic_string<char8_t> u8string;
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
/// A string of @c char16_t
|
||||
typedef basic_string<char16_t> u16string;
|
||||
|
@ -75,6 +75,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
template<> struct __byte_operand<unsigned char> { using __type = byte; };
|
||||
#ifdef _GLIBCXX_USE_WCHAR_T
|
||||
template<> struct __byte_operand<wchar_t> { using __type = byte; };
|
||||
#endif
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
template<> struct __byte_operand<char8_t> { using __type = byte; };
|
||||
#endif
|
||||
template<> struct __byte_operand<char16_t> { using __type = byte; };
|
||||
template<> struct __byte_operand<char32_t> { using __type = byte; };
|
||||
|
@ -82,8 +82,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
|
||||
template<typename _CharT,
|
||||
typename _Ch = typename remove_const<_CharT>::type>
|
||||
using __is_encoded_char
|
||||
= __or_<is_same<_Ch, char>, is_same<_Ch, wchar_t>,
|
||||
is_same<_Ch, char16_t>, is_same<_Ch, char32_t>>;
|
||||
= __or_<is_same<_Ch, char>,
|
||||
is_same<_Ch, wchar_t>,
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
is_same<_Ch, char8_t>,
|
||||
#endif
|
||||
is_same<_Ch, char16_t>,
|
||||
is_same<_Ch, char32_t>>;
|
||||
|
||||
template<typename _Iter,
|
||||
typename _Iter_traits = std::iterator_traits<_Iter>>
|
||||
@ -325,7 +330,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
|
||||
#if _GLIBCXX_USE_WCHAR_T
|
||||
std::wstring wstring() const;
|
||||
#endif
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
__attribute__((__abi_tag__("__u8")))
|
||||
std::u8string u8string() const;
|
||||
#else
|
||||
std::string u8string() const;
|
||||
#endif // _GLIBCXX_USE_CHAR8_T
|
||||
std::u16string u16string() const;
|
||||
std::u32string u32string() const;
|
||||
|
||||
@ -339,7 +349,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
|
||||
#if _GLIBCXX_USE_WCHAR_T
|
||||
std::wstring generic_wstring() const;
|
||||
#endif
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
__attribute__((__abi_tag__("__u8")))
|
||||
std::u8string generic_u8string() const;
|
||||
#else
|
||||
std::string generic_u8string() const;
|
||||
#endif // _GLIBCXX_USE_CHAR8_T
|
||||
std::u16string generic_u16string() const;
|
||||
std::u32string generic_u32string() const;
|
||||
|
||||
@ -674,10 +689,22 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
|
||||
static string_type
|
||||
_S_convert(const _CharT* __f, const _CharT* __l)
|
||||
{
|
||||
std::codecvt_utf8<_CharT> __cvt;
|
||||
std::string __str;
|
||||
if (__str_codecvt_out(__f, __l, __str, __cvt))
|
||||
return __str;
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
if constexpr (is_same<_CharT, char8_t>::value)
|
||||
{
|
||||
string_type __str(__f, __l);
|
||||
return __str;
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
std::codecvt_utf8<_CharT> __cvt;
|
||||
std::string __str;
|
||||
if (__str_codecvt_out(__f, __l, __str, __cvt))
|
||||
return __str;
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
}
|
||||
#endif
|
||||
_GLIBCXX_THROW_OR_ABORT(filesystem_error(
|
||||
"Cannot convert character sequence",
|
||||
std::make_error_code(errc::illegal_byte_sequence)));
|
||||
@ -867,12 +894,24 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
|
||||
_WString*
|
||||
operator()(const _String& __from, _WString& __to, false_type)
|
||||
{
|
||||
// use codecvt_utf8<_CharT> to convert UTF-8 to wide string
|
||||
codecvt_utf8<_CharT> __cvt;
|
||||
const char* __f = __from.data();
|
||||
const char* __l = __f + __from.size();
|
||||
if (__str_codecvt_in(__f, __l, __to, __cvt))
|
||||
return std::__addressof(__to);
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
if constexpr (is_same<_CharT, char8_t>::value)
|
||||
{
|
||||
__to.assign(__from.begin(), __from.end());
|
||||
return std::__addressof(__to);
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
// use codecvt_utf8<_CharT> to convert UTF-8 to wide string
|
||||
codecvt_utf8<_CharT> __cvt;
|
||||
const char* __f = __from.data();
|
||||
const char* __l = __f + __from.size();
|
||||
if (__str_codecvt_in(__f, __l, __to, __cvt))
|
||||
return std::__addressof(__to);
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
}
|
||||
#endif
|
||||
return nullptr;
|
||||
}
|
||||
} __dispatch;
|
||||
@ -881,10 +920,22 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
|
||||
return *__p;
|
||||
}
|
||||
#else
|
||||
codecvt_utf8<_CharT> __cvt;
|
||||
basic_string<_CharT, _Traits, _Allocator> __wstr{__a};
|
||||
if (__str_codecvt_in(__first, __last, __wstr, __cvt))
|
||||
return __wstr;
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
if constexpr (is_same<_CharT, char8_t>::value)
|
||||
{
|
||||
basic_string<_CharT, _Traits, _Allocator> __wstr{__first, __last, __a};
|
||||
return __wstr;
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
codecvt_utf8<_CharT> __cvt;
|
||||
basic_string<_CharT, _Traits, _Allocator> __wstr{__a};
|
||||
if (__str_codecvt_in(__first, __last, __wstr, __cvt))
|
||||
return __wstr;
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
_GLIBCXX_THROW_OR_ABORT(filesystem_error(
|
||||
"Cannot convert character sequence",
|
||||
@ -899,6 +950,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
|
||||
path::wstring() const { return string<wchar_t>(); }
|
||||
#endif
|
||||
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
inline std::u8string
|
||||
path::u8string() const { return string<char8_t>(); }
|
||||
#else
|
||||
inline std::string
|
||||
path::u8string() const
|
||||
{
|
||||
@ -917,6 +972,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
|
||||
return _M_pathname;
|
||||
#endif
|
||||
}
|
||||
#endif // _GLIBCXX_USE_CHAR8_T
|
||||
|
||||
inline std::u16string
|
||||
path::u16string() const { return string<char16_t>(); }
|
||||
@ -938,8 +994,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
|
||||
path::generic_wstring() const { return wstring(); }
|
||||
#endif
|
||||
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
inline std::u8string
|
||||
path::generic_u8string() const { return u8string(); }
|
||||
#else
|
||||
inline std::string
|
||||
path::generic_u8string() const { return u8string(); }
|
||||
#endif
|
||||
|
||||
inline std::u16string
|
||||
path::generic_u16string() const { return u16string(); }
|
||||
|
@ -73,6 +73,9 @@ inline namespace fundamentals_v2
|
||||
// basic_string typedef names using polymorphic allocator in namespace
|
||||
// std::experimental::pmr
|
||||
typedef basic_string<char> string;
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
typedef basic_string<char8_t> u8string;
|
||||
#endif
|
||||
typedef basic_string<char16_t> u16string;
|
||||
typedef basic_string<char32_t> u32string;
|
||||
typedef basic_string<wchar_t> wstring;
|
||||
|
@ -565,6 +565,9 @@ inline namespace fundamentals_v1
|
||||
using string_view = basic_string_view<char>;
|
||||
#ifdef _GLIBCXX_USE_WCHAR_T
|
||||
using wstring_view = basic_string_view<wchar_t>;
|
||||
#endif
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
using u8string_view = basic_string_view<char8_t>;
|
||||
#endif
|
||||
using u16string_view = basic_string_view<char16_t>;
|
||||
using u32string_view = basic_string_view<char32_t>;
|
||||
@ -605,6 +608,21 @@ inline namespace fundamentals_v1
|
||||
{ };
|
||||
#endif
|
||||
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
template<>
|
||||
struct hash<experimental::u8string_view>
|
||||
: public __hash_base<size_t, experimental::u8string_view>
|
||||
{
|
||||
size_t
|
||||
operator()(const experimental::u8string_view& __s) const noexcept
|
||||
{ return std::_Hash_impl::hash(__s.data(), __s.length()); }
|
||||
};
|
||||
|
||||
template<>
|
||||
struct __is_fast_hash<hash<experimental::u8string_view>> : std::false_type
|
||||
{ };
|
||||
#endif
|
||||
|
||||
template<>
|
||||
struct hash<experimental::u16string_view>
|
||||
: public __hash_base<size_t, experimental::u16string_view>
|
||||
@ -652,6 +670,12 @@ namespace experimental
|
||||
{ return basic_string_view<wchar_t>{__str, __len}; }
|
||||
#endif
|
||||
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
inline constexpr basic_string_view<char8_t>
|
||||
operator""sv(const char8_t* __str, size_t __len) noexcept
|
||||
{ return basic_string_view<char8_t>{__str, __len}; }
|
||||
#endif
|
||||
|
||||
inline constexpr basic_string_view<char16_t>
|
||||
operator""sv(const char16_t* __str, size_t __len) noexcept
|
||||
{ return basic_string_view<char16_t>{__str, __len}; }
|
||||
|
@ -904,6 +904,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
/// Explicit specialization for char8_t.
|
||||
template<>
|
||||
struct atomic<char8_t> : __atomic_base<char8_t>
|
||||
{
|
||||
typedef char8_t __integral_type;
|
||||
typedef __atomic_base<char8_t> __base_type;
|
||||
|
||||
atomic() noexcept = default;
|
||||
~atomic() noexcept = default;
|
||||
atomic(const atomic&) = delete;
|
||||
atomic& operator=(const atomic&) = delete;
|
||||
atomic& operator=(const atomic&) volatile = delete;
|
||||
|
||||
constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
|
||||
|
||||
using __base_type::operator __integral_type;
|
||||
using __base_type::operator=;
|
||||
|
||||
#if __cplusplus > 201402L
|
||||
static constexpr bool is_always_lock_free = ATOMIC_CHAR8_T_LOCK_FREE == 2;
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
/// Explicit specialization for char16_t.
|
||||
template<>
|
||||
struct atomic<char16_t> : __atomic_base<char16_t>
|
||||
@ -990,6 +1015,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
/// atomic_wchar_t
|
||||
typedef atomic<wchar_t> atomic_wchar_t;
|
||||
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
/// atomic_char8_t
|
||||
typedef atomic<char8_t> atomic_char8_t;
|
||||
#endif
|
||||
|
||||
/// atomic_char16_t
|
||||
typedef atomic<char16_t> atomic_char16_t;
|
||||
|
||||
|
@ -66,6 +66,9 @@ namespace __detail
|
||||
__not_<__is_one_of<_Tp, bool, char16_t, char32_t
|
||||
#if _GLIBCXX_USE_WCHAR_T
|
||||
, wchar_t
|
||||
#endif
|
||||
#if _GLIBCXX_USE_CHAR8_T
|
||||
, char8_t
|
||||
#endif
|
||||
>>>;
|
||||
|
||||
|
@ -374,6 +374,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
|
||||
// Now there follow 16 explicit specializations. Yes, 16. Make sure
|
||||
// you get the count right. (18 in C++11 mode, with char16_t and char32_t.)
|
||||
// (+1 if char8_t is enabled.)
|
||||
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 184. numeric_limits<bool> wording problems
|
||||
@ -725,6 +726,71 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
= round_toward_zero;
|
||||
};
|
||||
|
||||
#if _GLIBCXX_USE_CHAR8_T
|
||||
/// numeric_limits<char8_t> specialization.
|
||||
template<>
|
||||
struct numeric_limits<char8_t>
|
||||
{
|
||||
static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true;
|
||||
|
||||
static _GLIBCXX_CONSTEXPR char8_t
|
||||
min() _GLIBCXX_USE_NOEXCEPT { return __glibcxx_min (char8_t); }
|
||||
|
||||
static _GLIBCXX_CONSTEXPR char8_t
|
||||
max() _GLIBCXX_USE_NOEXCEPT { return __glibcxx_max (char8_t); }
|
||||
|
||||
static _GLIBCXX_CONSTEXPR char8_t
|
||||
lowest() _GLIBCXX_USE_NOEXCEPT { return min(); }
|
||||
|
||||
static _GLIBCXX_USE_CONSTEXPR int digits = __glibcxx_digits (char8_t);
|
||||
static _GLIBCXX_USE_CONSTEXPR int digits10 = __glibcxx_digits10 (char8_t);
|
||||
static _GLIBCXX_USE_CONSTEXPR int max_digits10 = 0;
|
||||
static _GLIBCXX_USE_CONSTEXPR bool is_signed = __glibcxx_signed (char8_t);
|
||||
static _GLIBCXX_USE_CONSTEXPR bool is_integer = true;
|
||||
static _GLIBCXX_USE_CONSTEXPR bool is_exact = true;
|
||||
static _GLIBCXX_USE_CONSTEXPR int radix = 2;
|
||||
|
||||
static _GLIBCXX_CONSTEXPR char8_t
|
||||
epsilon() _GLIBCXX_USE_NOEXCEPT { return 0; }
|
||||
|
||||
static _GLIBCXX_CONSTEXPR char8_t
|
||||
round_error() _GLIBCXX_USE_NOEXCEPT { return 0; }
|
||||
|
||||
static _GLIBCXX_USE_CONSTEXPR int min_exponent = 0;
|
||||
static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = 0;
|
||||
static _GLIBCXX_USE_CONSTEXPR int max_exponent = 0;
|
||||
static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = 0;
|
||||
|
||||
static _GLIBCXX_USE_CONSTEXPR bool has_infinity = false;
|
||||
static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = false;
|
||||
static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = false;
|
||||
static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm
|
||||
= denorm_absent;
|
||||
static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false;
|
||||
|
||||
static _GLIBCXX_CONSTEXPR char8_t
|
||||
infinity() _GLIBCXX_USE_NOEXCEPT { return char8_t(); }
|
||||
|
||||
static _GLIBCXX_CONSTEXPR char8_t
|
||||
quiet_NaN() _GLIBCXX_USE_NOEXCEPT { return char8_t(); }
|
||||
|
||||
static _GLIBCXX_CONSTEXPR char8_t
|
||||
signaling_NaN() _GLIBCXX_USE_NOEXCEPT { return char8_t(); }
|
||||
|
||||
static _GLIBCXX_CONSTEXPR char8_t
|
||||
denorm_min() _GLIBCXX_USE_NOEXCEPT { return char8_t(); }
|
||||
|
||||
static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false;
|
||||
static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true;
|
||||
static _GLIBCXX_USE_CONSTEXPR bool is_modulo = !is_signed;
|
||||
|
||||
static _GLIBCXX_USE_CONSTEXPR bool traps = __glibcxx_integral_traps;
|
||||
static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false;
|
||||
static _GLIBCXX_USE_CONSTEXPR float_round_style round_style
|
||||
= round_toward_zero;
|
||||
};
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
/// numeric_limits<char16_t> specialization.
|
||||
template<>
|
||||
|
@ -65,6 +65,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
using basic_string = std::basic_string<_CharT, _Traits,
|
||||
polymorphic_allocator<_CharT>>;
|
||||
using string = basic_string<char>;
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
using u8string = basic_string<char8_t>;
|
||||
#endif
|
||||
using u16string = basic_string<char16_t>;
|
||||
using u32string = basic_string<char32_t>;
|
||||
#ifdef _GLIBCXX_USE_WCHAR_T
|
||||
|
@ -583,7 +583,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
#ifdef _GLIBCXX_USE_WCHAR_T
|
||||
using wstring_view = basic_string_view<wchar_t>;
|
||||
#endif
|
||||
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
using u8string_view = basic_string_view<char8_t>;
|
||||
#endif
|
||||
using u16string_view = basic_string_view<char16_t>;
|
||||
using u32string_view = basic_string_view<char32_t>;
|
||||
|
||||
@ -621,6 +623,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
{ };
|
||||
#endif
|
||||
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
template<>
|
||||
struct hash<u8string_view>
|
||||
: public __hash_base<size_t, u8string_view>
|
||||
{
|
||||
size_t
|
||||
operator()(const u8string_view& __str) const noexcept
|
||||
{ return std::_Hash_impl::hash(__str.data(), __str.length()); }
|
||||
};
|
||||
|
||||
template<>
|
||||
struct __is_fast_hash<hash<u8string_view>> : std::false_type
|
||||
{ };
|
||||
#endif
|
||||
|
||||
template<>
|
||||
struct hash<u16string_view>
|
||||
: public __hash_base<size_t, u16string_view>
|
||||
@ -665,6 +682,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
{ return basic_string_view<wchar_t>{__str, __len}; }
|
||||
#endif
|
||||
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
inline constexpr basic_string_view<char8_t>
|
||||
operator""sv(const char8_t* __str, size_t __len) noexcept
|
||||
{ return basic_string_view<char8_t>{__str, __len}; }
|
||||
#endif
|
||||
|
||||
inline constexpr basic_string_view<char16_t>
|
||||
operator""sv(const char16_t* __str, size_t __len) noexcept
|
||||
{ return basic_string_view<char16_t>{__str, __len}; }
|
||||
|
@ -234,6 +234,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
: public true_type { };
|
||||
#endif
|
||||
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
template<>
|
||||
struct __is_integral_helper<char8_t>
|
||||
: public true_type { };
|
||||
#endif
|
||||
|
||||
template<>
|
||||
struct __is_integral_helper<char16_t>
|
||||
: public true_type { };
|
||||
@ -1680,8 +1686,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
= typename __match_cv_qualifiers<_Tp, __unsigned_type>::__type;
|
||||
};
|
||||
|
||||
// wchar_t, char16_t and char32_t are integral types but are neither
|
||||
// signed integer types nor unsigned integer types, so must be
|
||||
// wchar_t, char8_t, char16_t and char32_t are integral types but are
|
||||
// neither signed integer types nor unsigned integer types, so must be
|
||||
// transformed to the unsigned integer type with the smallest rank.
|
||||
// Use the partial specialization for enumeration types to do that.
|
||||
#if defined(_GLIBCXX_USE_WCHAR_T)
|
||||
@ -1693,6 +1699,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
template<>
|
||||
struct __make_unsigned<char8_t>
|
||||
{
|
||||
using __type
|
||||
= typename __make_unsigned_selector<char8_t, false, true>::__type;
|
||||
};
|
||||
#endif
|
||||
|
||||
template<>
|
||||
struct __make_unsigned<char16_t>
|
||||
{
|
||||
@ -1810,6 +1825,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(_GLIBCXX_USE_CHAR8_T)
|
||||
template<>
|
||||
struct __make_signed<char8_t>
|
||||
{
|
||||
using __type
|
||||
= typename __make_signed_selector<char8_t, false, true>::__type;
|
||||
};
|
||||
#endif
|
||||
|
||||
template<>
|
||||
struct __make_signed<char16_t>
|
||||
{
|
||||
|
@ -49,6 +49,9 @@
|
||||
#define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE
|
||||
#define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE
|
||||
#define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
#define ATOMIC_CHAR8_T_LOCK_FREE __GCC_ATOMIC_CHAR8_T_LOCK_FREE
|
||||
#endif
|
||||
#define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE
|
||||
#define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE
|
||||
#define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE
|
||||
|
@ -126,6 +126,16 @@ hashtable_c++0x.lo: hashtable_c++0x.cc
|
||||
hashtable_c++0x.o: hashtable_c++0x.cc
|
||||
$(CXXCOMPILE) -fimplicit-templates -c $<
|
||||
|
||||
# Use special rules for source files that require -fchar8_t.
|
||||
codecvt.lo: codecvt.cc
|
||||
$(LTCXXCOMPILE) -fchar8_t -c $<
|
||||
codecvt.o: codecvt.cc
|
||||
$(CXXCOMPILE) -fchar8_t -c $<
|
||||
limits.lo: limits.cc
|
||||
$(LTCXXCOMPILE) -fchar8_t -c $<
|
||||
limits.o: limits.cc
|
||||
$(CXXCOMPILE) -fchar8_t -c $<
|
||||
|
||||
if ENABLE_DUAL_ABI
|
||||
# Rewrite the type info for __ios_failure.
|
||||
rewrite_ios_failure_typeinfo = sed -e '/^_*_ZTISt13__ios_failure:/,/_ZTVN10__cxxabiv120__si_class_type_infoE/s/_ZTVN10__cxxabiv120__si_class_type_infoE/_ZTVSt19__iosfail_type_info/'
|
||||
|
@ -834,6 +834,16 @@ hashtable_c++0x.lo: hashtable_c++0x.cc
|
||||
hashtable_c++0x.o: hashtable_c++0x.cc
|
||||
$(CXXCOMPILE) -fimplicit-templates -c $<
|
||||
|
||||
# Use special rules for source files that require -fchar8_t.
|
||||
codecvt.lo: codecvt.cc
|
||||
$(LTCXXCOMPILE) -fchar8_t -c $<
|
||||
codecvt.o: codecvt.cc
|
||||
$(CXXCOMPILE) -fchar8_t -c $<
|
||||
limits.lo: limits.cc
|
||||
$(LTCXXCOMPILE) -fchar8_t -c $<
|
||||
limits.o: limits.cc
|
||||
$(CXXCOMPILE) -fchar8_t -c $<
|
||||
|
||||
@ENABLE_DUAL_ABI_TRUE@cxx11-ios_failure-lt.s: cxx11-ios_failure.cc
|
||||
@ENABLE_DUAL_ABI_TRUE@ $(LTCXXCOMPILE) -S $< -o tmp-cxx11-ios_failure-lt.s
|
||||
@ENABLE_DUAL_ABI_TRUE@ -test -f tmp-cxx11-ios_failure-lt.o && mv -f tmp-cxx11-ios_failure-lt.o tmp-cxx11-ios_failure-lt.s
|
||||
|
@ -193,8 +193,9 @@ namespace
|
||||
}
|
||||
|
||||
// If generate_header is set in mode write out UTF-8 BOM.
|
||||
template<typename C>
|
||||
bool
|
||||
write_utf8_bom(range<char>& to, codecvt_mode mode)
|
||||
write_utf8_bom(range<C>& to, codecvt_mode mode)
|
||||
{
|
||||
if (mode & generate_header)
|
||||
return write_bom(to, utf8_bom);
|
||||
@ -218,8 +219,9 @@ namespace
|
||||
}
|
||||
|
||||
// If consume_header is set in mode update from.next to after any BOM.
|
||||
template<typename C>
|
||||
void
|
||||
read_utf8_bom(range<const char>& from, codecvt_mode mode)
|
||||
read_utf8_bom(range<const C>& from, codecvt_mode mode)
|
||||
{
|
||||
if (mode & consume_header)
|
||||
read_bom(from, utf8_bom);
|
||||
@ -245,8 +247,9 @@ namespace
|
||||
// Read a codepoint from a UTF-8 multibyte sequence.
|
||||
// Updates from.next if the codepoint is not greater than maxcode.
|
||||
// Returns invalid_mb_sequence, incomplete_mb_character or the code point.
|
||||
template<typename C>
|
||||
char32_t
|
||||
read_utf8_code_point(range<const char>& from, unsigned long maxcode)
|
||||
read_utf8_code_point(range<const C>& from, unsigned long maxcode)
|
||||
{
|
||||
const size_t avail = from.size();
|
||||
if (avail == 0)
|
||||
@ -315,8 +318,9 @@ namespace
|
||||
return invalid_mb_sequence;
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
bool
|
||||
write_utf8_code_point(range<char>& to, char32_t code_point)
|
||||
write_utf8_code_point(range<C>& to, char32_t code_point)
|
||||
{
|
||||
if (code_point < 0x80)
|
||||
{
|
||||
@ -445,8 +449,9 @@ namespace
|
||||
}
|
||||
|
||||
// utf8 -> ucs4
|
||||
template<typename C>
|
||||
codecvt_base::result
|
||||
ucs4_in(range<const char>& from, range<char32_t>& to,
|
||||
ucs4_in(range<const C>& from, range<char32_t>& to,
|
||||
unsigned long maxcode = max_code_point, codecvt_mode mode = {})
|
||||
{
|
||||
read_utf8_bom(from, mode);
|
||||
@ -463,8 +468,9 @@ namespace
|
||||
}
|
||||
|
||||
// ucs4 -> utf8
|
||||
template<typename C>
|
||||
codecvt_base::result
|
||||
ucs4_out(range<const char32_t>& from, range<char>& to,
|
||||
ucs4_out(range<const char32_t>& from, range<C>& to,
|
||||
unsigned long maxcode = max_code_point, codecvt_mode mode = {})
|
||||
{
|
||||
if (!write_utf8_bom(to, mode))
|
||||
@ -522,9 +528,9 @@ namespace
|
||||
enum class surrogates { allowed, disallowed };
|
||||
|
||||
// utf8 -> utf16 (or utf8 -> ucs2 if s == surrogates::disallowed)
|
||||
template<typename C>
|
||||
template<typename C8, typename C16>
|
||||
codecvt_base::result
|
||||
utf16_in(range<const char>& from, range<C>& to,
|
||||
utf16_in(range<const C8>& from, range<C16>& to,
|
||||
unsigned long maxcode = max_code_point, codecvt_mode mode = {},
|
||||
surrogates s = surrogates::allowed)
|
||||
{
|
||||
@ -552,9 +558,9 @@ namespace
|
||||
}
|
||||
|
||||
// utf16 -> utf8 (or ucs2 -> utf8 if s == surrogates::disallowed)
|
||||
template<typename C>
|
||||
template<typename C16, typename C8>
|
||||
codecvt_base::result
|
||||
utf16_out(range<const C>& from, range<char>& to,
|
||||
utf16_out(range<const C16>& from, range<C8>& to,
|
||||
unsigned long maxcode = max_code_point, codecvt_mode mode = {},
|
||||
surrogates s = surrogates::allowed)
|
||||
{
|
||||
@ -593,11 +599,12 @@ namespace
|
||||
}
|
||||
|
||||
// return pos such that [begin,pos) is valid UTF-16 string no longer than max
|
||||
const char*
|
||||
utf16_span(const char* begin, const char* end, size_t max,
|
||||
template<typename C>
|
||||
const C*
|
||||
utf16_span(const C* begin, const C* end, size_t max,
|
||||
char32_t maxcode = max_code_point, codecvt_mode mode = {})
|
||||
{
|
||||
range<const char> from{ begin, end };
|
||||
range<const C> from{ begin, end };
|
||||
read_utf8_bom(from, mode);
|
||||
size_t count = 0;
|
||||
while (count+1 < max)
|
||||
@ -615,8 +622,9 @@ namespace
|
||||
}
|
||||
|
||||
// utf8 -> ucs2
|
||||
template<typename C>
|
||||
codecvt_base::result
|
||||
ucs2_in(range<const char>& from, range<char16_t>& to,
|
||||
ucs2_in(range<const C>& from, range<char16_t>& to,
|
||||
char32_t maxcode = max_code_point, codecvt_mode mode = {})
|
||||
{
|
||||
// UCS-2 only supports characters in the BMP, i.e. one UTF-16 code unit:
|
||||
@ -625,8 +633,9 @@ namespace
|
||||
}
|
||||
|
||||
// ucs2 -> utf8
|
||||
template<typename C>
|
||||
codecvt_base::result
|
||||
ucs2_out(range<const char16_t>& from, range<char>& to,
|
||||
ucs2_out(range<const char16_t>& from, range<C>& to,
|
||||
char32_t maxcode = max_code_point, codecvt_mode mode = {})
|
||||
{
|
||||
// UCS-2 only supports characters in the BMP, i.e. one UTF-16 code unit:
|
||||
@ -687,11 +696,12 @@ namespace
|
||||
return reinterpret_cast<const char16_t*>(from.next);
|
||||
}
|
||||
|
||||
const char*
|
||||
ucs2_span(const char* begin, const char* end, size_t max,
|
||||
template<typename C>
|
||||
const C*
|
||||
ucs2_span(const C* begin, const C* end, size_t max,
|
||||
char32_t maxcode, codecvt_mode mode)
|
||||
{
|
||||
range<const char> from{ begin, end };
|
||||
range<const C> from{ begin, end };
|
||||
read_utf8_bom(from, mode);
|
||||
// UCS-2 only supports characters in the BMP, i.e. one UTF-16 code unit:
|
||||
maxcode = std::min(max_single_utf16_unit, maxcode);
|
||||
@ -702,11 +712,12 @@ namespace
|
||||
}
|
||||
|
||||
// return pos such that [begin,pos) is valid UCS-4 string no longer than max
|
||||
const char*
|
||||
ucs4_span(const char* begin, const char* end, size_t max,
|
||||
template<typename C>
|
||||
const C*
|
||||
ucs4_span(const C* begin, const C* end, size_t max,
|
||||
char32_t maxcode = max_code_point, codecvt_mode mode = {})
|
||||
{
|
||||
range<const char> from{ begin, end };
|
||||
range<const C> from{ begin, end };
|
||||
read_utf8_bom(from, mode);
|
||||
char32_t c = 0;
|
||||
while (max-- && c <= maxcode)
|
||||
@ -875,6 +886,156 @@ codecvt<char32_t, char, mbstate_t>::do_max_length() const throw()
|
||||
return 4;
|
||||
}
|
||||
|
||||
#if defined(_GLIBCXX_USE_CHAR8_T)
|
||||
// Define members of codecvt<char16_t, char8_t, mbstate_t> specialization.
|
||||
// Converts from UTF-8 to UTF-16.
|
||||
|
||||
locale::id codecvt<char16_t, char8_t, mbstate_t>::id;
|
||||
|
||||
codecvt<char16_t, char8_t, mbstate_t>::~codecvt() { }
|
||||
|
||||
codecvt_base::result
|
||||
codecvt<char16_t, char8_t, mbstate_t>::
|
||||
do_out(state_type&,
|
||||
const intern_type* __from,
|
||||
const intern_type* __from_end, const intern_type*& __from_next,
|
||||
extern_type* __to, extern_type* __to_end,
|
||||
extern_type*& __to_next) const
|
||||
{
|
||||
range<const char16_t> from{ __from, __from_end };
|
||||
range<char8_t> to{ __to, __to_end };
|
||||
auto res = utf16_out(from, to);
|
||||
__from_next = from.next;
|
||||
__to_next = to.next;
|
||||
return res;
|
||||
}
|
||||
|
||||
codecvt_base::result
|
||||
codecvt<char16_t, char8_t, mbstate_t>::
|
||||
do_unshift(state_type&, extern_type* __to, extern_type*,
|
||||
extern_type*& __to_next) const
|
||||
{
|
||||
__to_next = __to;
|
||||
return noconv; // we don't use mbstate_t for the unicode facets
|
||||
}
|
||||
|
||||
codecvt_base::result
|
||||
codecvt<char16_t, char8_t, mbstate_t>::
|
||||
do_in(state_type&, const extern_type* __from, const extern_type* __from_end,
|
||||
const extern_type*& __from_next,
|
||||
intern_type* __to, intern_type* __to_end,
|
||||
intern_type*& __to_next) const
|
||||
{
|
||||
range<const char8_t> from{ __from, __from_end };
|
||||
range<char16_t> to{ __to, __to_end };
|
||||
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
codecvt_mode mode = {};
|
||||
#else
|
||||
codecvt_mode mode = little_endian;
|
||||
#endif
|
||||
auto res = utf16_in(from, to, max_code_point, mode);
|
||||
__from_next = from.next;
|
||||
__to_next = to.next;
|
||||
return res;
|
||||
}
|
||||
|
||||
int
|
||||
codecvt<char16_t, char8_t, mbstate_t>::do_encoding() const throw()
|
||||
{ return 0; } // UTF-8 is not a fixed-width encoding
|
||||
|
||||
bool
|
||||
codecvt<char16_t, char8_t, mbstate_t>::do_always_noconv() const throw()
|
||||
{ return false; }
|
||||
|
||||
int
|
||||
codecvt<char16_t, char8_t, mbstate_t>::
|
||||
do_length(state_type&, const extern_type* __from,
|
||||
const extern_type* __end, size_t __max) const
|
||||
{
|
||||
__end = utf16_span(__from, __end, __max);
|
||||
return __end - __from;
|
||||
}
|
||||
|
||||
int
|
||||
codecvt<char16_t, char8_t, mbstate_t>::do_max_length() const throw()
|
||||
{
|
||||
// A single character (one or two UTF-16 code units) requires
|
||||
// up to four UTF-8 code units.
|
||||
return 4;
|
||||
}
|
||||
|
||||
// Define members of codecvt<char32_t, char8_t, mbstate_t> specialization.
|
||||
// Converts from UTF-8 to UTF-32 (aka UCS-4).
|
||||
|
||||
locale::id codecvt<char32_t, char8_t, mbstate_t>::id;
|
||||
|
||||
codecvt<char32_t, char8_t, mbstate_t>::~codecvt() { }
|
||||
|
||||
codecvt_base::result
|
||||
codecvt<char32_t, char8_t, mbstate_t>::
|
||||
do_out(state_type&, const intern_type* __from, const intern_type* __from_end,
|
||||
const intern_type*& __from_next,
|
||||
extern_type* __to, extern_type* __to_end,
|
||||
extern_type*& __to_next) const
|
||||
{
|
||||
range<const char32_t> from{ __from, __from_end };
|
||||
range<char8_t> to{ __to, __to_end };
|
||||
auto res = ucs4_out(from, to);
|
||||
__from_next = from.next;
|
||||
__to_next = to.next;
|
||||
return res;
|
||||
}
|
||||
|
||||
codecvt_base::result
|
||||
codecvt<char32_t, char8_t, mbstate_t>::
|
||||
do_unshift(state_type&, extern_type* __to, extern_type*,
|
||||
extern_type*& __to_next) const
|
||||
{
|
||||
__to_next = __to;
|
||||
return noconv;
|
||||
}
|
||||
|
||||
codecvt_base::result
|
||||
codecvt<char32_t, char8_t, mbstate_t>::
|
||||
do_in(state_type&, const extern_type* __from, const extern_type* __from_end,
|
||||
const extern_type*& __from_next,
|
||||
intern_type* __to, intern_type* __to_end,
|
||||
intern_type*& __to_next) const
|
||||
{
|
||||
range<const char8_t> from{ __from, __from_end };
|
||||
range<char32_t> to{ __to, __to_end };
|
||||
auto res = ucs4_in(from, to);
|
||||
__from_next = from.next;
|
||||
__to_next = to.next;
|
||||
return res;
|
||||
}
|
||||
|
||||
int
|
||||
codecvt<char32_t, char8_t, mbstate_t>::do_encoding() const throw()
|
||||
{ return 0; } // UTF-8 is not a fixed-width encoding
|
||||
|
||||
bool
|
||||
codecvt<char32_t, char8_t, mbstate_t>::do_always_noconv() const throw()
|
||||
{ return false; }
|
||||
|
||||
int
|
||||
codecvt<char32_t, char8_t, mbstate_t>::
|
||||
do_length(state_type&, const extern_type* __from,
|
||||
const extern_type* __end, size_t __max) const
|
||||
{
|
||||
__end = ucs4_span(__from, __end, __max);
|
||||
return __end - __from;
|
||||
}
|
||||
|
||||
int
|
||||
codecvt<char32_t, char8_t, mbstate_t>::do_max_length() const throw()
|
||||
{
|
||||
// A single character (one UTF-32 code unit) requires
|
||||
// up to 4 UTF-8 code units.
|
||||
return 4;
|
||||
}
|
||||
#endif // _GLIBCXX_USE_CHAR8_T
|
||||
|
||||
// Define members of codecvt_utf8<char16_t> base class implementation.
|
||||
// Converts from UTF-8 to UCS-2.
|
||||
|
||||
@ -1636,5 +1797,12 @@ inline template class __codecvt_abstract_base<char32_t, char, mbstate_t>;
|
||||
template class codecvt_byname<char16_t, char, mbstate_t>;
|
||||
template class codecvt_byname<char32_t, char, mbstate_t>;
|
||||
|
||||
#if defined(_GLIBCXX_USE_CHAR8_T)
|
||||
inline template class __codecvt_abstract_base<char16_t, char8_t, mbstate_t>;
|
||||
inline template class __codecvt_abstract_base<char32_t, char8_t, mbstate_t>;
|
||||
template class codecvt_byname<char16_t, char8_t, mbstate_t>;
|
||||
template class codecvt_byname<char32_t, char8_t, mbstate_t>;
|
||||
#endif
|
||||
|
||||
_GLIBCXX_END_NAMESPACE_VERSION
|
||||
}
|
||||
|
@ -525,6 +525,33 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
const bool numeric_limits<long double>::tinyness_before;
|
||||
const float_round_style numeric_limits<long double>::round_style;
|
||||
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
// char8_t
|
||||
const bool numeric_limits<char8_t>::is_specialized;
|
||||
const int numeric_limits<char8_t>::digits;
|
||||
const int numeric_limits<char8_t>::digits10;
|
||||
const int numeric_limits<char8_t>::max_digits10;
|
||||
const bool numeric_limits<char8_t>::is_signed;
|
||||
const bool numeric_limits<char8_t>::is_integer;
|
||||
const bool numeric_limits<char8_t>::is_exact;
|
||||
const int numeric_limits<char8_t>::radix;
|
||||
const int numeric_limits<char8_t>::min_exponent;
|
||||
const int numeric_limits<char8_t>::min_exponent10;
|
||||
const int numeric_limits<char8_t>::max_exponent;
|
||||
const int numeric_limits<char8_t>::max_exponent10;
|
||||
const bool numeric_limits<char8_t>::has_infinity;
|
||||
const bool numeric_limits<char8_t>::has_quiet_NaN;
|
||||
const bool numeric_limits<char8_t>::has_signaling_NaN;
|
||||
const float_denorm_style numeric_limits<char8_t>::has_denorm;
|
||||
const bool numeric_limits<char8_t>::has_denorm_loss;
|
||||
const bool numeric_limits<char8_t>::is_iec559;
|
||||
const bool numeric_limits<char8_t>::is_bounded;
|
||||
const bool numeric_limits<char8_t>::is_modulo;
|
||||
const bool numeric_limits<char8_t>::traps;
|
||||
const bool numeric_limits<char8_t>::tinyness_before;
|
||||
const float_round_style numeric_limits<char8_t>::round_style;
|
||||
#endif // _GLIBCXX_USE_CHAR8_T
|
||||
|
||||
// char16_t
|
||||
const bool numeric_limits<char16_t>::is_specialized;
|
||||
const int numeric_limits<char16_t>::digits;
|
||||
|
@ -184,13 +184,13 @@ endif
|
||||
|
||||
# XXX TODO move locale_init.cc and localename.cc to src/c++11
|
||||
locale_init.lo: locale_init.cc
|
||||
$(LTCXXCOMPILE) -std=gnu++11 -c $<
|
||||
$(LTCXXCOMPILE) -std=gnu++11 -fchar8_t -c $<
|
||||
locale_init.o: locale_init.cc
|
||||
$(LTCXXCOMPILE) -std=gnu++11 -c $<
|
||||
$(LTCXXCOMPILE) -std=gnu++11 -fchar8_t -c $<
|
||||
localename.lo: localename.cc
|
||||
$(LTCXXCOMPILE) -std=gnu++11 -c $<
|
||||
$(LTCXXCOMPILE) -std=gnu++11 -fchar8_t -c $<
|
||||
localename.o: localename.cc
|
||||
$(LTCXXCOMPILE) -std=gnu++11 -c $<
|
||||
$(LTCXXCOMPILE) -std=gnu++11 -fchar8_t -c $<
|
||||
|
||||
# Use special rules for the deprecated source files so that they find
|
||||
# deprecated include files.
|
||||
|
@ -888,13 +888,13 @@ c++locale.o: c++locale.cc
|
||||
|
||||
# XXX TODO move locale_init.cc and localename.cc to src/c++11
|
||||
locale_init.lo: locale_init.cc
|
||||
$(LTCXXCOMPILE) -std=gnu++11 -c $<
|
||||
$(LTCXXCOMPILE) -std=gnu++11 -fchar8_t -c $<
|
||||
locale_init.o: locale_init.cc
|
||||
$(LTCXXCOMPILE) -std=gnu++11 -c $<
|
||||
$(LTCXXCOMPILE) -std=gnu++11 -fchar8_t -c $<
|
||||
localename.lo: localename.cc
|
||||
$(LTCXXCOMPILE) -std=gnu++11 -c $<
|
||||
$(LTCXXCOMPILE) -std=gnu++11 -fchar8_t -c $<
|
||||
localename.o: localename.cc
|
||||
$(LTCXXCOMPILE) -std=gnu++11 -c $<
|
||||
$(LTCXXCOMPILE) -std=gnu++11 -fchar8_t -c $<
|
||||
strstream.lo: strstream.cc
|
||||
$(LTCXXCOMPILE) -I$(GLIBCXX_INCLUDE_DIR)/backward -Wno-deprecated -c $<
|
||||
strstream.o: strstream.cc
|
||||
|
@ -209,6 +209,16 @@ namespace
|
||||
__attribute__ ((aligned(__alignof__(codecvt<char32_t, char, mbstate_t>))));
|
||||
fake_codecvt_c32 codecvt_c32;
|
||||
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
typedef char fake_codecvt_c16_c8[sizeof(codecvt<char16_t, char8_t, mbstate_t>)]
|
||||
__attribute__ ((aligned(__alignof__(codecvt<char16_t, char8_t, mbstate_t>))));
|
||||
fake_codecvt_c16_c8 codecvt_c16_c8;
|
||||
|
||||
typedef char fake_codecvt_c32_c8[sizeof(codecvt<char32_t, char8_t, mbstate_t>)]
|
||||
__attribute__ ((aligned(__alignof__(codecvt<char32_t, char8_t, mbstate_t>))));
|
||||
fake_codecvt_c32_c8 codecvt_c32_c8;
|
||||
#endif
|
||||
|
||||
// Storage for "C" locale caches.
|
||||
typedef char fake_num_cache_c[sizeof(std::__numpunct_cache<char>)]
|
||||
__attribute__ ((aligned(__alignof__(std::__numpunct_cache<char>))));
|
||||
@ -329,6 +339,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
#if _GLIBCXX_NUM_UNICODE_FACETS != 0
|
||||
&codecvt<char16_t, char, mbstate_t>::id,
|
||||
&codecvt<char32_t, char, mbstate_t>::id,
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
&codecvt<char16_t, char8_t, mbstate_t>::id,
|
||||
&codecvt<char32_t, char8_t, mbstate_t>::id,
|
||||
#endif
|
||||
#endif
|
||||
0
|
||||
};
|
||||
@ -536,6 +550,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
#if _GLIBCXX_NUM_UNICODE_FACETS != 0
|
||||
_M_init_facet(new (&codecvt_c16) codecvt<char16_t, char, mbstate_t>(1));
|
||||
_M_init_facet(new (&codecvt_c32) codecvt<char32_t, char, mbstate_t>(1));
|
||||
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
_M_init_facet(new (&codecvt_c16_c8) codecvt<char16_t, char8_t, mbstate_t>(1));
|
||||
_M_init_facet(new (&codecvt_c32_c8) codecvt<char32_t, char8_t, mbstate_t>(1));
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if _GLIBCXX_USE_DUAL_ABI
|
||||
|
@ -272,6 +272,12 @@ const int num_facets = _GLIBCXX_NUM_FACETS + _GLIBCXX_NUM_UNICODE_FACETS
|
||||
#if _GLIBCXX_NUM_UNICODE_FACETS != 0
|
||||
_M_init_facet(new codecvt<char16_t, char, mbstate_t>);
|
||||
_M_init_facet(new codecvt<char32_t, char, mbstate_t>);
|
||||
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
_M_init_facet(new codecvt<char16_t, char8_t, mbstate_t>);
|
||||
_M_init_facet(new codecvt<char32_t, char8_t, mbstate_t>);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if _GLIBCXX_USE_DUAL_ABI
|
||||
|
@ -220,6 +220,7 @@ check_version(symbol& test, bool added)
|
||||
known_versions.push_back("CXXABI_1.3.9");
|
||||
known_versions.push_back("CXXABI_1.3.10");
|
||||
known_versions.push_back("CXXABI_1.3.11");
|
||||
known_versions.push_back("CXXABI_1.3.12");
|
||||
known_versions.push_back("CXXABI_TM_1");
|
||||
known_versions.push_back("CXXABI_FLOAT128");
|
||||
}
|
||||
@ -238,7 +239,7 @@ check_version(symbol& test, bool added)
|
||||
|
||||
// Check that added symbols are added in the latest pre-release version.
|
||||
bool latestp = (test.version_name == "GLIBCXX_3.4.26"
|
||||
|| test.version_name == "CXXABI_1.3.11"
|
||||
|| test.version_name == "CXXABI_1.3.12"
|
||||
|| test.version_name == "CXXABI_FLOAT128"
|
||||
|| test.version_name == "CXXABI_TM_1");
|
||||
if (added && !latestp)
|
||||
|
Loading…
Reference in New Issue
Block a user