diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2017-01-02 19:18:58 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2017-01-02 19:18:58 +0000 |
| commit | 53a420fba21cf1644972b34dcd811a43cdb8368d (patch) | |
| tree | 66a19f6f8b65215772549a51d688492ab8addc0d /test/std/experimental/filesystem/class.path | |
| parent | b50f1549701eb950921e5d6f2e55ba1a1dadbb43 (diff) | |
Notes
Diffstat (limited to 'test/std/experimental/filesystem/class.path')
11 files changed, 331 insertions, 13 deletions
diff --git a/test/std/experimental/filesystem/class.path/path.member/path.append.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.append.pass.cpp index 1118497e06a8..f344e1153071 100644 --- a/test/std/experimental/filesystem/class.path/path.member/path.append.pass.cpp +++ b/test/std/experimental/filesystem/class.path/path.member/path.append.pass.cpp @@ -24,6 +24,7 @@ #include <experimental/filesystem> #include <type_traits> +#include <string_view> #include <cassert> #include "test_macros.h" @@ -77,6 +78,7 @@ void doAppendSourceAllocTest(AppendOperatorTestcase const& TC) using namespace fs; using Ptr = CharT const*; using Str = std::basic_string<CharT>; + using StrView = std::basic_string_view<CharT>; using InputIter = input_iterator<Ptr>; const Ptr L = TC.lhs; @@ -99,6 +101,16 @@ void doAppendSourceAllocTest(AppendOperatorTestcase const& TC) } assert(LHS == E); } + // basic_string_view + { + path LHS(L); PathReserve(LHS, ReserveSize); + StrView RHS(R); + { + DisableAllocationGuard g; + LHS /= RHS; + } + assert(LHS == E); + } // CharT* { path LHS(L); PathReserve(LHS, ReserveSize); @@ -153,6 +165,7 @@ void doAppendSourceTest(AppendOperatorTestcase const& TC) using namespace fs; using Ptr = CharT const*; using Str = std::basic_string<CharT>; + using StrView = std::basic_string_view<CharT>; using InputIter = input_iterator<Ptr>; const Ptr L = TC.lhs; const Ptr R = TC.rhs; @@ -172,6 +185,21 @@ void doAppendSourceTest(AppendOperatorTestcase const& TC) assert(LHS == E); assert(&Ref == &LHS); } + // basic_string_view + { + path LHS(L); + StrView RHS(R); + path& Ref = (LHS /= RHS); + assert(LHS == E); + assert(&Ref == &LHS); + } + { + path LHS(L); + StrView RHS(R); + path& Ref = LHS.append(RHS); + assert(LHS == E); + assert(&Ref == &LHS); + } // Char* { path LHS(L); @@ -218,6 +246,60 @@ void doAppendSourceTest(AppendOperatorTestcase const& TC) } } + + +template <class It, class = decltype(fs::path{}.append(std::declval<It>()))> +constexpr bool has_append(int) { return true; } +template <class It> +constexpr bool has_append(long) { return false; } + +template <class It, class = decltype(fs::path{}.operator/=(std::declval<It>()))> +constexpr bool has_append_op(int) { return true; } +template <class It> +constexpr bool has_append_op(long) { return false; } + +template <class It> +constexpr bool has_append() { + static_assert(has_append<It>(0) == has_append_op<It>(0), "must be same"); + return has_append<It>(0) && has_append_op<It>(0); +} + +void test_sfinae() +{ + using namespace fs; + { + using It = const char* const; + static_assert(has_append<It>(), ""); + } + { + using It = input_iterator<const char*>; + static_assert(has_append<It>(), ""); + } + { + struct Traits { + using iterator_category = std::input_iterator_tag; + using value_type = const char; + using pointer = const char*; + using reference = const char&; + using difference_type = std::ptrdiff_t; + }; + using It = input_iterator<const char*, Traits>; + static_assert(has_append<It>(), ""); + } + { + using It = output_iterator<const char*>; + static_assert(!has_append<It>(), ""); + + } + { + static_assert(!has_append<int*>(), ""); + } + { + static_assert(!has_append<char>(), ""); + static_assert(!has_append<const char>(), ""); + } +} + int main() { using namespace fs; @@ -238,4 +320,5 @@ int main() doAppendSourceAllocTest<char>(TC); doAppendSourceAllocTest<wchar_t>(TC); } + test_sfinae(); } diff --git a/test/std/experimental/filesystem/class.path/path.member/path.assign/source.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.assign/source.pass.cpp index 4c2d5112d10b..9e48cbf1e7f2 100644 --- a/test/std/experimental/filesystem/class.path/path.member/path.assign/source.pass.cpp +++ b/test/std/experimental/filesystem/class.path/path.member/path.assign/source.pass.cpp @@ -23,6 +23,7 @@ #include <experimental/filesystem> #include <type_traits> +#include <string_view> #include <cassert> #include "test_macros.h" @@ -69,6 +70,32 @@ void RunTestCase(MultiStringType const& MS) { assert(p.string<CharT>() == TestPath); assert(p.string<CharT>() == S); } + // basic_string<Char, Traits, Alloc> + { + const std::basic_string_view<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_view<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 { @@ -143,6 +170,49 @@ void RunTestCase(MultiStringType const& MS) { } } +template <class It, class = decltype(fs::path{}.assign(std::declval<It>()))> +constexpr bool has_assign(int) { return true; } +template <class It> +constexpr bool has_assign(long) { return false; } +template <class It> +constexpr bool has_assign() { return has_assign<It>(0); } + +void test_sfinae() { + using namespace fs; + { + using It = const char* const; + static_assert(std::is_assignable<path, It>::value, ""); + static_assert(has_assign<It>(), ""); + } + { + using It = input_iterator<const char*>; + static_assert(std::is_assignable<path, It>::value, ""); + static_assert(has_assign<It>(), ""); + } + { + struct Traits { + using iterator_category = std::input_iterator_tag; + using value_type = const char; + using pointer = const char*; + using reference = const char&; + using difference_type = std::ptrdiff_t; + }; + using It = input_iterator<const char*, Traits>; + static_assert(std::is_assignable<path, It>::value, ""); + static_assert(has_assign<It>(), ""); + } + { + using It = output_iterator<const char*>; + static_assert(!std::is_assignable<path, It>::value, ""); + static_assert(!has_assign<It>(), ""); + + } + { + static_assert(!std::is_assignable<path, int*>::value, ""); + static_assert(!has_assign<int*>(), ""); + } +} + int main() { for (auto const& MS : PathList) { RunTestCase<char>(MS); @@ -150,4 +220,5 @@ int main() { RunTestCase<char16_t>(MS); RunTestCase<char32_t>(MS); } + test_sfinae(); } diff --git a/test/std/experimental/filesystem/class.path/path.member/path.compare.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.compare.pass.cpp index 557c1b24d88f..69d08e6eb49a 100644 --- a/test/std/experimental/filesystem/class.path/path.member/path.compare.pass.cpp +++ b/test/std/experimental/filesystem/class.path/path.member/path.compare.pass.cpp @@ -73,6 +73,11 @@ const PathCompareTest CompareTestCases[] = #undef LONGC #undef LONGD +static inline int normalize_ret(int ret) +{ + return ret < 0 ? -1 : (ret > 0 ? 1 : 0); +} + int main() { using namespace fs; @@ -80,17 +85,18 @@ int main() const path p1(TC.LHS); const path p2(TC.RHS); const std::string R(TC.RHS); + const std::string_view RV(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); + int ret1 = normalize_ret(p1.compare(p2)); + int ret2 = normalize_ret(p1.compare(R)); + int ret3 = normalize_ret(p1.compare(TC.RHS)); + int ret4 = normalize_ret(p1.compare(RV)); + assert(ret1 == ret2 && ret1 == ret3 && ret1 == ret4); + assert(ret1 == E); // check signatures ASSERT_NOEXCEPT(p1.compare(p2)); diff --git a/test/std/experimental/filesystem/class.path/path.member/path.concat.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.concat.pass.cpp index 6e00afe0b49c..89269362d06f 100644 --- a/test/std/experimental/filesystem/class.path/path.member/path.concat.pass.cpp +++ b/test/std/experimental/filesystem/class.path/path.member/path.concat.pass.cpp @@ -14,8 +14,9 @@ // 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+=(const string_type& x); +// path& operator+=(string_view x); +// path& operator+=(const value_type* x); // path& operator+=(value_type x); // template <class Source> // path& operator+=(const Source& x); @@ -29,6 +30,8 @@ #include <experimental/filesystem> #include <type_traits> +#include <string> +#include <string_view> #include <cassert> #include "test_macros.h" @@ -82,6 +85,7 @@ void doConcatSourceAllocTest(ConcatOperatorTestcase const& TC) using namespace fs; using Ptr = CharT const*; using Str = std::basic_string<CharT>; + using StrView = std::basic_string_view<CharT>; using InputIter = input_iterator<Ptr>; const Ptr L = TC.lhs; @@ -98,6 +102,16 @@ void doConcatSourceAllocTest(ConcatOperatorTestcase const& TC) } assert(LHS == E); } + // basic_string_view + { + path LHS(L); PathReserve(LHS, ReserveSize); + StrView RHS(R); + { + DisableAllocationGuard g; + LHS += RHS; + } + assert(LHS == E); + } // CharT* { path LHS(L); PathReserve(LHS, ReserveSize); @@ -152,6 +166,7 @@ void doConcatSourceTest(ConcatOperatorTestcase const& TC) using namespace fs; using Ptr = CharT const*; using Str = std::basic_string<CharT>; + using StrView = std::basic_string_view<CharT>; using InputIter = input_iterator<Ptr>; const Ptr L = TC.lhs; const Ptr R = TC.rhs; @@ -171,6 +186,21 @@ void doConcatSourceTest(ConcatOperatorTestcase const& TC) assert(LHS == E); assert(&Ref == &LHS); } + // basic_string_view + { + path LHS(L); + StrView RHS(R); + path& Ref = (LHS += RHS); + assert(LHS == E); + assert(&Ref == &LHS); + } + { + path LHS(L); + StrView RHS(R); + path& Ref = LHS.concat(RHS); + assert(LHS == E); + assert(&Ref == &LHS); + } // Char* { path LHS(L); @@ -235,6 +265,68 @@ void doConcatECharTest(ConcatOperatorTestcase const& TC) } } + +template <class It, class = decltype(fs::path{}.concat(std::declval<It>()))> +constexpr bool has_concat(int) { return true; } +template <class It> +constexpr bool has_concat(long) { return false; } + +template <class It, class = decltype(fs::path{}.operator+=(std::declval<It>()))> +constexpr bool has_concat_op(int) { return true; } +template <class It> +constexpr bool has_concat_op(long) { return false; } +template <class It> +constexpr bool has_concat_op() { return has_concat_op<It>(0); } + +template <class It> +constexpr bool has_concat() { + static_assert(has_concat<It>(0) == has_concat_op<It>(0), "must be same"); + return has_concat<It>(0) && has_concat_op<It>(0); +} + +void test_sfinae() { + using namespace fs; + { + static_assert(has_concat_op<char>(), ""); + static_assert(has_concat_op<const char>(), ""); + static_assert(has_concat_op<char16_t>(), ""); + static_assert(has_concat_op<const char16_t>(), ""); + } + { + using It = const char* const; + static_assert(has_concat<It>(), ""); + } + { + using It = input_iterator<const char*>; + static_assert(has_concat<It>(), ""); + } + { + struct Traits { + using iterator_category = std::input_iterator_tag; + using value_type = const char; + using pointer = const char*; + using reference = const char&; + using difference_type = std::ptrdiff_t; + }; + using It = input_iterator<const char*, Traits>; + static_assert(has_concat<It>(), ""); + } + { + using It = output_iterator<const char*>; + static_assert(!has_concat<It>(), ""); + } + { + static_assert(!has_concat<int>(0), ""); + // operator+=(int) is well formed since it converts to operator+=(value_type) + // but concat(int) isn't valid because there is no concat(value_type). + // This should probably be addressed by a LWG issue. + static_assert(has_concat_op<int>(), ""); + } + { + static_assert(!has_concat<int*>(), ""); + } +} + int main() { using namespace fs; @@ -246,6 +338,13 @@ int main() assert(LHS == (const char*)TC.expect); assert(&Ref == &LHS); } + { + path LHS((const char*)TC.lhs); + std::string_view 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); @@ -265,6 +364,18 @@ int main() } assert(LHS == E); } + { + path LHS((const char*)TC.lhs); + std::string_view 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); } @@ -274,4 +385,5 @@ int main() doConcatECharTest<char16_t>(TC); doConcatECharTest<char32_t>(TC); } + test_sfinae(); } diff --git a/test/std/experimental/filesystem/class.path/path.member/path.construct/source.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.construct/source.pass.cpp index d89e7c815efb..a04f35af5780 100644 --- a/test/std/experimental/filesystem/class.path/path.member/path.construct/source.pass.cpp +++ b/test/std/experimental/filesystem/class.path/path.member/path.construct/source.pass.cpp @@ -47,6 +47,13 @@ void RunTestCase(MultiStringType const& MS) { assert(p.string<CharT>() == TestPath); assert(p.string<CharT>() == S); } + { + const std::basic_string_view<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); @@ -73,6 +80,37 @@ void RunTestCase(MultiStringType const& MS) { } } +void test_sfinae() { + using namespace fs; + { + using It = const char* const; + static_assert(std::is_constructible<path, It>::value, ""); + } + { + using It = input_iterator<const char*>; + static_assert(std::is_constructible<path, It>::value, ""); + } + { + struct Traits { + using iterator_category = std::input_iterator_tag; + using value_type = const char; + using pointer = const char*; + using reference = const char&; + using difference_type = std::ptrdiff_t; + }; + using It = input_iterator<const char*, Traits>; + static_assert(std::is_constructible<path, It>::value, ""); + } + { + using It = output_iterator<const char*>; + static_assert(!std::is_constructible<path, It>::value, ""); + + } + { + static_assert(!std::is_constructible<path, int*>::value, ""); + } +} + int main() { for (auto const& MS : PathList) { RunTestCase<char>(MS); @@ -80,4 +118,5 @@ int main() { RunTestCase<char16_t>(MS); RunTestCase<char32_t>(MS); } + test_sfinae(); } diff --git a/test/std/experimental/filesystem/class.path/path.member/path.modifiers/clear.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.modifiers/clear.pass.cpp index 5be934968c46..7881c9700d6e 100644 --- a/test/std/experimental/filesystem/class.path/path.member/path.modifiers/clear.pass.cpp +++ b/test/std/experimental/filesystem/class.path/path.member/path.modifiers/clear.pass.cpp @@ -28,7 +28,6 @@ namespace fs = std::experimental::filesystem; int main() { using namespace fs; - const path p("/foo/bar/baz"); { path p; ASSERT_NOEXCEPT(p.clear()); @@ -37,6 +36,7 @@ int main() { assert(p.empty()); } { + const path p("/foo/bar/baz"); path p2(p); assert(p == p2); p2.clear(); diff --git a/test/std/experimental/filesystem/class.path/path.member/path.modifiers/remove_filename.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.modifiers/remove_filename.pass.cpp index 4ad9084dbf81..e414202bf8ff 100644 --- a/test/std/experimental/filesystem/class.path/path.member/path.modifiers/remove_filename.pass.cpp +++ b/test/std/experimental/filesystem/class.path/path.member/path.modifiers/remove_filename.pass.cpp @@ -35,16 +35,24 @@ const RemoveFilenameTestcase TestCases[] = { {"", ""} , {"/", ""} + , {"//", ""} + , {"///", ""} , {"\\", ""} , {".", ""} , {"..", ""} , {"/foo", "/"} + , {"//foo", ""} + , {"//foo/", ""} + , {"//foo///", ""} + , {"///foo", "/"} + , {"///foo/", "///foo"} , {"/foo/", "/foo"} , {"/foo/.", "/foo"} , {"/foo/..", "/foo"} , {"/foo/////", "/foo"} , {"/foo\\\\", "/"} , {"/foo//\\/", "/foo//\\"} + , {"///foo", "/"} , {"file.txt", ""} , {"bar/../baz/./file.txt", "bar/../baz/."} }; diff --git a/test/std/experimental/filesystem/class.path/path.member/path.native.obs/c_str.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.native.obs/c_str.pass.cpp index 7cf3564bb9b1..796609432727 100644 --- a/test/std/experimental/filesystem/class.path/path.member/path.native.obs/c_str.pass.cpp +++ b/test/std/experimental/filesystem/class.path/path.member/path.native.obs/c_str.pass.cpp @@ -30,8 +30,8 @@ int main() using namespace fs; const char* const value = "hello world"; const std::string str_value = value; - path p(value); { // Check signature + path p(value); ASSERT_SAME_TYPE(path::value_type const*, decltype(p.c_str())); ASSERT_NOEXCEPT(p.c_str()); } diff --git a/test/std/experimental/filesystem/class.path/path.member/path.native.obs/native.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.native.obs/native.pass.cpp index 7f8df27faf0a..db1326483776 100644 --- a/test/std/experimental/filesystem/class.path/path.member/path.native.obs/native.pass.cpp +++ b/test/std/experimental/filesystem/class.path/path.member/path.native.obs/native.pass.cpp @@ -28,8 +28,8 @@ int main() { using namespace fs; const char* const value = "hello world"; - path p(value); { // Check signature + path p(value); ASSERT_SAME_TYPE(path::string_type const&, decltype(p.native())); ASSERT_NOEXCEPT(p.native()); } diff --git a/test/std/experimental/filesystem/class.path/path.member/path.native.obs/operator_string.pass.cpp b/test/std/experimental/filesystem/class.path/path.member/path.native.obs/operator_string.pass.cpp index 9ef83f989aa5..013d26cdb7f6 100644 --- a/test/std/experimental/filesystem/class.path/path.member/path.native.obs/operator_string.pass.cpp +++ b/test/std/experimental/filesystem/class.path/path.member/path.native.obs/operator_string.pass.cpp @@ -30,8 +30,8 @@ int main() using namespace fs; using string_type = path::string_type; const char* const value = "hello world"; - path p(value); { // Check signature + path p(value); 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())); diff --git a/test/std/experimental/filesystem/class.path/path.nonmember/path.io.pass.cpp b/test/std/experimental/filesystem/class.path/path.nonmember/path.io.pass.cpp index e8d150f1e39d..4b7ad735c7f8 100644 --- a/test/std/experimental/filesystem/class.path/path.nonmember/path.io.pass.cpp +++ b/test/std/experimental/filesystem/class.path/path.nonmember/path.io.pass.cpp @@ -40,7 +40,6 @@ 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; |
