On Tue, May 19, 2026 at 12:17 AM Jonathan Wakely <[email protected]> wrote:
> On Mon, 18 May 2026 at 16:48, Tomasz Kamiński <[email protected]> wrote: > > > > This implements additions from sections 4.3, 4.4, 4.5 of P3016R6. > > > > libstdc++-v3/ChangeLog: > > > > * include/bits/version.def (valarray): Define. > > * include/bits/version: Regenerate. > > * include/std/valarray (valarray::begin, valarray::end) > > (valarray::iterator, valarray::const_iterator) > > [__glibcxx_valarray >= 202511L]: Define. > > (std::begin(valarray<_Tp>&), std::begin(const valarray<_Tp>&)) > > (std::end(valarray<_Tp>&), std::end(const valarray<_Tp>&)): > Define > > only if __glibcxx_valarray < 202511L (i.e. not defined). > > * libstdc++-v3/include/bits/range_access.h (std::valarray) > > (std::begin(valarray<_Tp>&), std::begin(const valarray<_Tp>&)) > > (std::end(valarray<_Tp>&), std::end(const valarray<_Tp>&)): > Forward > > declare only if __glibcxx_valarray < 202511L (i.e. not defined). > > * testsuite/26_numerics/valarray/range_access3.cc: New test. > > --- > > I think it would make sense to backport this to C++11, or even C++98 > > (see range_access3.cc test for example use). But doing C++26 for now. > > > > Tested on x86_64-linux. OK for trunk? > > > > libstdc++-v3/include/bits/range_access.h | 2 + > > libstdc++-v3/include/bits/version.def | 7 ++++ > > libstdc++-v3/include/bits/version.h | 10 +++++ > > libstdc++-v3/include/std/valarray | 34 ++++++++++++++- > > .../26_numerics/valarray/range_access3.cc | 41 +++++++++++++++++++ > > 5 files changed, 92 insertions(+), 2 deletions(-) > > create mode 100644 > libstdc++-v3/testsuite/26_numerics/valarray/range_access3.cc > > > > diff --git a/libstdc++-v3/include/bits/range_access.h > b/libstdc++-v3/include/bits/range_access.h > > index b89129f0233..01f79086852 100644 > > --- a/libstdc++-v3/include/bits/range_access.h > > +++ b/libstdc++-v3/include/bits/range_access.h > > @@ -119,12 +119,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > > > > #if __cplusplus >= 201402L > > > > +#if __glibcxx_valarray < 202511L > > template<typename _Tp> class valarray; > > // These overloads must be declared for cbegin and cend to use them. > > template<typename _Tp> _Tp* begin(valarray<_Tp>&) noexcept; > > template<typename _Tp> const _Tp* begin(const valarray<_Tp>&) > noexcept; > > template<typename _Tp> _Tp* end(valarray<_Tp>&) noexcept; > > template<typename _Tp> const _Tp* end(const valarray<_Tp>&) noexcept; > > +#endif > > > > /** > > * @brief Return an iterator pointing to the first element of > > diff --git a/libstdc++-v3/include/bits/version.def > b/libstdc++-v3/include/bits/version.def > > index efcc0852af5..2f32a8bda98 100644 > > --- a/libstdc++-v3/include/bits/version.def > > +++ b/libstdc++-v3/include/bits/version.def > > @@ -2418,6 +2418,13 @@ ftms = { > > }; > > }; > > > > +ftms = { > > + name = valarray; > > + values = { > > + v = 202511; > > + cxxmin = 26; > > + }; > > +}; > > > > // Standard test specifications. > > stds[97] = ">= 199711L"; > > diff --git a/libstdc++-v3/include/bits/version.h > b/libstdc++-v3/include/bits/version.h > > index 9402f25df37..517b9020ec6 100644 > > --- a/libstdc++-v3/include/bits/version.h > > +++ b/libstdc++-v3/include/bits/version.h > > @@ -2685,4 +2685,14 @@ > > #endif /* !defined(__cpp_lib_initializer_list) */ > > #undef __glibcxx_want_initializer_list > > > > +#if !defined(__cpp_lib_valarray) > > +# if (__cplusplus > 202302L) > > +# define __glibcxx_valarray 202511L > > +# if defined(__glibcxx_want_all) || defined(__glibcxx_want_valarray) > > +# define __cpp_lib_valarray 202511L > > +# endif > > +# endif > > +#endif /* !defined(__cpp_lib_valarray) */ > > +#undef __glibcxx_want_valarray > > + > > #undef __glibcxx_want_all > > diff --git a/libstdc++-v3/include/std/valarray > b/libstdc++-v3/include/std/valarray > > index abb158d22c3..ee11199f15f 100644 > > --- a/libstdc++-v3/include/std/valarray > > +++ b/libstdc++-v3/include/std/valarray > > @@ -139,6 +139,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > > }; > > public: > > typedef _Tp value_type; > > +#if __glibcxx_valarray >= 202511L > > + typedef _Tp* iterator; > > + typedef const _Tp* const_iterator; > > +#endif > > > > // _lib.valarray.cons_ construct/destroy: > > /// Construct an empty array. > > @@ -572,6 +576,32 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > > */ > > void resize(size_t __size, _Tp __c = _Tp()); > > > > +#if __glibcxx_valarray >= 202511L > > + /** > > + * @brief Return an iterator pointing to the first element of > > + * the valarray. > > + */ > > + _GLIBCXX_NODISCARD iterator > > + begin() _GLIBCXX_NOTHROW > > Is the use of the NODISCARD and NOTHROW macros to allow this to be > backported to C++98 later, if we choose to? > Because otherwise it could just be [[nodiscard]] and noexcept here. > Ah, yes. I was experimenting with fully backporting it to C++98, and used macros, but forgot to change them back. I don't see value in making this declarations backward compatible just in case, so will change them back. > > The NOTHROW macro expands to throw() for C++98. If you only want > 'noexcept' in C++11 and later, and nothing in C++98, that's just > _GLIBCXX_NOEXCEPT. > <valarray> has a mix of both today :-\ > > > > + { return _M_data; } > > + > > + _GLIBCXX_NODISCARD const_iterator > > + begin() const _GLIBCXX_NOTHROW > > + { return _M_data; } > > + > > + /** > > + * @brief Return an iterator pointing to one past the last > element of > > + * the valarray. > > + */ > > + _GLIBCXX_NODISCARD iterator > > + end() _GLIBCXX_NOTHROW > > + { return _M_data + _M_size; } > > + > > + _GLIBCXX_NODISCARD const_iterator > > + end() const _GLIBCXX_NOTHROW > > + { return _M_data + _M_size; } > > +#endif > > + > > private: > > size_t _M_size; > > _Tp* __restrict__ _M_data; > > @@ -1218,7 +1248,7 @@ _DEFINE_BINARY_OPERATOR(>=, __greater_equal) > > #undef _DEFINE_BINARY_OPERATOR > > /// @endcond > > > > -#if __cplusplus >= 201103L > > +#if (__cplusplus >= 201103L) && (__glibcxx_valarray < 202511L) > > /** > > * @brief Return an iterator pointing to the first element of > > * the valarray. > > @@ -1272,7 +1302,7 @@ _DEFINE_BINARY_OPERATOR(>=, __greater_equal) > > else > > return nullptr; > > } > > -#endif // C++11 > > +#endif // C++11 to C++23 > > > > /// @} group numeric_arrays > > > > diff --git > a/libstdc++-v3/testsuite/26_numerics/valarray/range_access3.cc > b/libstdc++-v3/testsuite/26_numerics/valarray/range_access3.cc > > new file mode 100644 > > index 00000000000..0027622124f > > --- /dev/null > > +++ b/libstdc++-v3/testsuite/26_numerics/valarray/range_access3.cc > > @@ -0,0 +1,41 @@ > > +// { dg-do run { target c++26 } } > > + > > +#include <valarray> > > +#include <testsuite_hooks.h> > > + > > +void > > +test01() > > +{ > > + std::valarray<double> va(3); > > + va[0] = 1.0; va[1] = 2.0; va[2] = 3.0; > > + > > + typename std::valarray<double>::iterator it = va.begin(); > > + VERIFY( it != va.end() ); > > + VERIFY( *it++ == 1.0 ); > > + VERIFY( *it++ == 2.0 ); > > + VERIFY( *it++ == 3.0 ); > > + VERIFY( it == va.end() ); > > + > > + const std::valarray<double>& cva = va; > > + typename std::valarray<double>::const_iterator cit = cva.begin(); > > + VERIFY( cit != va.end() ); > > + VERIFY( *cit++ == 1.0 ); > > + VERIFY( *cit++ == 2.0 ); > > + VERIFY( *cit++ == 3.0 ); > > + VERIFY( cit == cva.end() ); > > +} > > + > > +void > > +test02() > > +{ > > + std::valarray<double> va; > > + VERIFY( va.begin() == va.end() ); > > + const std::valarray<double>& cva = va; > > + VERIFY( cva.begin() == cva.end() ); > > +} > > + > > +int main() > > +{ > > + test01(); > > + test02(); > > +} > > -- > > 2.54.0 > > > >
