+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.
{"basic_string", "<string>", cxx98},
{"string", "<string>", cxx98},
{"wstring", "<string>", cxx98},
+ {"u8string", "<string>", cxx2a},
{"u16string", "<string>", cxx11},
{"u32string", "<string>", cxx11},
/* <string_view>. */
+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.
_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;
# _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.
} 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 {
// 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
#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>
{ 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)
# 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
};
#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
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].
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,
#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
// 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.
};
# 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>
{
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>>
#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;
#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;
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)));
{
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;
}
}
#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",
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
{
return _M_pathname;
#endif
}
+#endif // _GLIBCXX_USE_CHAR8_T
inline std::u16string
path::u16string() const { return string<char16_t>(); }
{ 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
/// 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)
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
# 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
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;
/// 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;
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>;
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;
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; };
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>>
#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;
#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;
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)));
_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;
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",
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
{
return _M_pathname;
#endif
}
+#endif // _GLIBCXX_USE_CHAR8_T
inline std::u16string
path::u16string() const { return string<char16_t>(); }
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(); }
// 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;
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>;
{ };
#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>
{ 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}; }
#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>
/// 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;
__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
>>>;
// 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
= 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<>
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
#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>;
{ };
#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>
{ 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}; }
: 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 { };
= 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)
};
#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>
{
};
#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>
{
#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
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/'
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
}
// 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);
}
// 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);
// 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)
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)
{
}
// 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);
}
// 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))
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)
{
}
// 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)
{
}
// 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)
}
// 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:
}
// 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:
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);
}
// 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)
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.
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
}
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;
# 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.
# 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
__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>))));
#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
};
#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
#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
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");
}
// 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)