From b502b6070f62d9c385f578508ebde2d772d0a189 Mon Sep 17 00:00:00 2001 From: Arthur O'Dwyer Date: Thu, 8 Aug 2024 15:07:54 -0400 Subject: [PATCH] [containers] Tentative P/R for [LWG4123] "Container effects use..." https://cplusplus.github.io/LWG/issue4123 The superficial problem here is that "assignment operator or move assignment operator" is redundant. The real problem is that the container might use an assignment operator that's not a copy-or-move assignment operator, and/or a constructor that's not a copy-or-move constructor. We want to preserve the idea of "constructing or assigning a T from another T," as opposed to from a U. But we want to permit all the various ways of doing that, such as "implicitly convert the source T to U, then assign from U to T," as shown in this Godbolt: https://godbolt.org/z/8Ybbxr19e (If one of those various ways throws, then there might be effects, even though the throwing culprit wasn't a constructor or assignment operator of `T` at all.) We have similar problems in [optional], e.g. https://eel.is/c++draft/optional.optional#optional.ctor-6 "Any exception thrown by the selected constructor of T." (Overload resolution might select a conversion operator, not a constructor.) https://eel.is/c++draft/optional.optional#optional.assign-7 "If an exception is thrown during the call to T's copy constructor, no effect. If an exception is thrown during the call to T's copy assignment, the state of its contained value is as defined by the exception safety guarantee of T's copy assignment." (Overload resolution might select a constructor that is not a copy constructor, resp. an assignment [operator] that is not a copy assignment operator.) I have not attempted to fix those problems in this patch. --- source/containers.tex | 61 ++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 33 deletions(-) diff --git a/source/containers.tex b/source/containers.tex index b891a886c0..61f5049ae8 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -6841,8 +6841,8 @@ implementation-specific optimizations. \end{note} If the size is equal to the old capacity, or -if an exception is thrown other than by the move constructor -of a non-\oldconcept{CopyInsertable} \tcode{T}, +if an exception is thrown other than by +the move-construction of one object of non-\oldconcept{CopyInsertable} type \tcode{T} from another, then there are no effects. \pnum @@ -6908,16 +6908,14 @@ \pnum \remarks -If an exception is thrown other than by the -copy constructor, move constructor, -assignment operator, or move assignment operator of -\tcode{T}, +If an exception is thrown other than by +the construction or assignment of one object of type \tcode{T} from another, there are no effects. If an exception is thrown while inserting a single element at either end, there are no effects. -Otherwise, if an exception is thrown by the move constructor of a -non-\oldconcept{CopyInsertable} -\tcode{T}, the effects are unspecified. +Otherwise, if an exception is thrown by +the move-construction of one object of non-\oldconcept{CopyInsertable} type \tcode{T} from another, +the effects are unspecified. \end{itemdescr} \indexlibrarymember{erase}{deque}% @@ -6943,8 +6941,8 @@ \pnum \throws -Nothing unless an exception is thrown by the assignment operator of -\tcode{T}. +Nothing unless an exception is thrown by +the assignment of one object of type \tcode{T} from another. \pnum \complexity @@ -8966,8 +8964,8 @@ otherwise. Reallocation happens at this point if and only if the current capacity is less than the argument of -\tcode{reserve()}. If an exception is thrown -other than by the move constructor of a non-\oldconcept{CopyInsertable} type, +\tcode{reserve()}. If an exception is thrown other than by +the move-construction of one object of non-\oldconcept{CopyInsertable} type \tcode{T} from another, there are no effects. \pnum @@ -9017,8 +9015,9 @@ \end{note} It does not increase \tcode{capacity()}, but may reduce \tcode{capacity()} by causing reallocation. -If an exception is thrown other than by the move constructor -of a non-\oldconcept{CopyInsertable} \tcode{T}, there are no effects. +If an exception is thrown other than by +the move-construction of one object of non-\oldconcept{CopyInsertable} type \tcode{T} from another, +there are no effects. \pnum \complexity @@ -9074,8 +9073,9 @@ \pnum \remarks -If an exception is thrown other than by the move constructor of a non-\oldconcept{CopyInsertable} -\tcode{T}, there are no effects. +If an exception is thrown other than by +the move-construction of one object of non-\oldconcept{CopyInsertable} type \tcode{T} from another, +there are no effects. \end{itemdescr} \indexlibrarymember{resize}{vector}% @@ -9161,15 +9161,15 @@ including the past-the-end iterator, are invalidated. If an exception is thrown other than by -the copy constructor, move constructor, -assignment operator, or move assignment operator of -\tcode{T} or by any \tcode{InputIterator} operation, +the construction or assignment of one object of type \tcode{T} from another, +or by any \tcode{InputIterator} operation, there are no effects. If an exception is thrown while inserting a single element at the end and \tcode{T} is \oldconcept{CopyInsertable} or \tcode{is_nothrow_move_constructible_v} is \tcode{true}, there are no effects. -Otherwise, if an exception is thrown by the move constructor of a non-\oldconcept{CopyInsertable} -\tcode{T}, the effects are unspecified. +Otherwise, if an exception is thrown by +the move-construction of one object of non-\oldconcept{CopyInsertable} type \tcode{T} from another, +the effects are unspecified. \end{itemdescr} \indexlibrarymember{erase}{vector}% @@ -9186,9 +9186,8 @@ \pnum \throws -Nothing unless an exception is thrown by the -assignment operator or move assignment operator of -\tcode{T}. +Nothing unless an exception is thrown by +the construction or assignment of one object of type \tcode{T} from another. \pnum \complexity @@ -9893,13 +9892,9 @@ \pnum \remarks -If an exception is thrown other than by the -copy constructor, -move constructor, -assignment operator, or -move assignment operator -of \tcode{T} or by -any \tcode{InputIterator} operation, +If an exception is thrown other than by +the construction or assignment of one object of type \tcode{T} from another, +or by any \tcode{InputIterator} operation, there are no effects. Otherwise, if an exception is thrown, then @@ -10097,7 +10092,7 @@ \pnum \throws Nothing unless an exception is thrown by -the assignment operator or move assignment operator of \tcode{T}. +the assignment of one object of type \tcode{T} from another. \pnum \complexity