mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-12-19 09:05:17 +08:00
libstdc++: Fix experimental::filesystem::u8path(const Source&) for Windows
This function failed to compile when called with a std::string. Also, constructing a path with a char8_t string did not correctly treat the string as already UTF-8 encoded. * include/bits/fs_path.h (u8path(InputIterator, InputIterator)) (u8path(const Source&)) [_GLIBCXX_FILESYSTEM_IS_WINDOWS]: Simplify conditions. * include/experimental/bits/fs_path.h [_GLIBCXX_FILESYSTEM_IS_WINDOWS] (__u8path(const Source&, char)): Add overloads for std::string and types convertible to std::string. (_Cvt::_S_wconvert): Add a new overload for char8_t strings and use codecvt_utf8_utf16 to do the correct conversion. From-SVN: r278869
This commit is contained in:
parent
aa80d0650c
commit
3eda32cb9b
@ -1,3 +1,14 @@
|
||||
2019-11-30 Jonathan Wakely <jwakely@redhat.com>
|
||||
|
||||
* include/bits/fs_path.h (u8path(InputIterator, InputIterator))
|
||||
(u8path(const Source&)) [_GLIBCXX_FILESYSTEM_IS_WINDOWS]: Simplify
|
||||
conditions.
|
||||
* include/experimental/bits/fs_path.h [_GLIBCXX_FILESYSTEM_IS_WINDOWS]
|
||||
(__u8path(const Source&, char)): Add overloads for std::string and
|
||||
types convertible to std::string.
|
||||
(_Cvt::_S_wconvert): Add a new overload for char8_t strings and use
|
||||
codecvt_utf8_utf16 to do the correct conversion.
|
||||
|
||||
2019-11-29 Jonathan Wakely <jwakely@redhat.com>
|
||||
|
||||
* include/bits/fs_path.h (path::operator/=): Change template-head to
|
||||
|
@ -691,14 +691,8 @@ namespace __detail
|
||||
u8path(_InputIterator __first, _InputIterator __last)
|
||||
{
|
||||
#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
if constexpr (is_same_v<_CharT, char8_t>)
|
||||
if constexpr (is_same_v<_CharT, char>)
|
||||
{
|
||||
return path{ __first, __last };
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
// XXX This assumes native wide encoding is UTF-16.
|
||||
std::codecvt_utf8_utf16<path::value_type> __cvt;
|
||||
path::string_type __tmp;
|
||||
@ -710,16 +704,16 @@ namespace __detail
|
||||
else
|
||||
{
|
||||
const std::string __u8str{__first, __last};
|
||||
const char* const __ptr = __u8str.data();
|
||||
if (__str_codecvt_in_all(__ptr, __ptr + __u8str.size(), __tmp, __cvt))
|
||||
const char* const __p = __u8str.data();
|
||||
if (__str_codecvt_in_all(__p, __p + __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
|
||||
}
|
||||
#endif
|
||||
else
|
||||
return path{ __first, __last };
|
||||
#else
|
||||
// This assumes native normal encoding is UTF-8.
|
||||
return path{ __first, __last };
|
||||
@ -737,14 +731,8 @@ namespace __detail
|
||||
u8path(const _Source& __source)
|
||||
{
|
||||
#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
if constexpr (is_same_v<_CharT, char8_t>)
|
||||
if constexpr (is_same_v<_CharT, char>)
|
||||
{
|
||||
return path{ __source };
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
if constexpr (is_convertible_v<const _Source&, std::string_view>)
|
||||
{
|
||||
const std::string_view __s = __source;
|
||||
@ -755,9 +743,9 @@ namespace __detail
|
||||
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 };
|
||||
#else
|
||||
return path{ __source };
|
||||
#endif
|
||||
|
@ -644,8 +644,22 @@ namespace __detail
|
||||
|
||||
/// Create a path from a UTF-8-encoded sequence of char
|
||||
#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
|
||||
inline path
|
||||
__u8path(const string& __s, char)
|
||||
{
|
||||
return filesystem::u8path(__s.data(), __s.data() + __s.size());
|
||||
}
|
||||
|
||||
template<typename _Source>
|
||||
inline path
|
||||
inline __enable_if_t<is_convertible<const _Source&, string>::value, path>
|
||||
__u8path(const _Source& __source, char)
|
||||
{
|
||||
std::string __s = __source;
|
||||
return filesystem::u8path(__s.data(), __s.data() + __s.size());
|
||||
}
|
||||
|
||||
template<typename _Source>
|
||||
inline __enable_if_t<!is_convertible<const _Source&, string>::value, path>
|
||||
__u8path(const _Source& __source, char)
|
||||
{
|
||||
std::string __s = path::_S_string_from_iter(__source);
|
||||
@ -733,8 +747,21 @@ namespace __detail
|
||||
struct path::_Cvt
|
||||
{
|
||||
#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
static string_type
|
||||
_S_wconvert(const char* __f, const char* __l, true_type)
|
||||
_S_wconvert(const char8_t* __f, const char8_t* __l, const char8_t*)
|
||||
{
|
||||
const char* __f2 = (const char*)__f;
|
||||
const char* __l2 = (const char*)__l;
|
||||
std::wstring __wstr;
|
||||
std::codecvt_utf8_utf16<wchar_t> __wcvt;
|
||||
if (__str_codecvt_in_all(__f2, __l2, __wstr, __wcvt))
|
||||
return __wstr;
|
||||
}
|
||||
#endif
|
||||
|
||||
static string_type
|
||||
_S_wconvert(const char* __f, const char* __l, const char*)
|
||||
{
|
||||
using _Cvt = std::codecvt<wchar_t, char, mbstate_t>;
|
||||
const auto& __cvt = std::use_facet<_Cvt>(std::locale{});
|
||||
@ -747,36 +774,29 @@ namespace __detail
|
||||
}
|
||||
|
||||
static string_type
|
||||
_S_wconvert(const _CharT* __f, const _CharT* __l, false_type)
|
||||
_S_wconvert(const _CharT* __f, const _CharT* __l, const void*)
|
||||
{
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
if constexpr (is_same<_CharT, char8_t>::value)
|
||||
return _S_wconvert((const char*)__f, (const char*)__l, true_type());
|
||||
else
|
||||
#endif
|
||||
struct _UCvt : std::codecvt<_CharT, char, std::mbstate_t>
|
||||
{ } __cvt;
|
||||
std::string __str;
|
||||
if (__str_codecvt_out_all(__f, __l, __str, __cvt))
|
||||
{
|
||||
struct _UCvt : std::codecvt<_CharT, char, std::mbstate_t>
|
||||
{ } __cvt;
|
||||
std::string __str;
|
||||
if (__str_codecvt_out_all(__f, __l, __str, __cvt))
|
||||
{
|
||||
const char* __f2 = __str.data();
|
||||
const char* __l2 = __f2 + __str.size();
|
||||
std::codecvt_utf8_utf16<wchar_t> __wcvt;
|
||||
std::wstring __wstr;
|
||||
if (__str_codecvt_in_all(__f2, __l2, __wstr, __wcvt))
|
||||
return __wstr;
|
||||
}
|
||||
_GLIBCXX_THROW_OR_ABORT(filesystem_error(
|
||||
"Cannot convert character sequence",
|
||||
std::make_error_code(errc::illegal_byte_sequence)));
|
||||
const char* __f2 = __str.data();
|
||||
const char* __l2 = __f2 + __str.size();
|
||||
std::codecvt_utf8_utf16<wchar_t> __wcvt;
|
||||
std::wstring __wstr;
|
||||
if (__str_codecvt_in_all(__f2, __l2, __wstr, __wcvt))
|
||||
return __wstr;
|
||||
}
|
||||
_GLIBCXX_THROW_OR_ABORT(filesystem_error(
|
||||
"Cannot convert character sequence",
|
||||
std::make_error_code(errc::illegal_byte_sequence)));
|
||||
}
|
||||
|
||||
static string_type
|
||||
_S_convert(const _CharT* __f, const _CharT* __l)
|
||||
{
|
||||
return _S_wconvert(__f, __l, is_same<_CharT, char>{});
|
||||
return _S_wconvert(__f, __l, (const _CharT*)nullptr);
|
||||
}
|
||||
#else
|
||||
static string_type
|
||||
@ -786,19 +806,17 @@ namespace __detail
|
||||
if constexpr (is_same<_CharT, char8_t>::value)
|
||||
return string_type(__f, __l);
|
||||
else
|
||||
{
|
||||
#endif
|
||||
{
|
||||
struct _UCvt : std::codecvt<_CharT, char, std::mbstate_t>
|
||||
{ } __cvt;
|
||||
std::string __str;
|
||||
if (__str_codecvt_out_all(__f, __l, __str, __cvt))
|
||||
return __str;
|
||||
#ifdef _GLIBCXX_USE_CHAR8_T
|
||||
_GLIBCXX_THROW_OR_ABORT(filesystem_error(
|
||||
"Cannot convert character sequence",
|
||||
std::make_error_code(errc::illegal_byte_sequence)));
|
||||
}
|
||||
#endif
|
||||
_GLIBCXX_THROW_OR_ABORT(filesystem_error(
|
||||
"Cannot convert character sequence",
|
||||
std::make_error_code(errc::illegal_byte_sequence)));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user