From 6428e4e1ab8cdc7c6b57a5403ec3f6cbf2db2e17 Mon Sep 17 00:00:00 2001
From: ROUVREAU Vincent <vincent.rouvreau@inria.fr>
Date: Mon, 10 May 2021 15:16:19 +0200
Subject: [PATCH] Rework spaceship operator, and some phrasings

---
 3-Operators/2-Comparison.ipynb | 43 ++++++++++++++++++++++++++++------
 1 file changed, 36 insertions(+), 7 deletions(-)

diff --git a/3-Operators/2-Comparison.ipynb b/3-Operators/2-Comparison.ipynb
index 2aa90a2..8571de7 100644
--- a/3-Operators/2-Comparison.ipynb
+++ b/3-Operators/2-Comparison.ipynb
@@ -86,7 +86,7 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "Defining `<` operator does not automatically defines the others, but all may be defined once `operator<` and `operator!=` are defined:\n",
+    "Defining `operator<` does not automatically defines the others, but a **good practice** is to define the other comparison operators once `operator<` and `operator!=` are defined, and in function of these two as follows:\n",
     "\n",
     "* `operator>(lhs, rhs)` is `operator<(rhs, lhs)`\n",
     "* `operator>=(lhs, rhs)` is `!operator<(lhs, rhs)`\n",
@@ -100,7 +100,7 @@
     "\n",
     "* None is defined by default.\n",
     "* They are independant from each other: defining one **doesn't** define the other one...\n",
-    "* ... but **never** define `operator!=` as something other than `!operator==`!\n",
+    "* ... but **never** define `operator!=` as something other than `!(operator==)`\n",
     "* As we've seen above, they are not involved at all in implicit definitions of `<=` or `>=` if only `<` or `>` is explicitly defined. Same remark as the line above though!\n",
     "* Make sure you're thought well the result of your comparison:\n"
    ]
@@ -284,7 +284,7 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "C++ 20 introduces the so-called spaceship operator, which enables defining more concisely all those operators:"
+    "C++ 20 introduces the so-called spaceship operator, which enables defining more concisely all those operators  (the following code doesn't work in Xeus-cling; you may use [@Coliru](https://coliru.stacked-crooked.com/a/1cec8ddda8a1eece)):"
    ]
   },
   {
@@ -400,7 +400,7 @@
    "source": [
     "This is rather cumbersome to type, but it is even dangerous: if at some point we extend the class and add `Nsaw_` for instance, we need not to forget to update the operator as well!\n",
     "\n",
-    "C++ 20 will enable default behaviour for the comparison operators, so in this case you would be able to write instead ([@Coliru](https://coliru.stacked-crooked.com/a/11c22df77c7065fe)):"
+    "C++ 20 will enable default behaviour for the comparison operators, so in this case you would be able to write instead ([@Coliru](https://coliru.stacked-crooked.com/a/fa889df647c73a7f)):"
    ]
   },
   {
@@ -413,8 +413,9 @@
     "\n",
     "struct Toolbox\n",
     "{\n",
-    "    bool operator==(const Toolbox&) const = default; \n",
-    "    // < apparently only works with the internal declaration for operator==\n",
+    "    bool operator==(const Toolbox&) const = default;\n",
+    "\n",
+    "    auto operator<=>(const Toolbox&) const = default;\n",
     "    \n",
     "    unsigned int Nscrewdriver_;\n",
     "    \n",
@@ -437,6 +438,7 @@
     "    toolbox2.Nnails_ = 200;\n",
     "    \n",
     "    std::cout << std::boolalpha <<  (toolbox1 == toolbox2) << std::endl;\n",
+    "    std::cout << std::boolalpha <<  (toolbox1 <  toolbox2) << std::endl;\n",
     " \n",
     "    return EXIT_SUCCESS;   \n",
     "}"
@@ -446,7 +448,34 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "[Examples](https://www.modernescpp.com/index.php/c-20-more-details-to-the-spaceship-operator)  on [the](https://devblogs.microsoft.com/cppblog/simplify-your-code-with-rocket-science-c20s-spaceship-operator/) Web often show the defaulting of a comparison used directly upon the spaceship operator, which is something I will have to investigate when I upgrade to C++ 20 as it seems at first sight rather dangerous to me (see the `Rational` example, where even the default `operator==` is unlikely to be what we want)."
+    "As you can experiment, the `operator<` will compare data attributes in order of their declaration as if it was implemented this way:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "bool operator<(const Rational& lhs, const Rational& rhs)\n",
+    "{\n",
+    "    if !(toolbox1.Nscrewdriver_ == toolbox2.Nscrewdriver_)\n",
+    "        return toolbox1.Nscrewdriver_ < toolbox2.Nscrewdriver_;\n",
+    "    if !(toolbox1.Nhammer_ == toolbox2.Nhammer_)\n",
+    "        return toolbox1.Nhammer_ < toolbox2.Nhammer_;\n",
+    "    if !(toolbox1.Nnails_ == toolbox2.Nnails_)\n",
+    "        return toolbox1.Nnails_ < toolbox2.Nnails_;\n",
+    "    return false;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "[This example](https://www.modernescpp.com/index.php/c-20-more-details-to-the-spaceship-operator), or [that example](https://devblogs.microsoft.com/cppblog/simplify-your-code-with-rocket-science-c20s-spaceship-operator/) show other defaulting of a comparison used directly upon the spaceship operator.\n",
+    "\n",
+    "**Be aware** the default implementation may not be what you expected (see the `Rational` example, where even the default `operator==` is unlikely to be what we want)."
    ]
   },
   {
-- 
GitLab