<html><head>
<meta http-equiv="Content-Language" content="en-us">
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Defaulted comparison operators</title>
<style type="text/css">
.addition {
    background-color: #66FF99;
}
.removal {
    text-decoration: line-through;
}
</style>
</head>

<body>

  <table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="619">
    <tr>
      <td width="167" align="left" valign="top">Document number:</td>
      <td width="452"><i>Nnnnn=yy-nnnn</i></td>
    </tr>
    <tr>
      <td width="167" align="left" valign="top">Date:</td>
      <td width="452"><i>2013-12-21</i></td>
    </tr>
    <tr>
      <td width="167" align="left" valign="top">Project:</td>
      <td width="452">Programming Language C++, Language Evolution Working Group</td>
    </tr>
    <tr>
      <td width="167" align="left" valign="top">Reply-to:</td>
      <td width="452">Oleg Smolsky <a href="mailto:oleg.smolsky@gmail.com">oleg.smolsky@gmail.com</a></td>
    </tr>
  </table>

    <h1>I. Introduction</h1>
    <p>Provide means of generating default equality, inequality and comparison member operators
        for user-defined types. This is strictly
       an "opt in" feature so that semantics of existing code remain intact.
    <h1>II. Motivation and scope</h1>
    <p>This feature would be useful for modern C++ code that operates with types
       composed of "regular" members. The definition of equality is trivial in such cases -
       member-wise comparison. Inequality can then be generated as an inverse.
    <p>This proposal is based on the notion of "regular" types that naturally compose. Such
       cases are becoming more prevalent as people program more with value types and writing
       (in)equality manually becomes tiresome. This is especially true when trying to
       lexicographically compare members.

    <h1>III. Design decisions</h1>
    <h3>The proposed syntax</h3>
        Member-wise generation of special functions is already present in the Standard (see secion 12),
        so it seems naturation to extend the syntax to cover comparison member functions.

    The proposed syntax for generating the new "defaulted" member functions is as follows:
    <pre>
        struct Thing {
            int a, b, c, d;

            bool operator==(const Thing &) const = default;      // 1a
            bool operator<(const Thing &) const = default;       // 1b

            bool operator!=(const Thing &) const = default;      // 2

            bool operator>=(const Thing &) const = default;      // 3a
            bool operator>(const Thing &) const = default;       // 3b
            bool operator<=(const Thing &) const = default;      // 3c
        };</pre>
    <p>Aformentioned should generate definitions compatible to the following example:
    <pre>
        bool Thing::operator==(const Thing &r) const {
            return a == r.a && b == r.b && c == r.c && d == r.d;
        }
        bool Thing::operator<(const Thing &r) const {
            return std::tie(a, b, c, d) < std::tie(r.a, r.b, r.c, r.d);
        }

        bool Thing::operator!=(const Thing &r) const {
            return !(*this == r);
        }

        bool Thing::operator>=(const Thing &r) const {
            return !(*this < r);
        }
        bool Thing::operator>(const Thing &r) const {
            return r < *this;
        }
        bool Thing::operator<=(const Thing &r) const {
            return !(*this > r);
        }</pre>
    <p>I feel this is a natural choice because:
       <ul>
            <li>C++11 already has member function specifiers such as "default" and "delete"
            <li>Users must "opt in" to get the new behavior
            <li>Member functions must be declared and are, hence, seen in the source code
       </ul>

    <h3>Other points of consideration</h3>
    <p>It is possible to mandate that <code>operator!=()</code> is to be implemented in a member-wise
        fashion and it would we consistent with copy construction, assignment and equality. However:
        <ul>
            <li>Such an implementation is not useful
            <li>The most logical choice for inequality is the boolean inverse of equality
            <li>Users are free to implement their own behavior any way the see fit
        </ul>

    <h1>IV. Implementation</h1>
        <p>I have a working prototype implementation using Clang that does the following:
        <ul>
            <li>parses the proposed syntax
            <li>declares and defines the new member functions for an arbitrary number of built-in and   
                composite members
            <li>Equality is generated in a member-wise fashion. Both built-in and user-defined types 
                are supported.
            <li><code>opertator<()</code> is implemented via a call to <code>std::tie()</code>
            <li>performs minimal semantic checks
        </ul>

        <p> The following additional work is needed:
        <ul>
            <li>support for base classes
            <li>enhanced diagnostics pertinent to non-regular members
            <li>careful review by language and compiler experts
        </ul>

    <h1>V. Technical specifications</h1>
    <h3>Correction for "12 Special member function [special]" </h3>
    <p>The default constructor (12.1), copy constructor and copy assignment operator (12.8), 
        move constructor and move assignment operator (12.8)
        <span class="addition">, equality operators (12.10), comparison operator (12.11)</span>
        and destructor (12.4) are special member functions.
    <h3>Additional section</h3>
    <p><b>12.10 Comparing equality [class.equality]</b>
    <p>Composite types can provide overloaded equality and inequality operators. The implementation
       can be instructed to generate a default implementation via the <i>= default</i> notation
       as these member functions are considered special as per [special].

    <p>Example:
    <pre>
        struct Thing {
            int a, b, c, d;

            bool operator==(const Thing &) const = default;      // 1a
            bool operator<(const Thing &) const = default;       // 1b

            bool operator!=(const Thing &) const = default;      // 2

            bool operator>=(const Thing &) const = default;      // 3a
            bool operator>(const Thing &) const = default;       // 3b
            bool operator<=(const Thing &) const = default;      // 3c
        };</pre>
   
    <ul>
        <li>The implementation will generate a member-wise comparison for (1a) that will cover trivial
           types as well as composite types that provide an overloaded equality operator.
        <li>The implementation will generate a lexicographical comparison of member values
            compatible to <code>std::tie()</code> for (1b)
        <li>The implementation will generate a logical inverse of equality for (2)
        <li>The implementation will generate a logical inverse of <code>operator<()</code> for (3a)
        <li>The implementation will generate a "reverse" comparison for (3b)
        <li>The implementation will generate a logical inverse of <code>operator>()</code> for (3c)
    </ul>

    <h1>VI. Acknowledgments</h1>
        <p>The fundamental idea comes from Alex Stepanov as his work revolves around 
        "regular" types. Such types should be automatically copied, assigned and compared. 
        The first two points have been in the C++ language from the beginning and this 
        proposal attempts to address the last one.

</body></html>