Index: libcxx/include/filesystem =================================================================== --- libcxx/include/filesystem +++ libcxx/include/filesystem @@ -1117,7 +1117,12 @@ _LIBCPP_INLINE_VISIBILITY void clear() noexcept { __pn_.clear(); } - path& make_preferred() { return *this; } + path& make_preferred() { +#if defined(_LIBCPP_WIN32API) + std::replace(__pn_.begin(), __pn_.end(), '/', '\\'); +#endif + return *this; + } _LIBCPP_INLINE_VISIBILITY path& remove_filename() { Index: libcxx/src/filesystem/operations.cpp =================================================================== --- libcxx/src/filesystem/operations.cpp +++ libcxx/src/filesystem/operations.cpp @@ -49,6 +49,17 @@ _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM namespace { + +static bool isSeparator(path::value_type C) { + if (C == '/') + return true; +#if defined(_LIBCPP_WIN32API) + if (C == '\\') + return true; +#endif + return false; +} + namespace parser { using string_view_t = path::__string_view; @@ -266,21 +277,21 @@ } PosPtr consumeSeparator(PosPtr P, PosPtr End) const noexcept { - if (P == End || *P != '/') + if (P == End || !isSeparator(*P)) return nullptr; const int Inc = P < End ? 1 : -1; P += Inc; - while (P != End && *P == '/') + while (P != End && isSeparator(*P)) P += Inc; return P; } PosPtr consumeName(PosPtr P, PosPtr End) const noexcept { - if (P == End || *P == '/') + if (P == End || isSeparator(*P)) return nullptr; const int Inc = P < End ? 1 : -1; P += Inc; - while (P != End && *P != '/') + while (P != End && !isSeparator(*P)) P += Inc; return P; } @@ -1303,7 +1314,7 @@ auto PP = PathParser::CreateBegin(__pn_); if (PP.State == PathParser::PS_InRootName) { auto NextCh = PP.peek(); - if (NextCh && *NextCh == '/') { + if (NextCh && isSeparator(*NextCh)) { ++PP; return createView(__pn_.data(), &PP.RawEntry.back()); } @@ -1401,6 +1412,10 @@ return PK_DotDot; if (Part == PS("/")) return PK_RootSep; +#if defined(_LIBCPP_WIN32API) + if (Part == PS("\\")) + return PK_RootSep; +#endif return PK_Filename; }