libcxx

libcxx mirror with random patches
git clone https://git.neptards.moe/neptards/libcxx.git
Log | Files | Refs

path.compare.pass.cpp (5953B)


      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     {"foo", "/foo", -1}, // if !this->has_root_directory() and p.has_root_directory(), a value less than 0.
     69     {"/foo", "foo", 1}, //  if this->has_root_directory() and !p.has_root_directory(), a value greater than 0.
     70     {"//" LONGA "////" LONGB "/" LONGC "///" LONGD, "//" LONGA "/" LONGB "/" LONGC "/" LONGD, 0},
     71     { LONGA "/" LONGB "/" LONGC, LONGA "/" LONGB "/" LONGB, 1}
     72 
     73 };
     74 #undef LONGA
     75 #undef LONGB
     76 #undef LONGC
     77 #undef LONGD
     78 
     79 static inline int normalize_ret(int ret)
     80 {
     81   return ret < 0 ? -1 : (ret > 0 ? 1 : 0);
     82 }
     83 
     84 void test_compare_basic()
     85 {
     86   using namespace fs;
     87   for (auto const & TC : CompareTestCases) {
     88     const path p1(TC.LHS);
     89     const path p2(TC.RHS);
     90     const std::string R(TC.RHS);
     91     const std::string_view RV(TC.RHS);
     92     const int E = TC.expect;
     93     { // compare(...) functions
     94       DisableAllocationGuard g; // none of these operations should allocate
     95 
     96       // check runtime results
     97       int ret1 = normalize_ret(p1.compare(p2));
     98       int ret2 = normalize_ret(p1.compare(R));
     99       int ret3 = normalize_ret(p1.compare(TC.RHS));
    100       int ret4 = normalize_ret(p1.compare(RV));
    101 
    102       g.release();
    103       ASSERT_EQ(ret1, ret2);
    104       ASSERT_EQ(ret1, ret3);
    105       ASSERT_EQ(ret1, ret4);
    106       ASSERT_EQ(ret1, E)
    107           << DISPLAY(TC.LHS) << DISPLAY(TC.RHS);
    108 
    109       // check signatures
    110       ASSERT_NOEXCEPT(p1.compare(p2));
    111     }
    112     { // comparison operators
    113       DisableAllocationGuard g; // none of these operations should allocate
    114 
    115       // Check runtime result
    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       assert((p1 >  p2) == (E >  0));
    121       assert((p1 >= p2) == (E >= 0));
    122 
    123       // Check signatures
    124       ASSERT_NOEXCEPT(p1 == p2);
    125       ASSERT_NOEXCEPT(p1 != p2);
    126       ASSERT_NOEXCEPT(p1 <  p2);
    127       ASSERT_NOEXCEPT(p1 <= p2);
    128       ASSERT_NOEXCEPT(p1 >  p2);
    129       ASSERT_NOEXCEPT(p1 >= p2);
    130     }
    131     { // check hash values
    132       auto h1 = hash_value(p1);
    133       auto h2 = hash_value(p2);
    134       assert((h1 == h2) == (p1 == p2));
    135       // check signature
    136       ASSERT_SAME_TYPE(size_t, decltype(hash_value(p1)));
    137       ASSERT_NOEXCEPT(hash_value(p1));
    138     }
    139   }
    140 }
    141 
    142 int CompareElements(std::vector<std::string> const& LHS, std::vector<std::string> const& RHS) {
    143   bool IsLess = std::lexicographical_compare(LHS.begin(), LHS.end(), RHS.begin(), RHS.end());
    144   if (IsLess)
    145     return -1;
    146 
    147   bool IsGreater = std::lexicographical_compare(RHS.begin(), RHS.end(), LHS.begin(), LHS.end());
    148   if (IsGreater)
    149     return 1;
    150 
    151   return 0;
    152 }
    153 
    154 void test_compare_elements() {
    155   struct {
    156     std::vector<std::string> LHSElements;
    157     std::vector<std::string> RHSElements;
    158     int Expect;
    159   } TestCases[] = {
    160       {{"a"}, {"a"}, 0},
    161       {{"a"}, {"b"}, -1},
    162       {{"b"}, {"a"}, 1},
    163       {{"a", "b", "c"}, {"a", "b", "c"}, 0},
    164       {{"a", "b", "c"}, {"a", "b", "d"}, -1},
    165       {{"a", "b", "d"}, {"a", "b", "c"}, 1},
    166       {{"a", "b"}, {"a", "b", "c"}, -1},
    167       {{"a", "b", "c"}, {"a", "b"}, 1},
    168 
    169   };
    170 
    171   auto BuildPath = [](std::vector<std::string> const& Elems) {
    172     fs::path p;
    173     for (auto &E : Elems)
    174       p /= E;
    175     return p;
    176   };
    177 
    178   for (auto &TC : TestCases) {
    179     fs::path LHS = BuildPath(TC.LHSElements);
    180     fs::path RHS = BuildPath(TC.RHSElements);
    181     const int ExpectCmp = CompareElements(TC.LHSElements, TC.RHSElements);
    182     assert(ExpectCmp == TC.Expect);
    183     const int GotCmp = normalize_ret(LHS.compare(RHS));
    184     assert(GotCmp == TC.Expect);
    185   }
    186 }
    187 
    188 int main() {
    189   test_compare_basic();
    190   test_compare_elements();
    191 }