You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
193 lines
5.8 KiB
C++
193 lines
5.8 KiB
C++
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// UNSUPPORTED: c++98, c++03
|
|
|
|
// <filesystem>
|
|
|
|
// class path
|
|
|
|
// int compare(path const&) const noexcept;
|
|
// int compare(string_type const&) const;
|
|
// int compare(value_type const*) const;
|
|
//
|
|
// bool operator==(path const&, path const&) noexcept;
|
|
// bool operator!=(path const&, path const&) noexcept;
|
|
// bool operator< (path const&, path const&) noexcept;
|
|
// bool operator<=(path const&, path const&) noexcept;
|
|
// bool operator> (path const&, path const&) noexcept;
|
|
// bool operator>=(path const&, path const&) noexcept;
|
|
//
|
|
// size_t hash_value(path const&) noexcept;
|
|
|
|
|
|
#include "filesystem_include.hpp"
|
|
#include <type_traits>
|
|
#include <vector>
|
|
#include <cassert>
|
|
|
|
#include "test_macros.h"
|
|
#include "test_iterators.h"
|
|
#include "count_new.hpp"
|
|
#include "filesystem_test_helper.hpp"
|
|
#include "verbose_assert.h"
|
|
|
|
struct PathCompareTest {
|
|
const char* LHS;
|
|
const char* RHS;
|
|
int expect;
|
|
};
|
|
|
|
#define LONGA "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
|
#define LONGB "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
|
|
#define LONGC "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
|
|
#define LONGD "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"
|
|
const PathCompareTest CompareTestCases[] =
|
|
{
|
|
{"", "", 0},
|
|
{"a", "", 1},
|
|
{"", "a", -1},
|
|
{"a/b/c", "a/b/c", 0},
|
|
{"b/a/c", "a/b/c", 1},
|
|
{"a/b/c", "b/a/c", -1},
|
|
{"a/b", "a/b/c", -1},
|
|
{"a/b/c", "a/b", 1},
|
|
{"a/b/", "a/b/.", -1},
|
|
{"a/b/", "a/b", 1},
|
|
{"a/b//////", "a/b/////.", -1},
|
|
{"a/.././b", "a///..//.////b", 0},
|
|
{"//foo//bar///baz////", "//foo/bar/baz/", 0}, // duplicate separators
|
|
{"///foo/bar", "/foo/bar", 0}, // "///" is not a root directory
|
|
{"/foo/bar/", "/foo/bar", 1}, // trailing separator
|
|
{"foo", "/foo", -1}, // if !this->has_root_directory() and p.has_root_directory(), a value less than 0.
|
|
{"/foo", "foo", 1}, // if this->has_root_directory() and !p.has_root_directory(), a value greater than 0.
|
|
{"//" LONGA "////" LONGB "/" LONGC "///" LONGD, "//" LONGA "/" LONGB "/" LONGC "/" LONGD, 0},
|
|
{ LONGA "/" LONGB "/" LONGC, LONGA "/" LONGB "/" LONGB, 1}
|
|
|
|
};
|
|
#undef LONGA
|
|
#undef LONGB
|
|
#undef LONGC
|
|
#undef LONGD
|
|
|
|
static inline int normalize_ret(int ret)
|
|
{
|
|
return ret < 0 ? -1 : (ret > 0 ? 1 : 0);
|
|
}
|
|
|
|
void test_compare_basic()
|
|
{
|
|
using namespace fs;
|
|
for (auto const & TC : CompareTestCases) {
|
|
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 = 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));
|
|
|
|
g.release();
|
|
ASSERT_EQ(ret1, ret2);
|
|
ASSERT_EQ(ret1, ret3);
|
|
ASSERT_EQ(ret1, ret4);
|
|
ASSERT_EQ(ret1, E)
|
|
<< DISPLAY(TC.LHS) << DISPLAY(TC.RHS);
|
|
|
|
// check signatures
|
|
ASSERT_NOEXCEPT(p1.compare(p2));
|
|
}
|
|
{ // comparison operators
|
|
DisableAllocationGuard g; // none of these operations should allocate
|
|
|
|
// Check runtime result
|
|
assert((p1 == p2) == (E == 0));
|
|
assert((p1 != p2) == (E != 0));
|
|
assert((p1 < p2) == (E < 0));
|
|
assert((p1 <= p2) == (E <= 0));
|
|
assert((p1 > p2) == (E > 0));
|
|
assert((p1 >= p2) == (E >= 0));
|
|
|
|
// Check signatures
|
|
ASSERT_NOEXCEPT(p1 == p2);
|
|
ASSERT_NOEXCEPT(p1 != p2);
|
|
ASSERT_NOEXCEPT(p1 < p2);
|
|
ASSERT_NOEXCEPT(p1 <= p2);
|
|
ASSERT_NOEXCEPT(p1 > p2);
|
|
ASSERT_NOEXCEPT(p1 >= p2);
|
|
}
|
|
{ // check hash values
|
|
auto h1 = hash_value(p1);
|
|
auto h2 = hash_value(p2);
|
|
assert((h1 == h2) == (p1 == p2));
|
|
// check signature
|
|
ASSERT_SAME_TYPE(size_t, decltype(hash_value(p1)));
|
|
ASSERT_NOEXCEPT(hash_value(p1));
|
|
}
|
|
}
|
|
}
|
|
|
|
int CompareElements(std::vector<std::string> const& LHS, std::vector<std::string> const& RHS) {
|
|
bool IsLess = std::lexicographical_compare(LHS.begin(), LHS.end(), RHS.begin(), RHS.end());
|
|
if (IsLess)
|
|
return -1;
|
|
|
|
bool IsGreater = std::lexicographical_compare(RHS.begin(), RHS.end(), LHS.begin(), LHS.end());
|
|
if (IsGreater)
|
|
return 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
void test_compare_elements() {
|
|
struct {
|
|
std::vector<std::string> LHSElements;
|
|
std::vector<std::string> RHSElements;
|
|
int Expect;
|
|
} TestCases[] = {
|
|
{{"a"}, {"a"}, 0},
|
|
{{"a"}, {"b"}, -1},
|
|
{{"b"}, {"a"}, 1},
|
|
{{"a", "b", "c"}, {"a", "b", "c"}, 0},
|
|
{{"a", "b", "c"}, {"a", "b", "d"}, -1},
|
|
{{"a", "b", "d"}, {"a", "b", "c"}, 1},
|
|
{{"a", "b"}, {"a", "b", "c"}, -1},
|
|
{{"a", "b", "c"}, {"a", "b"}, 1},
|
|
|
|
};
|
|
|
|
auto BuildPath = [](std::vector<std::string> const& Elems) {
|
|
fs::path p;
|
|
for (auto &E : Elems)
|
|
p /= E;
|
|
return p;
|
|
};
|
|
|
|
for (auto &TC : TestCases) {
|
|
fs::path LHS = BuildPath(TC.LHSElements);
|
|
fs::path RHS = BuildPath(TC.RHSElements);
|
|
const int ExpectCmp = CompareElements(TC.LHSElements, TC.RHSElements);
|
|
assert(ExpectCmp == TC.Expect);
|
|
const int GotCmp = normalize_ret(LHS.compare(RHS));
|
|
assert(GotCmp == TC.Expect);
|
|
}
|
|
}
|
|
|
|
int main(int, char**) {
|
|
test_compare_basic();
|
|
test_compare_elements();
|
|
|
|
return 0;
|
|
}
|