From e12097eda087e492ec22adaaf368cc63c3284c4e Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Tue, 1 Oct 2019 22:02:22 +0100 Subject: [PATCH] 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. From-SVN: r276431 --- libstdc++-v3/ChangeLog | 6 +++ libstdc++-v3/include/parallel/algobase.h | 42 +++++++++++++++++++- libstdc++-v3/include/parallel/algorithmfwd.h | 4 ++ 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 2a957675112..45ad8517bf4 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,11 @@ 2019-10-01 Jonathan Wakely + * 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. + * testsuite/17_intro/using_namespace_std_tr1_neg.cc: Skip test for parallel mode. * testsuite/20_util/hash/84998.cc: Likewise. 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 + _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 + _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 + _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 + _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 @@ -391,10 +416,17 @@ namespace __parallel // Public interface template + _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 + _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 + _GLIBCXX20_CONSTEXPR bool equal(_IIter1, _IIter1, _IIter2); template + _GLIBCXX20_CONSTEXPR bool equal(_IIter1, _IIter1, _IIter2, _Predicate); @@ -285,10 +287,12 @@ namespace __parallel __gnu_parallel::sequential_tag); template + _GLIBCXX20_CONSTEXPR bool lexicographical_compare(_IIter1, _IIter1, _IIter2, _IIter2); template + _GLIBCXX20_CONSTEXPR bool lexicographical_compare(_IIter1, _IIter1, _IIter2, _IIter2, _Predicate);