Implement filesystem NB comments, relative paths, and related issues.

This is a fairly large patch that implements all of the filesystem NB comments
and the relative paths changes (ex. adding weakly_canonical). These issues
and papers are all interrelated so their implementation couldn't be split up
nicely.

This patch upgrades <experimental/filesystem> to match the C++17 spec and not
the published experimental TS spec. Some of the changes in this patch are both
API and ABI breaking, however libc++ makes no guarantee about stability for
experimental implementations.

The major changes in this patch are:

* Implement NB comments for filesystem (P0492R2), including:
  * Implement `perm_options` enum as part of NB comments, and update the
    `permissions` function to match.
  * Implement changes to `remove_filename` and `replace_filename`
  * Implement changes to `path::stem()` and `path::extension()` which support
    splitting examples like `.profile`.
  * Change path iteration to return an empty path instead of '.' for trailing
    separators.
  * Change `operator/=` to handle absolute paths on the RHS.
  * Change `absolute` to no longer accept a current path argument.

* Implement relative paths according to NB comments (P0219r1)

* Combine `path.cpp` and `operations.cpp` since some path functions require
  access to the operations internals, and some fs operations require access
  to the path parser.

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@329028 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Eric Fiselier
2018-04-02 23:03:41 +00:00
parent ead2a54952
commit 1e34c76d33
30 changed files with 1810 additions and 899 deletions

View File

@@ -31,6 +31,7 @@
#include "test_iterators.h"
#include "count_new.hpp"
#include "filesystem_test_helper.hpp"
#include "verbose_assert.h"
struct AppendOperatorTestcase {
@@ -45,13 +46,22 @@ const AppendOperatorTestcase Cases[] =
{S(""), S(""), S("")}
, {S("p1"), S("p2"), S("p1/p2")}
, {S("p1/"), S("p2"), S("p1/p2")}
, {S("p1"), S("/p2"), S("p1/p2")}
, {S("p1/"), S("/p2"), S("p1//p2")}
, {S("p1"), S("/p2"), S("/p2")}
, {S("p1/"), S("/p2"), S("/p2")}
, {S("p1"), S("\\p2"), S("p1/\\p2")}
, {S("p1\\"), S("p2"), S("p1\\/p2")}
, {S("p1\\"), S("\\p2"), S("p1\\/\\p2")}
, {S("p1"), S(""), S("p1")}
, {S(""), S("p2"), S("p2")}
, {S("/p1"), S("p2"), S("/p1/p2")}
, {S("/p1"), S("/p2"), S("/p2")}
, {S("/p1/p3"), S("p2"), S("/p1/p3/p2")}
, {S("/p1/p3/"), S("p2"), S("/p1/p3/p2")}
, {S("/p1/"), S("p2"), S("/p1/p2")}
, {S("/p1/p3/"), S("/p2/p4"), S("/p2/p4")}
, {S("/"), S(""), S("/")}
, {S("/p1"), S("/p2/"), S("/p2/")}
, {S("p1"), S(""), S("p1/")}
, {S("p1/"), S(""), S("p1/")}
};
@@ -59,7 +69,8 @@ const AppendOperatorTestcase LongLHSCases[] =
{
{S("p1"), S("p2"), S("p1/p2")}
, {S("p1/"), S("p2"), S("p1/p2")}
, {S("p1"), S("/p2"), S("p1/p2")}
, {S("p1"), S("/p2"), S("/p2")}
, {S("/p1"), S("p2"), S("/p1/p2")}
};
#undef S
@@ -98,7 +109,7 @@ void doAppendSourceAllocTest(AppendOperatorTestcase const& TC)
DisableAllocationGuard g;
LHS /= RHS;
}
assert(LHS == E);
ASSERT_PRED(PathEq, LHS , E);
}
// basic_string_view
{
@@ -108,7 +119,7 @@ void doAppendSourceAllocTest(AppendOperatorTestcase const& TC)
DisableAllocationGuard g;
LHS /= RHS;
}
assert(LHS == E);
assert(PathEq(LHS, E));
}
// CharT*
{
@@ -118,7 +129,7 @@ void doAppendSourceAllocTest(AppendOperatorTestcase const& TC)
DisableAllocationGuard g;
LHS /= RHS;
}
assert(LHS == E);
assert(PathEq(LHS, E));
}
{
path LHS(L); PathReserve(LHS, ReserveSize);
@@ -127,7 +138,7 @@ void doAppendSourceAllocTest(AppendOperatorTestcase const& TC)
DisableAllocationGuard g;
LHS.append(RHS, StrEnd(RHS));
}
assert(LHS == E);
assert(PathEq(LHS, E));
}
// input iterator - For non-native char types, appends needs to copy the
// iterator range into a contiguous block of memory before it can perform the
@@ -143,7 +154,7 @@ void doAppendSourceAllocTest(AppendOperatorTestcase const& TC)
if (DisableAllocations) g.requireExactly(0);
LHS /= RHS;
}
assert(LHS == E);
assert(PathEq(LHS, E));
}
{
path LHS(L); PathReserve(LHS, ReserveSize);
@@ -154,7 +165,7 @@ void doAppendSourceAllocTest(AppendOperatorTestcase const& TC)
if (DisableAllocations) g.requireExactly(0);
LHS.append(RHS, REnd);
}
assert(LHS == E);
assert(PathEq(LHS, E));
}
}
@@ -171,17 +182,18 @@ void doAppendSourceTest(AppendOperatorTestcase const& TC)
const Ptr E = TC.expect;
// basic_string
{
path LHS(L);
path Result(L);
Str RHS(R);
path& Ref = (LHS /= RHS);
assert(LHS == E);
assert(&Ref == &LHS);
path& Ref = (Result /= RHS);
ASSERT_EQ(Result, E)
<< DISPLAY(L) << DISPLAY(R);
assert(&Ref == &Result);
}
{
path LHS(L);
Str RHS(R);
path& Ref = LHS.append(RHS);
assert(LHS == E);
assert(PathEq(LHS, E));
assert(&Ref == &LHS);
}
// basic_string_view
@@ -189,14 +201,14 @@ void doAppendSourceTest(AppendOperatorTestcase const& TC)
path LHS(L);
StrView RHS(R);
path& Ref = (LHS /= RHS);
assert(LHS == E);
assert(PathEq(LHS, E));
assert(&Ref == &LHS);
}
{
path LHS(L);
StrView RHS(R);
path& Ref = LHS.append(RHS);
assert(LHS == E);
assert(PathEq(LHS, E));
assert(&Ref == &LHS);
}
// Char*
@@ -204,21 +216,22 @@ void doAppendSourceTest(AppendOperatorTestcase const& TC)
path LHS(L);
Str RHS(R);
path& Ref = (LHS /= RHS);
assert(LHS == E);
assert(PathEq(LHS, E));
assert(&Ref == &LHS);
}
{
path LHS(L);
Ptr RHS(R);
path& Ref = LHS.append(RHS);
assert(LHS == E);
assert(PathEq(LHS, E));
assert(&Ref == &LHS);
}
{
path LHS(L);
Ptr RHS(R);
path& Ref = LHS.append(RHS, StrEnd(RHS));
assert(LHS == E);
ASSERT_PRED(PathEq, LHS, E)
<< DISPLAY(L) << DISPLAY(R);
assert(&Ref == &LHS);
}
// iterators
@@ -226,13 +239,13 @@ void doAppendSourceTest(AppendOperatorTestcase const& TC)
path LHS(L);
InputIter RHS(R);
path& Ref = (LHS /= RHS);
assert(LHS == E);
assert(PathEq(LHS, E));
assert(&Ref == &LHS);
}
{
path LHS(L); InputIter RHS(R);
path& Ref = LHS.append(RHS);
assert(LHS == E);
assert(PathEq(LHS, E));
assert(&Ref == &LHS);
}
{
@@ -240,7 +253,7 @@ void doAppendSourceTest(AppendOperatorTestcase const& TC)
InputIter RHS(R);
InputIter REnd(StrEnd(R));
path& Ref = LHS.append(RHS, REnd);
assert(LHS == E);
assert(PathEq(LHS, E));
assert(&Ref == &LHS);
}
}
@@ -304,11 +317,14 @@ int main()
using namespace fs;
for (auto const & TC : Cases) {
{
path LHS((const char*)TC.lhs);
path RHS((const char*)TC.rhs);
path& Ref = (LHS /= RHS);
assert(LHS == (const char*)TC.expect);
assert(&Ref == &LHS);
const char* LHS_In = TC.lhs;
const char* RHS_In = TC.rhs;
path LHS(LHS_In);
path RHS(RHS_In);
path& Res = (LHS /= RHS);
ASSERT_PRED(PathEq, Res, (const char*)TC.expect)
<< DISPLAY(LHS_In) << DISPLAY(RHS_In);
assert(&Res == &LHS);
}
doAppendSourceTest<char> (TC);
doAppendSourceTest<wchar_t> (TC);