Skip to content

Commit 0466c33

Browse files
committed
wording: make swap noexcept precise for reference E; document error storage
Close the two loose ends from the storage fix: 1. The primary and void swap exception specifications tested is_nothrow_swappable_v<E>, which for a reference E asks whether the *referents* are nothrow-swappable -- over-conservative, since swap exchanges the errors as unexpected<E> (a pointer swap for E&, always noexcept). Respell the E terms as unexpected<E> in both swap noexcept specs and the primary swap's branch guard. Equivalent for object E; correctly noexcept for reference E. 2. Add a marked General paragraph to expected<T, E> and expected<void, E> stating the error is unex.error(), held as unexpected<E> so E may be an lvalue reference (E& cannot be a union member; unexpected<E&> holds a pointer). Pure additions. Verified: build clean at 93 pages; stripped diff vs expected-base.tex changes exactly 19 lines (3 relaxation + 13 storage + 3 swap), the two notes being additions; no churn.
1 parent 75b6265 commit 0466c33

1 file changed

Lines changed: 21 additions & 3 deletions

File tree

papers/expected-new.tex

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,15 @@
626626
Member \exposid{has_val} indicates whether the \tcode{expected<T, E>} object
627627
contains an object of type \tcode{T}.
628628

629+
\begin{addedblock}
630+
\pnum
631+
When \tcode{has_value()} is \tcode{false}, the error is
632+
\tcode{\exposid{unex}.error()}. The error is held as an \tcode{unexpected<E>},
633+
and not as an \tcode{E}, so that \tcode{E} may be an lvalue reference type: an
634+
\tcode{E\&} cannot be a union member, whereas \tcode{unexpected<E\&>} holds a
635+
pointer to an external object\iref{expected.un.ref}.
636+
\end{addedblock}
637+
629638
\pnum
630639
A type \tcode{T} is a \term{valid value type for \tcode{expected}},
631640
if \tcode{remove_cv_t<T>} is \tcode{void}
@@ -1348,7 +1357,7 @@
13481357
For the case where \tcode{rhs.has_value()} is \tcode{false} and
13491358
\tcode{this->has_value()} is \tcode{true}, equivalent to:
13501359
\begin{codeblock}
1351-
if constexpr (is_nothrow_move_constructible_v<E>) {
1360+
if constexpr (is_nothrow_move_constructible_v<unexpected<E>>) {
13521361
unexpected<E> tmp(std::move(rhs.@\exposid{unex}@));
13531362
destroy_at(addressof(rhs.@\exposid{unex}@));
13541363
try {
@@ -1384,7 +1393,7 @@
13841393
The exception specification is equivalent to:
13851394
\begin{codeblock}
13861395
is_nothrow_move_constructible_v<T> && is_nothrow_swappable_v<T> &&
1387-
is_nothrow_move_constructible_v<E> && is_nothrow_swappable_v<E>
1396+
is_nothrow_move_constructible_v<unexpected<E>> && is_nothrow_swappable_v<unexpected<E>>
13881397
\end{codeblock}
13891398
\end{itemdescr}
13901399

@@ -2038,6 +2047,15 @@
20382047
Member \exposid{has_val} indicates whether the \tcode{expected<T, E>} object
20392048
represents a value of type \tcode{T}.
20402049

2050+
\begin{addedblock}
2051+
\pnum
2052+
When \tcode{has_value()} is \tcode{false}, the error is
2053+
\tcode{\exposid{unex}.error()}. The error is held as an \tcode{unexpected<E>},
2054+
and not as an \tcode{E}, so that \tcode{E} may be an lvalue reference type: an
2055+
\tcode{E\&} cannot be a union member, whereas \tcode{unexpected<E\&>} holds a
2056+
pointer to an external object\iref{expected.un.ref}.
2057+
\end{addedblock}
2058+
20412059
\pnum
20422060
A program that instantiates
20432061
the definition of the template \tcode{expected<T, E>} with
@@ -2461,7 +2479,7 @@
24612479
\pnum
24622480
\remarks
24632481
The exception specification is equivalent to
2464-
\tcode{is_nothrow_move_constructible_v<E> \&\& is_nothrow_swappable_v<E>}.
2482+
\tcode{is_nothrow_move_constructible_v<unexpected<E>> \&\& is_nothrow_swappable_v<unexpected<E>>}.
24652483
\end{itemdescr}
24662484

24672485
\indexlibrarymember{swap}{expected<void>}%

0 commit comments

Comments
 (0)