diff options
author | Eric Fiselier <eric@efcs.ca> | 2016-06-17 19:46:40 +0000 |
---|---|---|
committer | Eric Fiselier <eric@efcs.ca> | 2016-06-17 19:46:40 +0000 |
commit | c79795874adef276115f8bcf0b46da4155d2d46d (patch) | |
tree | 3c58305df7b6b28f1626e65f704ca3aba480be3a /libcxx/test/std/experimental/filesystem/class.path | |
parent | 7a5813597dad665e4461372edbc3a6ea8e8cb8f0 (diff) | |
download | bcm5719-llvm-c79795874adef276115f8bcf0b46da4155d2d46d.tar.gz bcm5719-llvm-c79795874adef276115f8bcf0b46da4155d2d46d.zip |
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
Diffstat (limited to 'libcxx/test/std/experimental/filesystem/class.path')
34 files changed, 2560 insertions, 0 deletions
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 00000000000..4aa8ebc25d5 --- /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 00000000000..1118497e06a --- /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 00000000000..5c26f8464c1 --- /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 00000000000..7263424ad25 --- /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 00000000000..4c2d5112d10 --- /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 00000000000..557c1b24d88 --- /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 00000000000..6e00afe0b49 --- /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 00000000000..67b8a04049e --- /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 00000000000..f26504616d5 --- /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 00000000000..b8ac4b30700 --- /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 00000000000..d89e7c815ef --- /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 00000000000..4c83481aaf2 --- /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 00000000000..47e94c9a213 --- /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 00000000000..81d06843640 --- /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 00000000000..5be934968c4 --- /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 00000000000..559538cf0ec --- /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 00000000000..4ad9084dbf8 --- /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 00000000000..3dd218411c0 --- /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 00000000000..66c97218c83 --- /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 00000000000..04bbe3751a5 --- /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 00000000000..7cf3564bb9b --- /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 00000000000..2a83fef9f9e --- /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 00000000000..7f8df27faf0 --- /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 00000000000..9ef83f989aa --- /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 00000000000..e5fe89670bd --- /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 00000000000..9cf37d4cd53 --- /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 00000000000..58983778446 --- /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 00000000000..28867432c61 --- /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 00000000000..b03b8008b62 --- /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 00000000000..4853994b495 --- /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 00000000000..e8d150f1e39 --- /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 00000000000..3a9b48b2669 --- /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 00000000000..8d180463a57 --- /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 00000000000..b0a7b5cd65e --- /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); + } +} |