|
template <class _It>
|
|
_NODISCARD static consteval _Choice_t<_St> _Choose() noexcept {
|
|
using _Decayed = decay_t<_It>;
|
|
_STL_INTERNAL_STATIC_ASSERT(input_or_output_iterator<_Decayed>);
|
|
if constexpr (contiguous_iterator<_Decayed>) {
|
|
return {_St::_Span,
|
|
noexcept(span(_STD to_address(_STD declval<_It>()), iter_difference_t<_Decayed>{}))};
|
The second difference argument passed into span misses the size_t casting, which would cause a hard error if it is not implicitly-convertible to size_t.
testcase:
#include <ranges>
struct ContiguousIter {
using iterator_category = std::contiguous_iterator_tag;
using difference_type = std::_Signed128;
using element_type = char;
element_type& operator*() const;
ContiguousIter& operator++();
ContiguousIter operator++(int);
ContiguousIter& operator--();
ContiguousIter operator--(int);
ContiguousIter& operator+=(difference_type);
ContiguousIter& operator-=(difference_type);
element_type* operator->() const;
element_type& operator[](difference_type) const;
friend ContiguousIter operator+(ContiguousIter, difference_type);
friend ContiguousIter operator+(difference_type, ContiguousIter);
friend ContiguousIter operator-(ContiguousIter, difference_type);
friend difference_type operator-(ContiguousIter, ContiguousIter);
auto operator<=>(const ContiguousIter&) const = default;
};
int main() {
ContiguousIter it;
std::ranges::contiguous_range auto r = std::views::counted(it, 42); // boom
}
https://godbolt.org/z/e1hv1o6h8
This can be a good first issue.
STL/stl/inc/ranges
Lines 4214 to 4220 in 89ca073
The second difference argument passed into
spanmisses thesize_tcasting, which would cause a hard error if it is not implicitly-convertible tosize_t.testcase:
https://godbolt.org/z/e1hv1o6h8
This can be a good first issue.