[llvm-branch-commits] [libcxx] eb9b063 - [libc++] P1645 constexpr for <numeric>
Mark de Wever via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Nov 25 04:23:51 PST 2020
Author: Mark de Wever
Date: 2020-11-25T13:19:32+01:00
New Revision: eb9b063539c34d0d4dd14e8516eeb77bb8b9e4bd
URL: https://github.com/llvm/llvm-project/commit/eb9b063539c34d0d4dd14e8516eeb77bb8b9e4bd
DIFF: https://github.com/llvm/llvm-project/commit/eb9b063539c34d0d4dd14e8516eeb77bb8b9e4bd.diff
LOG: [libc++] P1645 constexpr for <numeric>
Implements P1645: constexpr for <numeric> algorithms
Reviewed By: ldionne, #libc
Differential Revision: https://reviews.llvm.org/D90569
Added:
Modified:
libcxx/docs/FeatureTestMacroTable.rst
libcxx/include/numeric
libcxx/include/version
libcxx/test/std/language.support/support.limits/support.limits.general/numeric.version.pass.cpp
libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp
libcxx/test/std/numerics/numeric.ops/accumulate/accumulate.pass.cpp
libcxx/test/std/numerics/numeric.ops/accumulate/accumulate_op.pass.cpp
libcxx/test/std/numerics/numeric.ops/adjacent.difference/adjacent_difference.pass.cpp
libcxx/test/std/numerics/numeric.ops/adjacent.difference/adjacent_difference_op.pass.cpp
libcxx/test/std/numerics/numeric.ops/exclusive.scan/exclusive_scan.pass.cpp
libcxx/test/std/numerics/numeric.ops/exclusive.scan/exclusive_scan_init_op.pass.cpp
libcxx/test/std/numerics/numeric.ops/inclusive.scan/inclusive_scan.pass.cpp
libcxx/test/std/numerics/numeric.ops/inclusive.scan/inclusive_scan_op.pass.cpp
libcxx/test/std/numerics/numeric.ops/inclusive.scan/inclusive_scan_op_init.pass.cpp
libcxx/test/std/numerics/numeric.ops/inner.product/inner_product.pass.cpp
libcxx/test/std/numerics/numeric.ops/inner.product/inner_product_comp.pass.cpp
libcxx/test/std/numerics/numeric.ops/numeric.iota/iota.pass.cpp
libcxx/test/std/numerics/numeric.ops/partial.sum/partial_sum.pass.cpp
libcxx/test/std/numerics/numeric.ops/partial.sum/partial_sum_op.pass.cpp
libcxx/test/std/numerics/numeric.ops/reduce/reduce.pass.cpp
libcxx/test/std/numerics/numeric.ops/reduce/reduce_init.pass.cpp
libcxx/test/std/numerics/numeric.ops/reduce/reduce_init_op.pass.cpp
libcxx/test/std/numerics/numeric.ops/transform.exclusive.scan/transform_exclusive_scan_init_bop_uop.pass.cpp
libcxx/test/std/numerics/numeric.ops/transform.inclusive.scan/transform_inclusive_scan_bop_uop.pass.cpp
libcxx/test/std/numerics/numeric.ops/transform.inclusive.scan/transform_inclusive_scan_bop_uop_init.pass.cpp
libcxx/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_init_bop_uop.pass.cpp
libcxx/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init.pass.cpp
libcxx/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init_op_op.pass.cpp
libcxx/utils/generate_feature_test_macro_components.py
libcxx/www/cxx2a_status.html
Removed:
################################################################################
diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index 637a4849e471..aa60a033edc3 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -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``
diff --git a/libcxx/include/numeric b/libcxx/include/numeric
index 50070ded8fed..ce4fc5f55347 100644
--- a/libcxx/include/numeric
+++ b/libcxx/include/numeric
@@ -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_
diff erence(InputIterator first, InputIterator last, OutputIterator result);
template <class InputIterator, class OutputIterator, class BinaryOperation>
- OutputIterator
+ constexpr OutputIterator // constexpr since C++20
adjacent_
diff erence(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_
diff erence(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
{
@@ -430,7 +440,7 @@ adjacent_
diff erence(_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_
diff erence(_InputIterator __first, _InputIterator __last, _OutputIterator __result,
_BinaryOperation __binary_op)
@@ -450,7 +460,7 @@ adjacent_
diff erence(_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_)
{
diff --git a/libcxx/include/version b/libcxx/include/version
index 58f676548fe7..2f1fd92db406 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -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
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/numeric.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/numeric.version.pass.cpp
index c43d7175e1ee..881c81474eb0 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/numeric.version.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/numeric.version.pass.cpp
@@ -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
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp
index efb8416924ce..0aaef3c51122 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp
@@ -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"
diff --git a/libcxx/test/std/numerics/numeric.ops/accumulate/accumulate.pass.cpp b/libcxx/test/std/numerics/numeric.ops/accumulate/accumulate.pass.cpp
index 8513635de3e1..12a2ab00de04 100644
--- a/libcxx/test/std/numerics/numeric.ops/accumulate/accumulate.pass.cpp
+++ b/libcxx/test/std/numerics/numeric.ops/accumulate/accumulate.pass.cpp
@@ -8,6 +8,7 @@
// <numeric>
+// Became constexpr in C++20
// template <InputIterator Iter, MoveConstructible T>
// requires HasPlus<T, Iter::reference>
// && HasAssign<T, HasPlus<T, Iter::reference>::result_type>
@@ -21,14 +22,14 @@
#include "test_iterators.h"
template <class Iter, class T>
-void
+TEST_CONSTEXPR_CXX20 void
test(Iter first, Iter last, T init, T x)
{
assert(std::accumulate(first, last, init) == x);
}
template <class Iter>
-void
+TEST_CONSTEXPR_CXX20 void
test()
{
int ia[] = {1, 2, 3, 4, 5, 6};
@@ -43,7 +44,8 @@ test()
test(Iter(ia), Iter(ia+sa), 10, 31);
}
-int main(int, char**)
+TEST_CONSTEXPR_CXX20 bool
+test()
{
test<input_iterator<const int*> >();
test<forward_iterator<const int*> >();
@@ -51,5 +53,14 @@ int main(int, char**)
test<random_access_iterator<const int*> >();
test<const int*>();
- return 0;
+ return true;
+}
+
+int main(int, char**)
+{
+ test();
+#if TEST_STD_VER > 17
+ static_assert(test());
+#endif
+ return 0;
}
diff --git a/libcxx/test/std/numerics/numeric.ops/accumulate/accumulate_op.pass.cpp b/libcxx/test/std/numerics/numeric.ops/accumulate/accumulate_op.pass.cpp
index f2e3a6bc26c3..27fed9cc9f65 100644
--- a/libcxx/test/std/numerics/numeric.ops/accumulate/accumulate_op.pass.cpp
+++ b/libcxx/test/std/numerics/numeric.ops/accumulate/accumulate_op.pass.cpp
@@ -8,6 +8,7 @@
// <numeric>
+// Became constexpr in C++20
// template <InputIterator Iter, MoveConstructible T,
// Callable<auto, const T&, Iter::reference> BinaryOperation>
// requires HasAssign<T, BinaryOperation::result_type>
@@ -23,14 +24,14 @@
#include "test_iterators.h"
template <class Iter, class T>
-void
+TEST_CONSTEXPR_CXX20 void
test(Iter first, Iter last, T init, T x)
{
assert(std::accumulate(first, last, init, std::multiplies<T>()) == x);
}
template <class Iter>
-void
+TEST_CONSTEXPR_CXX20 void
test()
{
int ia[] = {1, 2, 3, 4, 5, 6};
@@ -45,7 +46,8 @@ test()
test(Iter(ia), Iter(ia+sa), 10, 7200);
}
-int main(int, char**)
+TEST_CONSTEXPR_CXX20 bool
+test()
{
test<input_iterator<const int*> >();
test<forward_iterator<const int*> >();
@@ -53,5 +55,14 @@ int main(int, char**)
test<random_access_iterator<const int*> >();
test<const int*>();
- return 0;
+ return true;
+}
+
+int main(int, char**)
+{
+ test();
+#if TEST_STD_VER > 17
+ static_assert(test());
+#endif
+ return 0;
}
diff --git a/libcxx/test/std/numerics/numeric.ops/adjacent.
diff erence/adjacent_
diff erence.pass.cpp b/libcxx/test/std/numerics/numeric.ops/adjacent.
diff erence/adjacent_
diff erence.pass.cpp
index 3e043e5cb8fe..ed0e86e61881 100644
--- a/libcxx/test/std/numerics/numeric.ops/adjacent.
diff erence/adjacent_
diff erence.pass.cpp
+++ b/libcxx/test/std/numerics/numeric.ops/adjacent.
diff erence/adjacent_
diff erence.pass.cpp
@@ -8,6 +8,7 @@
// <numeric>
+// Became constexpr in C++20
// template <InputIterator InIter,
// OutputIterator<auto, const InIter::value_type&> OutIter>
// requires HasMinus<InIter::value_type, InIter::value_type>
@@ -25,7 +26,7 @@
#include "test_iterators.h"
template <class InIter, class OutIter>
-void
+TEST_CONSTEXPR_CXX20 void
test()
{
int ia[] = {15, 10, 6, 3, 1};
@@ -46,18 +47,18 @@ class X
{
int i_;
- X& operator=(const X&);
+ TEST_CONSTEXPR_CXX20 X& operator=(const X&);
public:
- explicit X(int i) : i_(i) {}
- X(const X& x) : i_(x.i_) {}
- X& operator=(X&& x)
+ TEST_CONSTEXPR_CXX20 explicit X(int i) : i_(i) {}
+ TEST_CONSTEXPR_CXX20 X(const X& x) : i_(x.i_) {}
+ TEST_CONSTEXPR_CXX20 X& operator=(X&& x)
{
i_ = x.i_;
x.i_ = -1;
return *this;
}
- friend X operator-(const X& x, const X& y) {return X(x.i_ - y.i_);}
+ TEST_CONSTEXPR_CXX20 friend X operator-(const X& x, const X& y) {return X(x.i_ - y.i_);}
friend class Y;
};
@@ -66,16 +67,17 @@ class Y
{
int i_;
- Y& operator=(const Y&);
+ TEST_CONSTEXPR_CXX20 Y& operator=(const Y&);
public:
- explicit Y(int i) : i_(i) {}
- Y(const Y& y) : i_(y.i_) {}
- void operator=(const X& x) {i_ = x.i_;}
+ TEST_CONSTEXPR_CXX20 explicit Y(int i) : i_(i) {}
+ TEST_CONSTEXPR_CXX20 Y(const Y& y) : i_(y.i_) {}
+ TEST_CONSTEXPR_CXX20 void operator=(const X& x) {i_ = x.i_;}
};
#endif
-int main(int, char**)
+TEST_CONSTEXPR_CXX20 bool
+test()
{
test<input_iterator<const int*>, output_iterator<int*> >();
test<input_iterator<const int*>, forward_iterator<int*> >();
@@ -113,5 +115,14 @@ int main(int, char**)
std::adjacent_
diff erence(x, x+3, y);
#endif
- return 0;
+ return true;
+}
+
+int main(int, char**)
+{
+ test();
+#if TEST_STD_VER > 17
+ static_assert(test());
+#endif
+ return 0;
}
diff --git a/libcxx/test/std/numerics/numeric.ops/adjacent.
diff erence/adjacent_
diff erence_op.pass.cpp b/libcxx/test/std/numerics/numeric.ops/adjacent.
diff erence/adjacent_
diff erence_op.pass.cpp
index 9a10105d0490..383541e6c3b5 100644
--- a/libcxx/test/std/numerics/numeric.ops/adjacent.
diff erence/adjacent_
diff erence_op.pass.cpp
+++ b/libcxx/test/std/numerics/numeric.ops/adjacent.
diff erence/adjacent_
diff erence_op.pass.cpp
@@ -8,6 +8,7 @@
// <numeric>
+// Became constexpr in C++20
// template <InputIterator InIter,
// OutputIterator<auto, const InIter::value_type&> OutIter,
// Callable<auto, const InIter::value_type&, const InIter::value_type&> BinaryOperation>
@@ -26,7 +27,7 @@
#include "test_iterators.h"
template <class InIter, class OutIter>
-void
+TEST_CONSTEXPR_CXX20 void
test()
{
int ia[] = {15, 10, 6, 3, 1};
@@ -48,18 +49,18 @@ class X
{
int i_;
- X& operator=(const X&);
+ TEST_CONSTEXPR_CXX20 X& operator=(const X&);
public:
- explicit X(int i) : i_(i) {}
- X(const X& x) : i_(x.i_) {}
- X& operator=(X&& x)
+ TEST_CONSTEXPR_CXX20 explicit X(int i) : i_(i) {}
+ TEST_CONSTEXPR_CXX20 X(const X& x) : i_(x.i_) {}
+ TEST_CONSTEXPR_CXX20 X& operator=(X&& x)
{
i_ = x.i_;
x.i_ = -1;
return *this;
}
- friend X operator-(const X& x, const X& y) {return X(x.i_ - y.i_);}
+ TEST_CONSTEXPR_CXX20 friend X operator-(const X& x, const X& y) {return X(x.i_ - y.i_);}
friend class Y;
};
@@ -68,17 +69,18 @@ class Y
{
int i_;
- Y& operator=(const Y&);
+ TEST_CONSTEXPR_CXX20 Y& operator=(const Y&);
public:
- explicit Y(int i) : i_(i) {}
- Y(const Y& y) : i_(y.i_) {}
- void operator=(const X& x) {i_ = x.i_;}
+ TEST_CONSTEXPR_CXX20 explicit Y(int i) : i_(i) {}
+ TEST_CONSTEXPR_CXX20 Y(const Y& y) : i_(y.i_) {}
+ TEST_CONSTEXPR_CXX20 void operator=(const X& x) {i_ = x.i_;}
};
#endif
-int main(int, char**)
+TEST_CONSTEXPR_CXX20 bool
+test()
{
test<input_iterator<const int*>, output_iterator<int*> >();
test<input_iterator<const int*>, forward_iterator<int*> >();
@@ -116,5 +118,14 @@ int main(int, char**)
std::adjacent_
diff erence(x, x+3, y, std::minus<X>());
#endif
- return 0;
+ return true;
+}
+
+int main(int, char**)
+{
+ test();
+#if TEST_STD_VER > 17
+ static_assert(test());
+#endif
+ return 0;
}
diff --git a/libcxx/test/std/numerics/numeric.ops/exclusive.scan/exclusive_scan.pass.cpp b/libcxx/test/std/numerics/numeric.ops/exclusive.scan/exclusive_scan.pass.cpp
index a4b7da0e1479..3f806679909c 100644
--- a/libcxx/test/std/numerics/numeric.ops/exclusive.scan/exclusive_scan.pass.cpp
+++ b/libcxx/test/std/numerics/numeric.ops/exclusive.scan/exclusive_scan.pass.cpp
@@ -9,6 +9,7 @@
// <numeric>
// UNSUPPORTED: c++03, c++11, c++14
+// Became constexpr in C++20
// template<class InputIterator, class OutputIterator, class T>
// OutputIterator exclusive_scan(InputIterator first, InputIterator last,
// OutputIterator result, T init);
@@ -16,6 +17,7 @@
#include <numeric>
#include <algorithm>
+#include <array>
#include <cassert>
#include <functional>
#include <iterator>
@@ -23,27 +25,42 @@
#include "test_macros.h"
#include "test_iterators.h"
+// FIXME Remove constexpr vector workaround introduced in D90569
+#if TEST_STD_VER > 17
+#include <span>
+#endif
template <class Iter1, class T, class Iter2>
-void
+TEST_CONSTEXPR_CXX20 void
test(Iter1 first, Iter1 last, T init, Iter2 rFirst, Iter2 rLast)
{
- std::vector<typename std::iterator_traits<Iter1>::value_type> v;
+ // C++17 doesn't test constexpr so can use a vector.
+ // C++20 can use vector in constexpr evaluation, but both libc++ and MSVC
+ // don't have the support yet. In these cases use a std::span for the test.
+ // FIXME Remove constexpr vector workaround introduced in D90569
+ size_t size = std::distance(first, last);
+#if TEST_STD_VER < 20 || \
+ (defined(__cpp_lib_constexpr_vector) && __cpp_lib_constexpr_vector >= 201907L)
+
+ std::vector<typename std::iterator_traits<Iter1>::value_type> v(size);
+#else
+ assert((size <= 5) && "Increment the size of the array");
+ typename std::iterator_traits<Iter1>::value_type b[5];
+ std::span<typename std::iterator_traits<Iter1>::value_type> v{b, size};
+#endif
// Not in place
- std::exclusive_scan(first, last, std::back_inserter(v), init);
+ std::exclusive_scan(first, last, v.begin(), init);
assert(std::equal(v.begin(), v.end(), rFirst, rLast));
// In place
- v.clear();
- v.assign(first, last);
+ std::copy(first, last, v.begin());
std::exclusive_scan(v.begin(), v.end(), v.begin(), init);
assert(std::equal(v.begin(), v.end(), rFirst, rLast));
}
-
template <class Iter>
-void
+TEST_CONSTEXPR_CXX20 void
test()
{
int ia[] = {1, 3, 5, 7, 9};
@@ -55,13 +72,14 @@ test()
test(Iter(ia), Iter(ia + i), 0, pRes, pRes + i);
}
-size_t triangle(size_t n) { return n*(n+1)/2; }
+constexpr size_t triangle(size_t n) { return n*(n+1)/2; }
// Basic sanity
-void basic_tests()
+TEST_CONSTEXPR_CXX20 void
+basic_tests()
{
{
- std::vector<size_t> v(10);
+ std::array<size_t, 10> v;
std::fill(v.begin(), v.end(), 3);
std::exclusive_scan(v.begin(), v.end(), v.begin(), size_t{50});
for (size_t i = 0; i < v.size(); ++i)
@@ -69,7 +87,7 @@ void basic_tests()
}
{
- std::vector<size_t> v(10);
+ std::array<size_t, 10> v;
std::iota(v.begin(), v.end(), 0);
std::exclusive_scan(v.begin(), v.end(), v.begin(), size_t{30});
for (size_t i = 0; i < v.size(); ++i)
@@ -77,7 +95,7 @@ void basic_tests()
}
{
- std::vector<size_t> v(10);
+ std::array<size_t, 10> v;
std::iota(v.begin(), v.end(), 1);
std::exclusive_scan(v.begin(), v.end(), v.begin(), size_t{40});
for (size_t i = 0; i < v.size(); ++i)
@@ -86,7 +104,8 @@ void basic_tests()
}
-int main(int, char**)
+TEST_CONSTEXPR_CXX20 bool
+test()
{
basic_tests();
@@ -98,5 +117,14 @@ int main(int, char**)
test<const int*>();
test< int*>();
- return 0;
+ return true;
+}
+
+int main(int, char**)
+{
+ test();
+#if TEST_STD_VER > 17
+ static_assert(test());
+#endif
+ return 0;
}
diff --git a/libcxx/test/std/numerics/numeric.ops/exclusive.scan/exclusive_scan_init_op.pass.cpp b/libcxx/test/std/numerics/numeric.ops/exclusive.scan/exclusive_scan_init_op.pass.cpp
index 471fa856be9c..d9e23f167788 100644
--- a/libcxx/test/std/numerics/numeric.ops/exclusive.scan/exclusive_scan_init_op.pass.cpp
+++ b/libcxx/test/std/numerics/numeric.ops/exclusive.scan/exclusive_scan_init_op.pass.cpp
@@ -9,6 +9,7 @@
// <numeric>
// UNSUPPORTED: c++03, c++11, c++14
+// Became constexpr in C++20
// template<class InputIterator, class OutputIterator, class T, class BinaryOperation>
// OutputIterator
// exclusive_scan(InputIterator first, InputIterator last,
@@ -17,6 +18,7 @@
#include <numeric>
#include <algorithm>
+#include <array>
#include <cassert>
#include <functional>
#include <iterator>
@@ -24,27 +26,43 @@
#include "test_macros.h"
#include "test_iterators.h"
+// FIXME Remove constexpr vector workaround introduced in D90569
+#if TEST_STD_VER > 17
+#include <span>
+#endif
template <class Iter1, class T, class Op, class Iter2>
-void
+TEST_CONSTEXPR_CXX20 void
test(Iter1 first, Iter1 last, T init, Op op, Iter2 rFirst, Iter2 rLast)
{
- std::vector<typename std::iterator_traits<Iter1>::value_type> v;
+ // C++17 doesn't test constexpr so can use a vector.
+ // C++20 can use vector in constexpr evaluation, but both libc++ and MSVC
+ // don't have the support yet. In these cases use a std::span for the test.
+ // FIXME Remove constexpr vector workaround introduced in D90569
+ size_t size = std::distance(first, last);
+#if TEST_STD_VER < 20 || \
+ (defined(__cpp_lib_constexpr_vector) && __cpp_lib_constexpr_vector >= 201907L)
+
+ std::vector<typename std::iterator_traits<Iter1>::value_type> v(size);
+#else
+ assert((size <= 5) && "Increment the size of the array");
+ typename std::iterator_traits<Iter1>::value_type b[5];
+ std::span<typename std::iterator_traits<Iter1>::value_type> v{b, size};
+#endif
// Not in place
- std::exclusive_scan(first, last, std::back_inserter(v), init, op);
+ std::exclusive_scan(first, last, v.begin(), init, op);
assert(std::equal(v.begin(), v.end(), rFirst, rLast));
// In place
- v.clear();
- v.assign(first, last);
+ std::copy(first, last, v.begin());
std::exclusive_scan(v.begin(), v.end(), v.begin(), init, op);
assert(std::equal(v.begin(), v.end(), rFirst, rLast));
}
template <class Iter>
-void
+TEST_CONSTEXPR_CXX20 void
test()
{
int ia[] = {1, 3, 5, 7, 9};
@@ -60,7 +78,8 @@ test()
}
}
-int main(int, char**)
+TEST_CONSTEXPR_CXX20 bool
+test()
{
// All the iterator categories
test<input_iterator <const int*> >();
@@ -72,10 +91,20 @@ int main(int, char**)
// Make sure that the calculations are done using the init typedef
{
- std::vector<unsigned char> v(10);
+ std::array<unsigned char, 10> v;
std::iota(v.begin(), v.end(), static_cast<unsigned char>(1));
+ // C++17 doesn't test constexpr so can use a vector.
+ // C++20 can use vector in constexpr evaluation, but both libc++ and MSVC
+ // don't have the support yet. In these cases use a std::span for the test.
+ // FIXME Remove constexpr vector workaround introduced in D90569
+#if TEST_STD_VER < 20 || \
+ (defined(__cpp_lib_constexpr_vector) && __cpp_lib_constexpr_vector >= 201907L)
std::vector<size_t> res;
std::exclusive_scan(v.begin(), v.end(), std::back_inserter(res), 1, std::multiplies<>());
+#else
+ std::array<size_t, 10> res;
+ std::exclusive_scan(v.begin(), v.end(), res.begin(), 1, std::multiplies<>());
+#endif
assert(res.size() == 10);
size_t j = 1;
@@ -87,5 +116,14 @@ int main(int, char**)
}
}
- return 0;
+ return true;
+}
+
+int main(int, char**)
+{
+ test();
+#if TEST_STD_VER > 17
+ static_assert(test());
+#endif
+ return 0;
}
diff --git a/libcxx/test/std/numerics/numeric.ops/inclusive.scan/inclusive_scan.pass.cpp b/libcxx/test/std/numerics/numeric.ops/inclusive.scan/inclusive_scan.pass.cpp
index ca262254c16c..3ba342c5022c 100644
--- a/libcxx/test/std/numerics/numeric.ops/inclusive.scan/inclusive_scan.pass.cpp
+++ b/libcxx/test/std/numerics/numeric.ops/inclusive.scan/inclusive_scan.pass.cpp
@@ -9,6 +9,7 @@
// <numeric>
// UNSUPPORTED: c++03, c++11, c++14
+// Became constexpr in C++20
// template<class InputIterator, class OutputIterator, class T>
// OutputIterator inclusive_scan(InputIterator first, InputIterator last,
// OutputIterator result, T init);
@@ -16,6 +17,7 @@
#include <numeric>
#include <algorithm>
+#include <array>
#include <cassert>
#include <functional>
#include <iterator>
@@ -23,27 +25,43 @@
#include "test_macros.h"
#include "test_iterators.h"
+// FIXME Remove constexpr vector workaround introduced in D90569
+#if TEST_STD_VER > 17
+#include <span>
+#endif
template <class Iter1, class Iter2>
-void
+TEST_CONSTEXPR_CXX20 void
test(Iter1 first, Iter1 last, Iter2 rFirst, Iter2 rLast)
{
- std::vector<typename std::iterator_traits<Iter1>::value_type> v;
+ // C++17 doesn't test constexpr so can use a vector.
+ // C++20 can use vector in constexpr evaluation, but both libc++ and MSVC
+ // don't have the support yet. In these cases use a std::span for the test.
+ // FIXME Remove constexpr vector workaround introduced in D90569
+ size_t size = std::distance(first, last);
+#if TEST_STD_VER < 20 || \
+ (defined(__cpp_lib_constexpr_vector) && __cpp_lib_constexpr_vector >= 201907L)
+
+ std::vector<typename std::iterator_traits<Iter1>::value_type> v(size);
+#else
+ assert((size <= 5) && "Increment the size of the array");
+ typename std::iterator_traits<Iter1>::value_type b[5];
+ std::span<typename std::iterator_traits<Iter1>::value_type> v{b, size};
+#endif
// Not in place
- std::inclusive_scan(first, last, std::back_inserter(v));
+ std::inclusive_scan(first, last, v.begin());
assert(std::equal(v.begin(), v.end(), rFirst, rLast));
// In place
- v.clear();
- v.assign(first, last);
+ std::copy(first, last, v.begin());
std::inclusive_scan(v.begin(), v.end(), v.begin());
assert(std::equal(v.begin(), v.end(), rFirst, rLast));
}
template <class Iter>
-void
+TEST_CONSTEXPR_CXX20 void
test()
{
int ia[] = {1, 3, 5, 7, 9};
@@ -55,13 +73,14 @@ test()
test(Iter(ia), Iter(ia + i), pRes, pRes + i);
}
-size_t triangle(size_t n) { return n*(n+1)/2; }
+constexpr size_t triangle(size_t n) { return n*(n+1)/2; }
// Basic sanity
-void basic_tests()
+TEST_CONSTEXPR_CXX20 void
+basic_tests()
{
{
- std::vector<size_t> v(10);
+ std::array<size_t, 10> v;
std::fill(v.begin(), v.end(), 3);
std::inclusive_scan(v.begin(), v.end(), v.begin());
for (size_t i = 0; i < v.size(); ++i)
@@ -69,7 +88,7 @@ void basic_tests()
}
{
- std::vector<size_t> v(10);
+ std::array<size_t, 10> v;
std::iota(v.begin(), v.end(), 0);
std::inclusive_scan(v.begin(), v.end(), v.begin());
for (size_t i = 0; i < v.size(); ++i)
@@ -77,7 +96,7 @@ void basic_tests()
}
{
- std::vector<size_t> v(10);
+ std::array<size_t, 10> v;
std::iota(v.begin(), v.end(), 1);
std::inclusive_scan(v.begin(), v.end(), v.begin());
for (size_t i = 0; i < v.size(); ++i)
@@ -85,13 +104,24 @@ void basic_tests()
}
{
+ // C++17 doesn't test constexpr so can use a vector.
+ // C++20 can use vector in constexpr evaluation, but both libc++ and MSVC
+ // don't have the support yet. In these cases use a std::span for the test.
+ // FIXME Remove constexpr vector workaround introduced in D90569
+#if TEST_STD_VER < 20 || \
+ (defined(__cpp_lib_constexpr_vector) && __cpp_lib_constexpr_vector >= 201907L)
std::vector<size_t> v, res;
std::inclusive_scan(v.begin(), v.end(), std::back_inserter(res));
+#else
+ std::array<size_t, 0> v, res;
+ std::inclusive_scan(v.begin(), v.end(), res.begin());
+#endif
assert(res.empty());
}
}
-int main(int, char**)
+TEST_CONSTEXPR_CXX20 bool
+test()
{
basic_tests();
@@ -103,5 +133,14 @@ int main(int, char**)
test<const int*>();
test< int*>();
- return 0;
+ return true;
+}
+
+int main(int, char**)
+{
+ test();
+#if TEST_STD_VER > 17
+ static_assert(test());
+#endif
+ return 0;
}
diff --git a/libcxx/test/std/numerics/numeric.ops/inclusive.scan/inclusive_scan_op.pass.cpp b/libcxx/test/std/numerics/numeric.ops/inclusive.scan/inclusive_scan_op.pass.cpp
index 322b502369f3..dca29c99e8fb 100644
--- a/libcxx/test/std/numerics/numeric.ops/inclusive.scan/inclusive_scan_op.pass.cpp
+++ b/libcxx/test/std/numerics/numeric.ops/inclusive.scan/inclusive_scan_op.pass.cpp
@@ -9,6 +9,7 @@
// <numeric>
// UNSUPPORTED: c++03, c++11, c++14
+// Became constexpr in C++20
// template<class InputIterator, class OutputIterator, class T, class BinaryOperation>
// OutputIterator
// inclusive_scan(InputIterator first, InputIterator last,
@@ -17,6 +18,7 @@
#include <numeric>
#include <algorithm>
+#include <array>
#include <cassert>
#include <functional>
#include <iterator>
@@ -24,27 +26,43 @@
#include "test_macros.h"
#include "test_iterators.h"
+// FIXME Remove constexpr vector workaround introduced in D90569
+#if TEST_STD_VER > 17
+#include <span>
+#endif
-template <class Iter1, class T, class Op, class Iter2>
-void
+template <class Iter1, class Op, class Iter2>
+TEST_CONSTEXPR_CXX20 void
test(Iter1 first, Iter1 last, Op op, Iter2 rFirst, Iter2 rLast)
{
- std::vector<typename std::iterator_traits<Iter1>::value_type> v;
+ // C++17 doesn't test constexpr so can use a vector.
+ // C++20 can use vector in constexpr evaluation, but both libc++ and MSVC
+ // don't have the support yet. In these cases use a std::span for the test.
+ // FIXME Remove constexpr vector workaround introduced in D90569
+ size_t size = std::distance(first, last);
+#if TEST_STD_VER < 20 || \
+ (defined(__cpp_lib_constexpr_vector) && __cpp_lib_constexpr_vector >= 201907L)
+
+ std::vector<typename std::iterator_traits<Iter1>::value_type> v(size);
+#else
+ assert((size <= 5) && "Increment the size of the array");
+ typename std::iterator_traits<Iter1>::value_type b[5];
+ std::span<typename std::iterator_traits<Iter1>::value_type> v{b, size};
+#endif
// Not in place
- std::inclusive_scan(first, last, std::back_inserter(v), op);
+ std::inclusive_scan(first, last, v.begin(), op);
assert(std::equal(v.begin(), v.end(), rFirst, rLast));
// In place
- v.clear();
- v.assign(first, last);
+ std::copy(first, last, v.begin());
std::inclusive_scan(v.begin(), v.end(), v.begin(), op);
assert(std::equal(v.begin(), v.end(), rFirst, rLast));
}
template <class Iter>
-void
+TEST_CONSTEXPR_CXX20 void
test()
{
int ia[] = {1, 3, 5, 7, 9};
@@ -60,13 +78,14 @@ test()
}
}
-size_t triangle(size_t n) { return n*(n+1)/2; }
+constexpr size_t triangle(size_t n) { return n*(n+1)/2; }
// Basic sanity
-void basic_tests()
+TEST_CONSTEXPR_CXX20 void
+basic_tests()
{
{
- std::vector<size_t> v(10);
+ std::array<size_t, 10> v;
std::fill(v.begin(), v.end(), 3);
std::inclusive_scan(v.begin(), v.end(), v.begin(), std::plus<>());
for (size_t i = 0; i < v.size(); ++i)
@@ -74,7 +93,7 @@ void basic_tests()
}
{
- std::vector<size_t> v(10);
+ std::array<size_t, 10> v;
std::iota(v.begin(), v.end(), 0);
std::inclusive_scan(v.begin(), v.end(), v.begin(), std::plus<>());
for (size_t i = 0; i < v.size(); ++i)
@@ -82,7 +101,7 @@ void basic_tests()
}
{
- std::vector<size_t> v(10);
+ std::array<size_t, 10> v;
std::iota(v.begin(), v.end(), 1);
std::inclusive_scan(v.begin(), v.end(), v.begin(), std::plus<>());
for (size_t i = 0; i < v.size(); ++i)
@@ -90,26 +109,43 @@ void basic_tests()
}
{
+ // C++17 doesn't test constexpr so can use a vector.
+ // C++20 can use vector in constexpr evaluation, but both libc++ and MSVC
+ // don't have the support yet. In these cases use a std::span for the test.
+ // FIXME Remove constexpr vector workaround introduced in D90569
+#if TEST_STD_VER < 20 || \
+ (defined(__cpp_lib_constexpr_vector) && __cpp_lib_constexpr_vector >= 201907L)
std::vector<size_t> v, res;
std::inclusive_scan(v.begin(), v.end(), std::back_inserter(res), std::plus<>());
+#else
+ std::array<size_t, 0> v, res;
+ std::inclusive_scan(v.begin(), v.end(), res.begin(), std::plus<>());
+#endif
assert(res.empty());
}
}
-
-int main(int, char**)
+TEST_CONSTEXPR_CXX20 bool
+test()
{
-
basic_tests();
// All the iterator categories
-// test<input_iterator <const int*> >();
-// test<forward_iterator <const int*> >();
-// test<bidirectional_iterator<const int*> >();
-// test<random_access_iterator<const int*> >();
-// test<const int*>();
-// test< int*>();
-
+ test<input_iterator <const int*> >();
+ test<forward_iterator <const int*> >();
+ test<bidirectional_iterator<const int*> >();
+ test<random_access_iterator<const int*> >();
+ test<const int*>();
+ test< int*>();
+
+ return true;
+}
- return 0;
+int main(int, char**)
+{
+ test();
+#if TEST_STD_VER > 17
+ static_assert(test());
+#endif
+ return 0;
}
diff --git a/libcxx/test/std/numerics/numeric.ops/inclusive.scan/inclusive_scan_op_init.pass.cpp b/libcxx/test/std/numerics/numeric.ops/inclusive.scan/inclusive_scan_op_init.pass.cpp
index d941a8439d25..a837b36f34fd 100644
--- a/libcxx/test/std/numerics/numeric.ops/inclusive.scan/inclusive_scan_op_init.pass.cpp
+++ b/libcxx/test/std/numerics/numeric.ops/inclusive.scan/inclusive_scan_op_init.pass.cpp
@@ -9,6 +9,7 @@
// <numeric>
// UNSUPPORTED: c++03, c++11, c++14
+// Became constexpr in C++20
// template<class InputIterator, class OutputIterator, class T, class BinaryOperation>
// OutputIterator
// inclusive_scan(InputIterator first, InputIterator last,
@@ -17,6 +18,7 @@
#include <numeric>
#include <algorithm>
+#include <array>
#include <cassert>
#include <functional>
#include <iterator>
@@ -24,27 +26,43 @@
#include "test_macros.h"
#include "test_iterators.h"
+// FIXME Remove constexpr vector workaround introduced in D90569
+#if TEST_STD_VER > 17
+#include <span>
+#endif
template <class Iter1, class T, class Op, class Iter2>
-void
+TEST_CONSTEXPR_CXX20 void
test(Iter1 first, Iter1 last, Op op, T init, Iter2 rFirst, Iter2 rLast)
{
- std::vector<typename std::iterator_traits<Iter1>::value_type> v;
+ // C++17 doesn't test constexpr so can use a vector.
+ // C++20 can use vector in constexpr evaluation, but both libc++ and MSVC
+ // don't have the support yet. In these cases use a std::span for the test.
+ // FIXME Remove constexpr vector workaround introduced in D90569
+ size_t size = std::distance(first, last);
+#if TEST_STD_VER < 20 || \
+ (defined(__cpp_lib_constexpr_vector) && __cpp_lib_constexpr_vector >= 201907L)
+
+ std::vector<typename std::iterator_traits<Iter1>::value_type> v(size);
+#else
+ assert((size <= 5) && "Increment the size of the array");
+ typename std::iterator_traits<Iter1>::value_type b[5];
+ std::span<typename std::iterator_traits<Iter1>::value_type> v{b, size};
+#endif
// Not in place
- std::inclusive_scan(first, last, std::back_inserter(v), op, init);
+ std::inclusive_scan(first, last, v.begin(), op, init);
assert(std::equal(v.begin(), v.end(), rFirst, rLast));
// In place
- v.clear();
- v.assign(first, last);
+ std::copy(first, last, v.begin());
std::inclusive_scan(v.begin(), v.end(), v.begin(), op, init);
assert(std::equal(v.begin(), v.end(), rFirst, rLast));
}
template <class Iter>
-void
+TEST_CONSTEXPR_CXX20 void
test()
{
int ia[] = {1, 3, 5, 7, 9};
@@ -60,13 +78,14 @@ test()
}
}
-size_t triangle(size_t n) { return n*(n+1)/2; }
+constexpr size_t triangle(size_t n) { return n*(n+1)/2; }
// Basic sanity
-void basic_tests()
+TEST_CONSTEXPR_CXX20 void
+basic_tests()
{
{
- std::vector<size_t> v(10);
+ std::array<size_t, 10> v;
std::fill(v.begin(), v.end(), 3);
std::inclusive_scan(v.begin(), v.end(), v.begin(), std::plus<>(), size_t{50});
for (size_t i = 0; i < v.size(); ++i)
@@ -74,7 +93,7 @@ void basic_tests()
}
{
- std::vector<size_t> v(10);
+ std::array<size_t, 10> v;
std::iota(v.begin(), v.end(), 0);
std::inclusive_scan(v.begin(), v.end(), v.begin(), std::plus<>(), size_t{40});
for (size_t i = 0; i < v.size(); ++i)
@@ -82,7 +101,7 @@ void basic_tests()
}
{
- std::vector<size_t> v(10);
+ std::array<size_t, 10> v;
std::iota(v.begin(), v.end(), 1);
std::inclusive_scan(v.begin(), v.end(), v.begin(), std::plus<>(), size_t{30});
for (size_t i = 0; i < v.size(); ++i)
@@ -90,17 +109,37 @@ void basic_tests()
}
{
+ // C++17 doesn't test constexpr so can use a vector.
+ // C++20 can use vector in constexpr evaluation, but both libc++ and MSVC
+ // don't have the support yet. In these cases use a std::span for the test.
+ // FIXME Remove constexpr vector workaround introduced in D90569
+#if TEST_STD_VER < 20 || \
+ (defined(__cpp_lib_constexpr_vector) && __cpp_lib_constexpr_vector >= 201907L)
std::vector<size_t> v, res;
std::inclusive_scan(v.begin(), v.end(), std::back_inserter(res), std::plus<>(), size_t{40});
+#else
+ std::array<size_t, 0> v, res;
+ std::inclusive_scan(v.begin(), v.end(), res.begin(), std::plus<>(), size_t{40});
+#endif
assert(res.empty());
}
// Make sure that the calculations are done using the init typedef
{
- std::vector<unsigned char> v(10);
+ std::array<unsigned char, 10> v;
std::iota(v.begin(), v.end(), static_cast<unsigned char>(1));
+ // C++17 doesn't test constexpr so can use a vector.
+ // C++20 can use vector in constexpr evaluation, but both libc++ and MSVC
+ // don't have the support yet. In these cases use a std::span for the test.
+ // FIXME Remove constexpr vector workaround introduced in D90569
+#if TEST_STD_VER < 20 || \
+ (defined(__cpp_lib_constexpr_vector) && __cpp_lib_constexpr_vector >= 201907L)
std::vector<size_t> res;
std::inclusive_scan(v.begin(), v.end(), std::back_inserter(res), std::multiplies<>(), size_t{1});
+#else
+ std::array<size_t, 10> res;
+ std::inclusive_scan(v.begin(), v.end(), res.begin(), std::multiplies<>(), size_t{1});
+#endif
assert(res.size() == 10);
size_t j = 1;
@@ -113,10 +152,9 @@ void basic_tests()
}
}
-
-int main(int, char**)
+TEST_CONSTEXPR_CXX20 bool
+test()
{
-
basic_tests();
// All the iterator categories
@@ -127,6 +165,14 @@ int main(int, char**)
test<const int*>();
test< int*>();
+ return true;
+}
- return 0;
+int main(int, char**)
+{
+ test();
+#if TEST_STD_VER > 17
+ static_assert(test());
+#endif
+ return 0;
}
diff --git a/libcxx/test/std/numerics/numeric.ops/inner.product/inner_product.pass.cpp b/libcxx/test/std/numerics/numeric.ops/inner.product/inner_product.pass.cpp
index 5e87325937a0..66ce97adf02c 100644
--- a/libcxx/test/std/numerics/numeric.ops/inner.product/inner_product.pass.cpp
+++ b/libcxx/test/std/numerics/numeric.ops/inner.product/inner_product.pass.cpp
@@ -8,6 +8,7 @@
// <numeric>
+// Became constexpr in C++20
// template <InputIterator Iter1, InputIterator Iter2, MoveConstructible T>
// requires HasMultiply<Iter1::reference, Iter2::reference>
// && HasPlus<T, HasMultiply<Iter1::reference, Iter2::reference>::result_type>
@@ -25,14 +26,14 @@
#include "test_iterators.h"
template <class Iter1, class Iter2, class T>
-void
+TEST_CONSTEXPR_CXX20 void
test(Iter1 first1, Iter1 last1, Iter2 first2, T init, T x)
{
assert(std::inner_product(first1, last1, first2, init) == x);
}
template <class Iter1, class Iter2>
-void
+TEST_CONSTEXPR_CXX20 void
test()
{
int a[] = {1, 2, 3, 4, 5, 6};
@@ -48,7 +49,8 @@ test()
test(Iter1(a), Iter1(a+sa), Iter2(b), 10, 66);
}
-int main(int, char**)
+TEST_CONSTEXPR_CXX20 bool
+test()
{
test<input_iterator<const int*>, input_iterator<const int*> >();
test<input_iterator<const int*>, forward_iterator<const int*> >();
@@ -80,5 +82,14 @@ int main(int, char**)
test<const int*, random_access_iterator<const int*> >();
test<const int*, const int*>();
- return 0;
+ return true;
+}
+
+int main(int, char**)
+{
+ test();
+#if TEST_STD_VER > 17
+ static_assert(test());
+#endif
+ return 0;
}
diff --git a/libcxx/test/std/numerics/numeric.ops/inner.product/inner_product_comp.pass.cpp b/libcxx/test/std/numerics/numeric.ops/inner.product/inner_product_comp.pass.cpp
index 3f9ed7ee8951..f57f4f726c5e 100644
--- a/libcxx/test/std/numerics/numeric.ops/inner.product/inner_product_comp.pass.cpp
+++ b/libcxx/test/std/numerics/numeric.ops/inner.product/inner_product_comp.pass.cpp
@@ -8,6 +8,7 @@
// <numeric>
+// Became constexpr in C++20
// template <InputIterator Iter1, InputIterator Iter2, MoveConstructible T,
// class BinaryOperation1,
// Callable<auto, Iter1::reference, Iter2::reference> BinaryOperation2>
@@ -27,7 +28,7 @@
#include "test_iterators.h"
template <class Iter1, class Iter2, class T>
-void
+TEST_CONSTEXPR_CXX20 void
test(Iter1 first1, Iter1 last1, Iter2 first2, T init, T x)
{
assert(std::inner_product(first1, last1, first2, init,
@@ -35,7 +36,7 @@ test(Iter1 first1, Iter1 last1, Iter2 first2, T init, T x)
}
template <class Iter1, class Iter2>
-void
+TEST_CONSTEXPR_CXX20 void
test()
{
int a[] = {1, 2, 3, 4, 5, 6};
@@ -51,7 +52,8 @@ test()
test(Iter1(a), Iter1(a+sa), Iter2(b), 10, 1176490);
}
-int main(int, char**)
+TEST_CONSTEXPR_CXX20 bool
+test()
{
test<input_iterator<const int*>, input_iterator<const int*> >();
test<input_iterator<const int*>, forward_iterator<const int*> >();
@@ -83,5 +85,14 @@ int main(int, char**)
test<const int*, random_access_iterator<const int*> >();
test<const int*, const int*>();
- return 0;
+ return true;
+}
+
+int main(int, char**)
+{
+ test();
+#if TEST_STD_VER > 17
+ static_assert(test());
+#endif
+ return 0;
}
diff --git a/libcxx/test/std/numerics/numeric.ops/numeric.iota/iota.pass.cpp b/libcxx/test/std/numerics/numeric.ops/numeric.iota/iota.pass.cpp
index 2cf99f8d44e3..8cb49b123faf 100644
--- a/libcxx/test/std/numerics/numeric.ops/numeric.iota/iota.pass.cpp
+++ b/libcxx/test/std/numerics/numeric.ops/numeric.iota/iota.pass.cpp
@@ -8,6 +8,7 @@
// <numeric>
+// Became constexpr in C++20
// template <class ForwardIterator, class T>
// void iota(ForwardIterator first, ForwardIterator last, T value);
@@ -18,7 +19,7 @@
#include "test_iterators.h"
template <class InIter>
-void
+TEST_CONSTEXPR_CXX20 void
test()
{
int ia[] = {1, 2, 3, 4, 5};
@@ -29,12 +30,22 @@ test()
assert(ia[i] == ir[i]);
}
-int main(int, char**)
+TEST_CONSTEXPR_CXX20 bool
+test()
{
test<forward_iterator<int*> >();
test<bidirectional_iterator<int*> >();
test<random_access_iterator<int*> >();
test<int*>();
- return 0;
+ return true;
+}
+
+int main(int, char**)
+{
+ test();
+#if TEST_STD_VER > 17
+ static_assert(test());
+#endif
+ return 0;
}
diff --git a/libcxx/test/std/numerics/numeric.ops/partial.sum/partial_sum.pass.cpp b/libcxx/test/std/numerics/numeric.ops/partial.sum/partial_sum.pass.cpp
index 51ef81340d10..78b45f29a98a 100644
--- a/libcxx/test/std/numerics/numeric.ops/partial.sum/partial_sum.pass.cpp
+++ b/libcxx/test/std/numerics/numeric.ops/partial.sum/partial_sum.pass.cpp
@@ -8,6 +8,7 @@
// <numeric>
+// Became constexpr in C++20
// template <InputIterator InIter, OutputIterator<auto, const InIter::value_type&> OutIter>
// requires HasPlus<InIter::value_type, InIter::reference>
// && HasAssign<InIter::value_type,
@@ -23,7 +24,7 @@
#include "test_iterators.h"
template <class InIter, class OutIter>
-void
+TEST_CONSTEXPR_CXX20 void
test()
{
int ia[] = {1, 2, 3, 4, 5};
@@ -36,7 +37,8 @@ test()
assert(ib[i] == ir[i]);
}
-int main(int, char**)
+TEST_CONSTEXPR_CXX20 bool
+test()
{
test<input_iterator<const int*>, output_iterator<int*> >();
test<input_iterator<const int*>, forward_iterator<int*> >();
@@ -68,5 +70,14 @@ int main(int, char**)
test<const int*, random_access_iterator<int*> >();
test<const int*, int*>();
- return 0;
+ return true;
+}
+
+int main(int, char**)
+{
+ test();
+#if TEST_STD_VER > 17
+ static_assert(test());
+#endif
+ return 0;
}
diff --git a/libcxx/test/std/numerics/numeric.ops/partial.sum/partial_sum_op.pass.cpp b/libcxx/test/std/numerics/numeric.ops/partial.sum/partial_sum_op.pass.cpp
index 9bc79fdcae74..7aa6eb67fe1d 100644
--- a/libcxx/test/std/numerics/numeric.ops/partial.sum/partial_sum_op.pass.cpp
+++ b/libcxx/test/std/numerics/numeric.ops/partial.sum/partial_sum_op.pass.cpp
@@ -8,6 +8,7 @@
// <numeric>
+// Became constexpr in C++20
// template<InputIterator InIter,
// OutputIterator<auto, const InIter::value_type&> OutIter,
// Callable<auto, const InIter::value_type&, InIter::reference> BinaryOperation>
@@ -25,7 +26,7 @@
#include "test_iterators.h"
template <class InIter, class OutIter>
-void
+TEST_CONSTEXPR_CXX20 void
test()
{
int ia[] = {1, 2, 3, 4, 5};
@@ -38,7 +39,8 @@ test()
assert(ib[i] == ir[i]);
}
-int main(int, char**)
+TEST_CONSTEXPR_CXX20 bool
+test()
{
test<input_iterator<const int*>, output_iterator<int*> >();
test<input_iterator<const int*>, forward_iterator<int*> >();
@@ -70,5 +72,14 @@ int main(int, char**)
test<const int*, random_access_iterator<int*> >();
test<const int*, int*>();
- return 0;
+ return true;
+}
+
+int main(int, char**)
+{
+ test();
+#if TEST_STD_VER > 17
+ static_assert(test());
+#endif
+ return 0;
}
diff --git a/libcxx/test/std/numerics/numeric.ops/reduce/reduce.pass.cpp b/libcxx/test/std/numerics/numeric.ops/reduce/reduce.pass.cpp
index adcdcaac26ca..6f4b291ab207 100644
--- a/libcxx/test/std/numerics/numeric.ops/reduce/reduce.pass.cpp
+++ b/libcxx/test/std/numerics/numeric.ops/reduce/reduce.pass.cpp
@@ -9,6 +9,7 @@
// <numeric>
// UNSUPPORTED: c++03, c++11, c++14
+// Became constexpr in C++20
// template<class InputIterator>
// typename iterator_traits<InputIterator>::value_type
// reduce(InputIterator first, InputIterator last);
@@ -20,7 +21,7 @@
#include "test_iterators.h"
template <class Iter, class T>
-void
+TEST_CONSTEXPR_CXX20 void
test(Iter first, Iter last, T x)
{
static_assert( std::is_same_v<typename std::iterator_traits<decltype(first)>::value_type,
@@ -29,7 +30,7 @@ test(Iter first, Iter last, T x)
}
template <class Iter>
-void
+TEST_CONSTEXPR_CXX20 void
test()
{
int ia[] = {1, 2, 3, 4, 5, 6};
@@ -41,13 +42,15 @@ test()
}
template <typename T>
-void test_return_type()
+TEST_CONSTEXPR_CXX20 void
+test_return_type()
{
T *p = nullptr;
static_assert( std::is_same_v<T, decltype(std::reduce(p, p))> );
}
-int main(int, char**)
+TEST_CONSTEXPR_CXX20 bool
+test()
{
test_return_type<char>();
test_return_type<int>();
@@ -61,5 +64,14 @@ int main(int, char**)
test<random_access_iterator<const int*> >();
test<const int*>();
- return 0;
+ return true;
+}
+
+int main(int, char**)
+{
+ test();
+#if TEST_STD_VER > 17
+ static_assert(test());
+#endif
+ return 0;
}
diff --git a/libcxx/test/std/numerics/numeric.ops/reduce/reduce_init.pass.cpp b/libcxx/test/std/numerics/numeric.ops/reduce/reduce_init.pass.cpp
index 6c9492330d3f..4fe4a4303a36 100644
--- a/libcxx/test/std/numerics/numeric.ops/reduce/reduce_init.pass.cpp
+++ b/libcxx/test/std/numerics/numeric.ops/reduce/reduce_init.pass.cpp
@@ -9,6 +9,7 @@
// <numeric>
// UNSUPPORTED: c++03, c++11, c++14
+// Became constexpr in C++20
// template<class InputIterator, class T>
// T reduce(InputIterator first, InputIterator last, T init);
@@ -19,7 +20,7 @@
#include "test_iterators.h"
template <class Iter, class T>
-void
+TEST_CONSTEXPR_CXX20 void
test(Iter first, Iter last, T init, T x)
{
static_assert( std::is_same_v<T, decltype(std::reduce(first, last, init))> );
@@ -27,7 +28,7 @@ test(Iter first, Iter last, T init, T x)
}
template <class Iter>
-void
+TEST_CONSTEXPR_CXX20 void
test()
{
int ia[] = {1, 2, 3, 4, 5, 6};
@@ -43,13 +44,15 @@ test()
}
template <typename T, typename Init>
-void test_return_type()
+TEST_CONSTEXPR_CXX20 void
+test_return_type()
{
T *p = nullptr;
static_assert( std::is_same_v<Init, decltype(std::reduce(p, p, Init{}))> );
}
-int main(int, char**)
+TEST_CONSTEXPR_CXX20 bool
+test()
{
test_return_type<char, int>();
test_return_type<int, int>();
@@ -65,5 +68,14 @@ int main(int, char**)
test<random_access_iterator<const int*> >();
test<const int*>();
- return 0;
+ return true;
+}
+
+int main(int, char**)
+{
+ test();
+#if TEST_STD_VER > 17
+ static_assert(test());
+#endif
+ return 0;
}
diff --git a/libcxx/test/std/numerics/numeric.ops/reduce/reduce_init_op.pass.cpp b/libcxx/test/std/numerics/numeric.ops/reduce/reduce_init_op.pass.cpp
index 044b70d4f9a1..7ad456687c5e 100644
--- a/libcxx/test/std/numerics/numeric.ops/reduce/reduce_init_op.pass.cpp
+++ b/libcxx/test/std/numerics/numeric.ops/reduce/reduce_init_op.pass.cpp
@@ -9,6 +9,7 @@
// <numeric>
// UNSUPPORTED: c++03, c++11, c++14
+// Became constexpr in C++20
// template<class InputIterator, class T, class BinaryOperation>
// T reduce(InputIterator first, InputIterator last, T init, BinaryOperation op);
@@ -19,7 +20,7 @@
#include "test_iterators.h"
template <class Iter, class T, class Op>
-void
+TEST_CONSTEXPR_CXX20 void
test(Iter first, Iter last, T init, Op op, T x)
{
static_assert( std::is_same_v<T, decltype(std::reduce(first, last, init, op))>, "" );
@@ -27,7 +28,7 @@ test(Iter first, Iter last, T init, Op op, T x)
}
template <class Iter>
-void
+TEST_CONSTEXPR_CXX20 void
test()
{
int ia[] = {1, 2, 3, 4, 5, 6};
@@ -43,13 +44,15 @@ test()
}
template <typename T, typename Init>
-void test_return_type()
+TEST_CONSTEXPR_CXX20 void
+test_return_type()
{
T *p = nullptr;
static_assert( std::is_same_v<Init, decltype(std::reduce(p, p, Init{}, std::plus<>()))>, "" );
}
-int main(int, char**)
+TEST_CONSTEXPR_CXX20 bool
+test()
{
test_return_type<char, int>();
test_return_type<int, int>();
@@ -72,5 +75,14 @@ int main(int, char**)
assert(res == 40320); // 8! will not fit into a char
}
- return 0;
+ return true;
+}
+
+int main(int, char**)
+{
+ test();
+#if TEST_STD_VER > 17
+ static_assert(test());
+#endif
+ return 0;
}
diff --git a/libcxx/test/std/numerics/numeric.ops/transform.exclusive.scan/transform_exclusive_scan_init_bop_uop.pass.cpp b/libcxx/test/std/numerics/numeric.ops/transform.exclusive.scan/transform_exclusive_scan_init_bop_uop.pass.cpp
index 301fb2f24242..881e9d3e5959 100644
--- a/libcxx/test/std/numerics/numeric.ops/transform.exclusive.scan/transform_exclusive_scan_init_bop_uop.pass.cpp
+++ b/libcxx/test/std/numerics/numeric.ops/transform.exclusive.scan/transform_exclusive_scan_init_bop_uop.pass.cpp
@@ -9,6 +9,7 @@
// <numeric>
// UNSUPPORTED: c++03, c++11, c++14
+// Became constexpr in C++20
// template<class InputIterator, class OutputIterator, class T,
// class BinaryOperation, class UnaryOperation>
// OutputIterator transform_exclusive_scan(InputIterator first, InputIterator last,
@@ -19,6 +20,7 @@
#include <numeric>
#include <algorithm>
+#include <array>
#include <cassert>
#include <functional>
#include <iterator>
@@ -26,6 +28,10 @@
#include "test_macros.h"
#include "test_iterators.h"
+// FIXME Remove constexpr vector workaround introduced in D90569
+#if TEST_STD_VER > 17
+#include <span>
+#endif
struct add_one {
template <typename T>
@@ -35,24 +41,37 @@ struct add_one {
};
template <class Iter1, class BOp, class UOp, class T, class Iter2>
-void
+TEST_CONSTEXPR_CXX20 void
test(Iter1 first, Iter1 last, BOp bop, UOp uop, T init, Iter2 rFirst, Iter2 rLast)
{
- std::vector<typename std::iterator_traits<Iter1>::value_type> v;
+ // C++17 doesn't test constexpr so can use a vector.
+ // C++20 can use vector in constexpr evaluation, but both libc++ and MSVC
+ // don't have the support yet. In these cases use a std::span for the test.
+ // FIXME Remove constexpr vector workaround introduced in D90569
+ size_t size = std::distance(first, last);
+#if TEST_STD_VER < 20 || \
+ (defined(__cpp_lib_constexpr_vector) && __cpp_lib_constexpr_vector >= 201907L)
+
+ std::vector<typename std::iterator_traits<Iter1>::value_type> v(size);
+#else
+ assert((size <= 5) && "Increment the size of the array");
+ typename std::iterator_traits<Iter1>::value_type b[5];
+ std::span<typename std::iterator_traits<Iter1>::value_type> v{b, size};
+#endif
+
// Test not in-place
- std::transform_exclusive_scan(first, last, std::back_inserter(v), init, bop, uop);
+ std::transform_exclusive_scan(first, last, v.begin(), init, bop, uop);
assert(std::equal(v.begin(), v.end(), rFirst, rLast));
// Test in-place
- v.clear();
- v.assign(first, last);
+ std::copy(first, last, v.begin());
std::transform_exclusive_scan(v.begin(), v.end(), v.begin(), init, bop, uop);
assert(std::equal(v.begin(), v.end(), rFirst, rLast));
}
template <class Iter>
-void
+TEST_CONSTEXPR_CXX20 void
test()
{
int ia[] = { 1, 3, 5, 7, 9 };
@@ -86,13 +105,14 @@ test()
}
}
-size_t triangle(size_t n) { return n*(n+1)/2; }
+constexpr size_t triangle(size_t n) { return n*(n+1)/2; }
// Basic sanity
-void basic_tests()
+TEST_CONSTEXPR_CXX20 void
+basic_tests()
{
{
- std::vector<size_t> v(10);
+ std::array<size_t, 10> v;
std::fill(v.begin(), v.end(), 3);
std::transform_exclusive_scan(v.begin(), v.end(), v.begin(), size_t{50}, std::plus<>(), add_one{});
for (size_t i = 0; i < v.size(); ++i)
@@ -100,7 +120,7 @@ void basic_tests()
}
{
- std::vector<size_t> v(10);
+ std::array<size_t, 10> v;
std::iota(v.begin(), v.end(), 0);
std::transform_exclusive_scan(v.begin(), v.end(), v.begin(), size_t{30}, std::plus<>(), add_one{});
for (size_t i = 0; i < v.size(); ++i)
@@ -108,7 +128,7 @@ void basic_tests()
}
{
- std::vector<size_t> v(10);
+ std::array<size_t, 10> v;
std::iota(v.begin(), v.end(), 1);
std::transform_exclusive_scan(v.begin(), v.end(), v.begin(), size_t{40}, std::plus<>(), add_one{});
for (size_t i = 0; i < v.size(); ++i)
@@ -116,17 +136,37 @@ void basic_tests()
}
{
+ // C++17 doesn't test constexpr so can use a vector.
+ // C++20 can use vector in constexpr evaluation, but both libc++ and MSVC
+ // don't have the support yet. In these cases use a std::span for the test.
+ // FIXME Remove constexpr vector workaround introduced in D90569
+#if TEST_STD_VER < 20 || \
+ (defined(__cpp_lib_constexpr_vector) && __cpp_lib_constexpr_vector >= 201907L)
std::vector<size_t> v, res;
std::transform_exclusive_scan(v.begin(), v.end(), std::back_inserter(res), size_t{40}, std::plus<>(), add_one{});
+#else
+ std::array<size_t, 0> v, res;
+ std::transform_exclusive_scan(v.begin(), v.end(), res.begin(), size_t{40}, std::plus<>(), add_one{});
+#endif
assert(res.empty());
}
// Make sure that the calculations are done using the init typedef
{
- std::vector<unsigned char> v(10);
+ std::array<unsigned char, 10> v;
std::iota(v.begin(), v.end(), static_cast<unsigned char>(1));
+ // C++17 doesn't test constexpr so can use a vector.
+ // C++20 can use vector in constexpr evaluation, but both libc++ and MSVC
+ // don't have the support yet. In these cases use a std::span for the test.
+ // FIXME Remove constexpr vector workaround introduced in D90569
+#if TEST_STD_VER < 20 || \
+ (defined(__cpp_lib_constexpr_vector) && __cpp_lib_constexpr_vector >= 201907L)
std::vector<size_t> res;
std::transform_exclusive_scan(v.begin(), v.end(), std::back_inserter(res), size_t{1}, std::multiplies<>(), add_one{});
+#else
+ std::array<size_t, 10> res;
+ std::transform_exclusive_scan(v.begin(), v.end(), res.begin(), size_t{1}, std::multiplies<>(), add_one{});
+#endif
assert(res.size() == 10);
size_t j = 1;
@@ -139,7 +179,8 @@ void basic_tests()
}
}
-int main(int, char**)
+TEST_CONSTEXPR_CXX20 bool
+test()
{
basic_tests();
@@ -151,5 +192,14 @@ int main(int, char**)
test<const int*>();
test< int*>();
- return 0;
+ return true;
+}
+
+int main(int, char**)
+{
+ test();
+#if TEST_STD_VER > 17
+ static_assert(test());
+#endif
+ return 0;
}
diff --git a/libcxx/test/std/numerics/numeric.ops/transform.inclusive.scan/transform_inclusive_scan_bop_uop.pass.cpp b/libcxx/test/std/numerics/numeric.ops/transform.inclusive.scan/transform_inclusive_scan_bop_uop.pass.cpp
index 9caec15ab853..c937b6f48519 100644
--- a/libcxx/test/std/numerics/numeric.ops/transform.inclusive.scan/transform_inclusive_scan_bop_uop.pass.cpp
+++ b/libcxx/test/std/numerics/numeric.ops/transform.inclusive.scan/transform_inclusive_scan_bop_uop.pass.cpp
@@ -10,6 +10,7 @@
// <numeric>
// UNSUPPORTED: c++03, c++11, c++14
+// Became constexpr in C++20
// template<class InputIterator, class OutputIterator, class T,
// class BinaryOperation, class UnaryOperation>
// OutputIterator transform_inclusive_scan(InputIterator first, InputIterator last,
@@ -20,6 +21,7 @@
#include <numeric>
#include <algorithm>
+#include <array>
#include <cassert>
#include <functional>
#include <iterator>
@@ -27,6 +29,10 @@
#include "test_macros.h"
#include "test_iterators.h"
+// FIXME Remove constexpr vector workaround introduced in D90569
+#if TEST_STD_VER > 17
+#include <span>
+#endif
struct add_one {
template <typename T>
@@ -36,24 +42,37 @@ struct add_one {
};
template <class Iter1, class BOp, class UOp, class Iter2>
-void
+TEST_CONSTEXPR_CXX20 void
test(Iter1 first, Iter1 last, BOp bop, UOp uop, Iter2 rFirst, Iter2 rLast)
{
- std::vector<typename std::iterator_traits<Iter1>::value_type> v;
+ // C++17 doesn't test constexpr so can use a vector.
+ // C++20 can use vector in constexpr evaluation, but both libc++ and MSVC
+ // don't have the support yet. In these cases use a std::span for the test.
+ // FIXME Remove constexpr vector workaround introduced in D90569
+ size_t size = std::distance(first, last);
+#if TEST_STD_VER < 20 || \
+ (defined(__cpp_lib_constexpr_vector) && __cpp_lib_constexpr_vector >= 201907L)
+
+ std::vector<typename std::iterator_traits<Iter1>::value_type> v(size);
+#else
+ assert((size <= 5) && "Increment the size of the array");
+ typename std::iterator_traits<Iter1>::value_type b[5];
+ std::span<typename std::iterator_traits<Iter1>::value_type> v{b, size};
+#endif
+
// Test not in-place
- std::transform_inclusive_scan(first, last, std::back_inserter(v), bop, uop);
+ std::transform_inclusive_scan(first, last, v.begin(), bop, uop);
assert(std::equal(v.begin(), v.end(), rFirst, rLast));
// Test in-place
- v.clear();
- v.assign(first, last);
+ std::copy(first, last, v.begin());
std::transform_inclusive_scan(v.begin(), v.end(), v.begin(), bop, uop);
assert(std::equal(v.begin(), v.end(), rFirst, rLast));
}
template <class Iter>
-void
+TEST_CONSTEXPR_CXX20 void
test()
{
int ia[] = { 1, 3, 5, 7, 9 };
@@ -75,13 +94,14 @@ test()
}
}
-size_t triangle(size_t n) { return n*(n+1)/2; }
+constexpr size_t triangle(size_t n) { return n*(n+1)/2; }
// Basic sanity
-void basic_tests()
+TEST_CONSTEXPR_CXX20 void
+basic_tests()
{
{
- std::vector<size_t> v(10);
+ std::array<size_t, 10> v;
std::fill(v.begin(), v.end(), 3);
std::transform_inclusive_scan(v.begin(), v.end(), v.begin(), std::plus<>(), add_one{});
for (size_t i = 0; i < v.size(); ++i)
@@ -89,7 +109,7 @@ void basic_tests()
}
{
- std::vector<size_t> v(10);
+ std::array<size_t, 10> v;
std::iota(v.begin(), v.end(), 0);
std::transform_inclusive_scan(v.begin(), v.end(), v.begin(), std::plus<>(), add_one{});
for (size_t i = 0; i < v.size(); ++i)
@@ -97,7 +117,7 @@ void basic_tests()
}
{
- std::vector<size_t> v(10);
+ std::array<size_t, 10> v;
std::iota(v.begin(), v.end(), 1);
std::transform_inclusive_scan(v.begin(), v.end(), v.begin(), std::plus<>(), add_one{});
for (size_t i = 0; i < v.size(); ++i)
@@ -105,13 +125,24 @@ void basic_tests()
}
{
+ // C++17 doesn't test constexpr so can use a vector.
+ // C++20 can use vector in constexpr evaluation, but both libc++ and MSVC
+ // don't have the support yet. In these cases use a std::span for the test.
+ // FIXME Remove constexpr vector workaround introduced in D90569
+#if TEST_STD_VER < 20 || \
+ (defined(__cpp_lib_constexpr_vector) && __cpp_lib_constexpr_vector >= 201907L)
std::vector<size_t> v, res;
std::transform_inclusive_scan(v.begin(), v.end(), std::back_inserter(res), std::plus<>(), add_one{});
+#else
+ std::array<size_t, 0> v, res;
+ std::transform_inclusive_scan(v.begin(), v.end(), res.begin(), std::plus<>(), add_one{});
+#endif
assert(res.empty());
}
}
-int main(int, char**)
+TEST_CONSTEXPR_CXX20 bool
+test()
{
basic_tests();
@@ -123,5 +154,14 @@ int main(int, char**)
test<const int*>();
test< int*>();
- return 0;
+ return true;
+}
+
+int main(int, char**)
+{
+ test();
+#if TEST_STD_VER > 17
+ static_assert(test());
+#endif
+ return 0;
}
diff --git a/libcxx/test/std/numerics/numeric.ops/transform.inclusive.scan/transform_inclusive_scan_bop_uop_init.pass.cpp b/libcxx/test/std/numerics/numeric.ops/transform.inclusive.scan/transform_inclusive_scan_bop_uop_init.pass.cpp
index 3b58d297ca99..0fff119f64cc 100644
--- a/libcxx/test/std/numerics/numeric.ops/transform.inclusive.scan/transform_inclusive_scan_bop_uop_init.pass.cpp
+++ b/libcxx/test/std/numerics/numeric.ops/transform.inclusive.scan/transform_inclusive_scan_bop_uop_init.pass.cpp
@@ -9,6 +9,7 @@
// <numeric>
// UNSUPPORTED: c++03, c++11, c++14
+// Became constexpr in C++20
// template<class InputIterator, class OutputIterator, class T,
// class BinaryOperation, class UnaryOperation>
// OutputIterator transform_inclusive_scan(InputIterator first, InputIterator last,
@@ -20,6 +21,7 @@
#include <numeric>
#include <algorithm>
+#include <array>
#include <cassert>
#include <functional>
#include <iterator>
@@ -27,6 +29,10 @@
#include "test_macros.h"
#include "test_iterators.h"
+// FIXME Remove constexpr vector workaround introduced in D90569
+#if TEST_STD_VER > 17
+#include <span>
+#endif
struct add_one {
template <typename T>
@@ -36,24 +42,37 @@ struct add_one {
};
template <class Iter1, class BOp, class UOp, class T, class Iter2>
-void
+TEST_CONSTEXPR_CXX20 void
test(Iter1 first, Iter1 last, BOp bop, UOp uop, T init, Iter2 rFirst, Iter2 rLast)
{
- std::vector<typename std::iterator_traits<Iter1>::value_type> v;
+ // C++17 doesn't test constexpr so can use a vector.
+ // C++20 can use vector in constexpr evaluation, but both libc++ and MSVC
+ // don't have the support yet. In these cases use a std::span for the test.
+ // FIXME Remove constexpr vector workaround introduced in D90569
+ size_t size = std::distance(first, last);
+#if TEST_STD_VER < 20 || \
+ (defined(__cpp_lib_constexpr_vector) && __cpp_lib_constexpr_vector >= 201907L)
+
+ std::vector<typename std::iterator_traits<Iter1>::value_type> v(size);
+#else
+ assert((size <= 5) && "Increment the size of the array");
+ typename std::iterator_traits<Iter1>::value_type b[5];
+ std::span<typename std::iterator_traits<Iter1>::value_type> v{b, size};
+#endif
+
// Test not in-place
- std::transform_inclusive_scan(first, last, std::back_inserter(v), bop, uop, init);
+ std::transform_inclusive_scan(first, last, v.begin(), bop, uop, init);
assert(std::equal(v.begin(), v.end(), rFirst, rLast));
// Test in-place
- v.clear();
- v.assign(first, last);
+ std::copy(first, last, v.begin());
std::transform_inclusive_scan(v.begin(), v.end(), v.begin(), bop, uop, init);
assert(std::equal(v.begin(), v.end(), rFirst, rLast));
}
template <class Iter>
-void
+TEST_CONSTEXPR_CXX20 void
test()
{
int ia[] = { 1, 3, 5, 7, 9 };
@@ -87,13 +106,14 @@ test()
}
}
-size_t triangle(size_t n) { return n*(n+1)/2; }
+constexpr size_t triangle(size_t n) { return n*(n+1)/2; }
// Basic sanity
-void basic_tests()
+TEST_CONSTEXPR_CXX20 void
+basic_tests()
{
{
- std::vector<size_t> v(10);
+ std::array<size_t, 10> v;
std::fill(v.begin(), v.end(), 3);
std::transform_inclusive_scan(v.begin(), v.end(), v.begin(), std::plus<>(), add_one{}, size_t{50});
for (size_t i = 0; i < v.size(); ++i)
@@ -101,7 +121,7 @@ void basic_tests()
}
{
- std::vector<size_t> v(10);
+ std::array<size_t, 10> v;
std::iota(v.begin(), v.end(), 0);
std::transform_inclusive_scan(v.begin(), v.end(), v.begin(), std::plus<>(), add_one{}, size_t{30});
for (size_t i = 0; i < v.size(); ++i)
@@ -109,7 +129,7 @@ void basic_tests()
}
{
- std::vector<size_t> v(10);
+ std::array<size_t, 10> v;
std::iota(v.begin(), v.end(), 1);
std::transform_inclusive_scan(v.begin(), v.end(), v.begin(), std::plus<>(), add_one{}, size_t{40});
for (size_t i = 0; i < v.size(); ++i)
@@ -117,17 +137,37 @@ void basic_tests()
}
{
+ // C++17 doesn't test constexpr so can use a vector.
+ // C++20 can use vector in constexpr evaluation, but both libc++ and MSVC
+ // don't have the support yet. In these cases use a std::span for the test.
+ // FIXME Remove constexpr vector workaround introduced in D90569
+#if TEST_STD_VER < 20 || \
+ (defined(__cpp_lib_constexpr_vector) && __cpp_lib_constexpr_vector >= 201907L)
std::vector<size_t> v, res;
std::transform_inclusive_scan(v.begin(), v.end(), std::back_inserter(res), std::plus<>(), add_one{}, size_t{1});
+#else
+ std::array<size_t, 0> v, res;
+ std::transform_inclusive_scan(v.begin(), v.end(), res.begin(), std::plus<>(), add_one{}, size_t{1});
+#endif
assert(res.empty());
}
// Make sure that the calculations are done using the init typedef
{
- std::vector<unsigned char> v(10);
+ std::array<unsigned char, 10> v;
std::iota(v.begin(), v.end(), static_cast<unsigned char>(1));
+ // C++17 doesn't test constexpr so can use a vector.
+ // C++20 can use vector in constexpr evaluation, but both libc++ and MSVC
+ // don't have the support yet. In these cases use a std::span for the test.
+ // FIXME Remove constexpr vector workaround introduced in D90569
+#if TEST_STD_VER < 20 || \
+ (defined(__cpp_lib_constexpr_vector) && __cpp_lib_constexpr_vector >= 201907L)
std::vector<size_t> res;
std::transform_inclusive_scan(v.begin(), v.end(), std::back_inserter(res), std::multiplies<>(), add_one{}, size_t{1});
+#else
+ std::array<size_t, 10> res;
+ std::transform_inclusive_scan(v.begin(), v.end(), res.begin(), std::multiplies<>(), add_one{}, size_t{1});
+#endif
assert(res.size() == 10);
size_t j = 2;
@@ -140,7 +180,8 @@ void basic_tests()
}
}
-int main(int, char**)
+TEST_CONSTEXPR_CXX20 bool
+test()
{
basic_tests();
@@ -152,5 +193,14 @@ int main(int, char**)
test<const int*>();
test< int*>();
- return 0;
+ return true;
+}
+
+int main(int, char**)
+{
+ test();
+#if TEST_STD_VER > 17
+ static_assert(test());
+#endif
+ return 0;
}
diff --git a/libcxx/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_init_bop_uop.pass.cpp b/libcxx/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_init_bop_uop.pass.cpp
index 78c38fcf76ca..c257312bd428 100644
--- a/libcxx/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_init_bop_uop.pass.cpp
+++ b/libcxx/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_init_bop_uop.pass.cpp
@@ -9,6 +9,7 @@
// <numeric>
// UNSUPPORTED: c++03, c++11, c++14
+// Became constexpr in C++20
// template <class InputIterator1, class T,
// class BinaryOperation, class UnaryOperation>
// T transform_reduce(InputIterator1 first1, InputIterator1 last1,
@@ -41,7 +42,7 @@ struct twice
};
template <class Iter1, class T, class BOp, class UOp>
-void
+TEST_CONSTEXPR_CXX20 void
test(Iter1 first1, Iter1 last1, T init, BOp bOp, UOp uOp, T x)
{
static_assert( std::is_same_v<T,
@@ -50,7 +51,7 @@ test(Iter1 first1, Iter1 last1, T init, BOp bOp, UOp uOp, T x)
}
template <class Iter>
-void
+TEST_CONSTEXPR_CXX20 void
test()
{
int ia[] = {1, 2, 3, 4, 5, 6};
@@ -76,14 +77,16 @@ test()
}
template <typename T, typename Init>
-void test_return_type()
+TEST_CONSTEXPR_CXX20 void
+test_return_type()
{
T *p = nullptr;
static_assert( std::is_same_v<Init,
decltype(std::transform_reduce(p, p, Init{}, std::plus<>(), identity()))> );
}
-void test_move_only_types()
+TEST_CONSTEXPR_CXX20 void
+test_move_only_types()
{
MoveOnly ia[] = {{1}, {2}, {3}};
assert(60 ==
@@ -92,7 +95,8 @@ void test_move_only_types()
[](const MoveOnly& target) { return MoveOnly{target.get() * 10}; }).get());
}
-int main(int, char**)
+TEST_CONSTEXPR_CXX20 bool
+test()
{
test_return_type<char, int>();
test_return_type<int, int>();
@@ -119,5 +123,14 @@ int main(int, char**)
test_move_only_types();
- return 0;
+ return true;
+}
+
+int main(int, char**)
+{
+ test();
+#if TEST_STD_VER > 17
+ static_assert(test());
+#endif
+ return 0;
}
diff --git a/libcxx/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init.pass.cpp b/libcxx/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init.pass.cpp
index 133b594e196f..e64f8bc408f3 100644
--- a/libcxx/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init.pass.cpp
+++ b/libcxx/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init.pass.cpp
@@ -9,6 +9,7 @@
// <numeric>
// UNSUPPORTED: c++03, c++11, c++14
+// Became constexpr in C++20
// template <class InputIterator1, class InputIterator2, class T>
// T transform_reduce(InputIterator1 first1, InputIterator1 last1,
// InputIterator2 first2, T init);
@@ -23,7 +24,7 @@
#include "test_iterators.h"
template <class Iter1, class Iter2, class T>
-void
+TEST_CONSTEXPR_CXX20 void
test(Iter1 first1, Iter1 last1, Iter2 first2, T init, T x)
{
static_assert( std::is_same_v<T,
@@ -32,7 +33,7 @@ test(Iter1 first1, Iter1 last1, Iter2 first2, T init, T x)
}
template <class SIter, class UIter>
-void
+TEST_CONSTEXPR_CXX20 void
test()
{
int ia[] = {1, 2, 3, 4, 5, 6};
@@ -51,14 +52,16 @@ test()
}
template <typename T, typename Init>
-void test_return_type()
+TEST_CONSTEXPR_CXX20 void
+test_return_type()
{
T *p = nullptr;
static_assert( std::is_same_v<Init,
decltype(std::transform_reduce(p, p, p, Init{}))> );
}
-void test_move_only_types()
+TEST_CONSTEXPR_CXX20 void
+test_move_only_types()
{
MoveOnly ia[] = {{1}, {2}, {3}};
MoveOnly ib[] = {{1}, {2}, {3}};
@@ -66,7 +69,8 @@ void test_move_only_types()
std::transform_reduce(std::begin(ia), std::end(ia), std::begin(ib), MoveOnly{0}).get());
}
-int main(int, char**)
+TEST_CONSTEXPR_CXX20 bool
+test()
{
test_return_type<char, int>();
test_return_type<int, int>();
@@ -105,5 +109,14 @@ int main(int, char**)
test_move_only_types();
- return 0;
+ return true;
+}
+
+int main(int, char**)
+{
+ test();
+#if TEST_STD_VER > 17
+ static_assert(test());
+#endif
+ return 0;
}
diff --git a/libcxx/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init_op_op.pass.cpp b/libcxx/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init_op_op.pass.cpp
index 6d99d465be64..6bd1208e1845 100644
--- a/libcxx/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init_op_op.pass.cpp
+++ b/libcxx/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init_op_op.pass.cpp
@@ -9,6 +9,7 @@
// <numeric>
// UNSUPPORTED: c++03, c++11, c++14
+// Became constexpr in C++20
// template <class InputIterator1, class InputIterator2, class T,
// class BinaryOperation1, class BinaryOperation2>
// T transform_reduce(InputIterator1 first1, InputIterator1 last1,
@@ -25,7 +26,7 @@
#include "test_iterators.h"
template <class Iter1, class Iter2, class T, class Op1, class Op2>
-void
+TEST_CONSTEXPR_CXX20 void
test(Iter1 first1, Iter1 last1, Iter2 first2, T init, Op1 op1, Op2 op2, T x)
{
static_assert( std::is_same_v<T,
@@ -34,7 +35,7 @@ test(Iter1 first1, Iter1 last1, Iter2 first2, T init, Op1 op1, Op2 op2, T x)
}
template <class SIter, class UIter>
-void
+TEST_CONSTEXPR_CXX20 void
test()
{
int ia[] = {1, 2, 3, 4, 5, 6};
@@ -53,14 +54,16 @@ test()
}
template <typename T, typename Init>
-void test_return_type()
+TEST_CONSTEXPR_CXX20 void
+test_return_type()
{
T *p = nullptr;
static_assert( std::is_same_v<Init,
decltype(std::transform_reduce(p, p, p, Init{}, std::plus<>(), std::multiplies<>()))> );
}
-void test_move_only_types()
+TEST_CONSTEXPR_CXX20 void
+test_move_only_types()
{
MoveOnly ia[] = {{1}, {2}, {3}};
MoveOnly ib[] = {{1}, {2}, {3}};
@@ -70,7 +73,8 @@ void test_move_only_types()
[](const MoveOnly& lhs, const MoveOnly& rhs) { return MoveOnly{lhs.get() * rhs.get()}; }).get());
}
-int main(int, char**)
+TEST_CONSTEXPR_CXX20 bool
+test()
{
test_return_type<char, int>();
test_return_type<int, int>();
@@ -109,5 +113,14 @@ int main(int, char**)
test_move_only_types();
- return 0;
+ return true;
+}
+
+int main(int, char**)
+{
+ test();
+#if TEST_STD_VER > 17
+ static_assert(test());
+#endif
+ return 0;
}
diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index 22389f85f4ad..79a9929ebb7c 100755
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -374,6 +374,10 @@ def add_version_header(tc):
"values": { "c++2a": int(201811) },
"headers": ["array", "functional", "iterator", "string_view", "tuple", "utility"],
"unimplemented": True,
+ }, {
+ "name": "__cpp_lib_constexpr_numeric",
+ "values": { "c++2a": int(201911) },
+ "headers": ["numeric"],
}, {
"name": "__cpp_lib_bind_front",
"values": { "c++2a": int(201811) },
diff --git a/libcxx/www/cxx2a_status.html b/libcxx/www/cxx2a_status.html
index bd112d8573bb..a62ab7e77315 100644
--- a/libcxx/www/cxx2a_status.html
+++ b/libcxx/www/cxx2a_status.html
@@ -198,7 +198,7 @@ <h3>Paper Status</h3>
<tr><td><a href="https://wg21.link/P1394">P1394</a></td><td>LWG</td><td>Range constructor for std::span </td><td>Belfast</td><td><i> </i></td><td></td></tr>
<tr><td><a href="https://wg21.link/P1456">P1456</a></td><td>LWG</td><td>Move-only views </td><td>Belfast</td><td><i> </i></td><td></td></tr>
<tr><td><a href="https://wg21.link/P1622">P1622</a></td><td>LWG</td><td>Mandating the Standard Library: Clause 32 - Thread support library </td><td>Belfast</td><td><i> </i></td><td></td></tr>
- <tr><td><a href="https://wg21.link/P1645">P1645</a></td><td>LWG</td><td>constexpr for numeric algorithms </td><td>Belfast</td><td><i> </i></td><td></td></tr>
+ <tr><td><a href="https://wg21.link/P1645">P1645</a></td><td>LWG</td><td>constexpr for numeric algorithms </td><td>Belfast</td><td>Complete</td><td>12.0</td></tr>
<tr><td><a href="https://wg21.link/P1664">P1664</a></td><td>LWG</td><td>reconstructible_range - a concept for putting ranges back together </td><td>Belfast</td><td><i> </i></td><td></td></tr>
<tr><td><a href="https://wg21.link/P1686">P1686</a></td><td>LWG</td><td>Mandating the Standard Library: Clause 27 - Time library </td><td>Belfast</td><td><i> </i></td><td></td></tr>
<tr><td><a href="https://wg21.link/P1690">P1690</a></td><td>LWG</td><td>Refinement Proposal for P0919 Heterogeneous lookup for unordered containers </td><td>Belfast</td><td>Complete</td><td>12.0</td></tr>
More information about the llvm-branch-commits
mailing list