diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config index c8e099aaadd..5bcf32d95ef 100644 --- a/libstdc++-v3/include/bits/c++config +++ b/libstdc++-v3/include/bits/c++config @@ -620,7 +620,7 @@ namespace std # endif #endif #ifdef _GLIBCXX_USE_CHAR8_T -# define __cpp_lib_char8_t 201811L +# define __cpp_lib_char8_t 201907L #endif /* Define if __float128 is supported on this host. */ diff --git a/libstdc++-v3/include/bits/fs_path.h b/libstdc++-v3/include/bits/fs_path.h index 71354515403..f3f539412fc 100644 --- a/libstdc++-v3/include/bits/fs_path.h +++ b/libstdc++-v3/include/bits/fs_path.h @@ -153,9 +153,24 @@ namespace __detail template())), - typename _Val = typename std::iterator_traits<_Iter>::value_type> + typename _Val = typename std::iterator_traits<_Iter>::value_type, + typename _UnqualVal = std::remove_const_t<_Val>> using __value_type_is_char - = std::enable_if_t, char>>; + = std::enable_if_t, + _UnqualVal>; + + template())), + typename _Val = typename std::iterator_traits<_Iter>::value_type, + typename _UnqualVal = std::remove_const_t<_Val>> + using __value_type_is_char_or_char8_t + = std::enable_if_t<__or_v< + std::is_same<_UnqualVal, char> +#ifdef _GLIBCXX_USE_CHAR8_T + ,std::is_same<_UnqualVal, char8_t> +#endif + >, + _UnqualVal>; // @} group filesystem-detail } // namespace __detail @@ -639,29 +654,41 @@ namespace __detail /// Create a path from a UTF-8-encoded sequence of char template, - typename _Require2 = __detail::__value_type_is_char<_InputIterator>> + typename _CharT = + __detail::__value_type_is_char_or_char8_t<_InputIterator>> inline path u8path(_InputIterator __first, _InputIterator __last) { #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS - // XXX This assumes native wide encoding is UTF-16. - std::codecvt_utf8_utf16 __cvt; - path::string_type __tmp; - if constexpr (is_pointer_v<_InputIterator>) +#ifdef _GLIBCXX_USE_CHAR8_T + if constexpr (is_same_v<_CharT, char8_t>) { - if (__str_codecvt_in_all(__first, __last, __tmp, __cvt)) - return path{ __tmp }; + return path{ __first, __last }; } else { - const std::string __u8str{__first, __last}; - const char* const __ptr = __u8str.data(); - if (__str_codecvt_in_all(__ptr, __ptr + __u8str.size(), __tmp, __cvt)) - return path{ __tmp }; +#endif + // XXX This assumes native wide encoding is UTF-16. + std::codecvt_utf8_utf16 __cvt; + path::string_type __tmp; + if constexpr (is_pointer_v<_InputIterator>) + { + if (__str_codecvt_in_all(__first, __last, __tmp, __cvt)) + return path{ __tmp }; + } + else + { + const std::string __u8str{__first, __last}; + const char* const __ptr = __u8str.data(); + if (__str_codecvt_in_all(__ptr, __ptr + __u8str.size(), __tmp, __cvt)) + return path{ __tmp }; + } + _GLIBCXX_THROW_OR_ABORT(filesystem_error( + "Cannot convert character sequence", + std::make_error_code(errc::illegal_byte_sequence))); +#ifdef _GLIBCXX_USE_CHAR8_T } - _GLIBCXX_THROW_OR_ABORT(filesystem_error( - "Cannot convert character sequence", - std::make_error_code(errc::illegal_byte_sequence))); +#endif #else // This assumes native normal encoding is UTF-8. return path{ __first, __last }; @@ -671,21 +698,32 @@ namespace __detail /// Create a path from a UTF-8-encoded sequence of char template, - typename _Require2 = __detail::__value_type_is_char<_Source>> + typename _CharT = __detail::__value_type_is_char_or_char8_t<_Source>> inline path u8path(const _Source& __source) { #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS - if constexpr (is_convertible_v) +#ifdef _GLIBCXX_USE_CHAR8_T + if constexpr (is_same_v<_CharT, char8_t>) { - const std::string_view __s = __source; - return filesystem::u8path(__s.data(), __s.data() + __s.size()); + return path{ __source }; } else { - std::string __s = path::_S_string_from_iter(__source); - return filesystem::u8path(__s.data(), __s.data() + __s.size()); +#endif + if constexpr (is_convertible_v) + { + const std::string_view __s = __source; + return filesystem::u8path(__s.data(), __s.data() + __s.size()); + } + else + { + std::string __s = path::_S_string_from_iter(__source); + return filesystem::u8path(__s.data(), __s.data() + __s.size()); + } +#ifdef _GLIBCXX_USE_CHAR8_T } +#endif #else return path{ __source }; #endif diff --git a/libstdc++-v3/include/experimental/bits/fs_path.h b/libstdc++-v3/include/experimental/bits/fs_path.h index 3f9a69514a1..7a8cd8d20de 100644 --- a/libstdc++-v3/include/experimental/bits/fs_path.h +++ b/libstdc++-v3/include/experimental/bits/fs_path.h @@ -169,10 +169,23 @@ namespace __detail template())), - typename _Val = typename std::iterator_traits<_Iter>::value_type> + typename _Val = typename std::iterator_traits<_Iter>::value_type, + typename _UnqualVal = typename std::remove_const<_Val>::type> using __value_type_is_char = typename std::enable_if< - std::is_same::type, char>::value - >::type; + std::is_same<_UnqualVal, char>::value, + _UnqualVal>::type; + + template())), + typename _Val = typename std::iterator_traits<_Iter>::value_type, + typename _UnqualVal = typename std::remove_const<_Val>::type> + using __value_type_is_char_or_char8_t = typename std::enable_if< + __or_< + std::is_same<_UnqualVal, char> +#ifdef _GLIBCXX_USE_CHAR8_T + ,std::is_same<_UnqualVal, char8_t> +#endif + >::value, _UnqualVal>::type; // @} group filesystem-ts-detail } // namespace __detail @@ -592,13 +605,11 @@ namespace __detail } /// Create a path from a UTF-8-encoded sequence of char - template, - typename _Require2 = __detail::__value_type_is_char<_InputIterator>> +#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS + template inline path - u8path(_InputIterator __first, _InputIterator __last) + __u8path(_InputIterator __first, _InputIterator __last, char) { -#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS // XXX This assumes native wide encoding is UTF-16. std::codecvt_utf8_utf16 __cvt; path::string_type __tmp; @@ -609,21 +620,61 @@ namespace __detail _GLIBCXX_THROW_OR_ABORT(filesystem_error( "Cannot convert character sequence", std::make_error_code(errc::illegal_byte_sequence))); + } + +#ifdef _GLIBCXX_USE_CHAR8_T + template + inline path + __u8path(_InputIterator __first, _InputIterator __last, char8_t) + { + return path{ __first, __last }; + } +#endif // _GLIBCXX_USE_CHAR8_T +#endif // _GLIBCXX_FILESYSTEM_IS_WINDOWS + + template, + typename _CharT = + __detail::__value_type_is_char_or_char8_t<_InputIterator>> + inline path + u8path(_InputIterator __first, _InputIterator __last) + { +#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS + return __u8path(__first, __last, _CharT{}); #else return path{ __first, __last }; #endif } /// Create a path from a UTF-8-encoded sequence of char +#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS + template + inline path + __u8path(const _Source& __source, char) + { + std::string __s = path::_S_string_from_iter(__source); + return filesystem::u8path(__s.data(), __s.data() + __s.size()); + } + +#ifdef _GLIBCXX_USE_CHAR8_T + template + inline path + __u8path(const _Source& __source, char8_t) + { + return path{ __source }; + } +#endif // _GLIBCXX_USE_CHAR8_T +#endif // _GLIBCXX_FILESYSTEM_IS_WINDOWS + template, - typename _Require2 = __detail::__value_type_is_char<_Source>> + typename _CharT = + __detail::__value_type_is_char_or_char8_t<_Source>> inline path u8path(const _Source& __source) { #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS - std::string __s = path::_S_string_from_iter(__source); - return filesystem::u8path(__s.data(), __s.data() + __s.size()); + return __u8path(__source, _CharT{}); #else return path{ __source }; #endif diff --git a/libstdc++-v3/include/std/ostream b/libstdc++-v3/include/std/ostream index 2541d978886..771c28db7b7 100644 --- a/libstdc++-v3/include/std/ostream +++ b/libstdc++-v3/include/std/ostream @@ -527,6 +527,47 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline basic_ostream& operator<<(basic_ostream& __out, unsigned char __c) { return (__out << static_cast(__c)); } + +#if __cplusplus > 201703L + // The following deleted overloads prevent formatting character values as + // numeric values. + +#ifdef _GLIBCXX_USE_WCHAR_T + template + basic_ostream& + operator<<(basic_ostream&, wchar_t) = delete; +#endif // _GLIBCXX_USE_WCHAR_T + +#ifdef _GLIBCXX_USE_CHAR8_T + template + basic_ostream& + operator<<(basic_ostream&, char8_t) = delete; +#endif + + template + basic_ostream& + operator<<(basic_ostream&, char16_t) = delete; + + template + basic_ostream& + operator<<(basic_ostream&, char32_t) = delete; + +#ifdef _GLIBCXX_USE_WCHAR_T +#ifdef _GLIBCXX_USE_CHAR8_T + template + basic_ostream& + operator<<(basic_ostream&, char8_t) = delete; +#endif // _GLIBCXX_USE_CHAR8_T + + template + basic_ostream& + operator<<(basic_ostream&, char16_t) = delete; + + template + basic_ostream& + operator<<(basic_ostream&, char32_t) = delete; +#endif // _GLIBCXX_USE_WCHAR_T +#endif // C++20 //@} //@{ @@ -582,6 +623,47 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline basic_ostream & operator<<(basic_ostream& __out, const unsigned char* __s) { return (__out << reinterpret_cast(__s)); } + +#if __cplusplus > 201703L + // The following deleted overloads prevent formatting strings as + // pointer values. + +#ifdef _GLIBCXX_USE_WCHAR_T + template + basic_ostream& + operator<<(basic_ostream&, const wchar_t*) = delete; +#endif // _GLIBCXX_USE_WCHAR_T + +#ifdef _GLIBCXX_USE_CHAR8_T + template + basic_ostream& + operator<<(basic_ostream&, const char8_t*) = delete; +#endif // _GLIBCXX_USE_CHAR8_T + + template + basic_ostream& + operator<<(basic_ostream&, const char16_t*) = delete; + + template + basic_ostream& + operator<<(basic_ostream&, const char32_t*) = delete; + +#ifdef _GLIBCXX_USE_WCHAR_T +#ifdef _GLIBCXX_USE_CHAR8_T + template + basic_ostream& + operator<<(basic_ostream&, const char8_t*) = delete; +#endif + + template + basic_ostream& + operator<<(basic_ostream&, const char16_t*) = delete; + + template + basic_ostream& + operator<<(basic_ostream&, const char32_t*) = delete; +#endif // _GLIBCXX_USE_WCHAR_T +#endif // C++20 //@} // Standard basic_ostream manipulators