forked from OSchip/llvm-project
[libcxx] Implement c++2a char8_t input/output of std::filesystem::path
This implements the std::filesystem parts of P0482 (which is already marked as in progress), and applies the actions that are suggested in P1423. Differential Revision: https://reviews.llvm.org/D90222
This commit is contained in:
parent
c17fdca188
commit
6be11e35d5
|
@ -115,7 +115,7 @@
|
|||
"`P1208 <https://wg21.link/P1208>`__","LWG","Adopt source_location for C++20","Cologne","",""
|
||||
"`P1355 <https://wg21.link/P1355>`__","LWG","Exposing a narrow contract for ceil2","Cologne","|Complete|","9.0"
|
||||
"`P1361 <https://wg21.link/P1361>`__","LWG","Integration of chrono with text formatting","Cologne","",""
|
||||
"`P1423 <https://wg21.link/P1423>`__","LWG","char8_t backward compatibility remediation","Cologne","",""
|
||||
"`P1423 <https://wg21.link/P1423>`__","LWG","char8_t backward compatibility remediation","Cologne","|In Progress|",""
|
||||
"`P1424 <https://wg21.link/P1424>`__","LWG","'constexpr' feature macro concerns","Cologne","Superseded by `P1902 <https://wg21.link/P1902>`__",""
|
||||
"`P1466 <https://wg21.link/P1466>`__","LWG","Miscellaneous minor fixes for chrono","Cologne","",""
|
||||
"`P1474 <https://wg21.link/P1474>`__","LWG","Helpful pointers for ContiguousIterator","Cologne","",""
|
||||
|
|
|
|
@ -56,3 +56,9 @@ API Changes
|
|||
- ``ceil2`` has been renamed to ``bit_ceil``
|
||||
- ``floor2`` has been renamed to ``bit_floor``
|
||||
- ``log2p1`` has been renamed to ``bit_width``
|
||||
|
||||
- In C++20 mode, ``std::filesystem::path::u8string()`` and
|
||||
``generic_u8string()`` now return ``std::u8string`` according to P0428,
|
||||
while they return ``std::string`` in C++17. This can cause source
|
||||
incompatibility, which is discussed and acknowledged in P1423, but that
|
||||
paper doesn't suggest any remediation for this incompatibility.
|
||||
|
|
|
@ -989,6 +989,12 @@ typedef unsigned int char32_t;
|
|||
# define _LIBCPP_DEPRECATED_IN_CXX20
|
||||
#endif
|
||||
|
||||
#if !defined(_LIBCPP_NO_HAS_CHAR8_T)
|
||||
# define _LIBCPP_DEPRECATED_WITH_CHAR8_T _LIBCPP_DEPRECATED
|
||||
#else
|
||||
# define _LIBCPP_DEPRECATED_WITH_CHAR8_T
|
||||
#endif
|
||||
|
||||
// Macros to enter and leave a state where deprecation warnings are suppressed.
|
||||
#if !defined(_LIBCPP_SUPPRESS_DEPRECATED_PUSH) && \
|
||||
(defined(_LIBCPP_COMPILER_CLANG) || defined(_LIBCPP_COMPILER_GCC))
|
||||
|
|
|
@ -547,6 +547,13 @@ struct __can_convert_char<wchar_t> {
|
|||
static const bool value = true;
|
||||
using __char_type = wchar_t;
|
||||
};
|
||||
#ifndef _LIBCPP_NO_HAS_CHAR8_T
|
||||
template <>
|
||||
struct __can_convert_char<char8_t> {
|
||||
static const bool value = true;
|
||||
using __char_type = char8_t;
|
||||
};
|
||||
#endif
|
||||
template <>
|
||||
struct __can_convert_char<char16_t> {
|
||||
static const bool value = true;
|
||||
|
@ -995,7 +1002,11 @@ public:
|
|||
_LIBCPP_INLINE_VISIBILITY operator string_type() const { return __pn_; }
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY _VSTD::string string() const { return __pn_; }
|
||||
#ifndef _LIBCPP_NO_HAS_CHAR8_T
|
||||
_LIBCPP_INLINE_VISIBILITY _VSTD::u8string u8string() const { return _VSTD::u8string(__pn_.begin(), __pn_.end()); }
|
||||
#else
|
||||
_LIBCPP_INLINE_VISIBILITY _VSTD::string u8string() const { return __pn_; }
|
||||
#endif
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
|
||||
template <class _ECharT, class _Traits = char_traits<_ECharT>,
|
||||
|
@ -1023,7 +1034,11 @@ public:
|
|||
|
||||
// generic format observers
|
||||
_VSTD::string generic_string() const { return __pn_; }
|
||||
#ifndef _LIBCPP_NO_HAS_CHAR8_T
|
||||
_VSTD::u8string generic_u8string() const { return _VSTD::u8string(__pn_.begin(), __pn_.end()); }
|
||||
#else
|
||||
_VSTD::string generic_u8string() const { return __pn_; }
|
||||
#endif
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
|
||||
template <class _ECharT, class _Traits = char_traits<_ECharT>,
|
||||
|
@ -1213,23 +1228,37 @@ _LIBCPP_FUNC_VIS
|
|||
size_t hash_value(const path& __p) noexcept;
|
||||
|
||||
template <class _Source>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T
|
||||
typename enable_if<__is_pathable<_Source>::value, path>::type
|
||||
u8path(const _Source& __s) {
|
||||
static_assert(
|
||||
#ifndef _LIBCPP_NO_HAS_CHAR8_T
|
||||
is_same<typename __is_pathable<_Source>::__char_type, char8_t>::value ||
|
||||
#endif
|
||||
is_same<typename __is_pathable<_Source>::__char_type, char>::value,
|
||||
"u8path(Source const&) requires Source have a character type of type "
|
||||
"'char'");
|
||||
"'char'"
|
||||
#ifndef _LIBCPP_NO_HAS_CHAR8_T
|
||||
" or 'char8_t'"
|
||||
#endif
|
||||
);
|
||||
return path(__s);
|
||||
}
|
||||
|
||||
template <class _InputIt>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T
|
||||
typename enable_if<__is_pathable<_InputIt>::value, path>::type
|
||||
u8path(_InputIt __f, _InputIt __l) {
|
||||
static_assert(
|
||||
#ifndef _LIBCPP_NO_HAS_CHAR8_T
|
||||
is_same<typename __is_pathable<_InputIt>::__char_type, char8_t>::value ||
|
||||
#endif
|
||||
is_same<typename __is_pathable<_InputIt>::__char_type, char>::value,
|
||||
"u8path(Iter, Iter) requires Iter have a value_type of type 'char'");
|
||||
"u8path(Iter, Iter) requires Iter have a value_type of type 'char'"
|
||||
#ifndef _LIBCPP_NO_HAS_CHAR8_T
|
||||
" or 'char8_t'"
|
||||
#endif
|
||||
);
|
||||
return path(__f, __l);
|
||||
}
|
||||
|
||||
|
|
|
@ -123,6 +123,9 @@ void test_sfinae() {
|
|||
int main(int, char**) {
|
||||
for (auto const& MS : PathList) {
|
||||
RunTestCase<char>(MS);
|
||||
#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
|
||||
RunTestCase<char8_t>(MS);
|
||||
#endif
|
||||
RunTestCase<wchar_t>(MS);
|
||||
RunTestCase<char16_t>(MS);
|
||||
RunTestCase<char32_t>(MS);
|
||||
|
|
|
@ -45,8 +45,15 @@ int main(int, char**)
|
|||
assert(s == value);
|
||||
}
|
||||
{
|
||||
#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
|
||||
ASSERT_SAME_TYPE(decltype(p.generic_u8string()), std::u8string);
|
||||
std::u8string s = p.generic_u8string();
|
||||
assert(s == (const char8_t*)MS);
|
||||
#else
|
||||
ASSERT_SAME_TYPE(decltype(p.generic_u8string()), std::string);
|
||||
std::string s = p.generic_u8string();
|
||||
assert(s == (const char*)MS);
|
||||
#endif
|
||||
}
|
||||
{
|
||||
std::wstring s = p.generic_wstring();
|
||||
|
|
|
@ -46,8 +46,15 @@ int main(int, char**)
|
|||
assert(s == value);
|
||||
}
|
||||
{
|
||||
#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
|
||||
ASSERT_SAME_TYPE(decltype(p.u8string()), std::u8string);
|
||||
std::u8string s = p.u8string();
|
||||
assert(s == (const char8_t*)MS);
|
||||
#else
|
||||
ASSERT_SAME_TYPE(decltype(p.u8string()), std::string);
|
||||
std::string s = p.u8string();
|
||||
assert(s == (const char*)MS);
|
||||
#endif
|
||||
}
|
||||
{
|
||||
std::wstring s = p.wstring();
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03
|
||||
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
|
||||
|
||||
// <filesystem>
|
||||
|
||||
|
@ -48,6 +49,29 @@ int main(int, char**)
|
|||
path p = fs::u8path(In3, In3End);
|
||||
assert(p == In1);
|
||||
}
|
||||
#if TEST_STD_VER > 17 && defined(__cpp_char8_t) && defined(_LIBCPP_VERSION)
|
||||
const char8_t* u8In1 = u8"abcd/efg";
|
||||
const std::u8string u8In2(u8In1);
|
||||
const auto u8In3 = u8In2.begin();
|
||||
const auto u8In3End = u8In2.end();
|
||||
// Proposed in P1423, marked tested only for libc++
|
||||
{
|
||||
path p = fs::u8path(u8In1);
|
||||
assert(p == In1);
|
||||
}
|
||||
{
|
||||
path p = fs::u8path(u8In2);
|
||||
assert(p == In1);
|
||||
}
|
||||
{
|
||||
path p = fs::u8path(u8In3);
|
||||
assert(p == In1);
|
||||
}
|
||||
{
|
||||
path p = fs::u8path(u8In3, u8In3End);
|
||||
assert(p == In1);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -430,16 +430,28 @@ struct CWDGuard {
|
|||
|
||||
// Misc test types
|
||||
|
||||
#define MKSTR(Str) {Str, TEST_CONCAT(L, Str), TEST_CONCAT(u, Str), TEST_CONCAT(U, Str)}
|
||||
#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
|
||||
#define CHAR8_ONLY(x) x,
|
||||
#else
|
||||
#define CHAR8_ONLY(x)
|
||||
#endif
|
||||
|
||||
#define MKSTR(Str) {Str, TEST_CONCAT(L, Str), CHAR8_ONLY(TEST_CONCAT(u8, Str)) TEST_CONCAT(u, Str), TEST_CONCAT(U, Str)}
|
||||
|
||||
struct MultiStringType {
|
||||
const char* s;
|
||||
const wchar_t* w;
|
||||
#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
|
||||
const char8_t* u8;
|
||||
#endif
|
||||
const char16_t* u16;
|
||||
const char32_t* u32;
|
||||
|
||||
operator const char* () const { return s; }
|
||||
operator const wchar_t* () const { return w; }
|
||||
#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
|
||||
operator const char8_t* () const { return u8; }
|
||||
#endif
|
||||
operator const char16_t* () const { return u16; }
|
||||
operator const char32_t* () const { return u32; }
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue