On Tue, 19 May 2026 at 06:37, Tomasz Kaminski <[email protected]> wrote:
>
>
>
> 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.
OK for trunk with [[nodiscard]] and noexcept instead of the macros, thanks.
>>
>>
>> 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
>> >
>>