Index: libcxx/docs/FeatureTestMacroTable.rst =================================================================== --- libcxx/docs/FeatureTestMacroTable.rst +++ libcxx/docs/FeatureTestMacroTable.rst @@ -196,6 +196,8 @@ ------------------------------------------------- ----------------- ``__cpp_lib_constexpr_misc`` *unimplemented* ------------------------------------------------- ----------------- + ``__cpp_lib_constexpr_numeric`` ``201911L`` + ------------------------------------------------- ----------------- ``__cpp_lib_constexpr_swap_algorithms`` *unimplemented* ------------------------------------------------- ----------------- ``__cpp_lib_constexpr_utility`` ``201811L`` Index: libcxx/include/numeric =================================================================== --- libcxx/include/numeric +++ libcxx/include/numeric @@ -17,7 +17,7 @@ { template - T + constexpr T // constexpr since C++20 accumulate(InputIterator first, InputIterator last, T init); template @@ -158,7 +158,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _Tp accumulate(_InputIterator __first, _InputIterator __last, _Tp __init) { Index: libcxx/include/version =================================================================== --- libcxx/include/version +++ libcxx/include/version @@ -48,6 +48,7 @@ __cpp_lib_constexpr_dynamic_alloc 201907L __cpp_lib_constexpr_misc 201811L +__cpp_lib_constexpr_numeric 201911L __cpp_lib_constexpr_swap_algorithms 201806L __cpp_lib_constexpr_utility 201811L __cpp_lib_destroying_delete 201806L @@ -253,6 +254,7 @@ // # 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 Index: libcxx/test/std/language.support/support.limits/support.limits.general/numeric.version.pass.cpp =================================================================== --- libcxx/test/std/language.support/support.limits/support.limits.general/numeric.version.pass.cpp +++ 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 /* 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 Index: libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp =================================================================== --- libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp +++ 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] @@ -226,6 +227,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 @@ -614,6 +619,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 @@ -1116,6 +1125,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 @@ -1897,6 +1910,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" Index: libcxx/test/std/numerics/numeric.ops/accumulate/accumulate.pass.cpp =================================================================== --- libcxx/test/std/numerics/numeric.ops/accumulate/accumulate.pass.cpp +++ libcxx/test/std/numerics/numeric.ops/accumulate/accumulate.pass.cpp @@ -21,14 +21,14 @@ #include "test_iterators.h" template -void +TEST_CONSTEXPR_CXX20 void test(Iter first, Iter last, T init, T x) { assert(std::accumulate(first, last, init) == x); } template -void +TEST_CONSTEXPR_CXX20 void test() { int ia[] = {1, 2, 3, 4, 5, 6}; @@ -43,7 +43,7 @@ test(Iter(ia), Iter(ia+sa), 10, 31); } -int main(int, char**) +TEST_CONSTEXPR_CXX20 bool test() { test >(); test >(); @@ -51,5 +51,14 @@ test >(); test(); - return 0; + return true; +} + +int main(int, char**) +{ + test(); +#if TEST_STD_VER > 17 + static_assert(test()); +#endif + return 0; } Index: libcxx/test/std/numerics/numeric.ops/exclusive.scan/exclusive_scan.pass.cpp =================================================================== --- libcxx/test/std/numerics/numeric.ops/exclusive.scan/exclusive_scan.pass.cpp +++ libcxx/test/std/numerics/numeric.ops/exclusive.scan/exclusive_scan.pass.cpp @@ -9,6 +9,7 @@ // // UNSUPPORTED: c++03, c++11, c++14 +// Became constexpr in C++20 // template // OutputIterator exclusive_scan(InputIterator first, InputIterator last, // OutputIterator result, T init); @@ -16,34 +17,48 @@ #include #include +#include #include #include #include +#if TEST_STD_VER > 17 +#include +#endif #include #include "test_macros.h" #include "test_iterators.h" template -void +TEST_CONSTEXPR_CXX20 void test(Iter1 first, Iter1 last, T init, Iter2 rFirst, Iter2 rLast) { - std::vector::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. + size_t size = std::distance(first, last); +#if TEST_STD_VER < 20 || \ + (defined(__cpp_lib_constexpr_vector) && __cpp_lib_constexpr_vector >= 201907L) + + std::vector::value_type> v(size); +#else + assert((size <= 5) && "Increment the size of the array"); + typename std::iterator_traits::value_type b[5]; + std::span::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 -void +TEST_CONSTEXPR_CXX20 void test() { int ia[] = {1, 3, 5, 7, 9}; @@ -55,13 +70,14 @@ 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 v(10); + std::array 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 +85,7 @@ } { - std::vector v(10); + std::array 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 +93,7 @@ } { - std::vector v(10); + std::array 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 +102,8 @@ } -int main(int, char**) +TEST_CONSTEXPR_CXX20 bool +test() { basic_tests(); @@ -98,5 +115,14 @@ test(); test< int*>(); - return 0; + return true; +} + +int main(int, char**) +{ + test(); +#if TEST_STD_VER > 17 + static_assert(test()); +#endif + return 0; } Index: libcxx/utils/generate_feature_test_macro_components.py =================================================================== --- libcxx/utils/generate_feature_test_macro_components.py +++ libcxx/utils/generate_feature_test_macro_components.py @@ -374,6 +374,10 @@ "values": { "c++2a": int(201811) }, "headers": ["array", "functional", "iterator", "string_view", "tuple", "utility"], "unimplemented": True, + }, { + "name": "__cpp_lib_constexpr_numeric", + "values": { "c++2a": int(201911) }, + "headers": ["numeric"], }, { "name": "__cpp_lib_bind_front", "values": { "c++2a": int(201811) }, Index: libcxx/www/cxx2a_status.html =================================================================== --- libcxx/www/cxx2a_status.html +++ libcxx/www/cxx2a_status.html @@ -198,7 +198,7 @@ P1394LWGRange constructor for std::span Belfast P1456LWGMove-only views Belfast P1622LWGMandating the Standard Library: Clause 32 - Thread support library Belfast - P1645LWGconstexpr for numeric algorithms Belfast + P1645LWGconstexpr for numeric algorithms BelfastComplete12.0 P1664LWGreconstructible_range - a concept for putting ranges back together Belfast P1686LWGMandating the Standard Library: Clause 27 - Time library Belfast P1690LWGRefinement Proposal for P0919 Heterogeneous lookup for unordered containers BelfastComplete12.0