Skip to content

Commit 878d78a

Browse files
authored
Merge 2019-07 LWG Motion 25
P1522R1 Iterator difference type and integer overflow Fixes #3029.
2 parents 69fe79d + 7698c3d commit 878d78a

File tree

2 files changed

+272
-41
lines changed

2 files changed

+272
-41
lines changed

source/iterators.tex

Lines changed: 116 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,7 @@
476476
is valid where \tcode{o} is a value of type \tcode{T}.
477477
For every iterator type
478478
\tcode{X},
479-
there is a corresponding signed integer type called the
479+
there is a corresponding signed integer-like type\iref{iterator.concept.winc} called the
480480
\term{difference type}
481481
of the iterator.
482482

@@ -1280,17 +1280,126 @@
12801280

12811281
\indexlibrary{\idxcode{WeaklyIncrementable}}%
12821282
\begin{codeblock}
1283+
template<class T>
1284+
inline constexpr bool @\placeholder{is-integer-like}@ = @\seebelow@; @\itcorr[-2]@ // exposition only
1285+
1286+
template<class T>
1287+
inline constexpr bool @\placeholder{is-signed-integer-like}@ = @\seebelow@; @\itcorr[-2]@ // exposition only
1288+
12831289
template<class I>
12841290
concept WeaklyIncrementable =
12851291
DefaultConstructible<I> && Movable<I> &&
12861292
requires(I i) {
12871293
typename iter_difference_t<I>;
1288-
requires SignedIntegral<iter_difference_t<I>>;
1289-
{ ++i } -> Same<I&>; // not required to be equality-preserving
1290-
i++; // not required to be equality-preserving
1294+
requires @\placeholdernc{is-signed-integer-like}@<iter_difference_t<I>>;
1295+
{ ++i } -> Same<I&>; // not required to be equality-preserving
1296+
i++; // not required to be equality-preserving
12911297
};
12921298
\end{codeblock}
12931299

1300+
\pnum
1301+
A type \tcode{I} is an \defnadj{integer-class}{type}
1302+
if it is in a set of implementation-defined class types
1303+
that behave as integer types do, as defined in below.
1304+
1305+
\pnum
1306+
The range of representable values of an integer-class type
1307+
is the continuous set of values over which it is defined.
1308+
The values 0 and 1 are part of the range of every integer-class type.
1309+
If any negative numbers are part of the range,
1310+
the type is a \defnadj{signed-integer-class}{type};
1311+
otherwise, it is an \defnadj{unsigned-integer-class}{type}.
1312+
1313+
\pnum
1314+
For every integer-class type \tcode{I},
1315+
let \tcode{B(I)} be a hypothetical extended integral type
1316+
of the same signedness with the smallest width\iref{basic.fundamental}
1317+
capable of representing the same range of values.
1318+
The width of \tcode{I} is equal to the width of \tcode{B(I)}.
1319+
1320+
\pnum
1321+
Let \tcode{a} and \tcode{b} be objects of integer-class type \tcode{I},
1322+
let \tcode{x} and \tcode{y} be objects of type \tcode{B(I)} as described above
1323+
that represent the same values as \tcode{a} and \tcode{b} respectively, and
1324+
let \tcode{c} be an lvalue of any integral type.
1325+
\begin{itemize}
1326+
\item
1327+
For every unary operator \tcode{@} for which the expression \tcode{@x}
1328+
is well-formed, \tcode{@a} shall also be well-formed
1329+
and have the same value, effects, and value category as \tcode{@x}
1330+
provided that value is representable by \tcode{I}.
1331+
If \tcode{@x} has type \tcode{bool}, so too does \tcode{@a};
1332+
if \tcode{@x} has type \tcode{B(I)}, then \tcode{@a} has type \tcode{I}.
1333+
\item
1334+
For every assignment operator \tcode{@=}
1335+
for which \tcode{c @= x} is well-formed,
1336+
\tcode{c @= a} shall also be well-formed and
1337+
shall have the same value and effects as \tcode{c @= x}.
1338+
The expression \tcode{c @= a} shall be an lvalue referring to \tcode{c}.
1339+
\item
1340+
For every binary operator \tcode{@} for which \tcode{x @ y} is well-formed,
1341+
\tcode{a @ b} shall also be well-formed and
1342+
shall have the same value, effects, and value category as \tcode{x @ y}
1343+
provided that value is representable by \tcode{I}.
1344+
If \tcode{x @ y} has type \tcode{bool}, so too does \tcode{a @ b};
1345+
if \tcode{x @ y} has type \tcode{B(I)}, then \tcode{a @ b} has type \tcode{I}.
1346+
\end{itemize}
1347+
1348+
\pnum
1349+
All integer-class types are explicitly convertible to all integral types and
1350+
implicitly and explicitly convertible from all integral types.
1351+
1352+
\pnum
1353+
All integer-class types are contextually convertible to \tcode{bool}
1354+
as if by \tcode{bool(a != I(0))}, where \tcode{a} is an
1355+
instance of the integral-class type \tcode{I}.
1356+
1357+
\pnum
1358+
All integer-class types model
1359+
\libconcept{Regular}\iref{concepts.object} and
1360+
\libconcept{StrictTotallyOrdered}\iref{concept.stricttotallyordered}.
1361+
1362+
\pnum
1363+
A value-initialized object of integer-class type has value 0.
1364+
1365+
\pnum
1366+
For every (possibly cv-qualified) integer-class type \tcode{I},
1367+
\tcode{numeric_limits<I>} is specialized such that:
1368+
\begin{itemize}
1369+
\item
1370+
\tcode{numeric_limits<I>::is_specialized} is \tcode{true},
1371+
\item
1372+
\tcode{numeric_limits<I>::is_signed} is \tcode{true}
1373+
if and only if \tcode{I} is a signed-integer-class type,
1374+
\item
1375+
\tcode{numeric_limits<I>::is_integer} is \tcode{true},
1376+
\item
1377+
\tcode{numeric_limits<I>::is_exact} is \tcode{true},
1378+
\item
1379+
\tcode{numeric_limits<I>::digits} is equal to the width of the integer-class type,
1380+
\item
1381+
\tcode{numeric_limits<I>::digits10} is equal to \tcode{static_cast<int>(digits * log10(2))}, and
1382+
\item
1383+
\tcode{numeric_limits<I>::min()} and \tcode{numeric_limits<I>::max()} return
1384+
the lowest and highest representable values of \tcode{I}, respectively, and
1385+
\tcode{numeric_limits<I>::lowest()} returns \tcode{numeric_limits<I>::\brk{}min()}.
1386+
\end{itemize}
1387+
1388+
\pnum
1389+
A type \tcode{I} is \defn{integer-like}
1390+
if it models \tcode{Integral<I>} or if it is an integer-class type.
1391+
A type \tcode{I} is \defn{signed-integer-like}
1392+
if it models \tcode{SignedIntegral<I>} or if it is a signed-integer-class type.
1393+
A type \tcode{I} is \defn{unsigned-integer-like}
1394+
if it models \tcode{UnsignedIntegral<I>} or
1395+
if it is an unsigned-integer-class type.
1396+
1397+
\pnum
1398+
\tcode{\placeholdernc{is-integer-like}<I>} is \tcode{true}
1399+
if and only if \tcode{I} is an integer-like type.
1400+
\tcode{\placeholdernc{is-signed-integer-like}<I>} is \tcode{true}
1401+
if and only if I is a signed-integer-like type.
1402+
12941403
\pnum
12951404
Let \tcode{i} be an object of type \tcode{I}. When \tcode{i} is in the domain of
12961405
both pre- and post-increment, \tcode{i} is said to be \term{incrementable}.
@@ -1773,6 +1882,8 @@
17731882
\oldconcept{Destructible} requirements\iref{utility.arg.requirements} and lvalues
17741883
of type \tcode{X} are swappable\iref{swappable.requirements}, and
17751884

1885+
\item \tcode{iterator_traits<X>::difference_type} is a signed integer type or \tcode{void}, and
1886+
17761887
\item the expressions in \tref{iterator} are valid and have
17771888
the indicated semantics.
17781889
\end{itemize}
@@ -2841,7 +2952,7 @@
28412952
\effects
28422953
If \tcode{R} models \libconcept{SizedRange}, equivalent to:
28432954
\begin{codeblock}
2844-
return ranges::size(r); // \ref{range.prim.size}
2955+
return static_cast<range_difference_t<R>>(ranges::size(r)); // \ref{range.prim.size}
28452956
\end{codeblock}
28462957
Otherwise, equivalent to:
28472958
\begin{codeblock}

0 commit comments

Comments
 (0)