tetl 0.1.0
Embedded Template Library
Loading...
Searching...
No Matches
copysign.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: BSL-1.0
2// SPDX-FileCopyrightText: Copyright (C) 2020 Tobias Hienzsch
3
4#ifndef TETL_CMATH_COPYSIGN_HPP
5#define TETL_CMATH_COPYSIGN_HPP
6
7#include <etl/_config/all.hpp>
8
9#include <etl/_type_traits/is_constant_evaluated.hpp>
10#include <etl/_type_traits/is_same.hpp>
11
12namespace etl {
13
14namespace detail {
15template <typename T>
16constexpr auto copysign_fallback(T x, T y) noexcept -> T
17{
18 if ((x < 0 and y > 0) or (x > 0 and y < 0)) {
19 return -x;
20 }
21 return x;
22}
23
24template <typename T>
25[[nodiscard]] constexpr auto copysign(T x, T y) noexcept -> T
26{
28 if constexpr (is_same_v<T, float>) {
29#if __has_builtin(__builtin_copysignf)
30 return __builtin_copysignf(x, y);
31#endif
32 }
33 if constexpr (is_same_v<T, double>) {
34#if __has_builtin(__builtin_copysign)
35 return __builtin_copysign(x, y);
36#endif
37 }
38 }
39 return copysign_fallback(x, y);
40}
41
42} // namespace detail
43
44/// \ingroup cmath
45/// @{
46
47/// Composes a floating point value with the magnitude of mag and the sign of sgn.
48///
49/// \details etl::copysign is the only portable way to manipulate the sign of a
50/// NaN value (to examine the sign of a NaN, signbit may also be used)
51///
52/// https://en.cppreference.com/w/cpp/numeric/math/copysign
53///
54/// \returns If no errors occur, the floating point value with the magnitude of
55/// mag and the sign of sgn is returned. If mag is NaN, then NaN with the sign
56/// of sgn is returned. If sgn is -0, the result is only negative if the
57/// implementation supports the signed zero consistently in arithmetic
58/// operations.
59[[nodiscard]] constexpr auto copysign(float mag, float sgn) -> float
60{
61 return detail::copysign(mag, sgn);
62}
63[[nodiscard]] constexpr auto copysignf(float mag, float sgn) -> float
64{
65 return detail::copysign(mag, sgn);
66}
67[[nodiscard]] constexpr auto copysign(double mag, double sgn) -> double
68{
69 return detail::copysign(mag, sgn);
70}
71[[nodiscard]] constexpr auto copysign(long double mag, long double sgn) -> long double
72{
73 return detail::copysign(mag, sgn);
74}
75
76[[nodiscard]] constexpr auto copysignl(long double mag, long double sgn) -> long double
77{
78 return detail::copysign(mag, sgn);
79}
80
81/// @}
82
83} // namespace etl
84
85#endif // TETL_CMATH_COPYSIGN_HPP
constexpr auto copysign(long double mag, long double sgn) -> long double
Definition copysign.hpp:71
constexpr auto copysign(float mag, float sgn) -> float
Definition copysign.hpp:59
constexpr auto copysignf(float mag, float sgn) -> float
Definition copysign.hpp:63
constexpr auto copysignl(long double mag, long double sgn) -> long double
Definition copysign.hpp:76
constexpr auto copysign(double mag, double sgn) -> double
Definition copysign.hpp:67
Definition adjacent_find.hpp:9
constexpr auto is_constant_evaluated() noexcept -> bool
Detects whether the function call occurs within a constant-evaluated context. Returns true if the eva...
Definition is_constant_evaluated.hpp:17