Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature/spaceship: Clause 28: Localization, Clause 29: Input/output #1593

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 30 additions & 4 deletions stl/inc/filesystem
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@
#include <xfilesystem_abi.h>
#include <xstring>

#if _HAS_CXX20
#include <compare>
#endif // _HAS_CXX20

#pragma pack(push, _CRT_PACKING)
#pragma warning(push, _STL_WARNING_LEVEL)
#pragma warning(disable : _STL_DISABLED_WARNINGS)
Expand Down Expand Up @@ -1399,6 +1403,11 @@ namespace filesystem {
return _Left.compare(_Right) == 0;
}

#if _HAS_CXX20
_NODISCARD friend strong_ordering operator<=>(const path& _Left, const path& _Right) noexcept {
return _Left.compare(_Right) <=> 0;
}
#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv
_NODISCARD friend bool operator!=(const path& _Left, const path& _Right) noexcept {
return _Left.compare(_Right) != 0;
}
Expand All @@ -1418,6 +1427,7 @@ namespace filesystem {
_NODISCARD friend bool operator>=(const path& _Left, const path& _Right) noexcept {
return _Left.compare(_Right) >= 0;
}
#endif // !_HAS_CXX20

_NODISCARD friend path operator/(const path& _Left, const path& _Right) { // append a pair of paths together
return path(_Left) /= _Right;
Expand Down Expand Up @@ -1967,6 +1977,12 @@ namespace filesystem {
return _Myperms;
}

#if _HAS_CXX20
_NODISCARD friend bool operator==(const file_status& _Lhs, const file_status& _Rhs) noexcept {
return _Lhs._Myftype == _Rhs._Myftype && _Lhs._Myperms == _Rhs._Myperms;
}
#endif // _HAS_CXX20

void _Refresh(const __std_win_error _Error, const __std_fs_stats& _Stats) noexcept {
if (_Error == __std_win_error::_Success) {
const auto _Attrs = _Stats._Attributes;
Expand Down Expand Up @@ -2445,18 +2461,23 @@ namespace filesystem {
return _Result._Status;
}

_NODISCARD bool operator<(const directory_entry& _Rhs) const noexcept {
return _Path < _Rhs._Path;
}

_NODISCARD bool operator==(const directory_entry& _Rhs) const noexcept {
return _Path == _Rhs._Path;
}

#if _HAS_CXX20
_NODISCARD strong_ordering operator<=>(const directory_entry& _Rhs) const noexcept {
return _Path <=> _Rhs._Path;
}
#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv
statementreply marked this conversation as resolved.
Show resolved Hide resolved
_NODISCARD bool operator!=(const directory_entry& _Rhs) const noexcept {
return _Path != _Rhs._Path;
}

_NODISCARD bool operator<(const directory_entry& _Rhs) const noexcept {
return _Path < _Rhs._Path;
}

_NODISCARD bool operator<=(const directory_entry& _Rhs) const noexcept {
return _Path <= _Rhs._Path;
}
Expand All @@ -2468,6 +2489,7 @@ namespace filesystem {
_NODISCARD bool operator>=(const directory_entry& _Rhs) const noexcept {
return _Path >= _Rhs._Path;
}
#endif // !_HAS_CXX20

private:
void _Refresh(const __std_fs_find_data& _Data) noexcept {
Expand Down Expand Up @@ -3641,6 +3663,10 @@ namespace filesystem {
uintmax_t capacity;
uintmax_t free;
uintmax_t available;

#if _HAS_CXX20
_NODISCARD friend constexpr bool operator==(const space_info&, const space_info&) noexcept = default;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I observe that this says constexpr and noexcept which are implied by the Standard but not depicted there. I think this is fine (I am somewhat torn between "generally avoid unnecessary code" and "this is a useful reminder"), no change requested.

#endif // _HAS_CXX20
};

_NODISCARD inline space_info space(const path& _Target) {
Expand Down
2 changes: 2 additions & 0 deletions stl/inc/xlocale
Original file line number Diff line number Diff line change
Expand Up @@ -389,9 +389,11 @@ public:
return _Ptr == _Loc._Ptr || (name().compare("*") != 0 && name().compare(_Loc.name()) == 0);
}

#if !_HAS_CXX20
_NODISCARD bool operator!=(const locale& _Right) const {
return !(*this == _Right);
}
#endif // !_HAS_CXX20

static _MRTIMP2_PURE const locale& __CLRCALL_PURE_OR_CDECL classic(); // classic "C" locale

Expand Down
49 changes: 49 additions & 0 deletions tests/std/tests/P1614R2_spaceship/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <compare>
#include <concepts>
#include <deque>
#include <filesystem>
#include <forward_list>
#include <functional>
#include <iostream>
Expand Down Expand Up @@ -482,6 +483,54 @@ void ordering_test_cases() {

spaceship_test<std::strong_ordering>(c_mem[0], c_mem[0], c_mem[1]);
}
{ // filesystem::space_info
constexpr std::filesystem::space_info si1{4'000'000'000'000, 2'000'000'000'000, 1'000'000'000'000};
constexpr std::filesystem::space_info si2{4'000'000'000'000, 2'000'000'000'000, 1'000'000'000'000};
constexpr std::filesystem::space_info si3{4'000'000'000'000, 2'000'000'000'000, 2'000'000'000'000};
constexpr std::filesystem::space_info si4{4'000'000'000'000, 3'000'000'000'000, 1'000'000'000'000};
constexpr std::filesystem::space_info si5{3'000'000'000'000, 2'000'000'000'000, 1'000'000'000'000};

static_assert(si1 == si2);
static_assert(si1 != si3);
static_assert(si1 != si4);
static_assert(si1 != si5);

assert(si1 == si2);
assert(si1 != si3);
assert(si1 != si4);
assert(si1 != si5);
}
{ // filesystem::path
const std::filesystem::path p1{R"(a/b/c)"};
const std::filesystem::path p2{LR"(a\b\c)"};
const std::filesystem::path p3{R"(a/b/d)"};

spaceship_test<std::strong_ordering>(p1, p2, p3);
}
{ // filesystem::file_status
std::filesystem::file_status s1;
s1.type(std::filesystem::file_type::regular);
s1.permissions(std::filesystem::perms{0755});

std::filesystem::file_status s2 = s1;

std::filesystem::file_status s3 = s1;
s3.type(std::filesystem::file_type::directory);

std::filesystem::file_status s4 = s1;
s4.permissions(std::filesystem::perms{0600});

assert(s1 == s2);
assert(s1 != s3);
assert(s1 != s4);
}
{ // filesystem::directory_entry
const std::filesystem::directory_entry de1{u8R"(a/b/c)"};
const std::filesystem::directory_entry de2{uR"(a\b\c)"};
const std::filesystem::directory_entry de3{u8R"(a/b/d)"};

spaceship_test<std::strong_ordering>(de1, de2, de3);
}
{ // thread::id
std::thread::id id1;
std::thread::id id1_equal;
Expand Down