mirror of
https://github.com/loot/libloot.git
synced 2026-07-27 14:16:01 -07:00
Replace C++ comparison operators with <=>
This commit is contained in:
@@ -45,55 +45,4 @@ std::vector<MessageContent> File::GetDetail() const { return detail_; }
|
||||
std::string File::GetCondition() const { return condition_; }
|
||||
|
||||
std::string File::GetConstraint() const { return constraint_; }
|
||||
|
||||
bool operator==(const File& lhs, const File& rhs) {
|
||||
return lhs.GetDisplayName() == rhs.GetDisplayName() &&
|
||||
lhs.GetCondition() == rhs.GetCondition() &&
|
||||
lhs.GetConstraint() == rhs.GetConstraint() &&
|
||||
lhs.GetName() == rhs.GetName() && lhs.GetDetail() == rhs.GetDetail();
|
||||
}
|
||||
|
||||
bool operator!=(const File& lhs, const File& rhs) { return !(lhs == rhs); }
|
||||
|
||||
bool operator<(const File& lhs, const File& rhs) {
|
||||
if (lhs.GetDisplayName() < rhs.GetDisplayName()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (rhs.GetDisplayName() < lhs.GetDisplayName()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (lhs.GetCondition() < rhs.GetCondition()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (rhs.GetCondition() < lhs.GetCondition()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (lhs.GetConstraint() < rhs.GetConstraint()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (rhs.GetConstraint() < lhs.GetConstraint()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (lhs.GetName() < rhs.GetName()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (rhs.GetName() < lhs.GetName()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return lhs.GetDetail() < rhs.GetDetail();
|
||||
}
|
||||
|
||||
bool operator>(const File& lhs, const File& rhs) { return rhs < lhs; }
|
||||
|
||||
bool operator<=(const File& lhs, const File& rhs) { return !(lhs > rhs); }
|
||||
|
||||
bool operator>=(const File& lhs, const File& rhs) { return !(lhs < rhs); }
|
||||
}
|
||||
|
||||
@@ -33,27 +33,22 @@ Filename::Filename(std::string_view filename) : filename_(filename) {}
|
||||
|
||||
Filename::operator std::string() const { return filename_; }
|
||||
|
||||
std::weak_ordering operator<=>(const Filename& lhs, const Filename& rhs) {
|
||||
auto result = loot::rust::new_filename(lhs.filename_)
|
||||
->cmp(*loot::rust::new_filename(rhs.filename_));
|
||||
|
||||
if (result > 0) {
|
||||
return std::weak_ordering::greater;
|
||||
}
|
||||
|
||||
if (result == 0) {
|
||||
return std::weak_ordering::equivalent;
|
||||
}
|
||||
|
||||
return std::weak_ordering::less;
|
||||
}
|
||||
|
||||
bool operator==(const Filename& lhs, const Filename& rhs) {
|
||||
return loot::rust::new_filename(lhs.filename_)
|
||||
->eq(*loot::rust::new_filename(rhs.filename_));
|
||||
}
|
||||
|
||||
bool operator!=(const Filename& lhs, const Filename& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
bool operator<(const Filename& lhs, const Filename& rhs) {
|
||||
return loot::rust::new_filename(lhs.filename_)
|
||||
->lt(*loot::rust::new_filename(rhs.filename_));
|
||||
}
|
||||
|
||||
bool operator>(const Filename& lhs, const Filename& rhs) { return rhs < lhs; }
|
||||
|
||||
bool operator<=(const Filename& lhs, const Filename& rhs) {
|
||||
return !(lhs > rhs);
|
||||
}
|
||||
|
||||
bool operator>=(const Filename& lhs, const Filename& rhs) {
|
||||
return !(lhs < rhs);
|
||||
return (lhs <=> rhs) == std::weak_ordering::equivalent;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,38 +35,4 @@ std::string Group::GetName() const { return name_; }
|
||||
std::string Group::GetDescription() const { return description_; }
|
||||
|
||||
std::vector<std::string> Group::GetAfterGroups() const { return afterGroups_; }
|
||||
|
||||
bool operator==(const Group& lhs, const Group& rhs) {
|
||||
return lhs.GetName() == rhs.GetName() &&
|
||||
lhs.GetDescription() == rhs.GetDescription() &&
|
||||
lhs.GetAfterGroups() == rhs.GetAfterGroups();
|
||||
}
|
||||
|
||||
bool operator!=(const Group& lhs, const Group& rhs) { return !(lhs == rhs); }
|
||||
|
||||
bool operator<(const Group& lhs, const Group& rhs) {
|
||||
if (lhs.GetName() < rhs.GetName()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (rhs.GetName() < lhs.GetName()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (lhs.GetDescription() < rhs.GetDescription()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (rhs.GetDescription() < lhs.GetDescription()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return lhs.GetAfterGroups() < rhs.GetAfterGroups();
|
||||
}
|
||||
|
||||
bool operator>(const Group& lhs, const Group& rhs) { return rhs < lhs; }
|
||||
|
||||
bool operator<=(const Group& lhs, const Group& rhs) { return !(lhs > rhs); }
|
||||
|
||||
bool operator>=(const Group& lhs, const Group& rhs) { return !(lhs < rhs); }
|
||||
}
|
||||
|
||||
@@ -31,34 +31,4 @@ Location::Location(std::string_view url, std::string_view name) :
|
||||
std::string Location::GetURL() const { return url_; }
|
||||
|
||||
std::string Location::GetName() const { return name_; }
|
||||
|
||||
bool operator==(const Location& lhs, const Location& rhs) {
|
||||
return lhs.GetURL() == rhs.GetURL() && lhs.GetName() == rhs.GetName();
|
||||
}
|
||||
|
||||
bool operator!=(const Location& lhs, const Location& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
bool operator<(const Location& lhs, const Location& rhs) {
|
||||
if (lhs.GetURL() < rhs.GetURL()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (rhs.GetURL() < lhs.GetURL()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return lhs.GetName() < rhs.GetName();
|
||||
}
|
||||
|
||||
bool operator>(const Location& lhs, const Location& rhs) { return rhs < lhs; }
|
||||
|
||||
bool operator<=(const Location& lhs, const Location& rhs) {
|
||||
return !(lhs > rhs);
|
||||
}
|
||||
|
||||
bool operator>=(const Location& lhs, const Location& rhs) {
|
||||
return !(lhs < rhs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,40 +54,4 @@ MessageType Message::GetType() const { return type_; }
|
||||
std::vector<MessageContent> Message::GetContent() const { return content_; }
|
||||
|
||||
std::string Message::GetCondition() const { return condition_; }
|
||||
|
||||
bool operator==(const Message& lhs, const Message& rhs) {
|
||||
return lhs.GetType() == rhs.GetType() &&
|
||||
lhs.GetCondition() == rhs.GetCondition() &&
|
||||
lhs.GetContent() == rhs.GetContent();
|
||||
}
|
||||
|
||||
bool operator!=(const Message& lhs, const Message& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
bool operator<(const Message& lhs, const Message& rhs) {
|
||||
if (lhs.GetType() < rhs.GetType()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (rhs.GetType() < lhs.GetType()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (lhs.GetCondition() < rhs.GetCondition()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (rhs.GetCondition() < lhs.GetCondition()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return lhs.GetContent() < rhs.GetContent();
|
||||
}
|
||||
|
||||
bool operator>(const Message& lhs, const Message& rhs) { return rhs < lhs; }
|
||||
|
||||
bool operator<=(const Message& lhs, const Message& rhs) { return !(lhs > rhs); }
|
||||
|
||||
bool operator>=(const Message& lhs, const Message& rhs) { return !(lhs < rhs); }
|
||||
}
|
||||
|
||||
@@ -33,39 +33,6 @@ std::string MessageContent::GetText() const { return text_; }
|
||||
|
||||
std::string MessageContent::GetLanguage() const { return language_; }
|
||||
|
||||
bool operator==(const MessageContent& lhs, const MessageContent& rhs) {
|
||||
return lhs.GetText() == rhs.GetText() &&
|
||||
lhs.GetLanguage() == rhs.GetLanguage();
|
||||
}
|
||||
|
||||
bool operator!=(const MessageContent& lhs, const MessageContent& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
bool operator<(const MessageContent& lhs, const MessageContent& rhs) {
|
||||
if (lhs.GetText() < rhs.GetText()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (rhs.GetText() < lhs.GetText()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return lhs.GetLanguage() < rhs.GetLanguage();
|
||||
}
|
||||
|
||||
bool operator>(const MessageContent& lhs, const MessageContent& rhs) {
|
||||
return rhs < lhs;
|
||||
}
|
||||
|
||||
bool operator<=(const MessageContent& lhs, const MessageContent& rhs) {
|
||||
return !(lhs > rhs);
|
||||
}
|
||||
|
||||
bool operator>=(const MessageContent& lhs, const MessageContent& rhs) {
|
||||
return !(lhs < rhs);
|
||||
}
|
||||
|
||||
std::optional<MessageContent> SelectMessageContent(
|
||||
const std::vector<MessageContent> content,
|
||||
std::string_view language) {
|
||||
|
||||
@@ -57,73 +57,4 @@ std::string PluginCleaningData::GetCleaningUtility() const { return utility_; }
|
||||
std::vector<MessageContent> PluginCleaningData::GetDetail() const {
|
||||
return detail_;
|
||||
}
|
||||
|
||||
bool operator==(const PluginCleaningData& lhs, const PluginCleaningData& rhs) {
|
||||
return lhs.GetCRC() == rhs.GetCRC() &&
|
||||
lhs.GetITMCount() == rhs.GetITMCount() &&
|
||||
lhs.GetDeletedReferenceCount() == rhs.GetDeletedReferenceCount() &&
|
||||
lhs.GetDeletedNavmeshCount() == rhs.GetDeletedNavmeshCount() &&
|
||||
lhs.GetCleaningUtility() == rhs.GetCleaningUtility() &&
|
||||
lhs.GetDetail() == rhs.GetDetail();
|
||||
}
|
||||
|
||||
bool operator!=(const PluginCleaningData& lhs, const PluginCleaningData& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
bool operator<(const PluginCleaningData& lhs, const PluginCleaningData& rhs) {
|
||||
if (lhs.GetCRC() < rhs.GetCRC()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (rhs.GetCRC() < lhs.GetCRC()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (lhs.GetCleaningUtility() < rhs.GetCleaningUtility()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (rhs.GetCleaningUtility() < lhs.GetCleaningUtility()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (lhs.GetITMCount() < rhs.GetITMCount()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (rhs.GetITMCount() < lhs.GetITMCount()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (lhs.GetDeletedReferenceCount() < rhs.GetDeletedReferenceCount()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (rhs.GetDeletedReferenceCount() < lhs.GetDeletedReferenceCount()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (lhs.GetDeletedNavmeshCount() < rhs.GetDeletedNavmeshCount()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (rhs.GetDeletedNavmeshCount() < lhs.GetDeletedNavmeshCount()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return lhs.GetDetail() < rhs.GetDetail();
|
||||
}
|
||||
|
||||
bool operator>(const PluginCleaningData& lhs, const PluginCleaningData& rhs) {
|
||||
return rhs < lhs;
|
||||
}
|
||||
|
||||
bool operator<=(const PluginCleaningData& lhs, const PluginCleaningData& rhs) {
|
||||
return !(lhs > rhs);
|
||||
}
|
||||
|
||||
bool operator>=(const PluginCleaningData& lhs, const PluginCleaningData& rhs) {
|
||||
return !(lhs < rhs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,33 +36,20 @@ std::string Tag::GetName() const { return name_; }
|
||||
|
||||
std::string Tag::GetCondition() const { return condition_; }
|
||||
|
||||
bool operator==(const Tag& lhs, const Tag& rhs) {
|
||||
return lhs.IsAddition() == rhs.IsAddition() &&
|
||||
lhs.GetName() == rhs.GetName() &&
|
||||
lhs.GetCondition() == rhs.GetCondition();
|
||||
}
|
||||
|
||||
bool operator!=(const Tag& lhs, const Tag& rhs) { return !(lhs == rhs); }
|
||||
|
||||
bool operator<(const Tag& lhs, const Tag& rhs) {
|
||||
std::strong_ordering operator<=>(const Tag& lhs, const Tag& rhs) {
|
||||
if (lhs.IsAddition() != rhs.IsAddition()) {
|
||||
return lhs.IsAddition() && !rhs.IsAddition();
|
||||
if (lhs.IsAddition()) {
|
||||
return std::strong_ordering::less;
|
||||
}
|
||||
|
||||
return std::strong_ordering::greater;
|
||||
}
|
||||
|
||||
if (lhs.GetName() < rhs.GetName()) {
|
||||
return true;
|
||||
auto nameOrder = lhs.GetName() <=> rhs.GetName();
|
||||
if (nameOrder != std::strong_ordering::equal) {
|
||||
return nameOrder;
|
||||
}
|
||||
|
||||
if (rhs.GetName() < lhs.GetName()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return lhs.GetCondition() < rhs.GetCondition();
|
||||
return lhs.GetCondition() <=> rhs.GetCondition();
|
||||
}
|
||||
|
||||
bool operator>(const Tag& lhs, const Tag& rhs) { return rhs < lhs; }
|
||||
|
||||
bool operator<=(const Tag& lhs, const Tag& rhs) { return !(lhs > rhs); }
|
||||
|
||||
bool operator>=(const Tag& lhs, const Tag& rhs) { return !(lhs < rhs); }
|
||||
}
|
||||
|
||||
@@ -615,6 +615,8 @@ mod ffi {
|
||||
|
||||
pub fn boxed_clone(&self) -> Box<Filename>;
|
||||
|
||||
pub fn cmp(&self, other: &Filename) -> i8;
|
||||
|
||||
pub fn eq(&self, other: &Filename) -> bool;
|
||||
|
||||
pub fn ne(&self, other: &Filename) -> bool;
|
||||
|
||||
+9
-1
@@ -446,7 +446,7 @@ impl From<Box<File>> for libloot::metadata::File {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
#[repr(transparent)]
|
||||
pub struct Filename(libloot::metadata::Filename);
|
||||
|
||||
@@ -459,6 +459,14 @@ impl Filename {
|
||||
Box::new(Self(self.0.clone()))
|
||||
}
|
||||
|
||||
#[expect(
|
||||
clippy::as_conversions,
|
||||
reason = "Ordering is repr(i8) but provides no way to convert to i8 without 'as'"
|
||||
)]
|
||||
pub fn cmp(&self, other: &Self) -> i8 {
|
||||
Ord::cmp(self, other) as i8
|
||||
}
|
||||
|
||||
delegate! {
|
||||
to self.0 {
|
||||
pub fn as_str(&self) -> &str;
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#include "loot/api.h"
|
||||
#include "tests/api/interface/metadata/file_test.h"
|
||||
#include "tests/api/interface/metadata/filename_test.h"
|
||||
#include "tests/api/interface/metadata/group_test.h"
|
||||
#include "tests/api/interface/metadata/location_test.h"
|
||||
#include "tests/api/interface/metadata/message_content_test.h"
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
/* LOOT
|
||||
|
||||
A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and
|
||||
Fallout: New Vegas.
|
||||
|
||||
Copyright (C) 2014-2016 WrinklyNinja
|
||||
|
||||
This file is part of LOOT.
|
||||
|
||||
LOOT is free software: you can redistribute
|
||||
it and/or modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
LOOT is distributed in the hope that it will
|
||||
be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with LOOT. If not, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef LOOT_TESTS_API_INTERFACE_METADATA_FILENAME_TEST
|
||||
#define LOOT_TESTS_API_INTERFACE_METADATA_FILENAME_TEST
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "loot/metadata/filename.h"
|
||||
|
||||
namespace loot::test {
|
||||
TEST(Filename, defaultConstructorShouldInitialiseEmptyString) {
|
||||
Filename filename;
|
||||
|
||||
EXPECT_EQ("", std::string(filename));
|
||||
}
|
||||
|
||||
TEST(Filename, stringConstructorShouldStoreGivenString) {
|
||||
Filename filename("name");
|
||||
|
||||
EXPECT_EQ("name", std::string(filename));
|
||||
}
|
||||
|
||||
TEST(Filename, equalityShouldBeCaseInsensitive) {
|
||||
Filename filename1("name");
|
||||
Filename filename2("name");
|
||||
|
||||
EXPECT_TRUE(filename1 == filename2);
|
||||
|
||||
filename1 = Filename("name");
|
||||
filename2 = Filename("Name");
|
||||
|
||||
EXPECT_TRUE(filename1 == filename2);
|
||||
|
||||
filename1 = Filename("name1");
|
||||
filename2 = Filename("name2");
|
||||
|
||||
EXPECT_FALSE(filename1 == filename2);
|
||||
}
|
||||
|
||||
TEST(Filename, orderingShouldBeWeakAndCaseInsensitivelyLexicographical) {
|
||||
Filename filename1("name");
|
||||
Filename filename2("name");
|
||||
|
||||
EXPECT_EQ(std::weak_ordering::equivalent, filename1 <=> filename2);
|
||||
|
||||
filename1 = Filename("name");
|
||||
filename2 = Filename("Name");
|
||||
|
||||
EXPECT_EQ(std::weak_ordering::equivalent, filename1 <=> filename2);
|
||||
|
||||
filename1 = Filename("name1");
|
||||
filename2 = Filename("name2");
|
||||
|
||||
EXPECT_EQ(std::weak_ordering::less, filename1 <=> filename2);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -47,6 +47,40 @@ TEST(Tag, dataConstructorShouldSetFieldsToGivenValues) {
|
||||
EXPECT_EQ("condition", tag.GetCondition());
|
||||
}
|
||||
|
||||
TEST(Tag, orderingShouldCompareNamesAndConditionsLexicographically) {
|
||||
Tag tag1("name", true, "condition");
|
||||
Tag tag2("name", true, "condition");
|
||||
|
||||
EXPECT_EQ(std::weak_ordering::equivalent, tag1 <=> tag2);
|
||||
|
||||
tag1 = Tag("name");
|
||||
tag2 = Tag("Name");
|
||||
|
||||
EXPECT_EQ(std::weak_ordering::greater, tag1 <=> tag2);
|
||||
|
||||
tag1 = Tag("name", true, "condition");
|
||||
tag2 = Tag("name", true, "Condition");
|
||||
|
||||
EXPECT_EQ(std::weak_ordering::greater, tag1 <=> tag2);
|
||||
|
||||
tag1 = Tag("name1");
|
||||
tag2 = Tag("name2");
|
||||
|
||||
EXPECT_EQ(std::weak_ordering::less, tag1 <=> tag2);
|
||||
|
||||
tag1 = Tag("name", true, "condition1");
|
||||
tag2 = Tag("name", true, "condition2");
|
||||
|
||||
EXPECT_EQ(std::weak_ordering::less, tag1 <=> tag2);
|
||||
}
|
||||
|
||||
TEST(Tag, orderingShouldMakeAdditionsLessThanRemovals) {
|
||||
Tag tag1("name", true);
|
||||
Tag tag2("name", false);
|
||||
|
||||
EXPECT_EQ(std::weak_ordering::less, tag1 <=> tag2);
|
||||
}
|
||||
|
||||
TEST(Tag, equalityShouldBeCaseSensitiveOnNameAndCondition) {
|
||||
Tag tag1("name", true, "condition");
|
||||
Tag tag2("name", true, "condition");
|
||||
|
||||
Reference in New Issue
Block a user