Make some parallel mode algorithms usable in constexpr contexts

Message ID 20191001210111.GP9487@redhat.com
State New
Headers show
Series
  • Make some parallel mode algorithms usable in constexpr contexts
Related show

Commit Message

Jonathan Wakely Oct. 1, 2019, 9:01 p.m.
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.

Patch

commit 9b07c6cfd553566a3ebdbab72b12e007d4912bf1
Author: Jonathan Wakely <jwakely@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);