GCC Code Coverage Report


Directory: include/polyfloat/
File: include/polyfloat/types/polyfloat.hpp
Date: 2026-11-09 15:28:50
Exec Total Coverage
Lines: 26 26 100.0%
Functions: 48 48 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 <eve/eve.hpp>
11 #include <polyfloat/details/abi.hpp>
12 #include <polyfloat/details/helpers.hpp>
13 #include <polyfloat/types/concepts.hpp>
14 #include <polyfloat/types/traits.hpp>
15 #include <polyfloat/details/inner_graillat.hpp>
16
17 namespace plf
18 {
19 //====================================================================================================================
20 //! @addtogroup types
21 //! @{
22 //====================================================================================================================
23
24 //====================================================================================================================
25 //! @class polyfloat
26 //! @brief representing an extended precision floating point by a sequence of standards ones
27 //====================================================================================================================
28 template<eve::floating_scalar_value Type, unsigned int N>
29 requires(N > 1 && N <= _::MAX_N)
30 struct polyfloat
31 {
32 using underlying_type = Type;
33 using is_polyfloat = void;
34 using ptype_t = polyfloat<Type, N>;
35
36 static constexpr auto static_dimension = N;
37 using data_type = kumi::result::fill_t<static_dimension, Type>;
38
39 /// Default Poly-Float constructor
40 6700 constexpr polyfloat() noexcept : contents{} {}
41
42 /// Construct a Poly-Float from a real value of the base type
43 55365087 constexpr polyfloat(Type v) noexcept : contents{} { kumi::get<0>(contents) = v; }
44
45 /// Construct a Poly-Float from a real value of another type
46 83784 template<eve::floating_scalar_value T> constexpr polyfloat(T v) noexcept : contents{}
47 {
48 using elt_t = eve::element_type_t<T>;
49 using elt_type = eve::element_type_t<Type>;
50 7 if constexpr (sizeof(elt_t) <= sizeof(elt_type)) kumi::get<0>(contents) = v;
51 else
52 {
53 83777 auto h = eve::convert(v, eve::as<elt_type>());
54 83777 kumi::get<0>(contents) = h;
55 83777 auto hc = eve::convert(h, eve::as<elt_t>());
56 83777 auto m = eve::convert(v - hc, eve::as<elt_type>());
57 83777 kumi::get<1>(contents) = m;
58 if constexpr (N == 3)
59 {
60 75932 auto l = eve::convert(v - (hc + eve::convert(m, eve::as<elt_t>())), eve::as<elt_type>());
61 75932 kumi::get<2>(contents) = l;
62 }
63 }
64 83784 }
65
66 /// Construct a Poly-Float instance from a pair of real values
67 template<std::convertible_to<Type> T0, std::convertible_to<Type> T1>
68 requires(2 <= static_dimension)
69 4543768 constexpr polyfloat(T0 v0, T1 v1) noexcept
70 : contents(
71 9087536 kumi::cat(eve::two_add[pedantic](static_cast<Type>(v0), static_cast<Type>(v1)), kumi::fill<(N - 2)>(Type{0})))
72 {
73 4543768 }
74
75 /// Construct a Poly-Float instance from a triple of real values
76 template<std::convertible_to<Type> T0, std::convertible_to<Type> T1, std::convertible_to<Type> T2>
77 requires(3 <= static_dimension)
78 268462 constexpr polyfloat(T0 v0, T1 v1, T2 v2) noexcept
79 268462 : contents(plf::_::inner_three_add(static_cast<Type>(v0), static_cast<Type>(v1), static_cast<Type>(v2)))
80 {
81 268462 }
82
83 /// Construct a Poly-Float instance from a properly sized product_type supposed normalized
84 29676952 constexpr polyfloat(eve::sized_product_type<N> auto const& vs) : contents{vs} {}
85
86 /// Constructs a Poly-Float instance from an Poly-Float of smaller dimension
87 template<unsigned int M>
88 requires(M > 1 && M <= N)
89 2 constexpr polyfloat(polyfloat<Type, M> const& a) noexcept
90 requires(N > 1)
91 4 : contents(kumi::cat(a.contents, kumi::fill<N - M>(Type{0})))
92 {
93 2 }
94
95 /// Assign a smaller Poly-Float to another
96 template<concepts::polyfloat T>
97 constexpr polyfloat& operator=(T const& a) noexcept
98 requires(T::static_dimension < N)
99 {
100 return (*this = polyfloat{a});
101 }
102
103 //==================================================================================================================
104 // ++/--
105 //==================================================================================================================
106
107 //! Pre-incrementation operator
108 POLYFLOAT_ABI auto& operator++() noexcept
109 {
110 kumi::get<0>(contents)++;
111 return *this;
112 };
113
114 //! Pre-decrementation operator
115 POLYFLOAT_ABI auto& operator--() noexcept
116 {
117 kumi::get<0>(contents)--;
118 return *this;
119 }
120
121 //! Post-incrementation operator
122 POLYFLOAT_ABI auto operator++(int) noexcept
123 {
124 auto that(*this);
125 this->operator++();
126 return that;
127 }
128
129 //! Post-decrementation operator
130 POLYFLOAT_ABI auto operator--(int) noexcept
131 {
132 auto that(*this);
133 this->operator--();
134 return that;
135 }
136
137 data_type contents;
138 };
139
140 //====================================================================================================================
141 //! @}
142 //====================================================================================================================
143
144 49878027 template<std::size_t I, typename T, unsigned int N> constexpr auto& get(polyfloat<T, N>& c) noexcept
145 {
146 99756054 return kumi::get<I>(c.contents);
147 }
148
149 289144074 template<std::size_t I, typename T, unsigned int N> constexpr auto get(polyfloat<T, N> const& c) noexcept
150 {
151 578288148 return kumi::get<I>(c.contents);
152 }
153
154 //====================================================================================================================
155 //! @name Deduction Guides
156 //! @related polyfloat
157 //! @{
158 //====================================================================================================================
159 /// Deduction guide for constructing from product type
160 // template<eve::product_type Tuple>
161 // polyfloat(Tuple const&) -> polyfloat<kumi::element_t<0, Tuple>, kumi::size_v<Tuple>>;
162
163 /// Deduction guide for constructing from one value
164 template<typename T0, std::convertible_to<T0>... Ts> polyfloat(T0) -> polyfloat<T0, 2u>;
165 /// Deduction guide for constructing from sequence of values
166 template<typename T0, std::convertible_to<T0>... Ts> polyfloat(T0, Ts...) -> polyfloat<T0, 1 + sizeof...(Ts)>;
167 //====================================================================================================================
168 //! @}
169 //====================================================================================================================
170 }
171
172 namespace plf::_
173 {
174 template<typename T, unsigned int N> inline constexpr unsigned int rank<polyfloat<T, N>> = N;
175
176 template<typename T, unsigned int N, eve::width_type L>
177 inline constexpr unsigned int rank<eve::wide<polyfloat<T, N>, L>> = N;
178 }
179
180 #if !defined(POLYFLOAT_DOXYGEN_INVOKED)
181 // std::tuple adaptation
182 template<typename T, unsigned int N>
183 struct std::tuple_size<plf::polyfloat<T, N>> : std::integral_constant<std::size_t, N>
184 {
185 };
186
187 template<typename T, unsigned int N, std::size_t I> struct std::tuple_element<I, plf::polyfloat<T, N>>
188 {
189 using type = T;
190 };
191
192 #endif
193 #include <polyfloat/types/double_real.hpp>
194 #include <polyfloat/types/triple_real.hpp>
195 #include <polyfloat/types/io.hpp>
196 #include <polyfloat/types/compounds.hpp>
197