GCC Code Coverage Report


Directory: include/polyfloat/
File: include/polyfloat/module/core/rem.hpp
Date: 2026-11-09 15:28:50
Exec Total Coverage
Lines: 9 9 100.0%
Functions: 42 42 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/trunc.hpp>
15 #include <polyfloat/module/core/nearest.hpp>
16 #include <polyfloat/module/core/ceil.hpp>
17 #include <polyfloat/module/core/floor.hpp>
18
19 namespace plf
20 {
21
22 template<typename Options>
23 struct rem_t : eve::strict_tuple_callable<rem_t,
24 Options,
25 raw_option,
26 pedantic_option,
27 to_nearest_option,
28 toward_zero_option,
29 downward_option,
30 upward_option>
31 {
32 template<concepts::polyfloat_like Z1, concepts::polyfloat_like Z2>
33 44 POLYFLOAT_ABI constexpr as_polyfloat_like_t<Z1, Z2> operator()(Z1 z1, Z2 z2) const noexcept
34 {
35 44 return POLYFLOAT_CALL(z1, z2);
36 }
37
38 44 POLYFLOAT_CALLABLE_OBJECT(rem_t, rem_);
39 };
40 //======================================================================================================================
41 //! @addtogroup core
42 //! @{
43 //! @var rem
44 //! @brief return the remender after division of the values.
45 //!
46 //! @groupheader{Header file}
47 //!
48 //! @code
49 //! #include <polyfloat/core.hpp>
50 //! @endcode
51 //!
52 //! @groupheader{Callable Signatures}
53 //!
54 //! @code
55 //! namespace polyfloat
56 //! {
57 //! template<polyfloat::concepts::polyfloat_like T1, polyfloat_like T2> constexpr auto rem(T1 x, T2 y) noexcept; //1
58 //!
59 //! // Semantic exclusive options
60 //! constexpr auto rem[upward](/*any of the above overloads*/) noexcept; // 2
61 //! constexpr auto rem[downward](/*any of the above overloads*/) noexcept; // 2
62 //! constexpr auto rem[toward_zero](/*any of the above overloads*/) noexcept; // 2
63 //! constexpr auto rem[to_nearest](/*any of the above overloads*/) noexcept; // 2
64 //! }
65 //! @endcode
66 //!
67 //! **Parameters**
68 //!
69 //! * `z1`, `z2`: Values to process.
70 //!
71 //! **Return value**
72 //!
73 //! 1. Return the remainder after division of `x` by `y` and is
74 //! equivalent to `x-div[toward_zero](x, y)*y`.
75 //! 2. The call is equivalent to `x-div[o](x, y)*y` where `o` is the chosen option.
76 //!
77 //!
78 //! @groupheader{Example}
79 //!
80 //! @godbolt_todo{doc/core/rem.cpp}
81 //======================================================================================================================
82
83 inline constexpr auto rem = eve::functor<rem_t>;
84 //======================================================================================================================
85 //! @}
86 //======================================================================================================================
87 }
88
89 namespace plf::_
90 {
91 template<typename T0, typename T1, eve::callable_options O>
92 44 constexpr auto rem_(POLYFLOAT_DELAY(), O const& o, T0 const& a, T1 const& b) noexcept
93 {
94 if constexpr (O::contains(to_nearest))
95 {
96 4 return if_else(plf::is_eqz(b) || plf::is_unordered(a, b),
97 4 plf::if_else(plf::is_eqz(a) || plf::is_infinite(b), a, nan(as(a))),
98 8 plf::fnma(b, plf::div[to_nearest](a, b), a)); // as remainder
99 }
100 else if constexpr (O::contains(upward) || O::contains(downward))
101 {
102 return plf::fnma(b, eve::div[o](a, b), a);
103 }
104 else
105 {
106 40 return plf::if_else(plf::is_unordered(a, b) || plf::is_infinite(a) || plf::is_eqz(b), plf::nan(as(a)),
107 80 plf::if_else(is_eqz(a), a, plf::fnma(b, plf::div[toward_zero](a, b), a)));
108 }
109 }
110 }
111