Commit eb9b0635 authored by Mark de Wever's avatar Mark de Wever
Browse files

[libc++] P1645 constexpr for <numeric>

Implements P1645: constexpr for <numeric> algorithms

Reviewed By: ldionne, #libc

Differential Revision: https://reviews.llvm.org/D90569
parent a38d13ed
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -196,6 +196,8 @@ Status
    ------------------------------------------------- -----------------
    ``__cpp_lib_constexpr_misc``                      *unimplemented*
    ------------------------------------------------- -----------------
    ``__cpp_lib_constexpr_numeric``                   ``201911L``
    ------------------------------------------------- -----------------
    ``__cpp_lib_constexpr_swap_algorithms``           *unimplemented*
    ------------------------------------------------- -----------------
    ``__cpp_lib_constexpr_utility``                   ``201811L``
+56 −46
Original line number Diff line number Diff line
@@ -17,115 +17,116 @@ namespace std
{

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>
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_PUSH_MACROS
_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 @@ accumulate(_InputIterator __first, _InputIterator __last, _Tp __init)
}

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 @@ accumulate(_InputIterator __first, _InputIterator __last, _Tp __init, _BinaryOpe

#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 @@ reduce(_InputIterator __first, _InputIterator __last, _Tp __init, _BinaryOp __b)
}

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 @@ reduce(_InputIterator __first, _InputIterator __last, _Tp __init)
}

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 @@ reduce(_InputIterator __first, _InputIterator __last)
#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 @@ inner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2
}

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 @@ inner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2

#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 @@ transform_reduce(_InputIterator __first, _InputIterator __last,

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 @@ transform_reduce(_InputIterator1 __first1, _InputIterator1 __last1,
}

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 @@ transform_reduce(_InputIterator1 __first1, _InputIterator1 __last1,
#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 @@ partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __res
}

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 @@ partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __res

#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 @@ exclusive_scan(_InputIterator __first, _InputIterator __last,
}

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 @@ exclusive_scan(_InputIterator __first, _InputIterator __last,
}

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 @@ _OutputIterator inclusive_scan(_InputIterator __first, _InputIterator __last,
}

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 @@ _OutputIterator inclusive_scan(_InputIterator __first, _InputIterator __last,
}

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 @@ _OutputIterator inclusive_scan(_InputIterator __first, _InputIterator __last,

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 @@ transform_exclusive_scan(_InputIterator __first, _InputIterator __last,
}

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 @@ _OutputIterator transform_inclusive_scan(_InputIterator __first, _InputIterator
}

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 @@ _OutputIterator transform_inclusive_scan(_InputIterator __first, _InputIterator
#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 @@ adjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterat
}

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 @@ adjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterat
}

template <class _ForwardIterator, class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
void
iota(_ForwardIterator __first, _ForwardIterator __last, _Tp __value_)
{
+2 −0
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ __cpp_lib_concepts 201806L <concepts>
__cpp_lib_constexpr_dynamic_alloc                       201907L <memory>
__cpp_lib_constexpr_misc                                201811L <array> <functional> <iterator>
                                                                <string_view> <tuple> <utility>
__cpp_lib_constexpr_numeric                             201911L <numeric>
__cpp_lib_constexpr_swap_algorithms                     201806L <algorithm>
__cpp_lib_constexpr_utility                             201811L <utility>
__cpp_lib_destroying_delete                             201806L <new>
@@ -254,6 +255,7 @@ __cpp_lib_void_t 201411L <type_traits>
// # define __cpp_lib_concepts                             201806L
# define __cpp_lib_constexpr_dynamic_alloc              201907L
// # define __cpp_lib_constexpr_misc                       201811L
# define __cpp_lib_constexpr_numeric                    201911L
// # define __cpp_lib_constexpr_swap_algorithms            201806L
# define __cpp_lib_constexpr_utility                    201811L
# if _LIBCPP_STD_VER > 17 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L
+20 −0
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
// Test the feature test macros defined by <numeric>

/*  Constant                        Value
    __cpp_lib_constexpr_numeric     201911L [C++2a]
    __cpp_lib_gcd_lcm               201606L [C++17]
    __cpp_lib_interpolate           201902L [C++2a]
    __cpp_lib_parallel_algorithm    201603L [C++17]
@@ -24,6 +25,10 @@

#if TEST_STD_VER < 14

# ifdef __cpp_lib_constexpr_numeric
#   error "__cpp_lib_constexpr_numeric should not be defined before c++2a"
# endif

# ifdef __cpp_lib_gcd_lcm
#   error "__cpp_lib_gcd_lcm should not be defined before c++17"
# endif
@@ -38,6 +43,10 @@

#elif TEST_STD_VER == 14

# ifdef __cpp_lib_constexpr_numeric
#   error "__cpp_lib_constexpr_numeric should not be defined before c++2a"
# endif

# ifdef __cpp_lib_gcd_lcm
#   error "__cpp_lib_gcd_lcm should not be defined before c++17"
# endif
@@ -52,6 +61,10 @@

#elif TEST_STD_VER == 17

# ifdef __cpp_lib_constexpr_numeric
#   error "__cpp_lib_constexpr_numeric should not be defined before c++2a"
# endif

# ifndef __cpp_lib_gcd_lcm
#   error "__cpp_lib_gcd_lcm should be defined in c++17"
# endif
@@ -78,6 +91,13 @@

#elif TEST_STD_VER > 17

# ifndef __cpp_lib_constexpr_numeric
#   error "__cpp_lib_constexpr_numeric should be defined in c++2a"
# endif
# if __cpp_lib_constexpr_numeric != 201911L
#   error "__cpp_lib_constexpr_numeric should have the value 201911L in c++2a"
# endif

# ifndef __cpp_lib_gcd_lcm
#   error "__cpp_lib_gcd_lcm should be defined in c++2a"
# endif
+20 −0
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@
    __cpp_lib_concepts                             201806L [C++2a]
    __cpp_lib_constexpr_dynamic_alloc              201907L [C++2a]
    __cpp_lib_constexpr_misc                       201811L [C++2a]
    __cpp_lib_constexpr_numeric                    201911L [C++2a]
    __cpp_lib_constexpr_swap_algorithms            201806L [C++2a]
    __cpp_lib_constexpr_utility                    201811L [C++2a]
    __cpp_lib_destroying_delete                    201806L [C++2a]
@@ -227,6 +228,10 @@
#   error "__cpp_lib_constexpr_misc should not be defined before c++2a"
# endif

# ifdef __cpp_lib_constexpr_numeric
#   error "__cpp_lib_constexpr_numeric should not be defined before c++2a"
# endif

# ifdef __cpp_lib_constexpr_swap_algorithms
#   error "__cpp_lib_constexpr_swap_algorithms should not be defined before c++2a"
# endif
@@ -619,6 +624,10 @@
#   error "__cpp_lib_constexpr_misc should not be defined before c++2a"
# endif

# ifdef __cpp_lib_constexpr_numeric
#   error "__cpp_lib_constexpr_numeric should not be defined before c++2a"
# endif

# ifdef __cpp_lib_constexpr_swap_algorithms
#   error "__cpp_lib_constexpr_swap_algorithms should not be defined before c++2a"
# endif
@@ -1125,6 +1134,10 @@
#   error "__cpp_lib_constexpr_misc should not be defined before c++2a"
# endif

# ifdef __cpp_lib_constexpr_numeric
#   error "__cpp_lib_constexpr_numeric should not be defined before c++2a"
# endif

# ifdef __cpp_lib_constexpr_swap_algorithms
#   error "__cpp_lib_constexpr_swap_algorithms should not be defined before c++2a"
# endif
@@ -1910,6 +1923,13 @@
#   endif
# endif

# ifndef __cpp_lib_constexpr_numeric
#   error "__cpp_lib_constexpr_numeric should be defined in c++2a"
# endif
# if __cpp_lib_constexpr_numeric != 201911L
#   error "__cpp_lib_constexpr_numeric should have the value 201911L in c++2a"
# endif

# if !defined(_LIBCPP_VERSION)
#   ifndef __cpp_lib_constexpr_swap_algorithms
#     error "__cpp_lib_constexpr_swap_algorithms should be defined in c++2a"
Loading