Tested x86_64-linux (normal and parallel modes), committed to trunk.
Most algos still aren't constexpr in parallel mode, this just fixes the ones needed by std::array.
commit 9b07c6cfd553566a3ebdbab72b12e007d4912bf1 Author: Jonathan Wakely <jwak...@redhat.com> Date: Tue Oct 1 20:33:08 2019 +0100 Make some parallel mode algorithms usable in constexpr contexts This makes the __parallel::equal and __parallel:lexicographical_compare algorithms usable in constant expressions, by dispatching to the sequential algorithm when calling during constant evaluation. * include/parallel/algobase.h (equal, lexicographical_compare): Add _GLIBCXX20_CONSTEXPR and dispatch to sequential algorithm when being constant evaluated. * include/parallel/algorithmfwd.h (equal, lexicographical_compare): Add _GLIBCXX20_CONSTEXPR. diff --git a/libstdc++-v3/include/parallel/algobase.h b/libstdc++-v3/include/parallel/algobase.h index 829eb11306b..d78bdc961a1 100644 --- a/libstdc++-v3/include/parallel/algobase.h +++ b/libstdc++-v3/include/parallel/algobase.h @@ -214,19 +214,31 @@ namespace __parallel // Public interface template<typename _IIter1, typename _IIter2> + _GLIBCXX20_CONSTEXPR inline bool equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2) { +#if __cplusplus > 201703L + if (std::is_constant_evaluated()) + return _GLIBCXX_STD_A::equal(__begin1, __end1, __begin2); +#endif + return __gnu_parallel::mismatch(__begin1, __end1, __begin2).first == __end1; } // Public interface template<typename _IIter1, typename _IIter2, typename _Predicate> + _GLIBCXX20_CONSTEXPR inline bool equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _Predicate __pred) { +#if __cplusplus > 201703L + if (std::is_constant_evaluated()) + return _GLIBCXX_STD_A::equal(__begin1, __end1, __begin2, __pred); +#endif + return __gnu_parallel::mismatch(__begin1, __end1, __begin2, __pred).first == __end1; } @@ -286,9 +298,15 @@ namespace __parallel } template<typename _IIter1, typename _IIter2> + _GLIBCXX20_CONSTEXPR inline bool equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2) { +#if __cplusplus > 201703L + if (std::is_constant_evaluated()) + return _GLIBCXX_STD_A::equal(__begin1, __end1, __begin2, __end2); +#endif + typedef __gnu_parallel::_EqualTo< typename std::iterator_traits<_IIter1>::value_type, typename std::iterator_traits<_IIter2>::value_type> _EqualTo; @@ -299,15 +317,22 @@ namespace __parallel } template<typename _IIter1, typename _IIter2, typename _BinaryPredicate> + _GLIBCXX20_CONSTEXPR inline bool equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _BinaryPredicate __binary_pred) { +#if __cplusplus > 201703L + if (std::is_constant_evaluated()) + return _GLIBCXX_STD_A::equal(__begin1, __end1, __begin2, __end2, + __binary_pred); +#endif + return __equal_switch(__begin1, __end1, __begin2, __end2, __binary_pred, std::__iterator_category(__begin1), std::__iterator_category(__begin2)); } -#endif +#endif // C++14 // Sequential fallback template<typename _IIter1, typename _IIter2> @@ -391,10 +416,17 @@ namespace __parallel // Public interface template<typename _IIter1, typename _IIter2> + _GLIBCXX20_CONSTEXPR inline bool lexicographical_compare(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2) { +#if __cplusplus > 201703L + if (std::is_constant_evaluated()) + return _GLIBCXX_STD_A::lexicographical_compare(__begin1, __end1, + __begin2, __end2); +#endif + typedef iterator_traits<_IIter1> _TraitsType1; typedef typename _TraitsType1::value_type _ValueType1; typedef typename _TraitsType1::iterator_category _IteratorCategory1; @@ -411,11 +443,19 @@ namespace __parallel // Public interface template<typename _IIter1, typename _IIter2, typename _Predicate> + _GLIBCXX20_CONSTEXPR inline bool lexicographical_compare(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _Predicate __pred) { +#if __cplusplus > 201703L + if (std::is_constant_evaluated()) + return _GLIBCXX_STD_A::lexicographical_compare(__begin1, __end1, + __begin2, __end2, + __pred); +#endif + typedef iterator_traits<_IIter1> _TraitsType1; typedef typename _TraitsType1::iterator_category _IteratorCategory1; diff --git a/libstdc++-v3/include/parallel/algorithmfwd.h b/libstdc++-v3/include/parallel/algorithmfwd.h index a6d03a50cfc..a227ebac2a3 100644 --- a/libstdc++-v3/include/parallel/algorithmfwd.h +++ b/libstdc++-v3/include/parallel/algorithmfwd.h @@ -130,10 +130,12 @@ namespace __parallel __gnu_parallel::sequential_tag); template<typename _IIter1, typename _IIter2> + _GLIBCXX20_CONSTEXPR bool equal(_IIter1, _IIter1, _IIter2); template<typename _IIter1, typename _IIter2, typename _Predicate> + _GLIBCXX20_CONSTEXPR bool equal(_IIter1, _IIter1, _IIter2, _Predicate); @@ -285,10 +287,12 @@ namespace __parallel __gnu_parallel::sequential_tag); template<typename _IIter1, typename _IIter2> + _GLIBCXX20_CONSTEXPR bool lexicographical_compare(_IIter1, _IIter1, _IIter2, _IIter2); template<typename _IIter1, typename _IIter2, typename _Predicate> + _GLIBCXX20_CONSTEXPR bool lexicographical_compare(_IIter1, _IIter1, _IIter2, _IIter2, _Predicate);