[libc++] P1645 constexpr for <numeric>

Implements P1645: constexpr for <numeric> algorithms

Reviewed By: ldionne, #libc

Differential Revision: https://reviews.llvm.org/D90569

GitOrigin-RevId: eb9b063539c34d0d4dd14e8516eeb77bb8b9e4bd
diff --git a/include/numeric b/include/numeric
index 50070de..ce4fc5f 100644
--- a/include/numeric
+++ b/include/numeric
@@ -17,115 +17,116 @@
 {
 
 template <class InputIterator, class T>
-    T
+    constexpr T  // constexpr since C++20
     accumulate(InputIterator first, InputIterator last, T init);
 
 template <class InputIterator, class T, class BinaryOperation>
-    T
+    constexpr T  // constexpr since C++20
     accumulate(InputIterator first, InputIterator last, T init, BinaryOperation binary_op);
 
 template<class InputIterator>
-    typename iterator_traits<InputIterator>::value_type
+    constexpr typename iterator_traits<InputIterator>::value_type  // constexpr since C++20
     reduce(InputIterator first, InputIterator last);  // C++17
 
 template<class InputIterator, class T>
-    T
+    constexpr T  // constexpr since C++20
     reduce(InputIterator first, InputIterator last, T init);  // C++17
 
 template<class InputIterator, class T, class BinaryOperation>
-    T
+    constexpr T  // constexpr since C++20
     reduce(InputIterator first, InputIterator last, T init, BinaryOperation binary_op);  // C++17
 
 template <class InputIterator1, class InputIterator2, class T>
-    T
+    constexpr T  // constexpr since C++20
     inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init);
 
 template <class InputIterator1, class InputIterator2, class T, class BinaryOperation1, class BinaryOperation2>
-    T
+    constexpr T  // constexpr since C++20
     inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2,
                   T init, BinaryOperation1 binary_op1, BinaryOperation2 binary_op2);
 
 
 template<class InputIterator1, class InputIterator2, class T>
-    T
+    constexpr T  // constexpr since C++20
     transform_reduce(InputIterator1 first1, InputIterator1 last1,
                      InputIterator2 first2, T init);  // C++17
 
 template<class InputIterator1, class InputIterator2, class T, class BinaryOperation1, class BinaryOperation2>
-    T
+    constexpr T  // constexpr since C++20
     transform_reduce(InputIterator1 first1, InputIterator1 last1,
                      InputIterator2 first2, T init,
                      BinaryOperation1 binary_op1, BinaryOperation2 binary_op2);  // C++17
 
 template<class InputIterator, class T, class BinaryOperation, class UnaryOperation>
-    T
+    constexpr T  // constexpr since C++20
     transform_reduce(InputIterator first, InputIterator last, T init,
                      BinaryOperation binary_op, UnaryOperation unary_op);  // C++17
 
 template <class InputIterator, class OutputIterator>
-    OutputIterator
+    constexpr OutputIterator  // constexpr since C++20
     partial_sum(InputIterator first, InputIterator last, OutputIterator result);
 
 template <class InputIterator, class OutputIterator, class BinaryOperation>
-    OutputIterator
+    constexpr OutputIterator  // constexpr since C++20
     partial_sum(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op);
 
 template<class InputIterator, class OutputIterator, class T>
-    OutputIterator
+    constexpr OutputIterator  // constexpr since C++20
     exclusive_scan(InputIterator first, InputIterator last,
                    OutputIterator result, T init); // C++17
 
 template<class InputIterator, class OutputIterator, class T, class BinaryOperation>
-    OutputIterator
+    constexpr OutputIterator  // constexpr since C++20
     exclusive_scan(InputIterator first, InputIterator last,
                    OutputIterator result, T init, BinaryOperation binary_op); // C++17
 
 template<class InputIterator, class OutputIterator>
-    OutputIterator
+    constexpr OutputIterator  // constexpr since C++20
     inclusive_scan(InputIterator first, InputIterator last, OutputIterator result);  // C++17
 
 template<class InputIterator, class OutputIterator, class BinaryOperation>
-    OutputIterator
+    constexpr OutputIterator  // constexpr since C++20
     inclusive_scan(InputIterator first, InputIterator last,
                    OutputIterator result, BinaryOperation binary_op);  // C++17
 
 template<class InputIterator, class OutputIterator, class BinaryOperation, class T>
-    OutputIterator
+    constexpr OutputIterator  // constexpr since C++20
     inclusive_scan(InputIterator first, InputIterator last,
                    OutputIterator result, BinaryOperation binary_op, T init);  // C++17
 
 template<class InputIterator, class OutputIterator, class T,
          class BinaryOperation, class UnaryOperation>
-    OutputIterator
+    constexpr OutputIterator  // constexpr since C++20
     transform_exclusive_scan(InputIterator first, InputIterator last,
                              OutputIterator result, T init,
                              BinaryOperation binary_op, UnaryOperation unary_op);  // C++17
 
 template<class InputIterator, class OutputIterator,
          class BinaryOperation, class UnaryOperation>
-    OutputIterator
+    constexpr OutputIterator  // constexpr since C++20
     transform_inclusive_scan(InputIterator first, InputIterator last,
                              OutputIterator result,
                              BinaryOperation binary_op, UnaryOperation unary_op);  // C++17
 
 template<class InputIterator, class OutputIterator,
          class BinaryOperation, class UnaryOperation, class T>
-    OutputIterator
+    constexpr OutputIterator  // constexpr since C++20
     transform_inclusive_scan(InputIterator first, InputIterator last,
                              OutputIterator result,
                              BinaryOperation binary_op, UnaryOperation unary_op,
                              T init);  // C++17
 
 template <class InputIterator, class OutputIterator>
-    OutputIterator
+    constexpr OutputIterator  // constexpr since C++20
     adjacent_difference(InputIterator first, InputIterator last, OutputIterator result);
 
 template <class InputIterator, class OutputIterator, class BinaryOperation>
-    OutputIterator
+    constexpr OutputIterator  // constexpr since C++20
     adjacent_difference(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op);
 
 template <class ForwardIterator, class T>
-    void iota(ForwardIterator first, ForwardIterator last, T value);
+    constexpr void  // constexpr since C++20
+    iota(ForwardIterator first, ForwardIterator last, T value);
 
 template <class M, class N>
     constexpr common_type_t<M,N> gcd(M m, N n);    // C++17
@@ -133,9 +134,11 @@
 template <class M, class N>
     constexpr common_type_t<M,N> lcm(M m, N n);    // C++17
 
-integer         midpoint(integer a, integer b);                  // C++20
-pointer         midpoint(pointer a, pointer b);                  // C++20
-floating_point  midpoint(floating_point a, floating_point b);    // C++20
+template<class T>
+    constexpr T midpoint(T a, T b) noexcept;  // C++20
+
+template<class T>
+    constexpr T* midpoint(T* a, T* b);        // C++20
 
 }  // std
 
@@ -158,7 +161,7 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _InputIterator, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 _Tp
 accumulate(_InputIterator __first, _InputIterator __last, _Tp __init)
 {
@@ -168,7 +171,7 @@
 }
 
 template <class _InputIterator, class _Tp, class _BinaryOperation>
-inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 _Tp
 accumulate(_InputIterator __first, _InputIterator __last, _Tp __init, _BinaryOperation __binary_op)
 {
@@ -179,7 +182,7 @@
 
 #if _LIBCPP_STD_VER > 14
 template <class _InputIterator, class _Tp, class _BinaryOp>
-inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 _Tp
 reduce(_InputIterator __first, _InputIterator __last, _Tp __init, _BinaryOp __b)
 {
@@ -189,7 +192,7 @@
 }
 
 template <class _InputIterator, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 _Tp
 reduce(_InputIterator __first, _InputIterator __last, _Tp __init)
 {
@@ -197,7 +200,7 @@
 }
 
 template <class _InputIterator>
-inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 typename iterator_traits<_InputIterator>::value_type
 reduce(_InputIterator __first, _InputIterator __last)
 {
@@ -207,7 +210,7 @@
 #endif
 
 template <class _InputIterator1, class _InputIterator2, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 _Tp
 inner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _Tp __init)
 {
@@ -217,7 +220,7 @@
 }
 
 template <class _InputIterator1, class _InputIterator2, class _Tp, class _BinaryOperation1, class _BinaryOperation2>
-inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 _Tp
 inner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2,
               _Tp __init, _BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2)
@@ -229,7 +232,7 @@
 
 #if _LIBCPP_STD_VER > 14
 template <class _InputIterator, class _Tp, class _BinaryOp, class _UnaryOp>
-inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 _Tp
 transform_reduce(_InputIterator __first, _InputIterator __last,
            _Tp __init,  _BinaryOp __b, _UnaryOp __u)
@@ -241,7 +244,7 @@
 
 template <class _InputIterator1, class _InputIterator2,
           class _Tp, class _BinaryOp1, class _BinaryOp2>
-inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 _Tp
 transform_reduce(_InputIterator1 __first1, _InputIterator1 __last1,
                  _InputIterator2 __first2, _Tp __init,  _BinaryOp1 __b1, _BinaryOp2 __b2)
@@ -252,7 +255,7 @@
 }
 
 template <class _InputIterator1, class _InputIterator2, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 _Tp
 transform_reduce(_InputIterator1 __first1, _InputIterator1 __last1,
                  _InputIterator2 __first2, _Tp __init)
@@ -263,7 +266,7 @@
 #endif
 
 template <class _InputIterator, class _OutputIterator>
-inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 _OutputIterator
 partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
 {
@@ -281,7 +284,7 @@
 }
 
 template <class _InputIterator, class _OutputIterator, class _BinaryOperation>
-inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 _OutputIterator
 partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __result,
               _BinaryOperation __binary_op)
@@ -301,7 +304,7 @@
 
 #if _LIBCPP_STD_VER > 14
 template <class _InputIterator, class _OutputIterator, class _Tp, class _BinaryOp>
-inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 _OutputIterator
 exclusive_scan(_InputIterator __first, _InputIterator __last,
                _OutputIterator __result, _Tp __init, _BinaryOp __b)
@@ -321,7 +324,7 @@
 }
 
 template <class _InputIterator, class _OutputIterator, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 _OutputIterator
 exclusive_scan(_InputIterator __first, _InputIterator __last,
                _OutputIterator __result, _Tp __init)
@@ -330,6 +333,7 @@
 }
 
 template <class _InputIterator, class _OutputIterator, class _Tp, class _BinaryOp>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 _OutputIterator inclusive_scan(_InputIterator __first, _InputIterator __last,
                                _OutputIterator __result, _BinaryOp __b,  _Tp __init)
 {
@@ -341,6 +345,7 @@
 }
 
 template <class _InputIterator, class _OutputIterator, class _BinaryOp>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 _OutputIterator inclusive_scan(_InputIterator __first, _InputIterator __last,
                                _OutputIterator __result, _BinaryOp __b)
 {
@@ -355,6 +360,7 @@
 }
 
 template <class _InputIterator, class _OutputIterator>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 _OutputIterator inclusive_scan(_InputIterator __first, _InputIterator __last,
                                _OutputIterator __result)
 {
@@ -363,7 +369,7 @@
 
 template <class _InputIterator, class _OutputIterator, class _Tp,
           class _BinaryOp, class _UnaryOp>
-inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 _OutputIterator
 transform_exclusive_scan(_InputIterator __first, _InputIterator __last,
                            _OutputIterator __result, _Tp __init,
@@ -384,7 +390,9 @@
 }
 
 template <class _InputIterator, class _OutputIterator, class _Tp, class _BinaryOp, class _UnaryOp>
-_OutputIterator transform_inclusive_scan(_InputIterator __first, _InputIterator __last,
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_OutputIterator
+transform_inclusive_scan(_InputIterator __first, _InputIterator __last,
                            _OutputIterator __result, _BinaryOp __b, _UnaryOp __u, _Tp __init)
 {
     for (; __first != __last; ++__first, (void) ++__result) {
@@ -396,7 +404,9 @@
 }
 
 template <class _InputIterator, class _OutputIterator, class _BinaryOp, class _UnaryOp>
-_OutputIterator transform_inclusive_scan(_InputIterator __first, _InputIterator __last,
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+_OutputIterator
+transform_inclusive_scan(_InputIterator __first, _InputIterator __last,
                                _OutputIterator __result, _BinaryOp __b, _UnaryOp __u)
 {
     if (__first != __last) {
@@ -411,7 +421,7 @@
 #endif
 
 template <class _InputIterator, class _OutputIterator>
-inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 _OutputIterator
 adjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
 {
@@ -430,7 +440,7 @@
 }
 
 template <class _InputIterator, class _OutputIterator, class _BinaryOperation>
-inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 _OutputIterator
 adjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterator __result,
                       _BinaryOperation __binary_op)
@@ -450,7 +460,7 @@
 }
 
 template <class _ForwardIterator, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 void
 iota(_ForwardIterator __first, _ForwardIterator __last, _Tp __value_)
 {