diff options
author | Mark de Wever <koraq@xs4all.nl> | 2020-11-28 14:50:53 +0100 |
---|---|---|
committer | Mark de Wever <koraq@xs4all.nl> | 2020-11-28 17:02:54 +0100 |
commit | 67c88e47bdba2578150a9034a717d6ddcace4e13 (patch) | |
tree | 0b2e9ea7e2d70c567b5a007dbbce1e19a78a452e /libcxx | |
parent | [clangd] Add symbol origin for remote index (diff) | |
download | llvm-project-67c88e47bdba2578150a9034a717d6ddcace4e13.tar.gz llvm-project-67c88e47bdba2578150a9034a717d6ddcace4e13.tar.bz2 llvm-project-67c88e47bdba2578150a9034a717d6ddcace4e13.zip |
[libc++] P1645 constexpr for <numeric>
Implements P1645: constexpr for <numeric> algorithms
Reviewed By: ldionne, #libc
Differential Revision: https://reviews.llvm.org/D90569
Diffstat (limited to 'libcxx')
30 files changed, 902 insertions, 259 deletions
diff --git a/libcxx/docs/Cxx2aStatusPaperStatus.csv b/libcxx/docs/Cxx2aStatusPaperStatus.csv index 456ac647b7a3..793fc92be5f2 100644 --- a/libcxx/docs/Cxx2aStatusPaperStatus.csv +++ b/libcxx/docs/Cxx2aStatusPaperStatus.csv @@ -138,7 +138,7 @@ "`P1394 <https://wg21.link/P1394>`__","LWG","Range constructor for std::span","Belfast","* *","" "`P1456 <https://wg21.link/P1456>`__","LWG","Move-only views","Belfast","* *","" "`P1622 <https://wg21.link/P1622>`__","LWG","Mandating the Standard Library: Clause 32 - Thread support library","Belfast","* *","" -"`P1645 <https://wg21.link/P1645>`__","LWG","constexpr for numeric algorithms","Belfast","* *","" +"`P1645 <https://wg21.link/P1645>`__","LWG","constexpr for numeric algorithms","Belfast","|Complete|","12.0" "`P1664 <https://wg21.link/P1664>`__","LWG","reconstructible_range - a concept for putting ranges back together","Belfast","* *","" "`P1686 <https://wg21.link/P1686>`__","LWG","Mandating the Standard Library: Clause 27 - Time library","Belfast","* *","" "`P1690 <https://wg21.link/P1690>`__","LWG","Refinement Proposal for P0919 Heterogeneous lookup for unordered containers","Belfast","|Complete|","12.0" 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 088bd7438d2b..5c10dd3c1e67 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_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) { @@ -172,7 +175,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) { @@ -187,7 +190,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) { @@ -197,7 +200,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) { @@ -205,7 +208,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) { @@ -215,7 +218,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) { @@ -229,7 +232,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) @@ -245,7 +248,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) @@ -257,7 +260,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) @@ -268,7 +271,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) @@ -279,7 +282,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) { @@ -301,7 +304,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) @@ -325,7 +328,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) @@ -345,7 +348,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) @@ -354,6 +357,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) { @@ -365,6 +369,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) { @@ -379,6 +384,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) { @@ -387,7 +393,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, @@ -408,7 +414,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) { @@ -420,7 +428,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) { @@ -435,7 +445,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) { @@ -458,7 +468,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) @@ -482,7 +492,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_) { 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..d491bc0394b3 100644 --- a/libcxx/test/std/numerics/numeric.ops/accumulate/accumulate.pass.cpp +++ b/libcxx/test/std/numerics/numeric.ops/accumulate/accumulate.pass.cpp @@ -7,7 +7,9 @@ //===----------------------------------------------------------------------===// // <numeric> +// UNSUPPORTED: clang-8 +// 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 +23,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 +45,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 +54,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 c2a430f370f7..bef328e5ba02 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 @@ -7,7 +7,9 @@ //===----------------------------------------------------------------------===// // <numeric> +// UNSUPPORTED: clang-8 +// Became constexpr in C++20 // template <InputIterator Iter, MoveConstructible T, // Callable<auto, const T&, Iter::reference> BinaryOperation> // requires HasAssign<T, BinaryOperation::result_type> @@ -29,25 +31,25 @@ struct rvalue_addable bool correctOperatorUsed = false; // make sure the predicate is passed an rvalue and an lvalue (so check that the first argument was moved) - rvalue_addable operator()(rvalue_addable&& r, rvalue_addable const&) { + constexpr rvalue_addable operator()(rvalue_addable&& r, rvalue_addable const&) { r.correctOperatorUsed = true; return std::move(r); } }; -rvalue_addable operator+(rvalue_addable& lhs, rvalue_addable const&) +constexpr rvalue_addable operator+(rvalue_addable& lhs, rvalue_addable const&) { lhs.correctOperatorUsed = false; return lhs; } -rvalue_addable operator+(rvalue_addable&& lhs, rvalue_addable const&) +constexpr rvalue_addable operator+(rvalue_addable&& lhs, rvalue_addable const&) { lhs.correctOperatorUsed = true; return std::move(lhs); } -void +constexpr void test_use_move() { rvalue_addable arr[100]; @@ -58,7 +60,15 @@ test_use_move() } #endif // TEST_STD_VER > 17 +// C++20 can use string in constexpr evaluation, but both libc++ and MSVC +// don't have the support yet. In these cases omit the constexpr test. +// FIXME Remove constexpr string workaround introduced in D90569 +#if TEST_STD_VER > 17 && \ + (!defined(__cpp_lib_constexpr_string) || __cpp_lib_constexpr_string < 201907L) void +#else +TEST_CONSTEXPR_CXX20 void +#endif test_string() { std::string sa[] = {"a", "b", "c"}; @@ -67,14 +77,14 @@ test_string() } 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}; @@ -89,7 +99,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*> >(); @@ -100,7 +111,23 @@ int main(int, char**) #if TEST_STD_VER > 17 test_use_move(); #endif // TEST_STD_VER > 17 + // C++20 can use string in constexpr evaluation, but both libc++ and MSVC + // don't have the support yet. In these cases omit the constexpr test. + // FIXME Remove constexpr string workaround introduced in D90569 +#if TEST_STD_VER > 17 && \ + (!defined(__cpp_lib_constexpr_string) || __cpp_lib_constexpr_string < 201907L) + if (!std::is_constant_evaluated()) +#endif test_string(); + 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.difference/adjacent_difference.pass.cpp b/libcxx/test/std/numerics/numeric.ops/adjacent.difference/adjacent_difference.pass.cpp index 3e043e5cb8fe..f39715cfb13e 100644 --- a/libcxx/test/std/numerics/numeric.ops/adjacent.difference/adjacent_difference.pass.cpp +++ b/libcxx/test/std/numerics/numeric.ops/adjacent.difference/adjacent_difference.pass.cpp @@ -7,7 +7,9 @@ //===----------------------------------------------------------------------===// // <numeric> +// UNSUPPORTED: clang-8 +// 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 +27,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 +48,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 +68,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 +116,14 @@ int main(int, char**) std::adjacent_difference(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.difference/adjacent_difference_op.pass.cpp b/libcxx/test/std/numerics/numeric.ops/adjacent.difference/adjacent_difference_op.pass.cpp index f8c12abd9e2b..636d50d0f4ff 100644 --- a/libcxx/test/std/numerics/numeric.ops/adjacent.difference/adjacent_difference_op.pass.cpp +++ b/libcxx/test/std/numerics/numeric.ops/adjacent.difference/adjacent_difference_op.pass.cpp @@ -7,7 +7,9 @@ //===----------------------------------------------------------------------===// // <numeric> +// UNSUPPORTED: clang-8 +// 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> @@ -32,25 +34,25 @@ struct rvalue_subtractable bool correctOperatorUsed = false; // make sure the predicate is passed an rvalue and an lvalue (so check that the first argument was moved) - rvalue_subtractable operator()(rvalue_subtractable const&, rvalue_subtractable&& r) { + constexpr rvalue_subtractable operator()(rvalue_subtractable const&, rvalue_subtractable&& r) { r.correctOperatorUsed = true; return std::move(r); } }; -rvalue_subtractable operator-(rvalue_subtractable const&, rvalue_subtractable& rhs) +constexpr rvalue_subtractable operator-(rvalue_subtractable const&, rvalue_subtractable& rhs) { rhs.correctOperatorUsed = false; return rhs; } -rvalue_subtractable operator-(rvalue_subtractable const&, rvalue_subtractable&& rhs) +constexpr rvalue_subtractable operator-(rvalue_subtractable const&, rvalue_subtractable&& rhs) { rhs.correctOperatorUsed = true; return std::move(rhs); } -void +constexpr void test_use_move() { const std::size_t size = 100; @@ -65,7 +67,15 @@ test_use_move() } #endif // TEST_STD_VER > 17 +// C++20 can use string in constexpr evaluation, but both libc++ and MSVC +// don't have the support yet. In these cases omit the constexpr test. +// FIXME Remove constexpr string workaround introduced in D90569 +#if TEST_STD_VER > 17 && \ + (!defined(__cpp_lib_constexpr_string) || __cpp_lib_constexpr_string < 201907L) void +#else +TEST_CONSTEXPR_CXX20 void +#endif test_string() { std::string sa[] = {"a", "b", "c"}; @@ -76,7 +86,7 @@ test_string() } template <class InIter, class OutIter> -void +TEST_CONSTEXPR_CXX20 void test() { int ia[] = {15, 10, 6, 3, 1}; @@ -98,18 +108,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; }; @@ -118,17 +128,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*> >(); @@ -169,7 +180,23 @@ int main(int, char**) #if TEST_STD_VER > 17 test_use_move(); #endif // TEST_STD_VER > 17 + // C++20 can use string in constexpr evaluation, but both libc++ and MSVC + // don't have the support yet. In these cases omit the constexpr test. + // FIXME Remove constexpr string workaround introduced in D90569 +#if TEST_STD_VER > 17 && \ + (!defined(__cpp_lib_constexpr_string) || __cpp_lib_constexpr_string < 201907L) + if (!std::is_constant_evaluated()) +#endif test_string(); + 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..1317c7664ada 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 @@ -8,7 +8,9 @@ // <numeric> // UNSUPPORTED: c++03, c++11, c++14 +// UNSUPPORTED: clang-8 +// 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 +18,7 @@ #include <numeric> #include <algorithm> +#include <array> #include <cassert> #include <functional> #include <iterator> @@ -23,27 +26,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 +73,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 +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::exclusive_scan(v.begin(), v.end(), v.begin(), size_t{30}); 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::exclusive_scan(v.begin(), v.end(), v.begin(), size_t{40}); for (size_t i = 0; i < v.size(); ++i) @@ -86,7 +105,8 @@ void basic_tests() } -int main(int, char**) +TEST_CONSTEXPR_CXX20 bool +test() { basic_tests(); @@ -98,5 +118,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..fb2078dae7af 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 @@ -8,7 +8,9 @@ // <numeric> // UNSUPPORTED: c++03, c++11, c++14 +// UNSUPPORTED: clang-8 +// Became constexpr in C++20 // template<class InputIterator, class OutputIterator, class T, class BinaryOperation> // OutputIterator // exclusive_scan(InputIterator first, InputIterator last, @@ -17,6 +19,7 @@ #include <numeric> #include <algorithm> +#include <array> #include <cassert> #include <functional> #include <iterator> @@ -24,27 +27,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 +79,8 @@ test() } } -int main(int, char**) +TEST_CONSTEXPR_CXX20 bool +test() { // All the iterator categories test<input_iterator <const int*> >(); @@ -72,10 +92,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 +117,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..18178153b0b8 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 @@ -8,7 +8,9 @@ // <numeric> // UNSUPPORTED: c++03, c++11, c++14 +// UNSUPPORTED: clang-8 +// 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 +18,7 @@ #include <numeric> #include <algorithm> +#include <array> #include <cassert> #include <functional> #include <iterator> @@ -23,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 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 +74,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 +89,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 +97,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 +105,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 +134,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..00092a69317c 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 @@ -8,7 +8,9 @@ // <numeric> // UNSUPPORTED: c++03, c++11, c++14 +// UNSUPPORTED: clang-8 +// Became constexpr in C++20 // template<class InputIterator, class OutputIterator, class T, class BinaryOperation> // OutputIterator // inclusive_scan(InputIterator first, InputIterator last, @@ -17,6 +19,7 @@ #include <numeric> #include <algorithm> +#include <array> #include <cassert> #include <functional> #include <iterator> @@ -24,27 +27,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 +79,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 +94,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 +102,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 +110,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..6c965000ccc0 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 @@ -8,7 +8,9 @@ // <numeric> // UNSUPPORTED: c++03, c++11, c++14 +// UNSUPPORTED: clang-8 +// Became constexpr in C++20 // template<class InputIterator, class OutputIterator, class T, class BinaryOperation> // OutputIterator // inclusive_scan(InputIterator first, InputIterator last, @@ -17,6 +19,7 @@ #include <numeric> #include <algorithm> +#include <array> #include <cassert> #include <functional> #include <iterator> @@ -24,27 +27,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 +79,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 +94,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 +102,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 +110,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 +153,9 @@ void basic_tests() } } - -int main(int, char**) +TEST_CONSTEXPR_CXX20 bool +test() { - basic_tests(); // All the iterator categories @@ -127,6 +166,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..aa74bb483f7b 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 @@ -7,7 +7,9 @@ //===----------------------------------------------------------------------===// // <numeric> +// UNSUPPORTED: clang-8 +// 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 +27,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 +50,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 +83,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 be325b65ec29..9e3edc1573ab 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 @@ -7,7 +7,9 @@ //===----------------------------------------------------------------------===// // <numeric> +// UNSUPPORTED: clang-8 +// Became constexpr in C++20 // template <InputIterator Iter1, InputIterator Iter2, MoveConstructible T, // class BinaryOperation1, // Callable<auto, Iter1::reference, Iter2::reference> BinaryOperation2> @@ -31,7 +33,7 @@ struct do_nothing_op { template<class T> - T operator()(T a, T) + constexpr T operator()(T a, T) { return a; } }; @@ -39,28 +41,28 @@ struct rvalue_addable { bool correctOperatorUsed = false; - rvalue_addable operator*(rvalue_addable const&) { return *this; } + constexpr rvalue_addable operator*(rvalue_addable const&) { return *this; } // make sure the predicate is passed an rvalue and an lvalue (so check that the first argument was moved) - rvalue_addable operator()(rvalue_addable&& r, rvalue_addable const&) { + constexpr rvalue_addable operator()(rvalue_addable&& r, rvalue_addable const&) { r.correctOperatorUsed = true; return std::move(r); } }; -rvalue_addable operator+(rvalue_addable& lhs, rvalue_addable const&) +constexpr rvalue_addable operator+(rvalue_addable& lhs, rvalue_addable const&) { lhs.correctOperatorUsed = false; return lhs; } -rvalue_addable operator+(rvalue_addable&& lhs, rvalue_addable const&) +constexpr rvalue_addable operator+(rvalue_addable&& lhs, rvalue_addable const&) { lhs.correctOperatorUsed = true; return std::move(lhs); } -void +constexpr void test_use_move() { rvalue_addable arr[100]; @@ -72,7 +74,15 @@ test_use_move() } #endif // TEST_STD_VER > 17 +// C++20 can use string in constexpr evaluation, but both libc++ and MSVC +// don't have the support yet. In these cases omit the constexpr test. +// FIXME Remove constexpr string workaround introduced in D90569 +#if TEST_STD_VER > 17 && \ + (!defined(__cpp_lib_constexpr_string) || __cpp_lib_constexpr_string < 201907L) void +#else +TEST_CONSTEXPR_CXX20 void +#endif test_string() { std::string sa[] = {"a", "b", "c"}; @@ -81,7 +91,7 @@ test_string() } 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, @@ -89,7 +99,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}; @@ -105,7 +115,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*> >(); @@ -140,7 +151,23 @@ int main(int, char**) #if TEST_STD_VER > 17 test_use_move(); #endif // TEST_STD_VER > 17 + // C++20 can use string in constexpr evaluation, but both libc++ and MSVC + // don't have the support yet. In these cases omit the constexpr test. + // FIXME Remove constexpr string workaround introduced in D90569 +#if TEST_STD_VER > 17 && \ + (!defined(__cpp_lib_constexpr_string) || __cpp_lib_constexpr_string < 201907L) + if (!std::is_constant_evaluated()) +#endif test_string(); + 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..50d0a0632f6a 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 @@ -7,7 +7,9 @@ //===----------------------------------------------------------------------===// // <numeric> +// UNSUPPORTED: clang-8 +// Became constexpr in C++20 // template <class ForwardIterator, class T> // void iota(ForwardIterator first, ForwardIterator last, T value); @@ -18,7 +20,7 @@ #include "test_iterators.h" template <class InIter> -void +TEST_CONSTEXPR_CXX20 void test() { int ia[] = {1, 2, 3, 4, 5}; @@ -29,12 +31,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..236b3fd00a8b 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 @@ -7,7 +7,9 @@ //===----------------------------------------------------------------------===// // <numeric> +// UNSUPPORTED: clang-8 +// 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 +25,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 +38,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 +71,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 133edd73b2b7..4095cee01dba 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 @@ -7,7 +7,9 @@ //===----------------------------------------------------------------------===// // <numeric> +// UNSUPPORTED: clang-8 +// Became constexpr in C++20 // template<InputIterator InIter, // OutputIterator<auto, const InIter::value_type&> OutIter, // Callable<auto, const InIter::value_type&, InIter::reference> BinaryOperation> @@ -31,25 +33,25 @@ struct rvalue_addable bool correctOperatorUsed = false; // make sure the predicate is passed an rvalue and an lvalue (so check that the first argument was moved) - rvalue_addable operator()(rvalue_addable&& r, rvalue_addable const&) { + constexpr rvalue_addable operator()(rvalue_addable&& r, rvalue_addable const&) { r.correctOperatorUsed = true; return std::move(r); } }; -rvalue_addable operator+(rvalue_addable& lhs, rvalue_addable const&) +constexpr rvalue_addable operator+(rvalue_addable& lhs, rvalue_addable const&) { lhs.correctOperatorUsed = false; return lhs; } -rvalue_addable operator+(rvalue_addable&& lhs, rvalue_addable const&) +constexpr rvalue_addable operator+(rvalue_addable&& lhs, rvalue_addable const&) { lhs.correctOperatorUsed = true; return std::move(lhs); } -void +constexpr void test_use_move() { const std::size_t size = 100; @@ -64,7 +66,15 @@ test_use_move() } #endif // TEST_STD_VER > 17 +// C++20 can use string in constexpr evaluation, but both libc++ and MSVC +// don't have the support yet. In these cases omit the constexpr test. +// FIXME Remove constexpr string workaround introduced in D90569 +#if TEST_STD_VER > 17 && \ + (!defined(__cpp_lib_constexpr_string) || __cpp_lib_constexpr_string < 201907L) void +#else +TEST_CONSTEXPR_CXX20 void +#endif test_string() { std::string sa[] = {"a", "b", "c"}; @@ -75,7 +85,7 @@ test_string() } template <class InIter, class OutIter> -void +TEST_CONSTEXPR_CXX20 void test() { int ia[] = {1, 2, 3, 4, 5}; @@ -88,7 +98,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*> >(); @@ -123,7 +134,24 @@ int main(int, char**) #if TEST_STD_VER > 17 test_use_move(); #endif // TEST_STD_VER > 17 + // C++20 can use string in constexpr evaluation, but both libc++ and MSVC + // don't have the support yet. In these cases omit the constexpr test. + // FIXME Remove constexpr string workaround introduced in D90569 +#if TEST_STD_VER > 17 && \ + (!defined(__cpp_lib_constexpr_string) || __cpp_lib_constexpr_string < 201907L) + if (!std::is_constant_evaluated()) +#endif test_string(); + 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..88e2e24b605a 100644 --- a/libcxx/test/std/numerics/numeric.ops/reduce/reduce.pass.cpp +++ b/libcxx/test/std/numerics/numeric.ops/reduce/reduce.pass.cpp @@ -8,7 +8,9 @@ // <numeric> // UNSUPPORTED: c++03, c++11, c++14 +// UNSUPPORTED: clang-8 +// Became constexpr in C++20 // template<class InputIterator> // typename iterator_traits<InputIterator>::value_type // reduce(InputIterator first, InputIterator last); @@ -20,7 +22,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 +31,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 +43,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 +65,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..073d3f8bc2c3 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 @@ -8,7 +8,9 @@ // <numeric> // UNSUPPORTED: c++03, c++11, c++14 +// UNSUPPORTED: clang-8 +// Became constexpr in C++20 // template<class InputIterator, class T> // T reduce(InputIterator first, InputIterator last, T init); @@ -19,7 +21,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 +29,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 +45,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 +69,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..0f3be386e05d 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 @@ -8,7 +8,9 @@ // <numeric> // UNSUPPORTED: c++03, c++11, c++14 +// UNSUPPORTED: clang-8 +// Became constexpr in C++20 // template<class InputIterator, class T, class BinaryOperation> // T reduce(InputIterator first, InputIterator last, T init, BinaryOperation op); @@ -19,7 +21,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 +29,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 +45,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 +76,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..d7fef8e90d19 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 @@ -8,7 +8,9 @@ // <numeric> // UNSUPPORTED: c++03, c++11, c++14 +// UNSUPPORTED: clang-8 +// 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 +21,7 @@ #include <numeric> #include <algorithm> +#include <array> #include <cassert> #include <functional> #include <iterator> @@ -26,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> @@ -35,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_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 +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_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 +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_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 +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_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 +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_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 +180,8 @@ void basic_tests() } } -int main(int, char**) +TEST_CONSTEXPR_CXX20 bool +test() { basic_tests(); @@ -151,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.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..41b3b6258d27 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 @@ -9,7 +9,9 @@ // <numeric> // UNSUPPORTED: c++03, c++11, c++14 +// UNSUPPORTED: clang-8 +// 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 +22,7 @@ #include <numeric> #include <algorithm> +#include <array> #include <cassert> #include <functional> #include <iterator> @@ -27,6 +30,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 +43,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 +95,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 +110,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 +118,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 +126,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 +155,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..3ffb954d02d3 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 @@ -8,7 +8,9 @@ // <numeric> // UNSUPPORTED: c++03, c++11, c++14 +// UNSUPPORTED: clang-8 +// 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 +22,7 @@ #include <numeric> #include <algorithm> +#include <array> #include <cassert> #include <functional> #include <iterator> @@ -27,6 +30,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 +43,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 +107,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 +122,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 +130,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 +138,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 +181,8 @@ void basic_tests() } } -int main(int, char**) +TEST_CONSTEXPR_CXX20 bool +test() { basic_tests(); @@ -152,5 +194,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..44abb822ea27 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 @@ -8,7 +8,9 @@ // <numeric> // UNSUPPORTED: c++03, c++11, c++14 +// UNSUPPORTED: clang-8 +// Became constexpr in C++20 // template <class InputIterator1, class T, // class BinaryOperation, class UnaryOperation> // T transform_reduce(InputIterator1 first1, InputIterator1 last1, @@ -41,7 +43,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 +52,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 +78,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 +96,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 +124,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..4b9d210597f2 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 @@ -8,7 +8,9 @@ // <numeric> // UNSUPPORTED: c++03, c++11, c++14 +// UNSUPPORTED: clang-8 +// 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 +25,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 +34,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 +53,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 +70,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 +110,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..73b110e2c7df 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 @@ -8,7 +8,9 @@ // <numeric> // UNSUPPORTED: c++03, c++11, c++14 +// UNSUPPORTED: clang-8 +// 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 +27,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 +36,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 +55,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 +74,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 +114,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 @@ -375,6 +375,10 @@ feature_test_macros = sorted([ add_version_header(x) for x in [ "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) }, "headers": ["functional"], |