On Thu, 11 Jan 2024, Jonathan Wakely wrote: > Tested x86_64-linux and aarch64-linux, with TBB 2020.3 only. > > Reviews requested. > > -- >8 -- > > This is a step towards implementing the C++23 change P2408R5, "Ranges > iterators as inputs to non-Ranges algorithms". C++20 random access > iterators which do not meet the C==17RandomAccessIterator requirements > will now be recognized by the PSTL algorithms.
IIUC P2408R5 only relaxes the iterator requirements on non-mutating algorithms, but presumably this patch relaxes the requirements for all parallel algorithms? Perhaps that's safe here, not sure.. Besides that LGTM. > > We can also optimize the C++17 implementation by using std::__or_, and > use std::__remove_cvref_t and std::__iter_category_t for readability. > This diverges from the upstream PSTL, but since libc++ is no longer > using that upstream (so we're the only consumer of this code) I think > it's reasonable to use libstdc++ extensions in localized places like > this. Rebasing this small header on upstream should not be difficult. > > libstdc++-v3/ChangeLog: > > PR libstdc++/110512 > * include/pstl/execution_impl.h (__are_random_access_iterators): > Recognize C++20 random access iterators, and use more efficient > implementations. > * testsuite/25_algorithms/pstl/110512.cc: New test. > --- > libstdc++-v3/include/pstl/execution_impl.h | 21 ++++++++++--- > .../testsuite/25_algorithms/pstl/110512.cc | 31 +++++++++++++++++++ > 2 files changed, 47 insertions(+), 5 deletions(-) > create mode 100644 libstdc++-v3/testsuite/25_algorithms/pstl/110512.cc > > diff --git a/libstdc++-v3/include/pstl/execution_impl.h > b/libstdc++-v3/include/pstl/execution_impl.h > index 64f6cc4357a..c84061848b9 100644 > --- a/libstdc++-v3/include/pstl/execution_impl.h > +++ b/libstdc++-v3/include/pstl/execution_impl.h > @@ -19,13 +19,24 @@ namespace __pstl > { > namespace __internal > { > - > -template <typename _IteratorTag, typename... _IteratorTypes> > -using __are_iterators_of = std::conjunction< > - std::is_base_of<_IteratorTag, typename > std::iterator_traits<std::decay_t<_IteratorTypes>>::iterator_category>...>; > +#if __glibcxx_concepts > +template<typename _Iter> > + concept __is_random_access_iter > + = std::is_base_of_v<std::random_access_iterator_tag, > + std::__iter_category_t<_Iter>> > + || std::random_access_iterator<_Iter>; > > template <typename... _IteratorTypes> > -using __are_random_access_iterators = > __are_iterators_of<std::random_access_iterator_tag, _IteratorTypes...>; > + using __are_random_access_iterators > + = > std::bool_constant<(__is_random_access_iter<std::remove_cvref_t<_IteratorTypes>> > && ...)>; > +#else > +template <typename... _IteratorTypes> > +using __are_random_access_iterators > + = std::__and_< > + std::is_base_of<std::random_access_iterator_tag, > + > std::__iter_category_t<std::__remove_cvref_t<_IteratorTypes>>>... > + >; > +#endif > > struct __serial_backend_tag > { > diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/110512.cc > b/libstdc++-v3/testsuite/25_algorithms/pstl/110512.cc > new file mode 100644 > index 00000000000..188c7c915e5 > --- /dev/null > +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/110512.cc > @@ -0,0 +1,31 @@ > +// { dg-do compile { target c++17 } } > + > +// Bug 110512 - C++20 random access iterators run sequentially with PSTL > + > +#include <algorithm> > +#include <execution> > +#include <ranges> > +#include <testsuite_iterators.h> > + > +using InputIter = __gnu_test::input_iterator_wrapper<int>; > +using FwdIter = __gnu_test::forward_iterator_wrapper<long>; > +using RAIter = __gnu_test::random_access_iterator_wrapper<float>; > + > +template<typename... Iter> > +constexpr bool all_random_access > + = __pstl::__internal::__are_random_access_iterators<Iter...>::value; > + > +using __pstl::__internal::__are_random_access_iterators; > +static_assert( all_random_access<RAIter> ); > +static_assert( all_random_access<int*, RAIter, const long*> ); > +static_assert( ! all_random_access<RAIter, FwdIter> ); > +static_assert( ! all_random_access<FwdIter, InputIter, RAIter> ); > + > +#if __cpp_lib_ranges > +using IotaIter = std::ranges::iterator_t<std::ranges::iota_view<int, int>>; > +static_assert( std::random_access_iterator<IotaIter> ); > +static_assert( all_random_access<IotaIter> ); > +static_assert( all_random_access<IotaIter, RAIter> ); > +static_assert( all_random_access<RAIter, IotaIter> ); > +static_assert( ! all_random_access<RAIter, IotaIter, FwdIter> ); > +#endif > -- > 2.43.0 > >