Skip to content

Commit c081cf4

Browse files
committed
LWG4420 [simd] conversions (constructor, load, stores, gather, and scatter) are incorrectly constrained for <stdfloat> types
Also fixes LWG4393, NB DE-288 (C++26 CD), NB DE-285 (C++26 CD).
1 parent ca77cdb commit c081cf4

File tree

1 file changed

+68
-48
lines changed

1 file changed

+68
-48
lines changed

source/numerics.tex

Lines changed: 68 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -16232,6 +16232,12 @@
1623216232
bool_constant<T() == T::value>::value &&
1623316233
bool_constant<static_cast<decltype(T::value)>(T()) == T::value>::value;
1623416234

16235+
template<class From, class To>
16236+
concept @\defexposconceptnc{explicitly-convertible-to}@ = // \expos
16237+
requires {
16238+
static_cast<To>(declval<From>());
16239+
};
16240+
1623516241
template<class T> using @\exposidnc{deduced-vec-t} = \seebelownc@; // \expos
1623616242

1623716243
template<class V, class T> using @\exposidnc{make-compatible-simd-t} = \seebelownc@; // \expos
@@ -16576,54 +16582,46 @@
1657616582
flags<Flags...> f = {});
1657716583

1657816584
template<class T, class Abi, ranges::@\libconcept{contiguous_range}@ R, class... Flags>
16579-
requires ranges::@\libconcept{sized_range}@<R> && @\libconcept{indirectly_writable}@<ranges::iterator_t<R>, T>
16585+
requires ranges::@\libconcept{sized_range}@<R>
1658016586
constexpr void unchecked_store(const basic_vec<T, Abi>& v, R&& r,
1658116587
flags<Flags...> f = {});
1658216588
template<class T, class Abi, ranges::@\libconcept{contiguous_range}@ R, class... Flags>
16583-
requires ranges::@\libconcept{sized_range}@<R> && @\libconcept{indirectly_writable}@<ranges::iterator_t<R>, T>
16589+
requires ranges::@\libconcept{sized_range}@<R>
1658416590
constexpr void unchecked_store(const basic_vec<T, Abi>& v, R&& r,
1658516591
const typename basic_vec<T, Abi>::mask_type& mask, flags<Flags...> f = {});
1658616592
template<class T, class Abi, @\libconcept{contiguous_iterator}@ I, class... Flags>
16587-
requires @\libconcept{indirectly_writable}@<I, T>
1658816593
constexpr void unchecked_store(const basic_vec<T, Abi>& v, I first,
1658916594
iter_difference_t<I> n, flags<Flags...> f = {});
1659016595
template<class T, class Abi, @\libconcept{contiguous_iterator}@ I, class... Flags>
16591-
requires @\libconcept{indirectly_writable}@<I, T>
1659216596
constexpr void unchecked_store(const basic_vec<T, Abi>& v, I first,
1659316597
iter_difference_t<I> n, const typename basic_vec<T, Abi>::mask_type& mask,
1659416598
flags<Flags...> f = {});
1659516599
template<class T, class Abi, @\libconcept{contiguous_iterator}@ I, @\libconcept{sized_sentinel_for}@<I> S, class... Flags>
16596-
requires @\libconcept{indirectly_writable}@<I, T>
1659716600
constexpr void unchecked_store(const basic_vec<T, Abi>& v, I first, S last,
1659816601
flags<Flags...> f = {});
1659916602
template<class T, class Abi, @\libconcept{contiguous_iterator}@ I, @\libconcept{sized_sentinel_for}@<I> S, class... Flags>
16600-
requires @\libconcept{indirectly_writable}@<I, T>
1660116603
constexpr void unchecked_store(const basic_vec<T, Abi>& v, I first, S last,
1660216604
const typename basic_vec<T, Abi>::mask_type& mask, flags<Flags...> f = {});
1660316605

1660416606
template<class T, class Abi, ranges::@\libconcept{contiguous_range}@ R, class... Flags>
16605-
requires ranges::@\libconcept{sized_range}@<R> && @\libconcept{indirectly_writable}@<ranges::iterator_t<R>, T>
16607+
requires ranges::@\libconcept{sized_range}@<R>
1660616608
constexpr void partial_store(const basic_vec<T, Abi>& v, R&& r,
1660716609
flags<Flags...> f = {});
1660816610
template<class T, class Abi, ranges::@\libconcept{contiguous_range}@ R, class... Flags>
16609-
requires ranges::@\libconcept{sized_range}@<R> && @\libconcept{indirectly_writable}@<ranges::iterator_t<R>, T>
16611+
requires ranges::@\libconcept{sized_range}@<R>
1661016612
constexpr void partial_store(const basic_vec<T, Abi>& v, R&& r,
1661116613
const typename basic_vec<T, Abi>::mask_type& mask, flags<Flags...> f = {});
1661216614
template<class T, class Abi, @\libconcept{contiguous_iterator}@ I, class... Flags>
16613-
requires @\libconcept{indirectly_writable}@<I, T>
1661416615
constexpr void partial_store(
1661516616
const basic_vec<T, Abi>& v, I first, iter_difference_t<I> n, flags<Flags...> f = {});
1661616617
template<class T, class Abi, @\libconcept{contiguous_iterator}@ I, class... Flags>
16617-
requires @\libconcept{indirectly_writable}@<I, T>
1661816618
constexpr void partial_store(
1661916619
const basic_vec<T, Abi>& v, I first, iter_difference_t<I> n,
1662016620
const typename basic_vec<T, Abi>::mask_type& mask, flags<Flags...> f = {});
1662116621
template<class T, class Abi, @\libconcept{contiguous_iterator}@ I, @\libconcept{sized_sentinel_for}@<I> S, class... Flags>
16622-
requires @\libconcept{indirectly_writable}@<I, T>
1662316622
constexpr void partial_store(const basic_vec<T, Abi>& v, I first, S last,
1662416623
flags<Flags...> f = {});
1662516624
template<class T, class Abi, @\libconcept{contiguous_iterator}@ I, @\libconcept{sized_sentinel_for}@<I> S, class... Flags>
16626-
requires @\libconcept{indirectly_writable}@<I, T>
1662716625
constexpr void partial_store(const basic_vec<T, Abi>& v, I first, S last,
1662816626
const typename basic_vec<T, Abi>::mask_type& mask, flags<Flags...> f = {});
1662916627

@@ -17713,7 +17711,7 @@
1771317711

1771417712
\pnum
1771517713
\constraints
17716-
\tcode{value_type} satisfies \tcode{\libconcept{constructible_from}<U>}.
17714+
\tcode{U} satisfies \tcode{\exposconcept{explicitly-convertible-to}<value_type>}.
1771717715

1771817716
\pnum
1771917717
\effects
@@ -17747,7 +17745,12 @@
1774717745
\begin{itemdescr}
1774817746
\pnum
1774917747
\constraints
17750-
\tcode{\exposid{simd-size-v}<U, UAbi> == size()} is \tcode{true}.
17748+
\begin{itemize}
17749+
\item
17750+
\tcode{\exposid{simd-size-v}<U, UAbi> == size()} is \tcode{true}, and
17751+
\item
17752+
\tcode{U} satisfies \tcode{\exposconcept{explicitly-convertible-to}<T>}.
17753+
\end{itemize}
1775117754

1775217755
\pnum
1775317756
\effects
@@ -17819,20 +17822,17 @@
1781917822
\begin{itemize}
1782017823
\item \tcode{R} models \tcode{ranges::\libconcept{contiguous_range}} and
1782117824
\tcode{ranges::\libconcept{sized_range}},
17822-
\item \tcode{ranges::size(r)} is a constant expression, and
17823-
\item \tcode{ranges::size(r)} is equal to \tcode{size()}.
17825+
\item \tcode{ranges::size(r)} is a constant expression,
17826+
\item \tcode{ranges::size(r)} is equal to \tcode{size()}, and
17827+
\item \tcode{ranges::range_value_t<R>} is a vectorizable type and satisfies
17828+
\tcode{\exposconcept{explicitly-convertible-to}<T>}.
1782417829
\end{itemize}
1782517830

1782617831
\pnum
1782717832
\mandates
17828-
\begin{itemize}
17829-
\item
17830-
\tcode{ranges::range_value_t<R>} is a vectorizable type, and
17831-
\item
17832-
if the template parameter pack \tcode{Flags} does not contain
17833-
\tcode{\exposid{convert-flag}}, then the conversion from
17834-
\tcode{ranges::range_value_t<R>} to \tcode{value_type} is value-preserving.
17835-
\end{itemize}
17833+
If the template parameter pack \tcode{Flags} does not contain
17834+
\tcode{\exposid{convert-flag}}, then the conversion from
17835+
\tcode{ranges::range_value_t<R>} to \tcode{value_type} is value-preserving.
1783617836

1783717837
\pnum
1783817838
\expects
@@ -18575,7 +18575,8 @@
1857518575
\mandates
1857618576
\begin{itemize}
1857718577
\item
18578-
\tcode{ranges::range_value_t<R>} is a vectorizable type,
18578+
\tcode{ranges::range_value_t<R>} is a vectorizable type and satisfies
18579+
\tcode{\exposconcept{explicitly-convertible-to}<T>},
1857918580
\item
1858018581
\tcode{same_as<remove_cvref_t<V>, V>} is \tcode{true},
1858118582
\item
@@ -18622,26 +18623,22 @@
1862218623
\indexlibrarymember{unchecked_store}{simd}
1862318624
\begin{itemdecl}
1862418625
template<class T, class Abi, ranges::@\libconcept{contiguous_range}@ R, class... Flags>
18625-
requires ranges::@\libconcept{sized_range}@<R> && @\libconcept{indirectly_writable}@<ranges::iterator_t<R>, T>
18626+
requires ranges::@\libconcept{sized_range}@<R>
1862618627
constexpr void unchecked_store(const basic_vec<T, Abi>& v, R&& r, flags<Flags...> f = {});
1862718628
template<class T, class Abi, ranges::@\libconcept{contiguous_range}@ R, class... Flags>
18628-
requires ranges::@\libconcept{sized_range}@<R> && @\libconcept{indirectly_writable}@<ranges::iterator_t<R>, T>
18629+
requires ranges::@\libconcept{sized_range}@<R>
1862918630
constexpr void unchecked_store(const basic_vec<T, Abi>& v, R&& r,
1863018631
const typename basic_vec<T, Abi>::mask_type& mask, flags<Flags...> f = {});
1863118632
template<class T, class Abi, @\libconcept{contiguous_iterator}@ I, class... Flags>
18632-
requires @\libconcept{indirectly_writable}@<I, T>
1863318633
constexpr void unchecked_store(const basic_vec<T, Abi>& v, I first, iter_difference_t<I> n,
1863418634
flags<Flags...> f = {});
1863518635
template<class T, class Abi, @\libconcept{contiguous_iterator}@ I, class... Flags>
18636-
requires @\libconcept{indirectly_writable}@<I, T>
1863718636
constexpr void unchecked_store(const basic_vec<T, Abi>& v, I first, iter_difference_t<I> n,
1863818637
const typename basic_vec<T, Abi>::mask_type& mask, flags<Flags...> f = {});
1863918638
template<class T, class Abi, @\libconcept{contiguous_iterator}@ I, @\libconcept{sized_sentinel_for}@<I> S, class... Flags>
18640-
requires @\libconcept{indirectly_writable}@<I, T>
1864118639
constexpr void unchecked_store(const basic_vec<T, Abi>& v, I first, S last,
1864218640
flags<Flags...> f = {});
1864318641
template<class T, class Abi, @\libconcept{contiguous_iterator}@ I, @\libconcept{sized_sentinel_for}@<I> S, class... Flags>
18644-
requires @\libconcept{indirectly_writable}@<I, T>
1864518642
constexpr void unchecked_store(const basic_vec<T, Abi>& v, I first, S last,
1864618643
const typename basic_vec<T, Abi>::mask_type& mask, flags<Flags...> f = {});
1864718644
\end{itemdecl}
@@ -18688,26 +18685,22 @@
1868818685
\indexlibrarymember{partial_store}{simd}
1868918686
\begin{itemdecl}
1869018687
template<class T, class Abi, ranges::@\libconcept{contiguous_range}@ R, class... Flags>
18691-
requires ranges::@\libconcept{sized_range}@<R> && @\libconcept{indirectly_writable}@<ranges::iterator_t<R>, T>
18688+
requires ranges::@\libconcept{sized_range}@<R>
1869218689
constexpr void partial_store(const basic_vec<T, Abi>& v, R&& r, flags<Flags...> f = {});
1869318690
template<class T, class Abi, ranges::@\libconcept{contiguous_range}@ R, class... Flags>
18694-
requires ranges::@\libconcept{sized_range}@<R> && @\libconcept{indirectly_writable}@<ranges::iterator_t<R>, T>
18691+
requires ranges::@\libconcept{sized_range}@<R>
1869518692
constexpr void partial_store(const basic_vec<T, Abi>& v, R&& r,
1869618693
const typename basic_vec<T, Abi>::mask_type& mask, flags<Flags...> f = {});
1869718694
template<class T, class Abi, @\libconcept{contiguous_iterator}@ I, class... Flags>
18698-
requires @\libconcept{indirectly_writable}@<I, T>
1869918695
constexpr void partial_store(const basic_vec<T, Abi>& v, I first, iter_difference_t<I> n,
1870018696
flags<Flags...> f = {});
1870118697
template<class T, class Abi, @\libconcept{contiguous_iterator}@ I, class... Flags>
18702-
requires @\libconcept{indirectly_writable}@<I, T>
1870318698
constexpr void partial_store(const basic_vec<T, Abi>& v, I first, iter_difference_t<I> n,
1870418699
const typename basic_vec<T, Abi>::mask_type& mask, flags<Flags...> f = {});
1870518700
template<class T, class Abi, @\libconcept{contiguous_iterator}@ I, @\libconcept{sized_sentinel_for}@<I> S, class... Flags>
18706-
requires @\libconcept{indirectly_writable}@<I, T>
1870718701
constexpr void partial_store(const basic_vec<T, Abi>& v, I first, S last,
1870818702
flags<Flags...> f = {});
1870918703
template<class T, class Abi, @\libconcept{contiguous_iterator}@ I, @\libconcept{sized_sentinel_for}@<I> S, class... Flags>
18710-
requires @\libconcept{indirectly_writable}@<I, T>
1871118704
constexpr void partial_store(const basic_vec<T, Abi>& v, I first, S last,
1871218705
const typename basic_vec<T, Abi>::mask_type& mask, flags<Flags...> f = {});
1871318706
\end{itemdecl}
@@ -18725,18 +18718,31 @@
1872518718
\item
1872618719
\tcode{r} be \tcode{R(first, n)} for the overloads with an \tcode{n}
1872718720
parameter and \tcode{R(first, last)} for the overloads with a \tcode{last}
18728-
parameter.
18721+
parameter;
18722+
\item
18723+
\tcode{U} be \tcode{ranges::range_value_t<R>}.
18724+
\end{itemize}
18725+
18726+
\pnum
18727+
\constraints
18728+
\begin{itemize}
18729+
\item
18730+
\tcode{ranges::iterator_t<R>} satisfies
18731+
\tcode{\libconcept{indirectly_writable}<U>}, and
18732+
\item
18733+
\tcode{T} satisfies
18734+
\tcode{\exposconcept{explicitly-convertible-to}<U>}.
1872918735
\end{itemize}
1873018736

1873118737
\pnum
1873218738
\mandates
1873318739
\begin{itemize}
1873418740
\item
18735-
\tcode{ranges::range_value_t<R>} is a vectorizable type, and
18741+
\tcode{U} is a vectorizable type, and
1873618742
\item
1873718743
if the template parameter pack \tcode{Flags} does not contain
1873818744
\tcode{\exposid{convert-flag}}, then the conversion from \tcode{T} to
18739-
\tcode{ranges::range_value_t<R>} is value-preserving.
18745+
\tcode{U} is value-preserving.
1874018746
\end{itemize}
1874118747

1874218748
\pnum
@@ -18751,8 +18757,7 @@
1875118757
\item
1875218758
If the template parameter pack \tcode{Flags} contains
1875318759
\tcode{\exposid{aligned-flag}}, \tcode{ranges::data(r)} points to storage
18754-
aligned by \tcode{alignment_v<basic_vec<T, Abi>,
18755-
ranges::range_value_t<R>>}.
18760+
aligned by \tcode{alignment_v<basic_vec<T, Abi>, U>}.
1875618761
\item
1875718762
If the template parameter pack \tcode{Flags} contains
1875818763
\tcode{\exposid{overaligned-flag}<N>}, \tcode{ranges::data(r)} points to
@@ -18763,7 +18768,7 @@
1876318768
\effects
1876418769
For all $i$ in the range of \range{0}{basic_vec<T, Abi>::size()}, if
1876518770
\tcode{mask[$i$] \&\& $i$ < ranges::\brk{}size(r)} is \tcode{true}, evaluates
18766-
\tcode{ranges::data(r)[$i$] = v[$i$]}.
18771+
\tcode{ranges::data(r)[$i$] = static_cast<U>(v[$i$])}.
1876718772
\end{itemdescr}
1876818773

1876918774
\rSec3[simd.permute.static]{Static permute}
@@ -18995,6 +19000,11 @@
1899519000
\tcode{T} be \tcode{typename V::value_type}.
1899619001
\end{itemize}
1899719002

19003+
\pnum
19004+
\constraints
19005+
\tcode{ranges::range_value_t<R>} is a vectorizable type and satisfies
19006+
\tcode{\exposconceptx{explicitly-con\-vert\-ible-to}{explicitly-convertible-to}<T>}.
19007+
1899819008
\pnum
1899919009
\mandates
1900019010
\begin{itemize}
@@ -19083,20 +19093,30 @@
1908319093
\pnum
1908419094
Let \tcode{mask} be \tcode{typename I::mask_type(true)} for the overload with
1908519095
no \tcode{mask} parameter.
19096+
Let \tcode{U} be \tcode{ranges::range_value_t<R>}.
1908619097

1908719098
\pnum
1908819099
\constraints
19089-
\tcode{V::size() == I::size()} is \tcode{true}.
19100+
\begin{itemize}
19101+
\item
19102+
\tcode{V::size() == I::size()} is \tcode{true},
19103+
\item
19104+
\tcode{ranges::iterator_t<R>} satisfies
19105+
\tcode{\libconcept{indirectly_writable}<U>}, and
19106+
\item
19107+
\tcode{typename V::value_type} satisfies
19108+
\tcode{\exposconcept{explicitly-convertible-to}<U>}.
19109+
\end{itemize}
1909019110

1909119111
\pnum
1909219112
\mandates
1909319113
\begin{itemize}
1909419114
\item
19095-
\tcode{ranges::range_value_t<R>} is a vectorizable type, and
19115+
\tcode{U} is a vectorizable type, and
1909619116
\item
1909719117
if the template parameter pack \tcode{Flags} does not contain \exposid{convert-flag},
19098-
then the conversion from \tcode{typename V::value_type}
19099-
to \tcode{ranges::range_value_t<R>} is value-preserving.
19118+
then the conversion from \tcode{typename V::value_type} to \tcode{U} is
19119+
value-preserving.
1910019120
\end{itemize}
1910119121

1910219122
\pnum
@@ -19107,7 +19127,7 @@
1910719127
\item
1910819128
If the template parameter pack \tcode{Flags} contains \exposid{aligned-flag},
1910919129
\tcode{ranges::data(out)} points to storage aligned by
19110-
\tcode{alignment_v<V, ranges::range_value_t<R>>}.
19130+
\tcode{alignment_v<V, U>}.
1911119131
\item
1911219132
If the template parameter pack \tcode{Flags} contains
1911319133
\tcode{\exposid{overaligned-flag}<N>},

0 commit comments

Comments
 (0)