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
> >
>
>

Reply via email to