diff --git a/src/libcmd/built-path.cc b/src/libcmd/built-path.cc index c5eb93c5d7e9..e67987873326 100644 --- a/src/libcmd/built-path.cc +++ b/src/libcmd/built-path.cc @@ -1,6 +1,7 @@ #include "built-path.hh" #include "derivations.hh" #include "store-api.hh" +#include "comparator.hh" #include @@ -8,30 +9,21 @@ namespace nix { -#define CMP_ONE(CHILD_TYPE, MY_TYPE, FIELD, COMPARATOR) \ - bool MY_TYPE ::operator COMPARATOR (const MY_TYPE & other) const \ - { \ - const MY_TYPE* me = this; \ - auto fields1 = std::tie(*me->drvPath, me->FIELD); \ - me = &other; \ - auto fields2 = std::tie(*me->drvPath, me->FIELD); \ - return fields1 COMPARATOR fields2; \ - } -#define CMP(CHILD_TYPE, MY_TYPE, FIELD) \ - CMP_ONE(CHILD_TYPE, MY_TYPE, FIELD, ==) \ - CMP_ONE(CHILD_TYPE, MY_TYPE, FIELD, !=) \ - CMP_ONE(CHILD_TYPE, MY_TYPE, FIELD, <) - -#define FIELD_TYPE std::pair -CMP(SingleBuiltPath, SingleBuiltPathBuilt, output) -#undef FIELD_TYPE - -#define FIELD_TYPE std::map -CMP(SingleBuiltPath, BuiltPathBuilt, outputs) -#undef FIELD_TYPE - -#undef CMP -#undef CMP_ONE +// Custom implementation to avoid `ref` ptr equality +GENERATE_CMP_EXT( + , + std::strong_ordering, + SingleBuiltPathBuilt, + *me->drvPath, + me->output); + +// Custom implementation to avoid `ref` ptr equality +GENERATE_CMP_EXT( + , + std::strong_ordering, + BuiltPathBuilt, + *me->drvPath, + me->outputs); StorePath SingleBuiltPath::outPath() const { diff --git a/src/libcmd/built-path.hh b/src/libcmd/built-path.hh index 99917e0eefba..d3dd9b8bbf33 100644 --- a/src/libcmd/built-path.hh +++ b/src/libcmd/built-path.hh @@ -18,7 +18,8 @@ struct SingleBuiltPathBuilt { static SingleBuiltPathBuilt parse(const StoreDirConfig & store, std::string_view, std::string_view); nlohmann::json toJSON(const StoreDirConfig & store) const; - DECLARE_CMP(SingleBuiltPathBuilt); + bool operator ==(const SingleBuiltPathBuilt &) const noexcept; + std::strong_ordering operator <=>(const SingleBuiltPathBuilt &) const noexcept; }; using _SingleBuiltPathRaw = std::variant< @@ -33,6 +34,9 @@ struct SingleBuiltPath : _SingleBuiltPathRaw { using Opaque = DerivedPathOpaque; using Built = SingleBuiltPathBuilt; + bool operator == (const SingleBuiltPath &) const = default; + auto operator <=> (const SingleBuiltPath &) const = default; + inline const Raw & raw() const { return static_cast(*this); } @@ -59,11 +63,12 @@ struct BuiltPathBuilt { ref drvPath; std::map outputs; + bool operator == (const BuiltPathBuilt &) const noexcept; + std::strong_ordering operator <=> (const BuiltPathBuilt &) const noexcept; + std::string to_string(const StoreDirConfig & store) const; static BuiltPathBuilt parse(const StoreDirConfig & store, std::string_view, std::string_view); nlohmann::json toJSON(const StoreDirConfig & store) const; - - DECLARE_CMP(BuiltPathBuilt); }; using _BuiltPathRaw = std::variant< @@ -82,6 +87,9 @@ struct BuiltPath : _BuiltPathRaw { using Opaque = DerivedPathOpaque; using Built = BuiltPathBuilt; + bool operator == (const BuiltPath &) const = default; + auto operator <=> (const BuiltPath &) const = default; + inline const Raw & raw() const { return static_cast(*this); } diff --git a/src/libexpr-c/nix_api_external.cc b/src/libexpr-c/nix_api_external.cc index 3c3dd6ca99d3..3565092a4a67 100644 --- a/src/libexpr-c/nix_api_external.cc +++ b/src/libexpr-c/nix_api_external.cc @@ -115,7 +115,7 @@ class NixCExternalValue : public nix::ExternalValueBase /** * Compare to another value of the same type. */ - virtual bool operator==(const ExternalValueBase & b) const override + virtual bool operator==(const ExternalValueBase & b) const noexcept override { if (!desc.equal) { return false; diff --git a/src/libexpr/attr-set.hh b/src/libexpr/attr-set.hh index ba798196d3cc..9ed84b95d078 100644 --- a/src/libexpr/attr-set.hh +++ b/src/libexpr/attr-set.hh @@ -28,9 +28,9 @@ struct Attr Attr(Symbol name, Value * value, PosIdx pos = noPos) : name(name), pos(pos), value(value) { }; Attr() { }; - bool operator < (const Attr & a) const + auto operator <=> (const Attr & a) const { - return name < a.name; + return name <=> a.name; } }; diff --git a/src/libexpr/eval-cache.hh b/src/libexpr/eval-cache.hh index cac9858296c5..b1911e3a4f79 100644 --- a/src/libexpr/eval-cache.hh +++ b/src/libexpr/eval-cache.hh @@ -31,7 +31,7 @@ struct CachedEvalError : EvalError class EvalCache : public std::enable_shared_from_this { friend class AttrCursor; - friend class CachedEvalError; + friend struct CachedEvalError; std::shared_ptr db; EvalState & state; @@ -87,7 +87,7 @@ typedef std::variant< class AttrCursor : public std::enable_shared_from_this { friend class EvalCache; - friend class CachedEvalError; + friend struct CachedEvalError; ref root; typedef std::optional, Symbol>> Parent; diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 6a38bbe45993..c5e9a7b2d567 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -2963,7 +2963,7 @@ std::string ExternalValueBase::coerceToString(EvalState & state, const PosIdx & } -bool ExternalValueBase::operator==(const ExternalValueBase & b) const +bool ExternalValueBase::operator==(const ExternalValueBase & b) const noexcept { return false; } diff --git a/src/libexpr/flake/flakeref.cc b/src/libexpr/flake/flakeref.cc index 6e4aad64d288..205e72ac009b 100644 --- a/src/libexpr/flake/flakeref.cc +++ b/src/libexpr/flake/flakeref.cc @@ -36,11 +36,6 @@ std::ostream & operator << (std::ostream & str, const FlakeRef & flakeRef) return str; } -bool FlakeRef::operator ==(const FlakeRef & other) const -{ - return input == other.input && subdir == other.subdir; -} - FlakeRef FlakeRef::resolve(ref store) const { auto [input2, extraAttrs] = lookupInRegistries(store, input); diff --git a/src/libexpr/flake/flakeref.hh b/src/libexpr/flake/flakeref.hh index 04c812ed099b..ec72778061a1 100644 --- a/src/libexpr/flake/flakeref.hh +++ b/src/libexpr/flake/flakeref.hh @@ -48,7 +48,7 @@ struct FlakeRef */ Path subdir; - bool operator==(const FlakeRef & other) const; + bool operator ==(const FlakeRef & other) const = default; FlakeRef(fetchers::Input && input, const Path & subdir) : input(std::move(input)), subdir(subdir) diff --git a/src/libexpr/flake/lockfile.cc b/src/libexpr/flake/lockfile.cc index d252214dd2ba..e5826b08fd71 100644 --- a/src/libexpr/flake/lockfile.cc +++ b/src/libexpr/flake/lockfile.cc @@ -243,11 +243,6 @@ bool LockFile::operator ==(const LockFile & other) const return toJSON().first == other.toJSON().first; } -bool LockFile::operator !=(const LockFile & other) const -{ - return !(*this == other); -} - InputPath parseInputPath(std::string_view s) { InputPath path; diff --git a/src/libexpr/flake/lockfile.hh b/src/libexpr/flake/lockfile.hh index 7e62e6d09701..99aba4ccc484 100644 --- a/src/libexpr/flake/lockfile.hh +++ b/src/libexpr/flake/lockfile.hh @@ -70,9 +70,6 @@ struct LockFile std::optional isUnlocked() const; bool operator ==(const LockFile & other) const; - // Needed for old gcc versions that don't synthesize it (like gcc 8.2.2 - // that is still the default on aarch64-linux) - bool operator !=(const LockFile & other) const; std::shared_ptr findInput(const InputPath & path); diff --git a/src/libexpr/pos-idx.hh b/src/libexpr/pos-idx.hh index e94fd85c6734..e13491560229 100644 --- a/src/libexpr/pos-idx.hh +++ b/src/libexpr/pos-idx.hh @@ -28,20 +28,15 @@ public: return id > 0; } - bool operator<(const PosIdx other) const + auto operator<=>(const PosIdx other) const { - return id < other.id; + return id <=> other.id; } bool operator==(const PosIdx other) const { return id == other.id; } - - bool operator!=(const PosIdx other) const - { - return id != other.id; - } }; inline PosIdx noPos = {}; diff --git a/src/libexpr/symbol-table.hh b/src/libexpr/symbol-table.hh index 967a186dd59a..dd21bc0b49f6 100644 --- a/src/libexpr/symbol-table.hh +++ b/src/libexpr/symbol-table.hh @@ -62,9 +62,8 @@ public: explicit operator bool() const { return id > 0; } - bool operator<(const Symbol other) const { return id < other.id; } + auto operator<=>(const Symbol other) const { return id <=> other.id; } bool operator==(const Symbol other) const { return id == other.id; } - bool operator!=(const Symbol other) const { return id != other.id; } }; /** diff --git a/src/libexpr/value.hh b/src/libexpr/value.hh index 208cab21d609..4a3359711d7f 100644 --- a/src/libexpr/value.hh +++ b/src/libexpr/value.hh @@ -112,7 +112,7 @@ class ExternalValueBase * Compare to another value of the same type. Defaults to uncomparable, * i.e. always false. */ - virtual bool operator ==(const ExternalValueBase & b) const; + virtual bool operator ==(const ExternalValueBase & b) const noexcept; /** * Print the value as JSON. Defaults to unconvertable, i.e. throws an error diff --git a/src/libfetchers/fetchers.cc b/src/libfetchers/fetchers.cc index 73923907c3a8..e0abd098016d 100644 --- a/src/libfetchers/fetchers.cc +++ b/src/libfetchers/fetchers.cc @@ -146,7 +146,7 @@ Attrs Input::toAttrs() const return attrs; } -bool Input::operator ==(const Input & other) const +bool Input::operator ==(const Input & other) const noexcept { return attrs == other.attrs; } diff --git a/src/libfetchers/fetchers.hh b/src/libfetchers/fetchers.hh index 551be9a1f9aa..227384715e69 100644 --- a/src/libfetchers/fetchers.hh +++ b/src/libfetchers/fetchers.hh @@ -73,7 +73,7 @@ public: */ bool isLocked() const; - bool operator ==(const Input & other) const; + bool operator ==(const Input & other) const noexcept; bool contains(const Input & other) const; diff --git a/src/libstore/build-result.cc b/src/libstore/build-result.cc index 18f519c5c61d..f6a5706f88cf 100644 --- a/src/libstore/build-result.cc +++ b/src/libstore/build-result.cc @@ -2,17 +2,7 @@ namespace nix { -GENERATE_CMP_EXT( - , - BuildResult, - me->status, - me->errorMsg, - me->timesBuilt, - me->isNonDeterministic, - me->builtOutputs, - me->startTime, - me->stopTime, - me->cpuUser, - me->cpuSystem); +bool BuildResult::operator ==(const BuildResult &) const noexcept = default; +std::strong_ordering BuildResult::operator <=>(const BuildResult &) const noexcept = default; } diff --git a/src/libstore/build-result.hh b/src/libstore/build-result.hh index 3636ad3a4c33..8c66cfeb3533 100644 --- a/src/libstore/build-result.hh +++ b/src/libstore/build-result.hh @@ -3,7 +3,6 @@ #include "realisation.hh" #include "derived-path.hh" -#include "comparator.hh" #include #include @@ -101,7 +100,8 @@ struct BuildResult */ std::optional cpuUser, cpuSystem; - DECLARE_CMP(BuildResult); + bool operator ==(const BuildResult &) const noexcept; + std::strong_ordering operator <=>(const BuildResult &) const noexcept; bool success() { diff --git a/src/libstore/content-address.hh b/src/libstore/content-address.hh index 5925f8e01a2d..6e13bb7319ee 100644 --- a/src/libstore/content-address.hh +++ b/src/libstore/content-address.hh @@ -5,7 +5,6 @@ #include "hash.hh" #include "path.hh" #include "file-content-address.hh" -#include "comparator.hh" #include "variant-wrapper.hh" namespace nix { @@ -55,7 +54,8 @@ struct ContentAddressMethod Raw raw; - GENERATE_CMP(ContentAddressMethod, me->raw); + bool operator ==(const ContentAddressMethod &) const = default; + auto operator <=>(const ContentAddressMethod &) const = default; MAKE_WRAPPER_CONSTRUCTOR(ContentAddressMethod); @@ -141,7 +141,8 @@ struct ContentAddress */ Hash hash; - GENERATE_CMP(ContentAddress, me->method, me->hash); + bool operator ==(const ContentAddress &) const = default; + auto operator <=>(const ContentAddress &) const = default; /** * Compute the content-addressability assertion @@ -200,7 +201,8 @@ struct StoreReferences */ size_t size() const; - GENERATE_CMP(StoreReferences, me->self, me->others); + bool operator ==(const StoreReferences &) const = default; + auto operator <=>(const StoreReferences &) const = default; }; // This matches the additional info that we need for makeTextPath @@ -217,7 +219,8 @@ struct TextInfo */ StorePathSet references; - GENERATE_CMP(TextInfo, me->hash, me->references); + bool operator ==(const TextInfo &) const = default; + auto operator <=>(const TextInfo &) const = default; }; struct FixedOutputInfo @@ -237,7 +240,8 @@ struct FixedOutputInfo */ StoreReferences references; - GENERATE_CMP(FixedOutputInfo, me->hash, me->references); + bool operator ==(const FixedOutputInfo &) const = default; + auto operator <=>(const FixedOutputInfo &) const = default; }; /** @@ -254,7 +258,8 @@ struct ContentAddressWithReferences Raw raw; - GENERATE_CMP(ContentAddressWithReferences, me->raw); + bool operator ==(const ContentAddressWithReferences &) const = default; + auto operator <=>(const ContentAddressWithReferences &) const = default; MAKE_WRAPPER_CONSTRUCTOR(ContentAddressWithReferences); diff --git a/src/libstore/derivations.hh b/src/libstore/derivations.hh index 522523e4597c..656c76d8e152 100644 --- a/src/libstore/derivations.hh +++ b/src/libstore/derivations.hh @@ -8,7 +8,6 @@ #include "repair-flag.hh" #include "derived-path-map.hh" #include "sync.hh" -#include "comparator.hh" #include "variant-wrapper.hh" #include @@ -33,7 +32,8 @@ struct DerivationOutput { StorePath path; - GENERATE_CMP(InputAddressed, me->path); + bool operator == (const InputAddressed &) const = default; + auto operator <=> (const InputAddressed &) const = default; }; /** @@ -57,7 +57,8 @@ struct DerivationOutput */ StorePath path(const StoreDirConfig & store, std::string_view drvName, OutputNameView outputName) const; - GENERATE_CMP(CAFixed, me->ca); + bool operator == (const CAFixed &) const = default; + auto operator <=> (const CAFixed &) const = default; }; /** @@ -77,7 +78,8 @@ struct DerivationOutput */ HashAlgorithm hashAlgo; - GENERATE_CMP(CAFloating, me->method, me->hashAlgo); + bool operator == (const CAFloating &) const = default; + auto operator <=> (const CAFloating &) const = default; }; /** @@ -85,7 +87,8 @@ struct DerivationOutput * isn't known yet. */ struct Deferred { - GENERATE_CMP(Deferred); + bool operator == (const Deferred &) const = default; + auto operator <=> (const Deferred &) const = default; }; /** @@ -104,7 +107,8 @@ struct DerivationOutput */ HashAlgorithm hashAlgo; - GENERATE_CMP(Impure, me->method, me->hashAlgo); + bool operator == (const Impure &) const = default; + auto operator <=> (const Impure &) const = default; }; typedef std::variant< @@ -117,7 +121,8 @@ struct DerivationOutput Raw raw; - GENERATE_CMP(DerivationOutput, me->raw); + bool operator == (const DerivationOutput &) const = default; + auto operator <=> (const DerivationOutput &) const = default; MAKE_WRAPPER_CONSTRUCTOR(DerivationOutput); @@ -178,7 +183,8 @@ struct DerivationType { */ bool deferred; - GENERATE_CMP(InputAddressed, me->deferred); + bool operator == (const InputAddressed &) const = default; + auto operator <=> (const InputAddressed &) const = default; }; /** @@ -202,7 +208,8 @@ struct DerivationType { */ bool fixed; - GENERATE_CMP(ContentAddressed, me->sandboxed, me->fixed); + bool operator == (const ContentAddressed &) const = default; + auto operator <=> (const ContentAddressed &) const = default; }; /** @@ -212,7 +219,8 @@ struct DerivationType { * type, but has some restrictions on its usage. */ struct Impure { - GENERATE_CMP(Impure); + bool operator == (const Impure &) const = default; + auto operator <=> (const Impure &) const = default; }; typedef std::variant< @@ -223,7 +231,8 @@ struct DerivationType { Raw raw; - GENERATE_CMP(DerivationType, me->raw); + bool operator == (const DerivationType &) const = default; + auto operator <=> (const DerivationType &) const = default; MAKE_WRAPPER_CONSTRUCTOR(DerivationType); @@ -313,14 +322,8 @@ struct BasicDerivation static std::string_view nameFromPath(const StorePath & storePath); - GENERATE_CMP(BasicDerivation, - me->outputs, - me->inputSrcs, - me->platform, - me->builder, - me->args, - me->env, - me->name); + bool operator == (const BasicDerivation &) const = default; + auto operator <=> (const BasicDerivation &) const = default; }; class Store; @@ -378,9 +381,8 @@ struct Derivation : BasicDerivation const nlohmann::json & json, const ExperimentalFeatureSettings & xpSettings = experimentalFeatureSettings); - GENERATE_CMP(Derivation, - static_cast(*me), - me->inputDrvs); + bool operator == (const Derivation &) const = default; + auto operator <=> (const Derivation &) const = default; }; diff --git a/src/libstore/derived-path-map.cc b/src/libstore/derived-path-map.cc index 4c1ea417a36d..998d3837ec1d 100644 --- a/src/libstore/derived-path-map.cc +++ b/src/libstore/derived-path-map.cc @@ -54,17 +54,15 @@ typename DerivedPathMap::ChildNode * DerivedPathMap::findSlot(const Single namespace nix { -GENERATE_CMP_EXT( - template<>, - DerivedPathMap>::ChildNode, - me->value, - me->childMap); +template<> +bool DerivedPathMap>::ChildNode::operator == ( + const DerivedPathMap>::ChildNode &) const noexcept = default; -GENERATE_CMP_EXT( - template<>, - DerivedPathMap>, - me->map); +template<> +std::strong_ordering DerivedPathMap>::ChildNode::operator <=> ( + const DerivedPathMap>::ChildNode &) const noexcept = default; +template struct DerivedPathMap>::ChildNode; template struct DerivedPathMap>; }; diff --git a/src/libstore/derived-path-map.hh b/src/libstore/derived-path-map.hh index 393cdedf747f..52507b760c28 100644 --- a/src/libstore/derived-path-map.hh +++ b/src/libstore/derived-path-map.hh @@ -47,7 +47,10 @@ struct DerivedPathMap { */ Map childMap; - DECLARE_CMP(ChildNode); + bool operator == (const ChildNode &) const noexcept; + + decltype(std::declval() <=> std::declval()) + operator <=> (const ChildNode &) const noexcept; }; /** @@ -60,7 +63,9 @@ struct DerivedPathMap { */ Map map; - DECLARE_CMP(DerivedPathMap); + bool operator == (const DerivedPathMap &) const = default; + + auto operator <=> (const DerivedPathMap &) const noexcept; /** * Find the node for `k`, creating it if needed. @@ -83,14 +88,18 @@ struct DerivedPathMap { ChildNode * findSlot(const SingleDerivedPath & k); }; +template<> +bool DerivedPathMap>::ChildNode::operator == ( + const DerivedPathMap>::ChildNode &) const noexcept; + +template<> +std::strong_ordering DerivedPathMap>::ChildNode::operator <=> ( + const DerivedPathMap>::ChildNode &) const noexcept; + +template<> +inline auto DerivedPathMap>::operator <=> (const DerivedPathMap> &) const noexcept = default; -DECLARE_CMP_EXT( - template<>, - DerivedPathMap>::, - DerivedPathMap>); -DECLARE_CMP_EXT( - template<>, - DerivedPathMap>::ChildNode::, - DerivedPathMap>::ChildNode); +extern template struct DerivedPathMap>::ChildNode; +extern template struct DerivedPathMap>; } diff --git a/src/libstore/derived-path.cc b/src/libstore/derived-path.cc index a7b404321087..d83ab5009264 100644 --- a/src/libstore/derived-path.cc +++ b/src/libstore/derived-path.cc @@ -1,6 +1,7 @@ #include "derived-path.hh" #include "derivations.hh" #include "store-api.hh" +#include "comparator.hh" #include @@ -8,26 +9,21 @@ namespace nix { -#define CMP_ONE(CHILD_TYPE, MY_TYPE, FIELD, COMPARATOR) \ - bool MY_TYPE ::operator COMPARATOR (const MY_TYPE & other) const \ - { \ - const MY_TYPE* me = this; \ - auto fields1 = std::tie(*me->drvPath, me->FIELD); \ - me = &other; \ - auto fields2 = std::tie(*me->drvPath, me->FIELD); \ - return fields1 COMPARATOR fields2; \ - } -#define CMP(CHILD_TYPE, MY_TYPE, FIELD) \ - CMP_ONE(CHILD_TYPE, MY_TYPE, FIELD, ==) \ - CMP_ONE(CHILD_TYPE, MY_TYPE, FIELD, !=) \ - CMP_ONE(CHILD_TYPE, MY_TYPE, FIELD, <) - -CMP(SingleDerivedPath, SingleDerivedPathBuilt, output) - -CMP(SingleDerivedPath, DerivedPathBuilt, outputs) - -#undef CMP -#undef CMP_ONE +// Custom implementation to avoid `ref` ptr equality +GENERATE_CMP_EXT( + , + std::strong_ordering, + SingleDerivedPathBuilt, + *me->drvPath, + me->output); + +// Custom implementation to avoid `ref` ptr equality +GENERATE_CMP_EXT( + , + std::strong_ordering, + DerivedPathBuilt, + *me->drvPath, + me->outputs); nlohmann::json DerivedPath::Opaque::toJSON(const StoreDirConfig & store) const { diff --git a/src/libstore/derived-path.hh b/src/libstore/derived-path.hh index b238f844e56d..a3c3d0576e2c 100644 --- a/src/libstore/derived-path.hh +++ b/src/libstore/derived-path.hh @@ -3,7 +3,6 @@ #include "path.hh" #include "outputs-spec.hh" -#include "comparator.hh" #include "config.hh" #include @@ -31,7 +30,8 @@ struct DerivedPathOpaque { static DerivedPathOpaque parse(const StoreDirConfig & store, std::string_view); nlohmann::json toJSON(const StoreDirConfig & store) const; - GENERATE_CMP(DerivedPathOpaque, me->path); + bool operator == (const DerivedPathOpaque &) const = default; + auto operator <=> (const DerivedPathOpaque &) const = default; }; struct SingleDerivedPath; @@ -78,7 +78,8 @@ struct SingleDerivedPathBuilt { const ExperimentalFeatureSettings & xpSettings = experimentalFeatureSettings); nlohmann::json toJSON(Store & store) const; - DECLARE_CMP(SingleDerivedPathBuilt); + bool operator == (const SingleDerivedPathBuilt &) const noexcept; + std::strong_ordering operator <=> (const SingleDerivedPathBuilt &) const noexcept; }; using _SingleDerivedPathRaw = std::variant< @@ -108,6 +109,9 @@ struct SingleDerivedPath : _SingleDerivedPathRaw { return static_cast(*this); } + bool operator == (const SingleDerivedPath &) const = default; + auto operator <=> (const SingleDerivedPath &) const = default; + /** * Get the store path this is ultimately derived from (by realising * and projecting outputs). @@ -201,7 +205,8 @@ struct DerivedPathBuilt { const ExperimentalFeatureSettings & xpSettings = experimentalFeatureSettings); nlohmann::json toJSON(Store & store) const; - DECLARE_CMP(DerivedPathBuilt); + bool operator == (const DerivedPathBuilt &) const noexcept; + std::strong_ordering operator <=> (const DerivedPathBuilt &) const noexcept; }; using _DerivedPathRaw = std::variant< diff --git a/src/libstore/nar-info.cc b/src/libstore/nar-info.cc index 0d219a48929a..3e0a754f981f 100644 --- a/src/libstore/nar-info.cc +++ b/src/libstore/nar-info.cc @@ -4,15 +4,6 @@ namespace nix { -GENERATE_CMP_EXT( - , - NarInfo, - me->url, - me->compression, - me->fileHash, - me->fileSize, - static_cast(*me)); - NarInfo::NarInfo(const Store & store, const std::string & s, const std::string & whence) : ValidPathInfo(StorePath(StorePath::dummy), Hash(Hash::dummy)) // FIXME: hack { diff --git a/src/libstore/nar-info.hh b/src/libstore/nar-info.hh index fd538a7cd9fc..d1f95694e412 100644 --- a/src/libstore/nar-info.hh +++ b/src/libstore/nar-info.hh @@ -24,7 +24,8 @@ struct NarInfo : ValidPathInfo NarInfo(const ValidPathInfo & info) : ValidPathInfo(info) { } NarInfo(const Store & store, const std::string & s, const std::string & whence); - DECLARE_CMP(NarInfo); + bool operator ==(const NarInfo &) const = default; + auto operator <=>(const NarInfo &) const = default; std::string to_string(const Store & store) const; diff --git a/src/libstore/outputs-spec.hh b/src/libstore/outputs-spec.hh index 1ef99a5fc67d..799ecd555a83 100644 --- a/src/libstore/outputs-spec.hh +++ b/src/libstore/outputs-spec.hh @@ -6,9 +6,7 @@ #include #include -#include "comparator.hh" #include "json-impls.hh" -#include "comparator.hh" #include "variant-wrapper.hh" namespace nix { @@ -60,7 +58,8 @@ struct OutputsSpec { Raw raw; - GENERATE_CMP(OutputsSpec, me->raw); + bool operator == (const OutputsSpec &) const = default; + auto operator <=> (const OutputsSpec &) const = default; MAKE_WRAPPER_CONSTRUCTOR(OutputsSpec); @@ -99,7 +98,8 @@ struct ExtendedOutputsSpec { Raw raw; - GENERATE_CMP(ExtendedOutputsSpec, me->raw); + bool operator == (const ExtendedOutputsSpec &) const = default; + auto operator <=> (const ExtendedOutputsSpec &) const = default; MAKE_WRAPPER_CONSTRUCTOR(ExtendedOutputsSpec); diff --git a/src/libstore/path-info.cc b/src/libstore/path-info.cc index ddd7f50d9fcf..ddc6a3e3bc9d 100644 --- a/src/libstore/path-info.cc +++ b/src/libstore/path-info.cc @@ -3,11 +3,13 @@ #include "path-info.hh" #include "store-api.hh" #include "json-utils.hh" +#include "comparator.hh" namespace nix { GENERATE_CMP_EXT( , + std::weak_ordering, UnkeyedValidPathInfo, me->deriver, me->narHash, @@ -19,12 +21,6 @@ GENERATE_CMP_EXT( me->sigs, me->ca); -GENERATE_CMP_EXT( - , - ValidPathInfo, - me->path, - static_cast(*me)); - std::string ValidPathInfo::fingerprint(const Store & store) const { if (narSize == 0) diff --git a/src/libstore/path-info.hh b/src/libstore/path-info.hh index b6dc0855d755..b940973fbc69 100644 --- a/src/libstore/path-info.hh +++ b/src/libstore/path-info.hh @@ -32,17 +32,47 @@ struct SubstitutablePathInfo using SubstitutablePathInfos = std::map; +/** + * Information about a store object. + * + * See `store/store-object` and `protocols/json/store-object-info` in + * the Nix manual + */ struct UnkeyedValidPathInfo { + /** + * Path to derivation that produced this store object, if known. + */ std::optional deriver; + /** * \todo document this */ Hash narHash; + + /** + * Other store objects this store object referes to. + */ StorePathSet references; + + /** + * When this store object was registered in the store that contains + * it, if known. + */ time_t registrationTime = 0; - uint64_t narSize = 0; // 0 = unknown - uint64_t id = 0; // internal use only + + /** + * 0 = unknown + */ + uint64_t narSize = 0; + + /** + * internal use only: SQL primary key for on-disk store objects with + * `LocalStore`. + * + * @todo Remove, layer violaiton + */ + uint64_t id = 0; /** * Whether the path is ultimately trusted, that is, it's a @@ -75,7 +105,12 @@ struct UnkeyedValidPathInfo UnkeyedValidPathInfo(Hash narHash) : narHash(narHash) { }; - DECLARE_CMP(UnkeyedValidPathInfo); + bool operator == (const UnkeyedValidPathInfo &) const noexcept; + + /** + * @todo return `std::strong_ordering` once `id` is removed + */ + std::weak_ordering operator <=> (const UnkeyedValidPathInfo &) const noexcept; virtual ~UnkeyedValidPathInfo() { } @@ -95,7 +130,8 @@ struct UnkeyedValidPathInfo struct ValidPathInfo : UnkeyedValidPathInfo { StorePath path; - DECLARE_CMP(ValidPathInfo); + bool operator == (const ValidPathInfo &) const = default; + auto operator <=> (const ValidPathInfo &) const = default; /** * Return a fingerprint of the store path to be used in binary diff --git a/src/libutil/args.cc b/src/libutil/args.cc index c202facdfea4..d58f4b4aeaf3 100644 --- a/src/libutil/args.cc +++ b/src/libutil/args.cc @@ -57,8 +57,7 @@ void Completions::add(std::string completion, std::string description) }); } -bool Completion::operator<(const Completion & other) const -{ return completion < other.completion || (completion == other.completion && description < other.description); } +auto Completion::operator<=>(const Completion & other) const noexcept = default; std::string completionMarker = "___COMPLETE___"; diff --git a/src/libutil/args.hh b/src/libutil/args.hh index 7759b74a93cc..69ec756520c9 100644 --- a/src/libutil/args.hh +++ b/src/libutil/args.hh @@ -380,7 +380,7 @@ struct Completion { std::string completion; std::string description; - bool operator<(const Completion & other) const; + auto operator<=>(const Completion & other) const noexcept; }; /** diff --git a/src/libutil/canon-path.hh b/src/libutil/canon-path.hh index 8f5a1c2793d6..f84347dc4580 100644 --- a/src/libutil/canon-path.hh +++ b/src/libutil/canon-path.hh @@ -169,7 +169,7 @@ public: * a directory is always followed directly by its children. For * instance, 'foo' < 'foo/bar' < 'foo!'. */ - bool operator < (const CanonPath & x) const + auto operator <=> (const CanonPath & x) const { auto i = path.begin(); auto j = x.path.begin(); @@ -178,10 +178,9 @@ public: if (c_i == '/') c_i = 0; auto c_j = *j; if (c_j == '/') c_j = 0; - if (c_i < c_j) return true; - if (c_i > c_j) return false; + if (auto cmp = c_i <=> c_j; cmp != 0) return cmp; } - return i == path.end() && j != x.path.end(); + return (i != path.end()) <=> (j != x.path.end()); } /** diff --git a/src/libutil/comparator.hh b/src/libutil/comparator.hh index cbc2bb4fd72a..34ba6f4534c3 100644 --- a/src/libutil/comparator.hh +++ b/src/libutil/comparator.hh @@ -1,17 +1,8 @@ #pragma once ///@file -#define DECLARE_ONE_CMP(PRE, QUAL, COMPARATOR, MY_TYPE) \ - PRE bool QUAL operator COMPARATOR(const MY_TYPE & other) const; -#define DECLARE_EQUAL(prefix, qualification, my_type) \ - DECLARE_ONE_CMP(prefix, qualification, ==, my_type) -#define DECLARE_LEQ(prefix, qualification, my_type) \ - DECLARE_ONE_CMP(prefix, qualification, <, my_type) -#define DECLARE_NEQ(prefix, qualification, my_type) \ - DECLARE_ONE_CMP(prefix, qualification, !=, my_type) - -#define GENERATE_ONE_CMP(PRE, QUAL, COMPARATOR, MY_TYPE, ...) \ - PRE bool QUAL operator COMPARATOR(const MY_TYPE & other) const { \ +#define GENERATE_ONE_CMP(PRE, RET, QUAL, COMPARATOR, MY_TYPE, ...) \ + PRE RET QUAL operator COMPARATOR(const MY_TYPE & other) const noexcept { \ __VA_OPT__(const MY_TYPE * me = this;) \ auto fields1 = std::tie( __VA_ARGS__ ); \ __VA_OPT__(me = &other;) \ @@ -19,30 +10,9 @@ return fields1 COMPARATOR fields2; \ } #define GENERATE_EQUAL(prefix, qualification, my_type, args...) \ - GENERATE_ONE_CMP(prefix, qualification, ==, my_type, args) -#define GENERATE_LEQ(prefix, qualification, my_type, args...) \ - GENERATE_ONE_CMP(prefix, qualification, <, my_type, args) -#define GENERATE_NEQ(prefix, qualification, my_type, args...) \ - GENERATE_ONE_CMP(prefix, qualification, !=, my_type, args) - -/** - * Declare comparison methods without defining them. - */ -#define DECLARE_CMP(my_type) \ - DECLARE_EQUAL(,,my_type) \ - DECLARE_LEQ(,,my_type) \ - DECLARE_NEQ(,,my_type) - -/** - * @param prefix This is for something before each declaration like - * `template`. - * - * @param my_type the type are defining operators for. - */ -#define DECLARE_CMP_EXT(prefix, qualification, my_type) \ - DECLARE_EQUAL(prefix, qualification, my_type) \ - DECLARE_LEQ(prefix, qualification, my_type) \ - DECLARE_NEQ(prefix, qualification, my_type) + GENERATE_ONE_CMP(prefix, bool, qualification, ==, my_type, args) +#define GENERATE_SPACESHIP(prefix, ret, qualification, my_type, args...) \ + GENERATE_ONE_CMP(prefix, ret, qualification, <=>, my_type, args) /** * Awful hacky generation of the comparison operators by doing a lexicographic @@ -55,15 +25,19 @@ * will generate comparison operators semantically equivalent to: * * ``` - * bool operator<(const ClassName& other) { - * return field1 < other.field1 && field2 < other.field2 && ...; + * auto operator<=>(const ClassName& other) const noexcept { + * if (auto cmp = field1 <=> other.field1; cmp != 0) + * return cmp; + * if (auto cmp = field2 <=> other.field2; cmp != 0) + * return cmp; + * ... + * return 0; * } * ``` */ #define GENERATE_CMP(args...) \ GENERATE_EQUAL(,,args) \ - GENERATE_LEQ(,,args) \ - GENERATE_NEQ(,,args) + GENERATE_SPACESHIP(,auto,,args) /** * @param prefix This is for something before each declaration like @@ -71,7 +45,6 @@ * * @param my_type the type are defining operators for. */ -#define GENERATE_CMP_EXT(prefix, my_type, args...) \ +#define GENERATE_CMP_EXT(prefix, ret, my_type, args...) \ GENERATE_EQUAL(prefix, my_type ::, my_type, args) \ - GENERATE_LEQ(prefix, my_type ::, my_type, args) \ - GENERATE_NEQ(prefix, my_type ::, my_type, args) + GENERATE_SPACESHIP(prefix, ret, my_type ::, my_type, args) diff --git a/src/libutil/error.cc b/src/libutil/error.cc index e01f064484c0..33c391963f35 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -46,27 +46,22 @@ std::ostream & operator <<(std::ostream & os, const HintFmt & hf) /** * An arbitrarily defined value comparison for the purpose of using traces in the key of a sorted container. */ -inline bool operator<(const Trace& lhs, const Trace& rhs) +inline std::strong_ordering operator<=>(const Trace& lhs, const Trace& rhs) { // `std::shared_ptr` does not have value semantics for its comparison // functions, so we need to check for nulls and compare the dereferenced // values here. if (lhs.pos != rhs.pos) { - if (!lhs.pos) - return true; - if (!rhs.pos) - return false; - if (*lhs.pos != *rhs.pos) - return *lhs.pos < *rhs.pos; + if (auto cmp = bool{lhs.pos} <=> bool{rhs.pos}; cmp != 0) + return cmp; + if (auto cmp = *lhs.pos <=> *rhs.pos; cmp != 0) + return cmp; } // This formats a freshly formatted hint string and then throws it away, which // shouldn't be much of a problem because it only runs when pos is equal, and this function is // used for trace printing, which is infrequent. - return lhs.hint.str() < rhs.hint.str(); + return lhs.hint.str() <=> rhs.hint.str(); } -inline bool operator> (const Trace& lhs, const Trace& rhs) { return rhs < lhs; } -inline bool operator<=(const Trace& lhs, const Trace& rhs) { return !(lhs > rhs); } -inline bool operator>=(const Trace& lhs, const Trace& rhs) { return !(lhs < rhs); } // print lines of code to the ostream, indicating the error column. void printCodeLines(std::ostream & out, diff --git a/src/libutil/error.hh b/src/libutil/error.hh index 269000016219..3d73a58aa54f 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -79,10 +79,7 @@ struct Trace { TracePrint print = TracePrint::Default; }; -inline bool operator<(const Trace& lhs, const Trace& rhs); -inline bool operator> (const Trace& lhs, const Trace& rhs); -inline bool operator<=(const Trace& lhs, const Trace& rhs); -inline bool operator>=(const Trace& lhs, const Trace& rhs); +inline std::strong_ordering operator<=>(const Trace& lhs, const Trace& rhs); struct ErrorInfo { Verbosity level; diff --git a/src/libutil/experimental-features.hh b/src/libutil/experimental-features.hh index 1da2a3ff55d6..6ffbc0c1028d 100644 --- a/src/libutil/experimental-features.hh +++ b/src/libutil/experimental-features.hh @@ -1,7 +1,6 @@ #pragma once ///@file -#include "comparator.hh" #include "error.hh" #include "json-utils.hh" #include "types.hh" diff --git a/src/libutil/git.hh b/src/libutil/git.hh index a65edb964fdf..40f433b66189 100644 --- a/src/libutil/git.hh +++ b/src/libutil/git.hh @@ -39,7 +39,8 @@ struct TreeEntry Mode mode; Hash hash; - GENERATE_CMP(TreeEntry, me->mode, me->hash); + bool operator ==(const TreeEntry &) const = default; + auto operator <=>(const TreeEntry &) const = default; }; /** diff --git a/src/libutil/hash.cc b/src/libutil/hash.cc index 2f2ed813848d..bee30f4ba1b4 100644 --- a/src/libutil/hash.cc +++ b/src/libutil/hash.cc @@ -41,7 +41,7 @@ Hash::Hash(HashAlgorithm algo) : algo(algo) } -bool Hash::operator == (const Hash & h2) const +bool Hash::operator == (const Hash & h2) const noexcept { if (hashSize != h2.hashSize) return false; for (unsigned int i = 0; i < hashSize; i++) @@ -50,7 +50,7 @@ bool Hash::operator == (const Hash & h2) const } -std::strong_ordering Hash::operator <=> (const Hash & h) const +std::strong_ordering Hash::operator <=> (const Hash & h) const noexcept { if (auto cmp = algo <=> h.algo; cmp != 0) return cmp; if (auto cmp = hashSize <=> h.hashSize; cmp != 0) return cmp; diff --git a/src/libutil/hash.hh b/src/libutil/hash.hh index ef96d08c9788..dc95b9f2f9b6 100644 --- a/src/libutil/hash.hh +++ b/src/libutil/hash.hh @@ -88,12 +88,12 @@ public: /** * Check whether two hashes are equal. */ - bool operator == (const Hash & h2) const; + bool operator == (const Hash & h2) const noexcept; /** * Compare how two hashes are ordered. */ - std::strong_ordering operator <=> (const Hash & h2) const; + std::strong_ordering operator <=> (const Hash & h2) const noexcept; /** * Returns the length of a base-16 representation of this hash. diff --git a/src/libutil/memory-source-accessor.hh b/src/libutil/memory-source-accessor.hh index c8f793922d68..235ada6303b0 100644 --- a/src/libutil/memory-source-accessor.hh +++ b/src/libutil/memory-source-accessor.hh @@ -15,11 +15,15 @@ struct MemorySourceAccessor : virtual SourceAccessor * defining what a "file system object" is in Nix. */ struct File { + bool operator == (const File &) const noexcept; + std::strong_ordering operator <=> (const File &) const noexcept; + struct Regular { bool executable = false; std::string contents; - GENERATE_CMP(Regular, me->executable, me->contents); + bool operator == (const Regular &) const = default; + auto operator <=> (const Regular &) const = default; }; struct Directory { @@ -27,13 +31,15 @@ struct MemorySourceAccessor : virtual SourceAccessor std::map> contents; - GENERATE_CMP(Directory, me->contents); + bool operator == (const Directory &) const noexcept; + auto operator <=> (const Directory &) const noexcept; }; struct Symlink { std::string target; - GENERATE_CMP(Symlink, me->target); + bool operator == (const Symlink &) const = default; + auto operator <=> (const Symlink &) const = default; }; using Raw = std::variant; @@ -41,14 +47,13 @@ struct MemorySourceAccessor : virtual SourceAccessor MAKE_WRAPPER_CONSTRUCTOR(File); - GENERATE_CMP(File, me->raw); - Stat lstat() const; }; File root { File::Directory {} }; - GENERATE_CMP(MemorySourceAccessor, me->root); + bool operator == (const MemorySourceAccessor &) const noexcept = default; + auto operator <=> (const MemorySourceAccessor &) const noexcept = default; std::string readFile(const CanonPath & path) override; bool pathExists(const CanonPath & path) override; @@ -72,6 +77,17 @@ struct MemorySourceAccessor : virtual SourceAccessor SourcePath addFile(CanonPath path, std::string && contents); }; + +bool MemorySourceAccessor::File::Directory::operator == ( + const MemorySourceAccessor::File::Directory &) const noexcept = default; +auto MemorySourceAccessor::File::Directory::operator <=> ( + const MemorySourceAccessor::File::Directory &) const noexcept = default; + +bool MemorySourceAccessor::File::operator == ( + const MemorySourceAccessor::File &) const noexcept = default; +std::strong_ordering MemorySourceAccessor::File::operator <=> ( + const MemorySourceAccessor::File &) const noexcept = default; + /** * Write to a `MemorySourceAccessor` at the given path */ diff --git a/src/libutil/position.cc b/src/libutil/position.cc index 724e560b7a48..573efeeb2d81 100644 --- a/src/libutil/position.cc +++ b/src/libutil/position.cc @@ -17,12 +17,6 @@ Pos::operator std::shared_ptr() const return std::make_shared(&*this); } -bool Pos::operator<(const Pos &rhs) const -{ - return std::forward_as_tuple(line, column, origin) - < std::forward_as_tuple(rhs.line, rhs.column, rhs.origin); -} - std::optional Pos::getCodeLines() const { if (line == 0) diff --git a/src/libutil/position.hh b/src/libutil/position.hh index 9bdf3b4b5dba..f8f34419b7a3 100644 --- a/src/libutil/position.hh +++ b/src/libutil/position.hh @@ -22,21 +22,17 @@ struct Pos struct Stdin { ref source; - bool operator==(const Stdin & rhs) const + bool operator==(const Stdin & rhs) const noexcept { return *source == *rhs.source; } - bool operator!=(const Stdin & rhs) const - { return *source != *rhs.source; } - bool operator<(const Stdin & rhs) const - { return *source < *rhs.source; } + std::strong_ordering operator<=>(const Stdin & rhs) const noexcept + { return *source <=> *rhs.source; } }; struct String { ref source; - bool operator==(const String & rhs) const + bool operator==(const String & rhs) const noexcept { return *source == *rhs.source; } - bool operator!=(const String & rhs) const - { return *source != *rhs.source; } - bool operator<(const String & rhs) const - { return *source < *rhs.source; } + std::strong_ordering operator<=>(const String & rhs) const noexcept + { return *source <=> *rhs.source; } }; typedef std::variant Origin; @@ -65,8 +61,7 @@ struct Pos std::optional getCodeLines() const; bool operator==(const Pos & rhs) const = default; - bool operator!=(const Pos & rhs) const = default; - bool operator<(const Pos & rhs) const; + auto operator<=>(const Pos & rhs) const = default; struct LinesIterator { using difference_type = size_t; diff --git a/src/libutil/ref.hh b/src/libutil/ref.hh index 03aa642739ca..c1f7b6846a83 100644 --- a/src/libutil/ref.hh +++ b/src/libutil/ref.hh @@ -89,9 +89,9 @@ public: return p != other.p; } - bool operator < (const ref & other) const + auto operator <=> (const ref & other) const { - return p < other.p; + return p <=> other.p; } private: diff --git a/src/libutil/source-accessor.hh b/src/libutil/source-accessor.hh index cc8db01f59c7..d3a3a45ffc13 100644 --- a/src/libutil/source-accessor.hh +++ b/src/libutil/source-accessor.hh @@ -151,9 +151,9 @@ struct SourceAccessor : std::enable_shared_from_this return number == x.number; } - bool operator < (const SourceAccessor & x) const + auto operator <=> (const SourceAccessor & x) const { - return number < x.number; + return number <=> x.number; } void setPathDisplay(std::string displayPrefix, std::string displaySuffix = ""); diff --git a/src/libutil/source-path.cc b/src/libutil/source-path.cc index 023b5ed4b914..759d3c355798 100644 --- a/src/libutil/source-path.cc +++ b/src/libutil/source-path.cc @@ -47,19 +47,14 @@ SourcePath SourcePath::operator / (const CanonPath & x) const SourcePath SourcePath::operator / (std::string_view c) const { return {accessor, path / c}; } -bool SourcePath::operator==(const SourcePath & x) const +bool SourcePath::operator==(const SourcePath & x) const noexcept { return std::tie(*accessor, path) == std::tie(*x.accessor, x.path); } -bool SourcePath::operator!=(const SourcePath & x) const +std::strong_ordering SourcePath::operator<=>(const SourcePath & x) const noexcept { - return std::tie(*accessor, path) != std::tie(*x.accessor, x.path); -} - -bool SourcePath::operator<(const SourcePath & x) const -{ - return std::tie(*accessor, path) < std::tie(*x.accessor, x.path); + return std::tie(*accessor, path) <=> std::tie(*x.accessor, x.path); } std::ostream & operator<<(std::ostream & str, const SourcePath & path) diff --git a/src/libutil/source-path.hh b/src/libutil/source-path.hh index 83ec6295de1d..faf0a5a31856 100644 --- a/src/libutil/source-path.hh +++ b/src/libutil/source-path.hh @@ -103,9 +103,8 @@ struct SourcePath */ SourcePath operator / (std::string_view c) const; - bool operator==(const SourcePath & x) const; - bool operator!=(const SourcePath & x) const; - bool operator<(const SourcePath & x) const; + bool operator==(const SourcePath & x) const noexcept; + std::strong_ordering operator<=>(const SourcePath & x) const noexcept; /** * Convenience wrapper around `SourceAccessor::resolveSymlinks()`. diff --git a/src/libutil/suggestions.hh b/src/libutil/suggestions.hh index 9abf5ee5fad4..08250e3338bf 100644 --- a/src/libutil/suggestions.hh +++ b/src/libutil/suggestions.hh @@ -1,7 +1,6 @@ #pragma once ///@file -#include "comparator.hh" #include "types.hh" #include @@ -20,7 +19,8 @@ public: std::string to_string() const; - GENERATE_CMP(Suggestion, me->distance, me->suggestion) + bool operator ==(const Suggestion &) const = default; + auto operator <=>(const Suggestion &) const = default; }; class Suggestions { diff --git a/src/libutil/url.cc b/src/libutil/url.cc index f4178f87fd99..bcbe9ea4eb21 100644 --- a/src/libutil/url.cc +++ b/src/libutil/url.cc @@ -132,7 +132,7 @@ std::string ParsedURL::to_string() const + (fragment.empty() ? "" : "#" + percentEncode(fragment)); } -bool ParsedURL::operator ==(const ParsedURL & other) const +bool ParsedURL::operator ==(const ParsedURL & other) const noexcept { return scheme == other.scheme diff --git a/src/libutil/url.hh b/src/libutil/url.hh index 6cd06e53d17c..738ee9f82e64 100644 --- a/src/libutil/url.hh +++ b/src/libutil/url.hh @@ -18,7 +18,7 @@ struct ParsedURL std::string to_string() const; - bool operator ==(const ParsedURL & other) const; + bool operator ==(const ParsedURL & other) const noexcept; /** * Remove `.` and `..` path elements. diff --git a/src/nix/profile.cc b/src/nix/profile.cc index a5a40e4f66c9..8546f056ae04 100644 --- a/src/nix/profile.cc +++ b/src/nix/profile.cc @@ -27,10 +27,10 @@ struct ProfileElementSource std::string attrPath; ExtendedOutputsSpec outputs; - bool operator < (const ProfileElementSource & other) const + auto operator <=> (const ProfileElementSource & other) const { return - std::tuple(originalRef.to_string(), attrPath, outputs) < + std::tuple(originalRef.to_string(), attrPath, outputs) <=> std::tuple(other.originalRef.to_string(), other.attrPath, other.outputs); } diff --git a/tests/unit/libutil/git.cc b/tests/unit/libutil/git.cc index ff934c117b8e..5ca07d42db8c 100644 --- a/tests/unit/libutil/git.cc +++ b/tests/unit/libutil/git.cc @@ -229,7 +229,7 @@ TEST_F(GitTest, both_roundrip) { mkSinkHook("", root.hash, BlobMode::Regular); - ASSERT_EQ(*files, *files2); + ASSERT_EQ(files->root, files2->root); } TEST(GitLsRemote, parseSymrefLineWithReference) {