1 //===----------------------------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 // UNSUPPORTED: c++98, c++03 11 12 // <filesystem> 13 14 // class path 15 16 // int compare(path const&) const noexcept; 17 // int compare(string_type const&) const; 18 // int compare(value_type const*) const; 19 // 20 // bool operator==(path const&, path const&) noexcept; 21 // bool operator!=(path const&, path const&) noexcept; 22 // bool operator< (path const&, path const&) noexcept; 23 // bool operator<=(path const&, path const&) noexcept; 24 // bool operator> (path const&, path const&) noexcept; 25 // bool operator>=(path const&, path const&) noexcept; 26 // 27 // size_t hash_value(path const&) noexcept; 28 29 30 #include "filesystem_include.hpp" 31 #include <type_traits> 32 #include <vector> 33 #include <cassert> 34 35 #include "test_macros.h" 36 #include "test_iterators.h" 37 #include "count_new.hpp" 38 #include "filesystem_test_helper.hpp" 39 #include "verbose_assert.h" 40 41 struct PathCompareTest { 42 const char* LHS; 43 const char* RHS; 44 int expect; 45 }; 46 47 #define LONGA "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" 48 #define LONGB "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" 49 #define LONGC "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC" 50 #define LONGD "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" 51 const PathCompareTest CompareTestCases[] = 52 { 53 {"", "", 0}, 54 {"a", "", 1}, 55 {"", "a", -1}, 56 {"a/b/c", "a/b/c", 0}, 57 {"b/a/c", "a/b/c", 1}, 58 {"a/b/c", "b/a/c", -1}, 59 {"a/b", "a/b/c", -1}, 60 {"a/b/c", "a/b", 1}, 61 {"a/b/", "a/b/.", -1}, 62 {"a/b/", "a/b", 1}, 63 {"a/b//////", "a/b/////.", -1}, 64 {"a/.././b", "a///..//.////b", 0}, 65 {"//foo//bar///baz////", "//foo/bar/baz/", 0}, // duplicate separators 66 {"///foo/bar", "/foo/bar", 0}, // "///" is not a root directory 67 {"/foo/bar/", "/foo/bar", 1}, // trailing separator 68 {"//" LONGA "////" LONGB "/" LONGC "///" LONGD, "//" LONGA "/" LONGB "/" LONGC "/" LONGD, 0}, 69 { LONGA "/" LONGB "/" LONGC, LONGA "/" LONGB "/" LONGB, 1} 70 71 }; 72 #undef LONGA 73 #undef LONGB 74 #undef LONGC 75 #undef LONGD 76 77 static inline int normalize_ret(int ret) 78 { 79 return ret < 0 ? -1 : (ret > 0 ? 1 : 0); 80 } 81 82 int main() 83 { 84 using namespace fs; 85 for (auto const & TC : CompareTestCases) { 86 const path p1(TC.LHS); 87 const path p2(TC.RHS); 88 const std::string R(TC.RHS); 89 const std::string_view RV(TC.RHS); 90 const int E = TC.expect; 91 { // compare(...) functions 92 DisableAllocationGuard g; // none of these operations should allocate 93 94 // check runtime results 95 int ret1 = normalize_ret(p1.compare(p2)); 96 int ret2 = normalize_ret(p1.compare(R)); 97 int ret3 = normalize_ret(p1.compare(TC.RHS)); 98 int ret4 = normalize_ret(p1.compare(RV)); 99 100 g.release(); 101 ASSERT_EQ(ret1, ret2); 102 ASSERT_EQ(ret1, ret3); 103 ASSERT_EQ(ret1, ret4); 104 ASSERT_EQ(ret1, E) 105 << DISPLAY(TC.LHS) << DISPLAY(TC.RHS); 106 107 // check signatures 108 ASSERT_NOEXCEPT(p1.compare(p2)); 109 } 110 { // comparison operators 111 DisableAllocationGuard g; // none of these operations should allocate 112 113 // Check runtime result 114 assert((p1 == p2) == (E == 0)); 115 assert((p1 != p2) == (E != 0)); 116 assert((p1 < p2) == (E < 0)); 117 assert((p1 <= p2) == (E <= 0)); 118 assert((p1 > p2) == (E > 0)); 119 assert((p1 >= p2) == (E >= 0)); 120 121 // Check signatures 122 ASSERT_NOEXCEPT(p1 == p2); 123 ASSERT_NOEXCEPT(p1 != p2); 124 ASSERT_NOEXCEPT(p1 < p2); 125 ASSERT_NOEXCEPT(p1 <= p2); 126 ASSERT_NOEXCEPT(p1 > p2); 127 ASSERT_NOEXCEPT(p1 >= p2); 128 } 129 { // check hash values 130 auto h1 = hash_value(p1); 131 auto h2 = hash_value(p2); 132 assert((h1 == h2) == (p1 == p2)); 133 // check signature 134 ASSERT_SAME_TYPE(size_t, decltype(hash_value(p1))); 135 ASSERT_NOEXCEPT(hash_value(p1)); 136 } 137 } 138 } 139