From 2fd4a6fac474fd1049e4af63b53bb71b277c6aab Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= <sebastien@dynare.org>
Date: Fri, 5 Jan 2024 18:32:18 +0100
Subject: [PATCH] C++20 modernization: use new spaceship operator to simplify
 comparisons

---
 mex/sources/libkorder/sylv/Vector.cc     | 15 ++++-----------
 mex/sources/libkorder/sylv/Vector.hh     | 18 ++----------------
 mex/sources/libkorder/tl/equivalence.cc  | 10 ++++++----
 mex/sources/libkorder/tl/equivalence.hh  |  5 +++--
 mex/sources/libkorder/tl/int_sequence.cc |  8 ++++----
 mex/sources/libkorder/tl/int_sequence.hh | 10 +++-------
 6 files changed, 22 insertions(+), 44 deletions(-)

diff --git a/mex/sources/libkorder/sylv/Vector.cc b/mex/sources/libkorder/sylv/Vector.cc
index 1887a62471..1972417052 100644
--- a/mex/sources/libkorder/sylv/Vector.cc
+++ b/mex/sources/libkorder/sylv/Vector.cc
@@ -317,17 +317,10 @@ ConstVector::operator==(const ConstVector& y) const
   return i == len;
 }
 
-bool
-ConstVector::operator<(const ConstVector& y) const
-{
-  int i = std::min(len, y.len);
-  int ii = 0;
-  while (ii < i && operator[](ii) == y[ii])
-    ii++;
-  if (ii < i)
-    return operator[](ii) < y[ii];
-  else
-    return len < y.len;
+std::partial_ordering
+ConstVector::operator<=>(const ConstVector& y) const
+{
+  return std::lexicographical_compare_three_way(data, data + len, y.data, y.data + y.len);
 }
 
 double
diff --git a/mex/sources/libkorder/sylv/Vector.hh b/mex/sources/libkorder/sylv/Vector.hh
index be6d5f378c..d097ac105b 100644
--- a/mex/sources/libkorder/sylv/Vector.hh
+++ b/mex/sources/libkorder/sylv/Vector.hh
@@ -25,6 +25,7 @@
    to avoid running virtual method invokation mechanism. Some
    members, and methods are thus duplicated */
 
+#include <compare>
 #include <complex>
 #include <utility>
 
@@ -220,22 +221,7 @@ public:
   // Exact equality
   bool operator==(const ConstVector& y) const;
   // Lexicographic ordering
-  bool operator<(const ConstVector& y) const;
-  bool
-  operator<=(const ConstVector& y) const
-  {
-    return operator<(y) || operator==(y);
-  }
-  bool
-  operator>(const ConstVector& y) const
-  {
-    return !operator<=(y);
-  }
-  bool
-  operator>=(const ConstVector& y) const
-  {
-    return !operator<(y);
-  }
+  [[nodiscard]] std::partial_ordering operator<=>(const ConstVector& y) const;
 
   [[nodiscard]] double getNorm() const;
   [[nodiscard]] double getMax() const;
diff --git a/mex/sources/libkorder/tl/equivalence.cc b/mex/sources/libkorder/tl/equivalence.cc
index 9b8f4de5a5..5728679fc6 100644
--- a/mex/sources/libkorder/tl/equivalence.cc
+++ b/mex/sources/libkorder/tl/equivalence.cc
@@ -1,6 +1,6 @@
 /*
  * Copyright © 2004 Ondra Kamenik
- * Copyright © 2019-2023 Dynare Team
+ * Copyright © 2019-2024 Dynare Team
  *
  * This file is part of Dynare.
  *
@@ -35,12 +35,14 @@ OrdSequence::operator[](int i) const
    orderings can be used for different problem sizes. We order them
    according to the average, and then according to the first item. */
 
-bool
-OrdSequence::operator<(const OrdSequence& s) const
+std::partial_ordering
+OrdSequence::operator<=>(const OrdSequence& s) const
 {
   double ta = average();
   double sa = s.average();
-  return (ta < sa || ((ta == sa) && (operator[](0) > s[0])));
+  if (auto cmp1 = ta <=> sa; cmp1 != 0)
+    return cmp1;
+  return operator[](0) <=> s[0];
 }
 
 bool
diff --git a/mex/sources/libkorder/tl/equivalence.hh b/mex/sources/libkorder/tl/equivalence.hh
index 1cc9e9abe2..82e635878a 100644
--- a/mex/sources/libkorder/tl/equivalence.hh
+++ b/mex/sources/libkorder/tl/equivalence.hh
@@ -55,6 +55,7 @@
 
 #include "int_sequence.hh"
 
+#include <compare>
 #include <list>
 #include <string>
 #include <vector>
@@ -62,7 +63,7 @@
 /* Here is the abstraction for an equivalence class. We implement it as
    vector<int>. We have a constructor for empty class, copy
    constructor. What is important here is the ordering operator
-   operator<() and methods for addition of an integer, and addition of
+   operator<=>() and methods for addition of an integer, and addition of
    another sequence. Also we provide method has() which returns true if a
    given integer is contained. */
 
@@ -76,7 +77,7 @@ public:
   }
   bool operator==(const OrdSequence& s) const;
   int operator[](int i) const;
-  bool operator<(const OrdSequence& s) const;
+  [[nodiscard]] std::partial_ordering operator<=>(const OrdSequence& s) const;
   [[nodiscard]] const std::vector<int>&
   getData() const
   {
diff --git a/mex/sources/libkorder/tl/int_sequence.cc b/mex/sources/libkorder/tl/int_sequence.cc
index 767de4b4b8..cd260caf66 100644
--- a/mex/sources/libkorder/tl/int_sequence.cc
+++ b/mex/sources/libkorder/tl/int_sequence.cc
@@ -1,6 +1,6 @@
 /*
  * Copyright © 2004 Ondra Kamenik
- * Copyright © 2019-2023 Dynare Team
+ * Copyright © 2019-2024 Dynare Team
  *
  * This file is part of Dynare.
  *
@@ -103,10 +103,10 @@ IntSequence::operator==(const IntSequence& s) const
   return std::equal(data, data + length, s.data, s.data + s.length);
 }
 
-bool
-IntSequence::operator<(const IntSequence& s) const
+std::strong_ordering
+IntSequence::operator<=>(const IntSequence& s) const
 {
-  return std::lexicographical_compare(data, data + length, s.data, s.data + s.length);
+  return std::lexicographical_compare_three_way(data, data + length, s.data, s.data + s.length);
 }
 
 bool
diff --git a/mex/sources/libkorder/tl/int_sequence.hh b/mex/sources/libkorder/tl/int_sequence.hh
index e3af71b3a0..dd8f5e3e5f 100644
--- a/mex/sources/libkorder/tl/int_sequence.hh
+++ b/mex/sources/libkorder/tl/int_sequence.hh
@@ -43,6 +43,7 @@
 #define INT_SEQUENCE_HH
 
 #include <algorithm>
+#include <compare>
 #include <initializer_list>
 #include <utility>
 #include <vector>
@@ -136,15 +137,10 @@ public:
     return length;
   }
 
-  /* We provide two orderings. The first operator<() is the linear
+  /* We provide two orderings. The first operator<=>() is the linear
      lexicographic ordering, the second less() is the non-linear Cartesian
      ordering. */
-  bool operator<(const IntSequence& s) const;
-  bool
-  operator<=(const IntSequence& s) const
-  {
-    return (operator==(s) || operator<(s));
-  }
+  [[nodiscard]] std::strong_ordering operator<=>(const IntSequence& s) const;
   [[nodiscard]] bool lessEq(const IntSequence& s) const;
   [[nodiscard]] bool less(const IntSequence& s) const;
 
-- 
GitLab