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 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 @@ -8,10 +8,11 @@ // +// Became constexpr in C++20 // template // requires HasPlus // && HasAssign::result_type> -// T +// constexpr T // accumulate(Iter first, Iter last, T init); #include @@ -20,36 +21,71 @@ #include "test_macros.h" #include "test_iterators.h" +#if _LIBCPP_STD_VER > 17 +template +constexpr T +constexpr_test(Iter first, Iter last, T init) +{ + return std::accumulate(first, last, init); +} + +template +constexpr void +constexpr_test() +{ + constexpr const int ia[] = {1, 2, 3, 4, 5, 6}; + constexpr unsigned sa = sizeof(ia) / sizeof(ia[0]); + + static_assert(constexpr_test(Iter(ia), Iter(ia), 0) == 0); + static_assert(constexpr_test(Iter(ia), Iter(ia), 10) == 10); + static_assert(constexpr_test(Iter(ia), Iter(ia + 1), 0) == 1); + static_assert(constexpr_test(Iter(ia), Iter(ia + 1), 10) == 11); + static_assert(constexpr_test(Iter(ia), Iter(ia + 2), 0) == 3); + static_assert(constexpr_test(Iter(ia), Iter(ia + 2), 10) == 13); + static_assert(constexpr_test(Iter(ia), Iter(ia + sa), 0) == 21); + static_assert(constexpr_test(Iter(ia), Iter(ia + sa), 10) == 31); +} +#endif + template void -test(Iter first, Iter last, T init, T x) +runtime_test(Iter first, Iter last, T init, T x) { assert(std::accumulate(first, last, init) == x); } template void -test() +runtime_test() { int ia[] = {1, 2, 3, 4, 5, 6}; unsigned sa = sizeof(ia) / sizeof(ia[0]); - test(Iter(ia), Iter(ia), 0, 0); - test(Iter(ia), Iter(ia), 10, 10); - test(Iter(ia), Iter(ia+1), 0, 1); - test(Iter(ia), Iter(ia+1), 10, 11); - test(Iter(ia), Iter(ia+2), 0, 3); - test(Iter(ia), Iter(ia+2), 10, 13); - test(Iter(ia), Iter(ia+sa), 0, 21); - test(Iter(ia), Iter(ia+sa), 10, 31); + + runtime_test(Iter(ia), Iter(ia), 0, 0); + runtime_test(Iter(ia), Iter(ia), 10, 10); + runtime_test(Iter(ia), Iter(ia+1), 0, 1); + runtime_test(Iter(ia), Iter(ia+1), 10, 11); + runtime_test(Iter(ia), Iter(ia+2), 0, 3); + runtime_test(Iter(ia), Iter(ia+2), 10, 13); + runtime_test(Iter(ia), Iter(ia+sa), 0, 21); + runtime_test(Iter(ia), Iter(ia+sa), 10, 31); } int main(int, char**) { - test >(); - test >(); - test >(); - test >(); - test(); +#if _LIBCPP_STD_VER > 17 + constexpr_test >(); + constexpr_test >(); + constexpr_test >(); + constexpr_test >(); + constexpr_test(); +#endif + + runtime_test >(); + runtime_test >(); + runtime_test >(); + runtime_test >(); + runtime_test(); 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 Belfast