path.compare.pass.cpp revision 2645dbe87f85bd563a623cf36e2c1917b3c45117
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// <experimental/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#include <experimental/filesystem>
30#include <type_traits>
31#include <vector>
32#include <cassert>
33
34#include "test_macros.h"
35#include "test_iterators.h"
36#include "count_new.hpp"
37#include "filesystem_test_helper.hpp"
38
39namespace fs = std::experimental::filesystem;
40
41struct 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"
51const 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/.", 0},
62    {"a/b//////", "a/b/////.", 0},
63    {"a/.././b", "a///..//.////b", 0},
64    {"//foo//bar///baz////", "//foo/bar/baz/", 0}, // duplicate separators
65    {"///foo/bar", "/foo/bar", 0}, // "///" is not a root directory
66    {"/foo/bar/", "/foo/bar", 1}, // trailing separator
67    {"//" LONGA "////" LONGB "/" LONGC "///" LONGD, "//" LONGA "/" LONGB "/" LONGC "/" LONGD, 0},
68    { LONGA "/" LONGB "/" LONGC, LONGA "/" LONGB "/" LONGB, 1}
69
70};
71#undef LONGA
72#undef LONGB
73#undef LONGC
74#undef LONGD
75
76int main()
77{
78  using namespace fs;
79  for (auto const & TC : CompareTestCases) {
80    const path p1(TC.LHS);
81    const path p2(TC.RHS);
82    const std::string R(TC.RHS);
83    const std::string_view RV(TC.RHS);
84    const int E = TC.expect;
85    { // compare(...) functions
86      DisableAllocationGuard g; // none of these operations should allocate
87
88      // check runtime results
89      int ret1 = p1.compare(p2);
90      int ret2 = p1.compare(R);
91      int ret3 = p1.compare(TC.RHS);
92      int ret4 = p1.compare(RV);
93      assert(ret1 == ret2 && ret1 == ret3 && ret1 == ret4);
94      int normalized_ret = ret1 < 0 ? -1 : (ret1 > 0 ? 1 : 0);
95      assert(normalized_ret == E);
96
97      // check signatures
98      ASSERT_NOEXCEPT(p1.compare(p2));
99    }
100    { // comparison operators
101      DisableAllocationGuard g; // none of these operations should allocate
102
103      // Check runtime result
104      assert((p1 == p2) == (E == 0));
105      assert((p1 != p2) == (E != 0));
106      assert((p1 <  p2) == (E <  0));
107      assert((p1 <= p2) == (E <= 0));
108      assert((p1 >  p2) == (E >  0));
109      assert((p1 >= p2) == (E >= 0));
110
111      // Check signatures
112      ASSERT_NOEXCEPT(p1 == p2);
113      ASSERT_NOEXCEPT(p1 != p2);
114      ASSERT_NOEXCEPT(p1 <  p2);
115      ASSERT_NOEXCEPT(p1 <= p2);
116      ASSERT_NOEXCEPT(p1 >  p2);
117      ASSERT_NOEXCEPT(p1 >= p2);
118    }
119    { // check hash values
120      auto h1 = hash_value(p1);
121      auto h2 = hash_value(p2);
122      assert((h1 == h2) == (p1 == p2));
123      // check signature
124      ASSERT_SAME_TYPE(size_t, decltype(hash_value(p1)));
125      ASSERT_NOEXCEPT(hash_value(p1));
126    }
127  }
128}
129