GCC Code Coverage Report


Directory: include/polyfloat/
File: include/polyfloat/module/core/add.hpp
Date: 2026-11-09 15:28:50
Exec Total Coverage
Lines: 15 15 100.0%
Functions: 233 233 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_not_finite.hpp>
15
16 namespace plf
17 {
18
19 template<typename Options> struct add_t : eve::strict_tuple_callable<add_t, Options, raw_option, pedantic_option>
20 {
21 template<typename... Ts> struct result : as_polyfloat_like<Ts...>
22 {
23 };
24
25 template<concepts::polyfloat_like... Ts>
26 requires(eve::same_lanes_or_scalar<Ts...>)
27 143217 POLYFLOAT_ABI typename result<Ts...>::type constexpr operator()(Ts... ts) const noexcept
28 {
29 143217 return POLYFLOAT_CALL(ts...);
30 }
31
32 template<eve::non_empty_product_type Tup>
33 requires(eve::same_lanes_or_scalar_tuple<Tup> && !concepts::polyfloat_like<Tup>)
34 29 POLYFLOAT_ABI constexpr kumi::apply_traits_t<result, Tup> operator()(Tup const& t) const noexcept
35 requires(kumi::size_v<Tup> >= 1)
36 {
37 29 return POLYFLOAT_CALL(t);
38 }
39
40 139727 POLYFLOAT_CALLABLE_OBJECT(add_t, add_);
41 };
42 //======================================================================================================================
43 //! @addtogroup core
44 //! @{
45 //! @var add
46 //! @brief return the sum of the parameters.
47 //!
48 //! @groupheader{Header file}
49 //!
50 //! @code
51 //! #include <polyfloat/core.hpp>
52 //! @endcode
53 //!
54 //! @groupheader{Callable Signatures}
55 //!
56 //! @code
57 //! namespace polyfloat
58 //! {
59 //! template<polyfloat::concepts::polyfloat_like Z1, polyfloat_like ... Zs> constexpr auto add(Z1 z1, Zs... zs) noexcept;
60 //! }
61 //! @endcode
62 //!
63 //! **Parameters**
64 //!
65 //! * `z1`, `zs...`: Values to process.
66 //!
67 //! **Return value**
68 //!
69 //! Returns the sum of the arguments.
70 //!
71 //! @groupheader{Example}
72 //!
73 //! @godbolt{doc/core/add.cpp}
74 //======================================================================================================================
75
76 inline constexpr auto add = eve::functor<add_t>;
77 //======================================================================================================================
78 //! @}
79 //======================================================================================================================
80
81 57 template<typename Options> constexpr auto neutral(add_t<Options>) noexcept
82 {
83 57 return plf::zero;
84 }
85
86 // Required for optimisation detections
87 using callable_add_ = eve::tag_t<add>;
88
89 }
90
91 namespace plf::_
92 {
93 template<typename T0, eve::callable_options O> constexpr auto add_(POLYFLOAT_DELAY(), O const&, T0 t0) noexcept
94 {
95 return t0;
96 }
97 template<typename T1, typename T2, eve::callable_options O>
98 139539 constexpr auto add_(POLYFLOAT_DELAY(), O const&, T1 const& t1, T2 const& t2) noexcept
99 {
100 139539 auto t12 = t1 + t2;
101 // if constexpr(O::contains(pedantic))
102 // {
103 // auto inf = plf::is_not_finite(t1) || plf::is_not_finite(t2);
104 // if (eve::any(inf))
105 // {
106 // return if_else(inf, plf::hi(t1)+plf::hi(t2), t12);
107 // }
108 // else
109 // return t12;
110 // }
111 // else
112 139539 return t12;
113 }
114
115 template<eve::callable_options O,
116 concepts::polyfloat_like T0,
117 concepts::polyfloat_like T1,
118 concepts::polyfloat_like... Ts>
119 183 constexpr auto add_(POLYFLOAT_DELAY(), O const& o, T0 const& t0, T1 const& t1, Ts const&... ts) noexcept
120 {
121 using t_t = as_polyfloat_t<T0, T1, Ts...>;
122 if constexpr (concepts::real<t_t>) return eve::add[o](t0, t1, ts...);
123 else
124 {
125 using u_t = eve::element_type_t<t_t>;
126 297 auto cvt = [](auto a) { return plf::convert(a, as<u_t>()); };
127 183 auto p0 = add[o](cvt(t0), cvt(t1));
128 183 ((p0 = add[o](p0, cvt(ts))), ...);
129 183 return p0;
130 }
131 }
132
133 }
134