From bb0f1d3c6481d57fc0e80d65bab4595a6475240e Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Wed, 13 Oct 2021 17:06:05 +0200 Subject: [PATCH] P2393R1 Cleaning up integer-class types --- source/algorithms.tex | 7 ++ source/iterators.tex | 157 ++++++++++++++++++++++++++---------------- source/ranges.tex | 12 ++-- 3 files changed, 110 insertions(+), 66 deletions(-) diff --git a/source/algorithms.tex b/source/algorithms.tex index 6efb5503fe..672230323d 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -246,6 +246,13 @@ return n; \end{codeblock} +\pnum +In the description of the algorithms, +given an iterator \tcode{a} whose difference type is \tcode{D}, and +an expression \tcode{n} of integer-like type other than \cv{} \tcode{D}, +the semantics of \tcode{a + n} and \tcode{a - n} are, respectively, +those of \tcode{a + D(n)} and \tcode{a - D(n)}. + \pnum In the description of algorithm return values, a sentinel value \tcode{s} denoting the end of a range \range{i}{s} diff --git a/source/iterators.tex b/source/iterators.tex index e29204ebd7..4582617920 100644 --- a/source/iterators.tex +++ b/source/iterators.tex @@ -1333,35 +1333,86 @@ \pnum A type \tcode{I} is an \defnadj{integer-class}{type} -if it is in a set of \impldef{integer-class type} class types +if it is in a set of \impldef{integer-class type} types that behave as integer types do, as defined below. +\begin{note} +An integer-class type is not necessarily a class type. +\end{note} \pnum The range of representable values of an integer-class type is the continuous set of values over which it is defined. -The values 0 and 1 are part of the range of every integer-class type. -If any negative numbers are part of the range, -the type is a \defnadj{signed-integer-class}{type}; -otherwise, it is an \defnadj{unsigned-integer-class}{type}. +For any integer-class type, +its range of representable values is +either $-2^{N-1}$ to $2^{N-1}-1$ (inclusive) for some integer $N$, +in which case it is a \defnadj{signed-integer-class}{type}, or +$0$ to $2^{N}-1$ (inclusive) for some integer $N$, +in which case it is an \defnadj{unsigned-integer-class}{type}. +In both cases, $N$ is called +the \defnx{width}{width!of integer-class type} of the integer-class type. +The width of an integer-class type is greater than +that of every integral type of the same signedness. + +\pnum +A type \tcode{I} other than \cv{}~\tcode{bool} is \defn{integer-like} +if it models \tcode{\libconcept{integral}} or +if it is an integer-class type. +An integer-like type \tcode{I} is \defn{signed-integer-like} +if it models \tcode{\libconcept{signed_integral}} or +if it is a signed-integer-class type. +An integer-like type \tcode{I} is \defn{unsigned-integer-like} +if it models \tcode{\libconcept{unsigned_integral}} or +if it is an unsigned-integer-class type. \pnum For every integer-class type \tcode{I}, -let \tcode{B(I)} be a hypothetical extended integer type -of the same signedness with the smallest width\iref{basic.fundamental} -capable of representing the same range of values. -The width of \tcode{I} is equal to the width of \tcode{B(I)}. +let \tcode{B(I)} be a unique hypothetical extended integer type +of the same signedness with the same width\iref{basic.fundamental} as \tcode{I}. +\begin{note} +The corresponding hypothetical specialization \tcode{numeric_limits} +meets the requirements on \tcode{numeric_limits} specializations +for integral types\iref{numeric.limits}. +\end{note} +For every integral type \tcode{J}, let \tcode{B(J)} be the same type as \tcode{J}. \pnum -Let \tcode{a} and \tcode{b} be objects of integer-class type \tcode{I}, -let \tcode{x} and \tcode{y} be objects of type \tcode{B(I)} as described above -that represent the same values as \tcode{a} and \tcode{b} respectively, and +Expressions of integer-class type are +explicitly convertible to any integer-like type, and +implicitly convertible to any integer-class type +of equal or greater width and the same signedness. +Expressions of integral type are +both implicitly and explicitly convertible to any integer-class type. +Conversions between integral and integer-class types +and between two integer-class types do not exit via an exception. +The result of such a conversion is the unique value of the destination type +that is congruent to the source modulo $2^N$, +where $N$ is the width of the destination type. + +\pnum +Let \tcode{a} be an object of integer-class type \tcode{I}, +let \tcode{b} be an object of integer-like type \tcode{I2} +such that the expression \tcode{b} is implicitly convertible to \tcode{I}, +let \tcode{x} and \tcode{y} be, respectively, +objects of type \tcode{B(I)} and \tcode{B(I2)} as described above +that represent the same values as \tcode{a} and \tcode{b}, and let \tcode{c} be an lvalue of any integral type. \begin{itemize} \item - For every unary operator \tcode{@} for which the expression \tcode{@x} +The expressions \tcode{a++} and \tcode{a--} shall be prvalues of type \tcode{I} +whose values are equal to +that of \tcode{a} prior to the evaluation of the expressions. +The expression \tcode{a++} shall modify the value of \tcode{a} +by adding \tcode{1} to it. +The expression \tcode{a--} shall modify the value of \tcode{a} +by subtracting \tcode{1} from it. +\item +The expressions \tcode{++a}, \tcode{--a}, and \tcode{\&a} shall be +expression-equivalent to +\tcode{a += 1}, \tcode{a -= 1}, and \tcode{addressof(a)}, respectively. +\item + For every \grammarterm{unary-operator} \tcode{@} other than \tcode{\&} for which the expression \tcode{@x} is well-formed, \tcode{@a} shall also be well-formed - and have the same value, effects, and value category as \tcode{@x} - provided that value is representable by \tcode{I}. + and have the same value, effects, and value category as \tcode{@x}. If \tcode{@x} has type \tcode{bool}, so too does \tcode{@a}; if \tcode{@x} has type \tcode{B(I)}, then \tcode{@a} has type \tcode{I}. \item @@ -1371,23 +1422,27 @@ shall have the same value and effects as \tcode{c @= x}. The expression \tcode{c @= a} shall be an lvalue referring to \tcode{c}. \item - For every binary operator \tcode{@} for which \tcode{x @ y} is well-formed, - \tcode{a @ b} shall also be well-formed and - shall have the same value, effects, and value category as \tcode{x @ y} - provided that value is representable by \tcode{I}. - If \tcode{x @ y} has type \tcode{bool}, so too does \tcode{a @ b}; - if \tcode{x @ y} has type \tcode{B(I)}, then \tcode{a @ b} has type \tcode{I}. +For every assignment operator \tcode{@=} +for which \tcode{x @= y} is well-formed, +\tcode{a @= b} shall also be well-formed and +shall have the same effects as \tcode{x @= y}, +except that the value that would be stored into \tcode{x} +is stored into \tcode{a}. +The expression \tcode{a @= b} shall be an lvalue referring to \tcode{a}. +\item + For every non-assignment binary operator \tcode{@} + for which \tcode{x @ y} and \tcode{y @ x} are well-formed, + \tcode{a @ b} and \tcode{b @ a} shall also be well-formed and + shall have the same value, effects, and value category as + \tcode{x @ y} and \tcode{y @ x}, respectively. + If \tcode{x @ y} or \tcode{y @ x} has type \tcode{B(I)}, + then \tcode{a @ b} or \tcode{b @ a}, respectively, has type \tcode{I}; + if \tcode{x @ y} or \tcode{y @ x} has type \tcode{B(I2)}, + then \tcode{a @ b} or \tcode{b @ a}, respectively, has type \tcode{I2}; + if \tcode{x @ y} or \tcode{y @ x} has any other type, + then \tcode{a @ b} or \tcode{b @ a}, respectively, has that type. \end{itemize} -\pnum -Expressions of integer-class type are -explicitly convertible to any integral type as well as any integer-class type. -Expressions of integral type are -both implicitly and explicitly convertible to any integer-class type. -Conversions between integral and integer-class types and -between two integer-class types -do not exit via an exception. - \pnum An expression \tcode{E} of integer-class type \tcode{I} is contextually convertible to \tcode{bool} @@ -1396,44 +1451,26 @@ \pnum All integer-class types model \libconcept{regular}\iref{concepts.object} and -\libconcept{totally_ordered}\iref{concept.totallyordered}. +\tcode{\libconcept{three_way_comparable}}\iref{cmp.concept}. \pnum A value-initialized object of integer-class type has value 0. \pnum For every (possibly cv-qualified) integer-class type \tcode{I}, -\tcode{numeric_limits} is specialized such that: -\begin{itemize} -\item - \tcode{numeric_limits::is_specialized} is \tcode{true}, -\item - \tcode{numeric_limits::is_signed} is \tcode{true} - if and only if \tcode{I} is a signed-integer-class type, -\item - \tcode{numeric_limits::is_integer} is \tcode{true}, -\item - \tcode{numeric_limits::is_exact} is \tcode{true}, -\item - \tcode{numeric_limits::digits} is equal to the width of the integer-class type, -\item - \tcode{numeric_limits::digits10} is equal to \tcode{static_cast(digits * log10(2))}, and -\item - \tcode{numeric_limits::min()} and \tcode{numeric_limits::max()} return - the lowest and highest representable values of \tcode{I}, respectively, and - \tcode{numeric_limits::lowest()} returns \tcode{numeric_limits::\brk{}min()}. -\end{itemize} +\tcode{numeric_limits} is specialized such that +each static data member \tcode{m} +has the same value as \tcode{numeric_limits::m}, and +each static member function \tcode{f} +returns \tcode{I(numeric_limits::f())}. \pnum -A type \tcode{I} other than \cv{}~\tcode{bool} is \defn{integer-like} -if it models \tcode{\libconcept{integral}} or -if it is an integer-class type. -An integer-like type \tcode{I} is \defn{signed-integer-like} -if it models \tcode{\libconcept{signed_integral}} or -if it is a signed-integer-class type. -An integer-like type \tcode{I} is \defn{unsigned-integer-like} -if it models \tcode{\libconcept{unsigned_integral}} or -if it is an unsigned-integer-class type. +For any two integer-like types \tcode{I1} and \tcode{I2}, +at least one of which is an integer-class type, +\tcode{common_type_t} denotes an integer-class type +whose width is not less than that of \tcode{I1} or \tcode{I2}. +If both \tcode{I1} and \tcode{I2} are signed-integer-like types, +then \tcode{common_type_t} is also a signed-integer-like type. \pnum For any two integer-like types \tcode{I1} and \tcode{I2}, diff --git a/source/ranges.tex b/source/ranges.tex index 8b9853c5fe..34920fb534 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -1754,7 +1754,7 @@ Equivalent to: \begin{itemize} \item If \exposid{StoreSize} is \tcode{true}, -\tcode{subrange(r, ranges::size(r))}. +\tcode{subrange(r, static_cast(ranges::size(r)))}. \item Otherwise, \tcode{subrange(ranges::begin(r), ranges::end(r))}. \end{itemize} \end{itemdescr} @@ -4700,7 +4700,7 @@ if constexpr (@\libconcept{random_access_range}@) return ranges::begin(@\exposid{base_}@); else { - auto sz = size(); + auto sz = range_difference_t(size()); return counted_iterator(ranges::begin(@\exposid{base_}@), sz); } } else @@ -4712,7 +4712,7 @@ if constexpr (@\libconcept{random_access_range}@) return ranges::begin(@\exposid{base_}@); else { - auto sz = size(); + auto sz = range_difference_t(size()); return counted_iterator(ranges::begin(@\exposid{base_}@), sz); } } else @@ -4722,7 +4722,7 @@ constexpr auto end() requires (!@\exposconcept{simple-view}@) { if constexpr (@\libconcept{sized_range}@) { if constexpr (@\libconcept{random_access_range}@) - return ranges::begin(@\exposid{base_}@) + size(); + return ranges::begin(@\exposid{base_}@) + range_difference_t(size()); else return default_sentinel; } else @@ -4732,7 +4732,7 @@ constexpr auto end() const requires @\libconcept{range}@ { if constexpr (@\libconcept{sized_range}@) { if constexpr (@\libconcept{random_access_range}@) - return ranges::begin(@\exposid{base_}@) + size(); + return ranges::begin(@\exposid{base_}@) + range_difference_t(size()); else return default_sentinel; } else @@ -6692,7 +6692,7 @@ \begin{itemize} \item If \tcode{T} models \libconcept{contiguous_iterator}, -then \tcode{span(to_address(E), static_cast(F))}. +then \tcode{span(to_address(E), static_cast(static_-\linebreak{}cast(F)))}. \item Otherwise, if \tcode{T} models \libconcept{random_access_iterator},