Skip to content

Commit

Permalink
Merge 2019-07 CWG Motion 9
Browse files Browse the repository at this point in the history
P1630R1 Spaceship needs a tune-up

Fixes #2988.
  • Loading branch information
zygoloid committed Aug 2, 2019
2 parents 6e5a3e9 + 5d1bb1c commit c88aa3c
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 52 deletions.
48 changes: 28 additions & 20 deletions source/classes.tex
Original file line number Diff line number Diff line change
Expand Up @@ -6708,6 +6708,12 @@
\item a friend of \tcode{C} having two parameters of type \tcode{const C\&}.
\end{itemize}

\pnum
A defaulted comparison operator function for class \tcode{C}
is defined as deleted if
any non-static data member of \tcode{C} is of reference type or
\tcode{C} is a union-like class\iref{class.union.anon}.

\pnum
If the class definition
does not explicitly declare an \tcode{==} operator function,
Expand Down Expand Up @@ -6744,15 +6750,22 @@
given a glvalue \tcode{x} of type \tcode{const C}, either:
\begin{itemize}
\item
\tcode{C} is a non-class type and \tcode{x <=> x} is a valid expression
of type \tcode{std::strong_ordering} or \tcode{std::strong_equality}, or
\tcode{C} is a non-class type and
\tcode{x <=> x} is a valid expression
of type \tcode{std::strong_ordering} or \tcode{std::strong_equality}, or

\item
\tcode{C} is a class type with an \tcode{==} operator
defined as defaulted in the definition of \tcode{C},
\tcode{x == x} is well-formed when contextually converted to \tcode{bool},
all of \tcode{C}'s base class subobjects and non-static data members
have strong structural equality, and
\tcode{C} has no \tcode{mutable} or \tcode{volatile} subobjects.
\tcode{C} is a class type
where all of the following hold:
\begin{itemize}
\item All of \tcode{C}'s base class subobjects and non-static data members
have strong structural equality.
\item \tcode{C} has no mutable or volatile non-static data members.
\item At the end of the definition of \tcode{C},
overload resolution performed for the expression \tcode{x == x} succeeds and
finds either a friend or public member \tcode{==} operator
that is defined as defaulted in the definition of \tcode{C}.
\end{itemize}
\end{itemize}

\pnum
Expand Down Expand Up @@ -6807,15 +6820,12 @@
with parameters \tcode{x} and \tcode{y} is defined as deleted if
\begin{itemize}
\item
overload resolution\iref{over.match}, as applied to \tcode{x == y}
(also considering synthesized candidates
with reversed order of parameters\iref{over.match.oper}),
results in an ambiguity or a function
that is deleted or inaccessible from the operator function, or
overload resolution\iref{over.match}, as applied to \tcode{x == y},
does not result in a usable function, or
\item
\tcode{x == y} cannot be contextually converted to \tcode{bool}.
\tcode{x == y} is not a prvalue of type \tcode{bool}.
\end{itemize}
Otherwise, the operator function yields \tcode{(x == y) ?\ false :\ true}.
Otherwise, the operator function yields \tcode{!(x == y)}.

\pnum
\begin{example}
Expand All @@ -6824,7 +6834,7 @@
int i;
friend bool operator==(const D& x, const D& y) = default;
// OK, returns \tcode{x.i == y.i}
bool operator!=(const D& z) const = default; // OK, returns \tcode{(*this == z) ?\ false :\ true}
bool operator!=(const D& z) const = default; // OK, returns \tcode{!(*this == z)}
};
\end{codeblock}
\end{example}
Expand Down Expand Up @@ -6990,10 +7000,8 @@
\begin{itemize}
\item
overload resolution\iref{over.match},
as applied to \tcode{x <=> y}
results in an ambiguity
or a function that is deleted or inaccessible from the operator function,
or
as applied to \tcode{x <=> y},
does not result in a usable function, or

\item
the operator \tcode{@}
Expand Down
31 changes: 31 additions & 0 deletions source/compatibility.tex
Original file line number Diff line number Diff line change
Expand Up @@ -2004,6 +2004,37 @@
};
\end{codeblock}

\rSec2[diff.cpp17.over]{\ref{over}: overloading}

\diffref{over.match.oper}
\change
Equality and inequality expressions can now find
reversed and rewritten candidates.
\rationale
Improve consistency of equality with three-way comparison
and make it easier to write the full complement of equality operations.
\effect
Equality and inequality expressions between two objects of different types,
where one is convertible to the other,
could invoke a different operator.
Equality and inequality expressions between two objects of the same type
could become ambiguous.
\begin{codeblock}
struct A {
operator int() const;
};

bool operator==(A, int); // \#1
// \#2 is built-in candidate: \tcode{bool operator==(int, int);}
// \#3 is built-in candidate: \tcode{bool operator!=(int, int);}

int check(A x, A y) {
return (x == y) + // ill-formed; previously well-formed
(10 == x) + // calls \#1, previously selected \#2
(10 != x); // calls \#1, previously selected \#3
}
\end{codeblock}

\rSec2[diff.cpp17.temp]{\ref{temp}: templates}

\diffref{temp.names}
Expand Down
77 changes: 45 additions & 32 deletions source/overloading.tex
Original file line number Diff line number Diff line change
Expand Up @@ -1077,44 +1077,44 @@
that is not a function template specialization.
\end{itemize}

\item
The rewritten candidate set is determined as follows:
\begin{itemize}
\item
For the relational\iref{expr.rel} operators,
the rewritten candidates include
all member, non-member, and built-in candidates
for the operator \tcode{<=>}
for which the rewritten expression
\tcode{(x <=> y) @ 0} is well-formed using that \tcode{operator<=>}.
all non-rewritten candidates
for the expression \tcode{x <=> y}.
\item
For the
relational\iref{expr.rel} and
three-way comparison\iref{expr.spaceship}
operators,
the rewritten candidates also include
a synthesized candidate,
with the order of the two parameters reversed,
for each member, non-member, and built-in candidate
for the operator \tcode{<=>}
for which the rewritten expression
\tcode{0 @ (y <=> x)} is well-formed using that \tcode{operator<=>}.
for each non-rewritten candidate
for the expression
\tcode{y <=> x}.
\item
For the \tcode{!=} operator\iref{expr.eq},
the rewritten candidates
include all member, non-member, and built-in candidates
for the operator \tcode{==}
for which the rewritten expression \tcode{(x == y)} is well-formed
when contextually converted to \tcode{bool} using that operator \tcode{==}.
include all non-rewritten candidates
for the expression \tcode{x == y}.
\item
For the equality operators,
the rewritten candidates also include a synthesized candidate,
with the order of the two parameters reversed,
for each member, non-member, and built-in candidate for the operator \tcode{==}
for which the rewritten expression \tcode{(y == x)} is well-formed
when contextually converted to \tcode{bool} using that operator \tcode{==}.
for each non-rewritten candidate
for the expression \tcode{y == x}.
\item
For all other operators, the rewritten candidate set is empty.
\end{itemize}
\begin{note}
A candidate synthesized from a member candidate has its implicit
object parameter as the second parameter, thus implicit conversions
are considered for the first, but not for the second, parameter.
\end{note}
In each case, rewritten candidates are not considered
in the context of the rewritten expression.
For all other operators, the rewritten candidate set is empty.
\end{itemize}

\pnum
Expand Down Expand Up @@ -1165,26 +1165,39 @@
\end{example}

\pnum
If a rewritten candidate is selected by overload resolution
for a relational or three-way comparison operator \tcode{@},
If a rewritten \tcode{operator<=>} candidate
is selected by overload resolution
for an operator \tcode{@},
\tcode{x @ y}
is interpreted as the rewritten expression:
is interpreted as
\tcode{0 @ (y <=> x)}
if the selected candidate is a synthesized candidate
with reversed order of parameters,
or \tcode{(x <=> y) @ 0} otherwise,
using the selected rewritten \tcode{operator<=>} candidate.
If a rewritten candidate is selected by overload resolution
for a \tcode{!=} operator,
\tcode{x != y} is interpreted as \tcode{(y == x) ?\ false :\ true}
if the selected candidate is a synthesized candidate
with reversed order of parameters, or
\tcode{(x == y) ?\ false :\ true} otherwise,
using the selected rewritten \tcode{operator==} candidate.
If a rewritten candidate is selected by overload resolution
for an \tcode{==} operator,
\tcode{x == y} is interpreted as \tcode{(y == x) ?\ true :\ false}
using the selected rewritten \tcode{operator==} candidate.
Rewritten candidates for the operator \tcode{@}
are not considered in the context of the resulting expression.

\pnum
If a rewritten \tcode{operator==} candidate
is selected by overload resolution
for an operator \tcode{@},
its return type shall be \cv{} \tcode{bool}, and
\tcode{x @ y} is interpreted as:
\begin{itemize}
\item
if \tcode{@} is \tcode{!=}
and the selected candidate is a synthesized candidate
with reversed order of parameters,
\tcode{!(y == x)},
\item
otherwise, if \tcode{@} is \tcode{!=},
\tcode{!(x == y)},
\item
otherwise (when \tcode{@} is \tcode{==}),
\tcode{y == x},
\end{itemize}
in each case using the selected rewritten \tcode{operator==} candidate.

\pnum
If a built-in candidate is selected by overload resolution, the
Expand Down

0 comments on commit c88aa3c

Please sign in to comment.