GCC Code Coverage Report


Directory: include/polyfloat/
File: include/polyfloat/module/core/fmod.hpp
Date: 2026-11-09 15:28:50
Exec Total Coverage
Lines: 9 9 100.0%
Functions: 28 28 100.0%
Branches: 0 0 -%

Line Branch Exec Source
1 //======================================================================================================================
2 /*
3 POLYFLOAT - Extended precision floating points
4 Copyright : POLYFLOAT Contributors & Maintainers
5 SPDX-License-Identifier: BSL-1.0
6 */
7 //======================================================================================================================
8 #pragma once
9
10 #include <polyfloat/details/callable.hpp>
11 #include <polyfloat/types/concepts.hpp>
12 #include <polyfloat/types/traits.hpp>
13 #include <type_traits>
14 #include <polyfloat/module/core/is_unordered.hpp>
15 #include <polyfloat/module/core/is_infinite.hpp>
16 #include <polyfloat/module/core/is_eqz.hpp>
17
18 namespace plf
19 {
20
21 template<typename Options>
22 struct fmod_t : plf::strict_tuple_callable<fmod_t, eve::fmod_t, Options, raw_option, pedantic_option>
23 {
24 template<concepts::polyfloat_like Z1, concepts::polyfloat_like Z2>
25 26 POLYFLOAT_ABI constexpr as_polyfloat_like_t<Z1, Z2> operator()(Z1 z1, Z2 z2) const noexcept
26 {
27 26 return POLYFLOAT_CALL(z1, z2);
28 }
29
30 24 POLYFLOAT_CALLABLE_OBJECT(fmod_t, fmod_);
31 };
32 //======================================================================================================================
33 //! @addtogroup core
34 //! @{
35 //! @var fmod
36 //! @brief return the remainder of the values.
37 //!
38 //! @groupheader{Header file}
39 //!
40 //! @code
41 //! #include <polyfloat/core.hpp>
42 //! @endcode
43 //!
44 //! @groupheader{Callable Signatures}
45 //!
46 //!
47 //! @code
48 //! namespace plf
49 //! {
50 //! // Regular overload
51 //! constexpr auto fmod(floating_value auto x, floating_value auto y) noexcept; // 1
52 //!
53 //! // Lanes masking
54 //! constexpr auto fmod[conditional_expr auto c](floating_value auto x, floating_value auto y) noexcept; // 2
55 //! constexpr auto fmod[logical_value auto m](floating_value auto x, floating_value auto y) noexcept; // 2
56 //! }
57 //! @endcode
58 //!
59 //! **Parameters**
60 //!
61 //! * `x`, `y`: `floating_value` argumentx.
62 //! * `c`: `conditional_expr` masking the operation.
63 //! * `m`: `logical_value` masking the operation.
64 //!
65 //! **Return value**
66 //!
67 //! 1. Returns the remainder after division division of `x` by `y` and mimick
68 //! the behaviour of std::fmod. In particular:
69 //! * If `x` is \f$\pm0\f$, \f$\pm0\f$ is returned.
70 //! * If `x` is \f$\pm\inf\f$ or `NaN`, `NaN` is returned.
71 //! * If `y` is \f$\pm0\f$, `NaN` is returned.
72 //! * If `y` is \f$\pm\inf\f$ and `x` is finite, `x`is returned.
73 //! 2. [The operation is performed conditionnaly](@ref conditional).
74 //!
75 //! @groupheader{External references}
76 //! * [C++ standard reference](https://en.cppreference.com/w/cpp/numeric/math/fmod)
77 //!
78 //! @groupheader{Example}
79 //!
80 //! @godbolt{doc/core/fmod.cpp}
81 //======================================================================================================================
82
83 inline constexpr auto fmod = eve::functor<fmod_t>;
84 //======================================================================================================================
85 //! @}
86 //======================================================================================================================
87 }
88
89 namespace plf::_
90 {
91 template<typename Z1, typename Z2, eve::callable_options O>
92 24 constexpr auto fmod_(POLYFLOAT_DELAY(), O const&, Z1 const& aa, Z2 const& bb) noexcept
93 {
94 using plf_t = as_polyfloat_t<Z1, Z2>;
95 using u_t = eve::element_type_t<plf_t>;
96 24 auto cvt = [](auto a) { return plf::convert(a, as<u_t>()); };
97 24 auto a = cvt(aa);
98 24 auto b = cvt(bb);
99 24 return if_else(is_unordered(a, b) || is_infinite(a) || is_eqz(b), eve::allbits,
100 48 plf::if_else(is_eqz(a) || is_infinite(b), a, fnma(b, div[toward_zero](a, b), a)));
101 }
102 }
103