Add Filesystem TS -- Complete

Add the completed std::experimental::filesystem implementation and tests.
The implementation supports C++11 or newer.

The TS is built as part of 'libc++experimental.a'. Users of the TS need to
manually link this library. Building and testing the TS can be disabled using
the CMake option '-DLIBCXX_ENABLE_FILESYSTEM=OFF'.

Currently 'libc++experimental.a' is not installed by default. To turn on the
installation of the library use '-DLIBCXX_INSTALL_EXPERIMENTAL_LIBRARY=ON'.

llvm-svn: 273034
diff --git a/libcxx/test/std/experimental/filesystem/class.path/path.itr/iterator.pass.cpp b/libcxx/test/std/experimental/filesystem/class.path/path.itr/iterator.pass.cpp
new file mode 100644
index 0000000..4aa8ebc
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/class.path/path.itr/iterator.pass.cpp
@@ -0,0 +1,104 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// class path
+
+// template <class Source>
+//      path(const Source& source);
+// template <class InputIterator>
+//      path(InputIterator first, InputIterator last);
+
+
+#include <experimental/filesystem>
+#include <iterator>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "filesystem_test_helper.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+
+template <class It>
+std::reverse_iterator<It> mkRev(It it) {
+  return std::reverse_iterator<It>(it);
+}
+
+
+void checkIteratorConcepts() {
+  using namespace fs;
+  using It = path::iterator;
+  using Traits = std::iterator_traits<It>;
+  ASSERT_SAME_TYPE(Traits::iterator_category, std::bidirectional_iterator_tag);
+  ASSERT_SAME_TYPE(Traits::value_type, path);
+  ASSERT_SAME_TYPE(Traits::pointer,   path const*);
+  ASSERT_SAME_TYPE(Traits::reference, path const&);
+  {
+    It it;
+    ASSERT_SAME_TYPE(It&, decltype(++it));
+    ASSERT_SAME_TYPE(It, decltype(it++));
+    ASSERT_SAME_TYPE(It&, decltype(--it));
+    ASSERT_SAME_TYPE(It, decltype(it--));
+    ASSERT_SAME_TYPE(Traits::reference, decltype(*it));
+    ASSERT_SAME_TYPE(Traits::pointer, decltype(it.operator->()));
+    ASSERT_SAME_TYPE(std::string const&, decltype(it->native()));
+    ASSERT_SAME_TYPE(bool, decltype(it == it));
+    ASSERT_SAME_TYPE(bool, decltype(it != it));
+  }
+  {
+    path const p;
+    ASSERT_SAME_TYPE(It, decltype(p.begin()));
+    ASSERT_SAME_TYPE(It, decltype(p.end()));
+    assert(p.begin() == p.end());
+  }
+}
+
+void checkBeginEndBasic() {
+  using namespace fs;
+  using It = path::iterator;
+  {
+    path const p;
+    ASSERT_SAME_TYPE(It, decltype(p.begin()));
+    ASSERT_SAME_TYPE(It, decltype(p.end()));
+    assert(p.begin() == p.end());
+  }
+  {
+    path const p("foo");
+    It default_constructed;
+    default_constructed = p.begin();
+    assert(default_constructed == p.begin());
+    assert(default_constructed != p.end());
+    default_constructed = p.end();
+    assert(default_constructed == p.end());
+    assert(default_constructed != p.begin());
+  }
+  {
+    path p("//root_name//first_dir////second_dir");
+    const path expect[] = {"//root_name", "/", "first_dir", "second_dir"};
+    assert(checkCollectionsEqual(p.begin(), p.end(), std::begin(expect), std::end(expect)));
+    assert(checkCollectionsEqual(mkRev(p.end()), mkRev(p.begin()), mkRev(std::end(expect)), mkRev(std::begin(expect))));
+  }
+  {
+    path p("////foo/bar/baz///");
+    const path expect[] = {"/", "foo", "bar", "baz", "."};
+    assert(checkCollectionsEqual(p.begin(), p.end(), std::begin(expect), std::end(expect)));
+    assert(checkCollectionsEqual(mkRev(p.end()), mkRev(p.begin()), mkRev(std::end(expect)), mkRev(std::begin(expect))));
+  }
+}
+
+int main() {
+  using namespace fs;
+  checkIteratorConcepts();
+  checkBeginEndBasic(); // See path.decompose.pass.cpp for more tests.
+}
diff --git a/libcxx/test/std/experimental/filesystem/class.path/path.member/path.append.pass.cpp b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.append.pass.cpp
new file mode 100644
index 0000000..1118497
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.append.pass.cpp
@@ -0,0 +1,241 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// class path
+
+// path& operator/=(path const&)
+// template <class Source>
+//      path& operator/=(Source const&);
+// template <class Source>
+//      path& append(Source const&);
+// template <class InputIterator>
+//      path& append(InputIterator first, InputIterator last);
+
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+struct AppendOperatorTestcase {
+  MultiStringType lhs;
+  MultiStringType rhs;
+  MultiStringType expect;
+};
+
+#define S(Str) MKSTR(Str)
+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("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")}
+    };
+
+
+const AppendOperatorTestcase LongLHSCases[] =
+    {
+        {S("p1"),   S("p2"),    S("p1/p2")}
+      , {S("p1/"),  S("p2"),    S("p1/p2")}
+      , {S("p1"),   S("/p2"),   S("p1/p2")}
+    };
+#undef S
+
+
+// The append operator may need to allocate a temporary buffer before a code_cvt
+// conversion. Test if this allocation occurs by:
+//   1. Create a path, `LHS`, and reserve enough space to append `RHS`.
+//      This prevents `LHS` from allocating during the actual appending.
+//   2. Create a `Source` object `RHS`, which represents a "large" string.
+//      (The string must not trigger the SSO)
+//   3. Append `RHS` to `LHS` and check for the expected allocation behavior.
+template <class CharT>
+void doAppendSourceAllocTest(AppendOperatorTestcase const& TC)
+{
+  using namespace fs;
+  using Ptr = CharT const*;
+  using Str = std::basic_string<CharT>;
+  using InputIter = input_iterator<Ptr>;
+
+  const Ptr L = TC.lhs;
+  Str RShort = (Ptr)TC.rhs;
+  Str EShort = (Ptr)TC.expect;
+  assert(RShort.size() >= 2);
+  CharT c = RShort.back();
+  RShort.append(100, c);
+  EShort.append(100, c);
+  const Ptr R = RShort.data();
+  const Str& E = EShort;
+  std::size_t ReserveSize = E.size() + 3;
+  // basic_string
+  {
+    path LHS(L); PathReserve(LHS, ReserveSize);
+    Str  RHS(R);
+    {
+      DisableAllocationGuard g;
+      LHS /= RHS;
+    }
+    assert(LHS == E);
+  }
+  // CharT*
+  {
+    path LHS(L); PathReserve(LHS, ReserveSize);
+    Ptr RHS(R);
+    {
+      DisableAllocationGuard g;
+      LHS /= RHS;
+    }
+    assert(LHS == E);
+  }
+  {
+    path LHS(L); PathReserve(LHS, ReserveSize);
+    Ptr RHS(R);
+    {
+      DisableAllocationGuard g;
+      LHS.append(RHS, StrEnd(RHS));
+    }
+    assert(LHS == E);
+  }
+  // input iterator - For non-native char types, appends needs to copy the
+  // iterator range into a contigious block of memory before it can perform the
+  // code_cvt conversions.
+  // For "char" no allocations will be performed because no conversion is
+  // required.
+  bool DisableAllocations = std::is_same<CharT, char>::value;
+  {
+    path LHS(L); PathReserve(LHS, ReserveSize);
+    InputIter RHS(R);
+    {
+      RequireAllocationGuard  g; // requires 1 or more allocations occur by default
+      if (DisableAllocations) g.requireExactly(0);
+      LHS /= RHS;
+    }
+    assert(LHS == E);
+  }
+  {
+    path LHS(L); PathReserve(LHS, ReserveSize);
+    InputIter RHS(R);
+    InputIter REnd(StrEnd(R));
+    {
+      RequireAllocationGuard g;
+      if (DisableAllocations) g.requireExactly(0);
+      LHS.append(RHS, REnd);
+    }
+    assert(LHS == E);
+  }
+}
+
+template <class CharT>
+void doAppendSourceTest(AppendOperatorTestcase const& TC)
+{
+  using namespace fs;
+  using Ptr = CharT const*;
+  using Str = std::basic_string<CharT>;
+  using InputIter = input_iterator<Ptr>;
+  const Ptr L = TC.lhs;
+  const Ptr R = TC.rhs;
+  const Ptr E = TC.expect;
+  // basic_string
+  {
+    path LHS(L);
+    Str RHS(R);
+    path& Ref = (LHS /= RHS);
+    assert(LHS == E);
+    assert(&Ref == &LHS);
+  }
+  {
+    path LHS(L);
+    Str RHS(R);
+    path& Ref = LHS.append(RHS);
+    assert(LHS == E);
+    assert(&Ref == &LHS);
+  }
+  // Char*
+  {
+    path LHS(L);
+    Str RHS(R);
+    path& Ref = (LHS /= RHS);
+    assert(LHS == E);
+    assert(&Ref == &LHS);
+  }
+  {
+    path LHS(L);
+    Ptr RHS(R);
+    path& Ref = LHS.append(RHS);
+    assert(LHS == E);
+    assert(&Ref == &LHS);
+  }
+  {
+    path LHS(L);
+    Ptr RHS(R);
+    path& Ref = LHS.append(RHS, StrEnd(RHS));
+    assert(LHS == E);
+    assert(&Ref == &LHS);
+  }
+  // iterators
+  {
+    path LHS(L);
+    InputIter RHS(R);
+    path& Ref = (LHS /= RHS);
+    assert(LHS == E);
+    assert(&Ref == &LHS);
+  }
+  {
+    path LHS(L); InputIter RHS(R);
+    path& Ref = LHS.append(RHS);
+    assert(LHS == E);
+    assert(&Ref == &LHS);
+  }
+  {
+    path LHS(L);
+    InputIter RHS(R);
+    InputIter REnd(StrEnd(R));
+    path& Ref = LHS.append(RHS, REnd);
+    assert(LHS == E);
+    assert(&Ref == &LHS);
+  }
+}
+
+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);
+    }
+    doAppendSourceTest<char>    (TC);
+    doAppendSourceTest<wchar_t> (TC);
+    doAppendSourceTest<char16_t>(TC);
+    doAppendSourceTest<char32_t>(TC);
+  }
+  for (auto const & TC : LongLHSCases) {
+    doAppendSourceAllocTest<char>(TC);
+    doAppendSourceAllocTest<wchar_t>(TC);
+  }
+}
diff --git a/libcxx/test/std/experimental/filesystem/class.path/path.member/path.assign/copy.pass.cpp b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.assign/copy.pass.cpp
new file mode 100644
index 0000000..5c26f84
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.assign/copy.pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// class path
+
+// path& operator=(path const&);
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+namespace fs = std::experimental::filesystem;
+
+int main() {
+  using namespace fs;
+  static_assert(std::is_copy_assignable<path>::value, "");
+  static_assert(!std::is_nothrow_copy_assignable<path>::value, "should not be noexcept");
+  const std::string s("foo");
+  const path p(s);
+  path p2;
+  path& pref = (p2 = p);
+  assert(p.native() == s);
+  assert(p2.native() == s);
+  assert(&pref == &p2);
+}
diff --git a/libcxx/test/std/experimental/filesystem/class.path/path.member/path.assign/move.pass.cpp b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.assign/move.pass.cpp
new file mode 100644
index 0000000..7263424
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.assign/move.pass.cpp
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// class path
+
+// path& operator=(path&&) noexcept
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "count_new.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+int main() {
+  using namespace fs;
+  static_assert(std::is_nothrow_move_assignable<path>::value, "");
+  assert(globalMemCounter.checkOutstandingNewEq(0));
+  const std::string s("we really really really really really really really "
+                      "really really long string so that we allocate");
+  assert(globalMemCounter.checkOutstandingNewEq(1));
+  path p(s);
+  {
+    DisableAllocationGuard g;
+    path p2;
+    path& pref = (p2 = std::move(p));
+    assert(p2.native() == s);
+    assert(p.native() != s); // Testing moved from state
+    assert(&pref == &p2);
+  }
+}
diff --git a/libcxx/test/std/experimental/filesystem/class.path/path.member/path.assign/source.pass.cpp b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.assign/source.pass.cpp
new file mode 100644
index 0000000..4c2d511
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.assign/source.pass.cpp
@@ -0,0 +1,153 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// class path
+
+// template <class Source>
+//      path& operator=(Source const&);
+// template <class Source>
+//      path& assign(Source const&);
+// template <class InputIterator>
+//      path& assign(InputIterator first, InputIterator last);
+
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+#include <iostream>
+
+namespace fs = std::experimental::filesystem;
+
+template <class CharT>
+void RunTestCase(MultiStringType const& MS) {
+  using namespace fs;
+  const char* Expect = MS;
+  const CharT* TestPath = MS;
+  const CharT* TestPathEnd = StrEnd(TestPath);
+  const std::size_t Size = TestPathEnd - TestPath;
+  const std::size_t SSize = StrEnd(Expect) - Expect;
+  assert(Size == SSize);
+  //////////////////////////////////////////////////////////////////////////////
+  // basic_string<Char, Traits, Alloc>
+  {
+    const std::basic_string<CharT> S(TestPath);
+    path p; PathReserve(p, S.length() + 1);
+    {
+      // string provides a contigious iterator. No allocation needed.
+      DisableAllocationGuard g;
+      path& pref = (p = S);
+      assert(&pref == &p);
+    }
+    assert(p.native() == Expect);
+    assert(p.string<CharT>() == TestPath);
+    assert(p.string<CharT>() == S);
+  }
+  {
+    const std::basic_string<CharT> S(TestPath);
+    path p; PathReserve(p, S.length() + 1);
+    {
+      DisableAllocationGuard g;
+      path& pref = p.assign(S);
+      assert(&pref == &p);
+    }
+    assert(p.native() == Expect);
+    assert(p.string<CharT>() == TestPath);
+    assert(p.string<CharT>() == S);
+  }
+  //////////////////////////////////////////////////////////////////////////////
+  // Char* pointers
+  {
+    path p; PathReserve(p, Size + 1);
+    {
+      // char* pointers are contigious and can be used with code_cvt directly.
+      // no allocations needed.
+      DisableAllocationGuard g;
+      path& pref = (p = TestPath);
+      assert(&pref == &p);
+    }
+    assert(p.native() == Expect);
+    assert(p.string<CharT>() == TestPath);
+  }
+  {
+    path p; PathReserve(p, Size + 1);
+    {
+      DisableAllocationGuard g;
+      path& pref = p.assign(TestPath);
+      assert(&pref == &p);
+    }
+    assert(p.native() == Expect);
+    assert(p.string<CharT>() == TestPath);
+  }
+  {
+    path p; PathReserve(p, Size + 1);
+    {
+      DisableAllocationGuard g;
+      path& pref = p.assign(TestPath, TestPathEnd);
+      assert(&pref == &p);
+    }
+    assert(p.native() == Expect);
+    assert(p.string<CharT>() == TestPath);
+  }
+  //////////////////////////////////////////////////////////////////////////////
+  // Iterators
+  {
+    using It = input_iterator<const CharT*>;
+    path p; PathReserve(p, Size + 1);
+    It it(TestPath);
+    {
+      // Iterators cannot be used with code_cvt directly. This assignment
+      // may allocate if it's larger than a "short-string".
+      path& pref = (p = it);
+      assert(&pref == &p);
+    }
+    assert(p.native() == Expect);
+    assert(p.string<CharT>() == TestPath);
+  }
+  {
+    using It = input_iterator<const CharT*>;
+    path p; PathReserve(p, Size + 1);
+    It it(TestPath);
+    {
+      path& pref = p.assign(it);
+      assert(&pref == &p);
+    }
+    assert(p.native() == Expect);
+    assert(p.string<CharT>() == TestPath);
+  }
+  {
+    using It = input_iterator<const CharT*>;
+    path p; PathReserve(p, Size + 1);
+    It it(TestPath);
+    It e(TestPathEnd);
+    {
+      path& pref = p.assign(it, e);
+      assert(&pref == &p);
+    }
+    assert(p.native() == Expect);
+    assert(p.string<CharT>() == TestPath);
+  }
+}
+
+int main() {
+  for (auto const& MS : PathList) {
+    RunTestCase<char>(MS);
+    RunTestCase<wchar_t>(MS);
+    RunTestCase<char16_t>(MS);
+    RunTestCase<char32_t>(MS);
+  }
+}
diff --git a/libcxx/test/std/experimental/filesystem/class.path/path.member/path.compare.pass.cpp b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.compare.pass.cpp
new file mode 100644
index 0000000..557c1b2
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.compare.pass.cpp
@@ -0,0 +1,126 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// class path
+
+// int compare(path const&) const noexcept;
+// int compare(string_type const&) const;
+// int compare(value_type const*) const;
+//
+// bool operator==(path const&, path const&) noexcept;
+// bool operator!=(path const&, path const&) noexcept;
+// bool operator< (path const&, path const&) noexcept;
+// bool operator<=(path const&, path const&) noexcept;
+// bool operator> (path const&, path const&) noexcept;
+// bool operator>=(path const&, path const&) noexcept;
+//
+// size_t hash_value(path const&) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <vector>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+struct PathCompareTest {
+  const char* LHS;
+  const char* RHS;
+  int expect;
+};
+
+#define LONGA "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+#define LONGB "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
+#define LONGC "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
+#define LONGD "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"
+const PathCompareTest CompareTestCases[] =
+{
+    {"", "",  0},
+    {"a", "", 1},
+    {"", "a", -1},
+    {"a/b/c", "a/b/c", 0},
+    {"b/a/c", "a/b/c", 1},
+    {"a/b/c", "b/a/c", -1},
+    {"a/b", "a/b/c", -1},
+    {"a/b/c", "a/b", 1},
+    {"a/b/", "a/b/.", 0},
+    {"a/b//////", "a/b/////.", 0},
+    {"a/.././b", "a///..//.////b", 0},
+    {"//foo//bar///baz////", "//foo/bar/baz/", 0}, // duplicate separators
+    {"///foo/bar", "/foo/bar", 0}, // "///" is not a root directory
+    {"/foo/bar/", "/foo/bar", 1}, // trailing separator
+    {"//" LONGA "////" LONGB "/" LONGC "///" LONGD, "//" LONGA "/" LONGB "/" LONGC "/" LONGD, 0},
+    { LONGA "/" LONGB "/" LONGC, LONGA "/" LONGB "/" LONGB, 1}
+
+};
+#undef LONGA
+#undef LONGB
+#undef LONGC
+#undef LONGD
+
+int main()
+{
+  using namespace fs;
+  for (auto const & TC : CompareTestCases) {
+    const path p1(TC.LHS);
+    const path p2(TC.RHS);
+    const std::string R(TC.RHS);
+    const int E = TC.expect;
+    { // compare(...) functions
+      DisableAllocationGuard g; // none of these operations should allocate
+
+      // check runtime results
+      int ret1 = p1.compare(p2);
+      int ret2 = p1.compare(R);
+      int ret3 = p1.compare(TC.RHS);
+      assert(ret1 == ret2 && ret1 == ret3);
+      int normalized_ret = ret1 < 0 ? -1 : (ret1 > 0 ? 1 : 0);
+      assert(normalized_ret == E);
+
+      // check signatures
+      ASSERT_NOEXCEPT(p1.compare(p2));
+    }
+    { // comparison operators
+      DisableAllocationGuard g; // none of these operations should allocate
+
+      // Check runtime result
+      assert((p1 == p2) == (E == 0));
+      assert((p1 != p2) == (E != 0));
+      assert((p1 <  p2) == (E <  0));
+      assert((p1 <= p2) == (E <= 0));
+      assert((p1 >  p2) == (E >  0));
+      assert((p1 >= p2) == (E >= 0));
+
+      // Check signatures
+      ASSERT_NOEXCEPT(p1 == p2);
+      ASSERT_NOEXCEPT(p1 != p2);
+      ASSERT_NOEXCEPT(p1 <  p2);
+      ASSERT_NOEXCEPT(p1 <= p2);
+      ASSERT_NOEXCEPT(p1 >  p2);
+      ASSERT_NOEXCEPT(p1 >= p2);
+    }
+    { // check hash values
+      auto h1 = hash_value(p1);
+      auto h2 = hash_value(p2);
+      assert((h1 == h2) == (p1 == p2));
+      // check signature
+      ASSERT_SAME_TYPE(size_t, decltype(hash_value(p1)));
+      ASSERT_NOEXCEPT(hash_value(p1));
+    }
+  }
+}
diff --git a/libcxx/test/std/experimental/filesystem/class.path/path.member/path.concat.pass.cpp b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.concat.pass.cpp
new file mode 100644
index 0000000..6e00afe
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.concat.pass.cpp
@@ -0,0 +1,277 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// class path
+
+// path& operator+=(const path& x);
+// path& operator+=(const string_type& x); // Implemented as Source template
+// path& operator+=(const value_type* x);  // Implemented as Source template
+// path& operator+=(value_type x);
+// template <class Source>
+//   path& operator+=(const Source& x);
+// template <class EcharT>
+//   path& operator+=(EcharT x);
+// template <class Source>
+//   path& concat(const Source& x);
+// template <class InputIterator>
+//   path& concat(InputIterator first, InputIterator last);
+
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+struct ConcatOperatorTestcase {
+  MultiStringType lhs;
+  MultiStringType rhs;
+  MultiStringType expect;
+};
+
+#define LONGSTR "LONGSTR_LONGSTR_LONGSTR_LONGSTR_LONGSTR_LONGSTR_LONGSTR_LONGSTR_LONGSTR_LONGSTR_LONGSTR_LONGSTR"
+#define S(Str) MKSTR(Str)
+const ConcatOperatorTestcase Cases[] =
+    {
+        {S(""),         S(""),                  S("")}
+      , {S("p1"),       S("p2"),                S("p1p2")}
+      , {S("p1/"),      S("/p2"),               S("p1//p2")}
+      , {S(""),         S("\\foo/bar/baz"),     S("\\foo/bar/baz")}
+      , {S("c:\\foo"),  S(""),                  S("c:\\foo")}
+      , {S(LONGSTR),    S("foo"),               S(LONGSTR "foo")}
+      , {S("abcdefghijklmnopqrstuvwxyz/\\"), S("/\\123456789"), S("abcdefghijklmnopqrstuvwxyz/\\/\\123456789")}
+    };
+const ConcatOperatorTestcase LongLHSCases[] =
+    {
+        {S(""),        S(LONGSTR),     S(LONGSTR)}
+      , {S("p1/"),     S(LONGSTR),      S("p1/" LONGSTR)}
+    };
+const ConcatOperatorTestcase CharTestCases[] =
+    {
+        {S(""),       S("P"), S("P")}
+      , {S("/fooba"), S("r"), S("/foobar")}
+    };
+#undef S
+#undef LONGSTR
+
+// The concat operator may need to allocate a temporary buffer before a code_cvt
+// conversion. Test if this allocation occurs by:
+//   1. Create a path, `LHS`, and reserve enough space to append `RHS`.
+//      This prevents `LHS` from allocating during the actual appending.
+//   2. Create a `Source` object `RHS`, which represents a "large" string.
+//      (The string must not trigger the SSO)
+//   3. Concat `RHS` to `LHS` and check for the expected allocation behavior.
+template <class CharT>
+void doConcatSourceAllocTest(ConcatOperatorTestcase const& TC)
+{
+  using namespace fs;
+  using Ptr = CharT const*;
+  using Str = std::basic_string<CharT>;
+  using InputIter = input_iterator<Ptr>;
+
+  const Ptr L = TC.lhs;
+  const Ptr R = TC.rhs;
+  const Ptr E =  TC.expect;
+  std::size_t ReserveSize = StrLen(E) + 1;
+  // basic_string
+  {
+    path LHS(L); PathReserve(LHS, ReserveSize);
+    Str  RHS(R);
+    {
+      DisableAllocationGuard g;
+      LHS += RHS;
+    }
+    assert(LHS == E);
+  }
+  // CharT*
+  {
+    path LHS(L); PathReserve(LHS, ReserveSize);
+    Ptr RHS(R);
+    {
+      DisableAllocationGuard g;
+      LHS += RHS;
+    }
+    assert(LHS == E);
+  }
+  {
+    path LHS(L); PathReserve(LHS, ReserveSize);
+    Ptr RHS(R);
+    {
+      DisableAllocationGuard g;
+      LHS.concat(RHS, StrEnd(RHS));
+    }
+    assert(LHS == E);
+  }
+  // input iterator - For non-native char types, appends needs to copy the
+  // iterator range into a contigious block of memory before it can perform the
+  // code_cvt conversions.
+  // For "char" no allocations will be performed because no conversion is
+  // required.
+  bool DisableAllocations = std::is_same<CharT, char>::value;
+  {
+    path LHS(L); PathReserve(LHS, ReserveSize);
+    InputIter RHS(R);
+    {
+      RequireAllocationGuard  g; // requires 1 or more allocations occur by default
+      if (DisableAllocations) g.requireExactly(0);
+      LHS += RHS;
+    }
+    assert(LHS == E);
+  }
+  {
+    path LHS(L); PathReserve(LHS, ReserveSize);
+    InputIter RHS(R);
+    InputIter REnd(StrEnd(R));
+    {
+      RequireAllocationGuard g;
+      if (DisableAllocations) g.requireExactly(0);
+      LHS.concat(RHS, REnd);
+    }
+    assert(LHS == E);
+  }
+}
+
+template <class CharT>
+void doConcatSourceTest(ConcatOperatorTestcase const& TC)
+{
+  using namespace fs;
+  using Ptr = CharT const*;
+  using Str = std::basic_string<CharT>;
+  using InputIter = input_iterator<Ptr>;
+  const Ptr L = TC.lhs;
+  const Ptr R = TC.rhs;
+  const Ptr E = TC.expect;
+  // basic_string
+  {
+    path LHS(L);
+    Str RHS(R);
+    path& Ref = (LHS += RHS);
+    assert(LHS == E);
+    assert(&Ref == &LHS);
+  }
+  {
+    path LHS(L);
+    Str RHS(R);
+    path& Ref = LHS.concat(RHS);
+    assert(LHS == E);
+    assert(&Ref == &LHS);
+  }
+  // Char*
+  {
+    path LHS(L);
+    Str RHS(R);
+    path& Ref = (LHS += RHS);
+    assert(LHS == E);
+    assert(&Ref == &LHS);
+  }
+  {
+    path LHS(L);
+    Ptr RHS(R);
+    path& Ref = LHS.concat(RHS);
+    assert(LHS == E);
+    assert(&Ref == &LHS);
+  }
+  {
+    path LHS(L);
+    Ptr RHS(R);
+    path& Ref = LHS.concat(RHS, StrEnd(RHS));
+    assert(LHS == E);
+    assert(&Ref == &LHS);
+  }
+  // iterators
+  {
+    path LHS(L);
+    InputIter RHS(R);
+    path& Ref = (LHS += RHS);
+    assert(LHS == E);
+    assert(&Ref == &LHS);
+  }
+  {
+    path LHS(L); InputIter RHS(R);
+    path& Ref = LHS.concat(RHS);
+    assert(LHS == E);
+    assert(&Ref == &LHS);
+  }
+  {
+    path LHS(L);
+    InputIter RHS(R);
+    InputIter REnd(StrEnd(R));
+    path& Ref = LHS.concat(RHS, REnd);
+    assert(LHS == E);
+    assert(&Ref == &LHS);
+  }
+}
+
+template <class CharT>
+void doConcatECharTest(ConcatOperatorTestcase const& TC)
+{
+  using namespace fs;
+  using Ptr = CharT const*;
+  const Ptr RStr = TC.rhs;
+  assert(StrLen(RStr) == 1);
+  const Ptr L   = TC.lhs;
+  const CharT R = RStr[0];
+  const Ptr E   = TC.expect;
+  {
+    path LHS(L);
+    path& Ref = (LHS += R);
+    assert(LHS == E);
+    assert(&Ref == &LHS);
+  }
+}
+
+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);
+    }
+    doConcatSourceTest<char>    (TC);
+    doConcatSourceTest<wchar_t> (TC);
+    doConcatSourceTest<char16_t>(TC);
+    doConcatSourceTest<char32_t>(TC);
+  }
+  for (auto const & TC : LongLHSCases) {
+    // Do path test
+    {
+      path LHS((const char*)TC.lhs);
+      path RHS((const char*)TC.rhs);
+      const char* E = TC.expect;
+      PathReserve(LHS, StrLen(E) + 5);
+      {
+        DisableAllocationGuard g;
+        path& Ref = (LHS += RHS);
+        assert(&Ref == &LHS);
+      }
+      assert(LHS == E);
+    }
+    doConcatSourceAllocTest<char>(TC);
+    doConcatSourceAllocTest<wchar_t>(TC);
+  }
+  for (auto const& TC : CharTestCases) {
+    doConcatECharTest<char>(TC);
+    doConcatECharTest<wchar_t>(TC);
+    doConcatECharTest<char16_t>(TC);
+    doConcatECharTest<char32_t>(TC);
+  }
+}
diff --git a/libcxx/test/std/experimental/filesystem/class.path/path.member/path.construct/copy.pass.cpp b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.construct/copy.pass.cpp
new file mode 100644
index 0000000..67b8a04
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.construct/copy.pass.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// class path
+
+// path(path const&)
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+namespace fs = std::experimental::filesystem;
+
+int main() {
+  using namespace fs;
+  static_assert(std::is_copy_constructible<path>::value, "");
+  static_assert(!std::is_nothrow_copy_constructible<path>::value, "should not be noexcept");
+  const std::string s("foo");
+  const path p(s);
+  path p2(p);
+  assert(p.native() == s);
+  assert(p2.native() == s);
+}
diff --git a/libcxx/test/std/experimental/filesystem/class.path/path.member/path.construct/default.pass.cpp b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.construct/default.pass.cpp
new file mode 100644
index 0000000..f265046
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.construct/default.pass.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// class path
+
+// path() noexcept
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+namespace fs = std::experimental::filesystem;
+
+int main() {
+  using namespace fs;
+  static_assert(std::is_nothrow_default_constructible<path>::value, "");
+  const path p;
+  assert(p.empty());
+}
diff --git a/libcxx/test/std/experimental/filesystem/class.path/path.member/path.construct/move.pass.cpp b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.construct/move.pass.cpp
new file mode 100644
index 0000000..b8ac4b3
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.construct/move.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// class path
+
+// path(path&&) noexcept
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "count_new.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+int main() {
+  using namespace fs;
+  static_assert(std::is_nothrow_move_constructible<path>::value, "");
+  assert(globalMemCounter.checkOutstandingNewEq(0));
+  const std::string s("we really really really really really really really "
+                      "really really long string so that we allocate");
+  assert(globalMemCounter.checkOutstandingNewEq(1));
+  path p(s);
+  {
+    DisableAllocationGuard g;
+    path p2(std::move(p));
+    assert(p2.native() == s);
+    assert(p.native() != s); // Testing moved from state
+  }
+}
diff --git a/libcxx/test/std/experimental/filesystem/class.path/path.member/path.construct/source.pass.cpp b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.construct/source.pass.cpp
new file mode 100644
index 0000000..d89e7c8
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.construct/source.pass.cpp
@@ -0,0 +1,83 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// class path
+
+// template <class Source>
+//      path(const Source& source);
+// template <class InputIterator>
+//      path(InputIterator first, InputIterator last);
+
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "min_allocator.h"
+#include "filesystem_test_helper.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+template <class CharT>
+void RunTestCase(MultiStringType const& MS) {
+  using namespace fs;
+  const char* Expect = MS;
+  const CharT* TestPath = MS;
+  const CharT* TestPathEnd = StrEnd(TestPath);
+  const std::size_t Size = TestPathEnd - TestPath;
+  const std::size_t SSize = StrEnd(Expect) - Expect;
+  assert(Size == SSize);
+  // StringTypes
+  {
+    const std::basic_string<CharT> S(TestPath);
+    path p(S);
+    assert(p.native() == Expect);
+    assert(p.string<CharT>() == TestPath);
+    assert(p.string<CharT>() == S);
+  }
+  // Char* pointers
+  {
+    path p(TestPath);
+    assert(p.native() == Expect);
+    assert(p.string<CharT>() == TestPath);
+  }
+  {
+    path p(TestPath, TestPathEnd);
+    assert(p.native() == Expect);
+    assert(p.string<CharT>() == TestPath);
+  }
+  // Iterators
+  {
+    using It = input_iterator<const CharT*>;
+    path p(It{TestPath});
+    assert(p.native() == Expect);
+    assert(p.string<CharT>() == TestPath);
+  }
+  {
+    using It = input_iterator<const CharT*>;
+    path p(It{TestPath}, It{TestPathEnd});
+    assert(p.native() == Expect);
+    assert(p.string<CharT>() == TestPath);
+  }
+}
+
+int main() {
+  for (auto const& MS : PathList) {
+    RunTestCase<char>(MS);
+    RunTestCase<wchar_t>(MS);
+    RunTestCase<char16_t>(MS);
+    RunTestCase<char32_t>(MS);
+  }
+}
diff --git a/libcxx/test/std/experimental/filesystem/class.path/path.member/path.decompose/path.decompose.pass.cpp b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.decompose/path.decompose.pass.cpp
new file mode 100644
index 0000000..4c83481a
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.decompose/path.decompose.pass.cpp
@@ -0,0 +1,198 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// class path
+
+// 8.4.9 path decomposition [path.decompose]
+//------------------------------------------
+// path root_name() const;
+// path root_directory() const;
+// path root_path() const;
+// path relative_path() const;
+// path parent_path() const;
+// path filename() const;
+// path stem() const;
+// path extension() const;
+//-------------------------------
+// 8.4.10 path query [path.query]
+//-------------------------------
+// bool empty() const noexcept;
+// bool has_root_path() const;
+// bool has_root_name() const;
+// bool has_root_directory() const;
+// bool has_relative_path() const;
+// bool has_parent_path() const;
+// bool has_filename() const;
+// bool has_stem() const;
+// bool has_extension() const;
+// bool is_absolute() const;
+// bool is_relative() const;
+//-------------------------------
+// 8.5 path iterators [path.itr]
+//-------------------------------
+// iterator begin() const;
+// iterator end() const;
+
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <vector>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+
+template <class It>
+std::reverse_iterator<It> mkRev(It it) {
+  return std::reverse_iterator<It>(it);
+}
+
+
+namespace fs = std::experimental::filesystem;
+struct PathDecomposeTestcase
+{
+    std::string raw;
+    std::vector<std::string> elements;
+    std::string root_path;
+    std::string root_name;
+    std::string root_directory;
+    std::string relative_path;
+    std::string parent_path;
+    std::string filename;
+};
+
+const PathDecomposeTestcase PathTestCases[] =
+  {
+      {"", {}, "", "", "", "", "", ""}
+    , {".", {"."}, "", "", "", ".", "", "."}
+    , {"..", {".."}, "", "", "", "..", "", ".."}
+    , {"foo", {"foo"}, "", "", "", "foo", "", "foo"}
+    , {"/", {"/"}, "/", "", "/", "", "", "/"}
+    , {"/foo", {"/", "foo"}, "/", "", "/", "foo", "/", "foo"}
+    , {"foo/", {"foo", "."}, "", "", "", "foo/", "foo", "."}
+    , {"/foo/", {"/", "foo", "."}, "/", "", "/", "foo/", "/foo", "."}
+    , {"foo/bar", {"foo","bar"}, "",  "", "",  "foo/bar", "foo", "bar"}
+    , {"/foo//bar", {"/","foo","bar"}, "/", "", "/", "foo/bar", "/foo", "bar"}
+    , {"//net", {"//net"}, "//net", "//net", "", "", "", "//net"}
+    , {"//net/foo", {"//net", "/", "foo"}, "//net/", "//net", "/", "foo", "//net/", "foo"}
+    , {"///foo///", {"/", "foo", "."}, "/", "", "/", "foo///", "///foo", "."}
+    , {"///foo///bar", {"/", "foo", "bar"}, "/", "", "/", "foo///bar", "///foo", "bar"}
+    , {"/.", {"/", "."}, "/", "", "/", ".", "/", "."}
+    , {"./", {".", "."}, "", "", "", "./", ".", "."}
+    , {"/..", {"/", ".."}, "/", "", "/", "..", "/", ".."}
+    , {"../", {"..", "."}, "", "", "", "../", "..", "."}
+    , {"foo/.", {"foo", "."}, "", "", "", "foo/.", "foo", "."}
+    , {"foo/..", {"foo", ".."}, "", "", "", "foo/..", "foo", ".."}
+    , {"foo/./", {"foo", ".", "."}, "", "", "", "foo/./", "foo/.", "."}
+    , {"foo/./bar", {"foo", ".", "bar"}, "", "", "", "foo/./bar", "foo/.", "bar"}
+    , {"foo/../", {"foo", "..", "."}, "", "", "", "foo/../", "foo/..", "."}
+    , {"foo/../bar", {"foo", "..", "bar"}, "", "", "", "foo/../bar", "foo/..", "bar"}
+    , {"c:", {"c:"}, "", "", "", "c:", "", "c:"}
+    , {"c:/", {"c:", "."}, "", "", "", "c:/", "c:", "."}
+    , {"c:foo", {"c:foo"}, "", "", "", "c:foo", "", "c:foo"}
+    , {"c:/foo", {"c:", "foo"}, "", "", "", "c:/foo", "c:", "foo"}
+    , {"c:foo/", {"c:foo", "."}, "", "", "", "c:foo/", "c:foo", "."}
+    , {"c:/foo/", {"c:", "foo", "."}, "", "", "", "c:/foo/",  "c:/foo", "."}
+    , {"c:/foo/bar", {"c:", "foo", "bar"}, "", "", "", "c:/foo/bar", "c:/foo", "bar"}
+    , {"prn:", {"prn:"}, "", "", "", "prn:", "", "prn:"}
+    , {"c:\\", {"c:\\"}, "", "", "", "c:\\", "", "c:\\"}
+    , {"c:\\foo", {"c:\\foo"}, "", "", "", "c:\\foo", "", "c:\\foo"}
+    , {"c:foo\\", {"c:foo\\"}, "", "", "", "c:foo\\", "", "c:foo\\"}
+    , {"c:\\foo\\", {"c:\\foo\\"}, "", "", "", "c:\\foo\\", "", "c:\\foo\\"}
+    , {"c:\\foo/",  {"c:\\foo", "."}, "", "", "", "c:\\foo/", "c:\\foo", "."}
+    , {"c:/foo\\bar", {"c:", "foo\\bar"}, "", "", "", "c:/foo\\bar", "c:", "foo\\bar"}
+    , {"//", {"//"}, "//", "//", "", "", "", "//"}
+  };
+
+void decompPathTest()
+{
+  using namespace fs;
+  for (auto const & TC : PathTestCases) {
+    path p(TC.raw);
+    assert(p == TC.raw);
+
+    assert(p.root_path() == TC.root_path);
+    assert(p.has_root_path() !=  TC.root_path.empty());
+
+    assert(p.root_name() == TC.root_name);
+    assert(p.has_root_name() !=  TC.root_name.empty());
+
+    assert(p.root_directory() == TC.root_directory);
+    assert(p.has_root_directory() !=  TC.root_directory.empty());
+
+    assert(p.relative_path() == TC.relative_path);
+    assert(p.has_relative_path() !=  TC.relative_path.empty());
+
+    assert(p.parent_path() == TC.parent_path);
+    assert(p.has_parent_path() !=  TC.parent_path.empty());
+
+    assert(p.filename() == TC.filename);
+    assert(p.has_filename() !=  TC.filename.empty());
+
+    assert(p.is_absolute() == p.has_root_directory());
+    assert(p.is_relative() !=  p.is_absolute());
+
+    assert(checkCollectionsEqual(p.begin(), p.end(),
+                                 TC.elements.begin(), TC.elements.end()));
+    // check backwards
+    assert(checkCollectionsEqual(mkRev(p.end()), mkRev(p.begin()),
+                                 TC.elements.rbegin(), TC.elements.rend()));
+  }
+}
+
+
+struct FilenameDecompTestcase
+{
+  std::string raw;
+  std::string filename;
+  std::string stem;
+  std::string extension;
+};
+
+const FilenameDecompTestcase FilenameTestCases[] =
+{
+    {"", "", "", ""}
+  , {".", ".", ".", ""}
+  , {"..", "..", "..", ""}
+  , {"/", "/", "/", ""}
+  , {"foo", "foo", "foo", ""}
+  , {"/foo/bar.txt", "bar.txt", "bar", ".txt"}
+  , {"foo..txt", "foo..txt", "foo.", ".txt"}
+};
+
+
+void decompFilenameTest()
+{
+  using namespace fs;
+  for (auto const & TC : FilenameTestCases) {
+    path p(TC.raw);
+    assert(p == TC.raw);
+
+    assert(p.filename() == TC.filename);
+    assert(p.has_filename() != TC.filename.empty());
+
+    assert(p.stem() == TC.stem);
+    assert(p.has_stem() != TC.stem.empty());
+
+    assert(p.extension() == TC.extension);
+    assert(p.has_extension() != TC.extension.empty());
+  }
+}
+
+int main()
+{
+  decompPathTest();
+  decompFilenameTest();
+}
diff --git a/libcxx/test/std/experimental/filesystem/class.path/path.member/path.generic.obs/generic_string_alloc.pass.cpp b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.generic.obs/generic_string_alloc.pass.cpp
new file mode 100644
index 0000000..47e94c9
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.generic.obs/generic_string_alloc.pass.cpp
@@ -0,0 +1,57 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// class path
+
+// template <class ECharT, class Traits = char_traits<ECharT>,
+//           class Allocator = allocator<ECharT>>
+// basic_string<ECharT, Traits, Allocator>
+// generic_string(const Allocator& a = Allocator()) const;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "min_allocator.h"
+#include "filesystem_test_helper.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+MultiStringType longString = MKSTR("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/123456789/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
+
+
+// generic_string<C, T, A> forwards to string<C, T, A>. Tests for
+// string<C, T, A>() are in "path.native.op/string_alloc.pass.cpp".
+// generic_string is minimally tested here.
+int main()
+{
+  using namespace fs;
+  using CharT = wchar_t;
+  using Traits = std::char_traits<CharT>;
+  using Alloc = malloc_allocator<CharT>;
+  using Str = std::basic_string<CharT, Traits, Alloc>;
+  const wchar_t* expect = longString;
+  const path p((const char*)longString);
+  {
+    DisableAllocationGuard g;
+    Alloc a;
+    Alloc::disable_default_constructor = true;
+    Str s = p.generic_string<wchar_t, Traits, Alloc>(a);
+    assert(s == expect);
+    assert(Alloc::alloc_count > 0);
+    assert(Alloc::outstanding_alloc() == 1);
+  }
+}
diff --git a/libcxx/test/std/experimental/filesystem/class.path/path.member/path.generic.obs/named_overloads.pass.cpp b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.generic.obs/named_overloads.pass.cpp
new file mode 100644
index 0000000..81d0684
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.generic.obs/named_overloads.pass.cpp
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// class path
+
+// std::string  generic_string() const;
+// std::wstring generic_wstring() const;
+// std::u8string  generic_u8string() const;
+// std::u16string generic_u16string() const;
+// std::u32string generic_u32string() const;
+
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "min_allocator.h"
+#include "filesystem_test_helper.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+MultiStringType longString = MKSTR("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/123456789/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
+
+int main()
+{
+  using namespace fs;
+  auto const& MS = longString;
+  const char* value = longString;
+  const path p(value);
+  {
+    std::string s = p.generic_string();
+    assert(s == value);
+  }
+  {
+    std::string s = p.generic_u8string();
+    assert(s == (const char*)MS);
+  }
+  {
+    std::wstring s = p.generic_wstring();
+    assert(s == (const wchar_t*)MS);
+  }
+  {
+    std::u16string s = p.generic_u16string();
+    assert(s == (const char16_t*)MS);
+  }
+  {
+    std::u32string s = p.generic_u32string();
+    assert(s == (const char32_t*)MS);
+  }
+}
diff --git a/libcxx/test/std/experimental/filesystem/class.path/path.member/path.modifiers/clear.pass.cpp b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.modifiers/clear.pass.cpp
new file mode 100644
index 0000000..5be9349
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.modifiers/clear.pass.cpp
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// class path
+
+// void clear() noexcept
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+int main() {
+  using namespace fs;
+  const path p("/foo/bar/baz");
+  {
+    path p;
+    ASSERT_NOEXCEPT(p.clear());
+    ASSERT_SAME_TYPE(void, decltype(p.clear()));
+    p.clear();
+    assert(p.empty());
+  }
+  {
+    path p2(p);
+    assert(p == p2);
+    p2.clear();
+    assert(p2.empty());
+  }
+}
diff --git a/libcxx/test/std/experimental/filesystem/class.path/path.member/path.modifiers/make_preferred.pass.cpp b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.modifiers/make_preferred.pass.cpp
new file mode 100644
index 0000000..559538c
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.modifiers/make_preferred.pass.cpp
@@ -0,0 +1,55 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// class path
+
+// path& make_preferred()
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+struct MakePreferredTestcase {
+  const char* value;
+};
+
+const MakePreferredTestcase TestCases[] =
+  {
+      {""}
+    , {"hello_world"}
+    , {"/"}
+    , {"/foo/bar/baz/"}
+    , {"\\"}
+    , {"\\foo\\bar\\baz\\"}
+    , {"\\foo\\/bar\\/baz\\"}
+  };
+
+int main()
+{
+  // This operation is an identity operation on linux.
+  using namespace fs;
+  for (auto const & TC : TestCases) {
+    path p(TC.value);
+    assert(p == TC.value);
+    path& Ref = (p.make_preferred());
+    assert(p.native() == TC.value);
+    assert(&Ref == &p);
+  }
+}
diff --git a/libcxx/test/std/experimental/filesystem/class.path/path.member/path.modifiers/remove_filename.pass.cpp b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.modifiers/remove_filename.pass.cpp
new file mode 100644
index 0000000..4ad9084
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.modifiers/remove_filename.pass.cpp
@@ -0,0 +1,72 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// class path
+
+// path& remove_filename()
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+struct RemoveFilenameTestcase {
+  const char* value;
+  const char* expect;
+};
+
+const RemoveFilenameTestcase TestCases[] =
+  {
+      {"", ""}
+    , {"/", ""}
+    , {"\\", ""}
+    , {".", ""}
+    , {"..", ""}
+    , {"/foo", "/"}
+    , {"/foo/", "/foo"}
+    , {"/foo/.", "/foo"}
+    , {"/foo/..", "/foo"}
+    , {"/foo/////", "/foo"}
+    , {"/foo\\\\", "/"}
+    , {"/foo//\\/", "/foo//\\"}
+    , {"file.txt", ""}
+    , {"bar/../baz/./file.txt", "bar/../baz/."}
+  };
+
+int main()
+{
+  using namespace fs;
+  for (auto const & TC : TestCases) {
+    path const p_orig(TC.value);
+    path p(p_orig);
+    assert(p == TC.value);
+    path& Ref = (p.remove_filename());
+    assert(p == TC.expect);
+    assert(&Ref == &p);
+    {
+      const path parentp = p_orig.parent_path();
+      if (parentp == p_orig.root_name()) {
+
+        assert(p.empty());
+      } else {
+        assert(p == parentp);
+      }
+    }
+  }
+}
diff --git a/libcxx/test/std/experimental/filesystem/class.path/path.member/path.modifiers/replace_extension.pass.cpp b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.modifiers/replace_extension.pass.cpp
new file mode 100644
index 0000000..3dd2184
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.modifiers/replace_extension.pass.cpp
@@ -0,0 +1,73 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// class path
+
+// path& replace_extension(path const& p = path())
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+struct ReplaceExtensionTestcase {
+  const char* value;
+  const char* expect;
+  const char* extension;
+};
+
+const ReplaceExtensionTestcase TestCases[] =
+  {
+      {"", "", ""}
+    , {"foo.cpp", "foo", ""}
+    , {"foo.cpp", "foo.", "."}
+    , {"foo..cpp", "foo..txt", "txt"}
+    , {"", ".txt", "txt"}
+    , {"", ".txt", ".txt"}
+    , {"/foo", "/foo.txt", ".txt"}
+    , {"/foo", "/foo.txt", "txt"}
+    , {"/foo.cpp", "/foo.txt", ".txt"}
+    , {"/foo.cpp", "/foo.txt", "txt"}
+  };
+const ReplaceExtensionTestcase NoArgCases[] =
+  {
+      {"", ""}
+    , {"foo", "foo"}
+    , {"foo.cpp", "foo"}
+    , {"foo..cpp", "foo."}
+};
+
+int main()
+{
+  using namespace fs;
+  for (auto const & TC : TestCases) {
+    path p(TC.value);
+    assert(p == TC.value);
+    path& Ref = (p.replace_extension(TC.extension));
+    assert(p == TC.expect);
+    assert(&Ref == &p);
+  }
+  for (auto const& TC : NoArgCases) {
+    path p(TC.value);
+    assert(p == TC.value);
+    path& Ref = (p.replace_extension());
+    assert(p == TC.expect);
+    assert(&Ref == &p);
+  }
+}
diff --git a/libcxx/test/std/experimental/filesystem/class.path/path.member/path.modifiers/replace_filename.pass.cpp b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.modifiers/replace_filename.pass.cpp
new file mode 100644
index 0000000..66c9721
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.modifiers/replace_filename.pass.cpp
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// class path
+
+// path& replace_filename()
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+struct ReplaceFilenameTestcase {
+  const char* value;
+  const char* expect;
+  const char* filename;
+};
+
+const ReplaceFilenameTestcase TestCases[] =
+  {
+      {"/foo", "/bar", "bar"}
+    , {"/foo", "/", ""}
+    , {"foo", "bar", "bar"}
+    , {"/", "bar", "bar"}
+    , {"\\", "bar", "bar"}
+    , {"///", "bar", "bar"}
+    , {"\\\\", "bar", "bar"}
+    , {"\\/\\", "\\/bar", "bar"}
+    , {".", "bar", "bar"}
+    , {"..", "bar", "bar"}
+    , {"/foo\\baz/bong/", "/foo\\baz/bong/bar", "bar"}
+    , {"/foo\\baz/bong", "/foo\\baz/bar", "bar"}
+  };
+
+int main()
+{
+  using namespace fs;
+  for (auto const & TC : TestCases) {
+    path p(TC.value);
+    assert(p == TC.value);
+    path& Ref = (p.replace_filename(TC.filename));
+    assert(p == TC.expect);
+    assert(&Ref == &p);
+    // Tests Effects "as-if": remove_filename() append(filename)
+    {
+      path p2(TC.value);
+      path replace(TC.filename);
+      p2.remove_filename();
+      p2 /= replace;
+      assert(p2 == p);
+    }
+  }
+}
diff --git a/libcxx/test/std/experimental/filesystem/class.path/path.member/path.modifiers/swap.pass.cpp b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.modifiers/swap.pass.cpp
new file mode 100644
index 0000000..04bbe37
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.modifiers/swap.pass.cpp
@@ -0,0 +1,81 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// class path
+
+// void swap(path& rhs) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+struct SwapTestcase {
+  const char* value1;
+  const char* value2;
+};
+
+#define LONG_STR1 "_THIS_IS_LONG_THIS_IS_LONG_THIS_IS_LONG_THIS_IS_LONG_THIS_IS_LONG_THIS_IS_LONG_THIS_IS_LONG"
+#define LONG_STR2 "_THIS_IS_LONG2_THIS_IS_LONG2_THIS_IS_LONG2_THIS_IS_LONG2_THIS_IS_LONG2_THIS_IS_LONG2_THIS_IS_LONG2"
+const SwapTestcase TestCases[] =
+  {
+      {"", ""}
+    , {"shortstr", LONG_STR1}
+    , {LONG_STR1, "shortstr"}
+    , {LONG_STR1, LONG_STR2}
+  };
+#undef LONG_STR1
+#undef LONG_STR2
+
+int main()
+{
+  using namespace fs;
+  {
+    path p;
+    ASSERT_NOEXCEPT(p.swap(p));
+    ASSERT_SAME_TYPE(void, decltype(p.swap(p)));
+  }
+  for (auto const & TC : TestCases) {
+    path p1(TC.value1);
+    path p2(TC.value2);
+    {
+      DisableAllocationGuard g;
+      p1.swap(p2);
+    }
+    assert(p1 == TC.value2);
+    assert(p2 == TC.value1);
+    {
+      DisableAllocationGuard g;
+      p1.swap(p2);
+    }
+    assert(p1 == TC.value1);
+    assert(p2 == TC.value2);
+  }
+  // self-swap
+  {
+    const char* Val = "aoeuaoeuaoeuaoeuaoeuaoeuaoeuaoeuaoeu";
+    path p1(Val);
+    assert(p1 == Val);
+    {
+      DisableAllocationGuard g;
+      p1.swap(p1);
+    }
+    assert(p1 == Val);
+  }
+}
diff --git a/libcxx/test/std/experimental/filesystem/class.path/path.member/path.native.obs/c_str.pass.cpp b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.native.obs/c_str.pass.cpp
new file mode 100644
index 0000000..7cf3564
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.native.obs/c_str.pass.cpp
@@ -0,0 +1,43 @@
+
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// class path
+
+// const value_type* c_str() const noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "filesystem_test_helper.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+int main()
+{
+  using namespace fs;
+  const char* const value = "hello world";
+  const std::string str_value = value;
+  path p(value);
+  { // Check signature
+    ASSERT_SAME_TYPE(path::value_type const*, decltype(p.c_str()));
+    ASSERT_NOEXCEPT(p.c_str());
+  }
+  {
+    path p(value);
+    assert(p.c_str() == str_value);
+    assert(p.native().c_str() == p.c_str());
+  }
+}
diff --git a/libcxx/test/std/experimental/filesystem/class.path/path.member/path.native.obs/named_overloads.pass.cpp b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.native.obs/named_overloads.pass.cpp
new file mode 100644
index 0000000..2a83fef
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.native.obs/named_overloads.pass.cpp
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// class path
+
+// std::string  string() const;
+// std::wstring wstring() const;
+// std::u8string  u8string() const;
+// std::u16string u16string() const;
+// std::u32string u32string() const;
+
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "min_allocator.h"
+#include "filesystem_test_helper.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+MultiStringType longString = MKSTR("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/123456789/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
+
+int main()
+{
+  using namespace fs;
+  auto const& MS = longString;
+  const char* value = longString;
+  const path p(value);
+  {
+    std::string s = p.string();
+    assert(s == value);
+  }
+  {
+    std::string s = p.u8string();
+    assert(s == (const char*)MS);
+  }
+  {
+    std::wstring s = p.wstring();
+    assert(s == (const wchar_t*)MS);
+  }
+  {
+    std::u16string s = p.u16string();
+    assert(s == (const char16_t*)MS);
+  }
+  {
+    std::u32string s = p.u32string();
+    assert(s == (const char32_t*)MS);
+  }
+}
diff --git a/libcxx/test/std/experimental/filesystem/class.path/path.member/path.native.obs/native.pass.cpp b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.native.obs/native.pass.cpp
new file mode 100644
index 0000000..7f8df27
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.native.obs/native.pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// class path
+
+// const string_type& native() const noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "filesystem_test_helper.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+int main()
+{
+  using namespace fs;
+  const char* const value = "hello world";
+  path p(value);
+  { // Check signature
+    ASSERT_SAME_TYPE(path::string_type const&, decltype(p.native()));
+    ASSERT_NOEXCEPT(p.native());
+  }
+  { // native() is tested elsewhere
+    path p(value);
+    assert(p.native() == value);
+  }
+}
diff --git a/libcxx/test/std/experimental/filesystem/class.path/path.member/path.native.obs/operator_string.pass.cpp b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.native.obs/operator_string.pass.cpp
new file mode 100644
index 0000000..9ef83f9
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.native.obs/operator_string.pass.cpp
@@ -0,0 +1,47 @@
+
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// class path
+
+// operator string_type() const;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "filesystem_test_helper.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+int main()
+{
+  using namespace fs;
+  using string_type = path::string_type;
+  const char* const value = "hello world";
+  path p(value);
+  { // Check signature
+    static_assert(std::is_convertible<path, string_type>::value, "");
+    static_assert(std::is_constructible<string_type, path>::value, "");
+    ASSERT_SAME_TYPE(string_type, decltype(p.operator string_type()));
+    ASSERT_NOT_NOEXCEPT(p.operator string_type());
+  }
+  {
+    path p(value);
+    assert(p.native() == value);
+    string_type s = p;
+    assert(s == value);
+    assert(p == value);
+  }
+}
diff --git a/libcxx/test/std/experimental/filesystem/class.path/path.member/path.native.obs/string_alloc.pass.cpp b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.native.obs/string_alloc.pass.cpp
new file mode 100644
index 0000000..e5fe896
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.native.obs/string_alloc.pass.cpp
@@ -0,0 +1,113 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// class path
+
+// template <class ECharT, class Traits = char_traits<ECharT>,
+//           class Allocator = allocator<ECharT>>
+// basic_string<ECharT, Traits, Allocator>
+// string(const Allocator& a = Allocator()) const;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "min_allocator.h"
+#include "filesystem_test_helper.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+MultiStringType shortString = MKSTR("abc");
+MultiStringType longString = MKSTR("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/123456789/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
+
+template <class CharT>
+void doShortStringTest(MultiStringType const& MS) {
+  using namespace fs;
+  using Ptr = CharT const*;
+  using Str = std::basic_string<CharT>;
+  using Alloc = std::allocator<CharT>;
+  Ptr value = MS;
+  const path p((const char*)MS);
+  {
+      DisableAllocationGuard g; // should not allocate
+      Str s = p.string<CharT>();
+      assert(s == value);
+      Str s2 = p.string<CharT>(Alloc{});
+      assert(s2 == value);
+  }
+}
+
+template <class CharT>
+void doLongStringTest(MultiStringType const& MS) {
+  using namespace fs;
+  using Ptr = CharT const*;
+  using Str = std::basic_string<CharT>;
+  Ptr value = MS;
+  const path p((const char*)MS);
+  { // Default allocator
+      using Alloc = std::allocator<CharT>;
+      RequireAllocationGuard g; // should not allocate because
+      Str s = p.string<CharT>();
+      assert(s == value);
+      Str s2 = p.string<CharT>(Alloc{});
+      assert(s2 == value);
+  }
+  using MAlloc = malloc_allocator<CharT>;
+  MAlloc::reset();
+  { // Other allocator - default construct
+      using Traits = std::char_traits<CharT>;
+      using AStr = std::basic_string<CharT, Traits, MAlloc>;
+      DisableAllocationGuard g;
+      AStr s = p.string<CharT, Traits, MAlloc>();
+      assert(s == value);
+      assert(MAlloc::alloc_count > 0);
+      assert(MAlloc::outstanding_alloc() == 1);
+  }
+  MAlloc::reset();
+  { // Other allocator - provided copy
+      using Traits = std::char_traits<CharT>;
+      using AStr = std::basic_string<CharT, Traits, MAlloc>;
+      DisableAllocationGuard g;
+      MAlloc a;
+      // don't allow another allocator to be default constructed.
+      MAlloc::disable_default_constructor = true;
+      AStr s = p.string<CharT, Traits, MAlloc>(a);
+      assert(s == value);
+      assert(MAlloc::alloc_count > 0);
+      assert(MAlloc::outstanding_alloc() == 1);
+  }
+  MAlloc::reset();
+  /////////////////////////////////////////////////////////////////////////////
+}
+
+int main()
+{
+  using namespace fs;
+  {
+    auto const& S = shortString;
+    doShortStringTest<char>(S);
+    doShortStringTest<wchar_t>(S);
+    doShortStringTest<char16_t>(S);
+    doShortStringTest<char32_t>(S);
+  }
+  {
+    auto const& S = longString;
+    doLongStringTest<char>(S);
+    doLongStringTest<wchar_t>(S);
+    doLongStringTest<char16_t>(S);
+    doLongStringTest<char32_t>(S);
+  }
+}
diff --git a/libcxx/test/std/experimental/filesystem/class.path/path.member/path.query/tested_in_path_decompose.pass.cpp b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.query/tested_in_path_decompose.pass.cpp
new file mode 100644
index 0000000..9cf37d4
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/class.path/path.member/path.query/tested_in_path_decompose.pass.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// class path
+
+//-------------------------------
+// 8.4.10 path query [path.query]
+//-------------------------------
+// bool empty() const noexcept;
+// bool has_root_path() const;
+// bool has_root_name() const;
+// bool has_root_directory() const;
+// bool has_relative_path() const;
+// bool has_parent_path() const;
+// bool has_filename() const;
+// bool has_stem() const;
+// bool has_extension() const;
+// bool is_absolute() const;
+// bool is_relative() const;
+
+// tested in path.decompose
+int main() {}
diff --git a/libcxx/test/std/experimental/filesystem/class.path/path.nonmember/append_op.pass.cpp b/libcxx/test/std/experimental/filesystem/class.path/path.nonmember/append_op.pass.cpp
new file mode 100644
index 0000000..5898377
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/class.path/path.nonmember/append_op.pass.cpp
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// path operator/(path const&, path const&);
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "filesystem_test_helper.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+// This is mainly tested via the member append functions.
+int main()
+{
+  using namespace fs;
+  path p1("abc");
+  path p2("def");
+  path p3 = p1 / p2;
+  assert(p3 == "abc/def");
+}
diff --git a/libcxx/test/std/experimental/filesystem/class.path/path.nonmember/comparison_ops_tested_elsewhere.pass.cpp b/libcxx/test/std/experimental/filesystem/class.path/path.nonmember/comparison_ops_tested_elsewhere.pass.cpp
new file mode 100644
index 0000000..2886743
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/class.path/path.nonmember/comparison_ops_tested_elsewhere.pass.cpp
@@ -0,0 +1,14 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// The comparison operators are tested as part of [path.compare]
+// in class.path/path.members/path.compare.pass.cpp
+int main() {}
diff --git a/libcxx/test/std/experimental/filesystem/class.path/path.nonmember/hash_value_tested_elswhere.pass.cpp b/libcxx/test/std/experimental/filesystem/class.path/path.nonmember/hash_value_tested_elswhere.pass.cpp
new file mode 100644
index 0000000..b03b800
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/class.path/path.nonmember/hash_value_tested_elswhere.pass.cpp
@@ -0,0 +1,14 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// The "hash_value" function is tested as part of [path.compare]
+// in class.path/path.members/path.compare.pass.cpp
+int main() {}
diff --git a/libcxx/test/std/experimental/filesystem/class.path/path.nonmember/path.factory.pass.cpp b/libcxx/test/std/experimental/filesystem/class.path/path.nonmember/path.factory.pass.cpp
new file mode 100644
index 0000000..4853994
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/class.path/path.nonmember/path.factory.pass.cpp
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// template <class Source>
+//    path u8path(Source const&);
+// template <class InputIter>
+//   path u8path(InputIter, InputIter);
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+int main()
+{
+  using namespace fs;
+  const char* In1 = "abcd/efg";
+  const std::string In2(In1);
+  const auto In3 = In2.begin();
+  const auto In3End = In2.end();
+  {
+    path p = fs::u8path(In1);
+    assert(p == In1);
+  }
+  {
+    path p = fs::u8path(In2);
+    assert(p == In1);
+  }
+  {
+    path p = fs::u8path(In3);
+    assert(p == In1);
+  }
+  {
+    path p = fs::u8path(In3, In3End);
+    assert(p == In1);
+  }
+}
diff --git a/libcxx/test/std/experimental/filesystem/class.path/path.nonmember/path.io.pass.cpp b/libcxx/test/std/experimental/filesystem/class.path/path.nonmember/path.io.pass.cpp
new file mode 100644
index 0000000..e8d150f
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/class.path/path.nonmember/path.io.pass.cpp
@@ -0,0 +1,66 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// class path
+
+// template <class charT, class traits>
+// basic_ostream<charT, traits>&
+// operator<<(basic_ostream<charT, traits>& os, const path& p);
+//
+// template <class charT, class traits>
+// basic_istream<charT, traits>&
+// operator>>(basic_istream<charT, traits>& is, path& p)
+//
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <sstream>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+
+MultiStringType InStr =  MKSTR("abcdefg/\"hijklmnop\"/qrstuvwxyz/123456789");
+MultiStringType OutStr = MKSTR("\"abcdefg/\\\"hijklmnop\\\"/qrstuvwxyz/123456789\"");
+
+template <class CharT>
+void doIOTest() {
+  using namespace fs;
+  using Ptr = const CharT*;
+  using StrStream = std::basic_stringstream<CharT>;
+  const char* const InCStr = InStr;
+  const Ptr E = OutStr;
+  const path p((const char*)InStr);
+  StrStream ss;
+  { // test output
+    auto& ret = (ss << p);
+    assert(ss.str() == E);
+    assert(&ret == &ss);
+  }
+  { // test input
+    path p_in;
+    auto& ret = ss >> p_in;
+    assert(p_in.native() == (const char*)InStr);
+    assert(&ret == &ss);
+  }
+}
+
+
+int main() {
+  doIOTest<char>();
+  doIOTest<wchar_t>();
+  //doIOTest<char16_t>();
+  //doIOTest<char32_t>();
+}
diff --git a/libcxx/test/std/experimental/filesystem/class.path/path.nonmember/path.io.unicode_bug.pass.cpp b/libcxx/test/std/experimental/filesystem/class.path/path.nonmember/path.io.unicode_bug.pass.cpp
new file mode 100644
index 0000000..3a9b48b
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/class.path/path.nonmember/path.io.unicode_bug.pass.cpp
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// class path
+
+// template <class charT, class traits>
+// basic_ostream<charT, traits>&
+// operator<<(basic_ostream<charT, traits>& os, const path& p);
+//
+// template <class charT, class traits>
+// basic_istream<charT, traits>&
+// operator>>(basic_istream<charT, traits>& is, path& p)
+//
+
+// TODO(EricWF) This test fails because "std::quoted" fails to compile
+// for char16_t and char32_t types. Combine with path.io.pass.cpp when this
+// passes.
+// XFAIL: *
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <sstream>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+
+MultiStringType InStr =  MKSTR("abcdefg/\"hijklmnop\"/qrstuvwxyz/123456789");
+MultiStringType OutStr = MKSTR("\"abcdefg/\\\"hijklmnop\\\"/qrstuvwxyz/123456789\"");
+
+template <class CharT>
+void doIOTest() {
+  using namespace fs;
+  using Ptr = const CharT*;
+  using StrStream = std::basic_stringstream<CharT>;
+  const char* const InCStr = InStr;
+  const Ptr E = OutStr;
+  const path p((const char*)InStr);
+  StrStream ss;
+  { // test output
+    auto& ret = (ss << p);
+    assert(ss.str() == E);
+    assert(&ret == &ss);
+  }
+  { // test input
+    path p_in;
+    auto& ret = ss >> p_in;
+    assert(p_in.native() == (const char*)InStr);
+    assert(&ret == &ss);
+  }
+}
+
+
+int main() {
+  doIOTest<char16_t>();
+  doIOTest<char32_t>();
+}
diff --git a/libcxx/test/std/experimental/filesystem/class.path/path.nonmember/swap.pass.cpp b/libcxx/test/std/experimental/filesystem/class.path/path.nonmember/swap.pass.cpp
new file mode 100644
index 0000000..8d18046
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/class.path/path.nonmember/swap.pass.cpp
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// void swap(path& lhs, path& rhs) noexcept;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "count_new.hpp"
+#include "filesystem_test_helper.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+// NOTE: this is tested in path.members/path.modifiers via the member swap.
+int main()
+{
+  using namespace fs;
+  const char* value1 = "foo/bar/baz";
+  const char* value2 = "_THIS_IS_LONG_THIS_IS_LONG_THIS_IS_LONG_THIS_IS_LONG_THIS_IS_LONG_THIS_IS_LONG_THIS_IS_LONG";
+  path p1(value1);
+  path p2(value2);
+  {
+    using namespace std; using namespace fs;
+    ASSERT_NOEXCEPT(swap(p1, p2));
+    ASSERT_SAME_TYPE(void, decltype(swap(p1, p2)));
+  }
+  {
+    DisableAllocationGuard g;
+    using namespace std;
+    using namespace fs;
+    swap(p1, p2);
+    assert(p1.native() == value2);
+    assert(p2.native() == value1);
+    swap(p1, p2);
+    assert(p1.native() == value1);
+    assert(p2.native() == value2);
+  }
+}
diff --git a/libcxx/test/std/experimental/filesystem/class.path/synop.pass.cpp b/libcxx/test/std/experimental/filesystem/class.path/synop.pass.cpp
new file mode 100644
index 0000000..b0a7b5c
--- /dev/null
+++ b/libcxx/test/std/experimental/filesystem/class.path/synop.pass.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <experimental/filesystem>
+
+// class path
+
+// typedef ... value_type;
+// typedef basic_string<value_type> string_type;
+// static constexpr value_type preferred_separator = ...;
+
+#include <experimental/filesystem>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+namespace fs = std::experimental::filesystem;
+
+int main() {
+  using namespace fs;
+  ASSERT_SAME_TYPE(path::value_type, char);
+  ASSERT_SAME_TYPE(path::string_type, std::basic_string<path::value_type>);
+  {
+    ASSERT_SAME_TYPE(const path::value_type, decltype(path::preferred_separator));
+    static_assert(path::preferred_separator == '/', "");
+    // Make preferred_separator ODR used by taking it's address.
+    const char* dummy = &path::preferred_separator;
+    ((void)dummy);
+  }
+}