public inbox for libstdc++-cvs@sourceware.org help / color / mirror / Atom feed
From: Jonathan Wakely <redi@gcc.gnu.org> To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc r11-9113] libstdc++: Add additional overload of std::lerp [PR101870] Date: Tue, 12 Oct 2021 10:59:33 +0000 (GMT) [thread overview] Message-ID: <20211012105933.81C653857C51@sourceware.org> (raw) https://gcc.gnu.org/g:371e12a7fd0295251340eabae77dd060577054c3 commit r11-9113-g371e12a7fd0295251340eabae77dd060577054c3 Author: Jonathan Wakely <jwakely@redhat.com> Date: Thu Aug 12 17:35:25 2021 +0100 libstdc++: Add additional overload of std::lerp [PR101870] The [cmath.syn] p1 wording about additional overloads sufficient to handle any arithmetic types also applies to std::lerp. This adds a new overload of std::lerp that does the required promotions to support arguments of arbitrary arithmetic types. A new __promoted_t alias template is added, which the C++17 function templates std::hypot and std::lerp can use to avoid instantiating the __promote_3 class template. Signed-off-by: Jonathan Wakely <jwakely@redhat.com> libstdc++-v3/ChangeLog: PR libstdc++/101870 * include/c_global/cmath (hypot): Use __promoted_t. (lerp): Add new overload accepting any arithmetic types. * include/ext/type_traits.h (__promoted_t): New alias template. * testsuite/26_numerics/lerp.cc: Moved to... * testsuite/26_numerics/lerp/1.cc: ...here. * testsuite/26_numerics/lerp/constexpr.cc: New test. * testsuite/26_numerics/lerp/version.cc: New test. (cherry picked from commit 9017326e19fe278d5f62898cca4682b17f8e8e07) Diff: --- libstdc++-v3/include/c_global/cmath | 16 ++++++++++++---- libstdc++-v3/include/ext/type_traits.h | 8 +++++++- .../testsuite/26_numerics/{lerp.cc => lerp/1.cc} | 0 .../testsuite/26_numerics/lerp/constexpr.cc | 21 +++++++++++++++++++++ libstdc++-v3/testsuite/26_numerics/lerp/version.cc | 10 ++++++++++ 5 files changed, 50 insertions(+), 5 deletions(-) diff --git a/libstdc++-v3/include/c_global/cmath b/libstdc++-v3/include/c_global/cmath index 39a6b036b8c..3233228fdee 100644 --- a/libstdc++-v3/include/c_global/cmath +++ b/libstdc++-v3/include/c_global/cmath @@ -1844,7 +1844,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif // _GLIBCXX_USE_C99_MATH_TR1 #endif // C++11 -#if __cplusplus > 201402L +#if __cplusplus >= 201703L // [c.math.hypot3], three-dimensional hypotenuse #define __cpp_lib_hypot 201603 @@ -1877,15 +1877,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return std::__hypot3<long double>(__x, __y, __z); } template<typename _Tp, typename _Up, typename _Vp> - typename __gnu_cxx::__promote_3<_Tp, _Up, _Vp>::__type + __gnu_cxx::__promoted_t<_Tp, _Up, _Vp> hypot(_Tp __x, _Up __y, _Vp __z) { - using __type = typename __gnu_cxx::__promote_3<_Tp, _Up, _Vp>::__type; + using __type = __gnu_cxx::__promoted_t<_Tp, _Up, _Vp>; return std::__hypot3<__type>(__x, __y, __z); } #endif // C++17 -#if __cplusplus > 201703L +#if __cplusplus >= 202002L // linear interpolation # define __cpp_lib_interpolate 201902L @@ -1918,6 +1918,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr long double lerp(long double __a, long double __b, long double __t) noexcept { return std::__lerp(__a, __b, __t); } + + template<typename _Tp, typename _Up, typename _Vp> + constexpr __gnu_cxx::__promoted_t<_Tp, _Up, _Vp> + lerp(_Tp __x, _Up __y, _Vp __z) noexcept + { + using __type = __gnu_cxx::__promoted_t<_Tp, _Up, _Vp>; + return std::__lerp<__type>(__x, __y, __z); + } #endif // C++20 _GLIBCXX_END_NAMESPACE_VERSION diff --git a/libstdc++-v3/include/ext/type_traits.h b/libstdc++-v3/include/ext/type_traits.h index ff067c83f62..065edb4e9a5 100644 --- a/libstdc++-v3/include/ext/type_traits.h +++ b/libstdc++-v3/include/ext/type_traits.h @@ -163,7 +163,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return true; } #endif - // For complex and cmath + // For arithmetic promotions in <complex> and <cmath> + template<typename _Tp, bool = std::__is_integer<_Tp>::__value> struct __promote { typedef double __type; }; @@ -187,6 +188,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __promote<float> { typedef float __type; }; +#if __cpp_fold_expressions + template<typename... _Tp> + using __promoted_t = decltype((typename __promote<_Tp>::__type(0) + ...)); +#endif + template<typename _Tp, typename _Up, typename _Tp2 = typename __promote<_Tp>::__type, typename _Up2 = typename __promote<_Up>::__type> diff --git a/libstdc++-v3/testsuite/26_numerics/lerp.cc b/libstdc++-v3/testsuite/26_numerics/lerp/1.cc similarity index 100% rename from libstdc++-v3/testsuite/26_numerics/lerp.cc rename to libstdc++-v3/testsuite/26_numerics/lerp/1.cc diff --git a/libstdc++-v3/testsuite/26_numerics/lerp/constexpr.cc b/libstdc++-v3/testsuite/26_numerics/lerp/constexpr.cc new file mode 100644 index 00000000000..f1ab42b5a42 --- /dev/null +++ b/libstdc++-v3/testsuite/26_numerics/lerp/constexpr.cc @@ -0,0 +1,21 @@ +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +#include <cmath> + +// Fails template argument deduction unless both arguments are the same type. +template<typename T> +constexpr bool +eq(T result, T expected) { return result == expected; } + +static_assert( eq( std::lerp(-10.0, 10.0, 0.25), -5.0 ) ); +static_assert( eq( std::lerp(2.0f, 2.0f, 200.0f), 2.0f ) ); +static_assert( eq( std::lerp(2.0L, 4.0L, 200.0L), 402.0L ) ); +// at least one type is long double, so result is long double +static_assert( eq( std::lerp(2.0L, 4.0f, -20.0), -38.0L ) ); +// at least one type is double, so result is double: +static_assert( eq( std::lerp(-8.0f, 10.0, 0.5f), 1.0 ) ); +// int promotes to double, so result is double +static_assert( eq( std::lerp(0, 1, 0), 0.0 ) ); +// int promotes to double, so result is double +static_assert( eq( std::lerp(2.0f, -10.0f, 1), -10.0 ) ); diff --git a/libstdc++-v3/testsuite/26_numerics/lerp/version.cc b/libstdc++-v3/testsuite/26_numerics/lerp/version.cc new file mode 100644 index 00000000000..3ccb032bc67 --- /dev/null +++ b/libstdc++-v3/testsuite/26_numerics/lerp/version.cc @@ -0,0 +1,10 @@ +// { dg-options "-std=gnu++2a" } +// { dg-do preprocess { target c++2a } } + +#include <version> + +#ifndef __cpp_lib_interpolate +# error "Feature-test macro for midpoint and lerp missing in <version>" +#elif __cpp_lib_interpolate != 201902L +# error "Feature-test macro for midpoint and lerp has wrong value in <version>" +#endif
reply other threads:[~2021-10-12 10:59 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20211012105933.81C653857C51@sourceware.org \ --to=redi@gcc.gnu.org \ --cc=gcc-cvs@gcc.gnu.org \ --cc=libstdc++-cvs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).