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