27 #include <xlnt/xlnt_config.hpp> 34 #include <type_traits> 45 template <
typename Number>
46 constexpr Number abs(Number val)
48 return (val < Number{0}) ? -val : val;
54 template <
typename NumberL,
typename NumberR>
55 constexpr
typename std::common_type<NumberL, NumberR>::type (max)(NumberL lval, NumberR rval)
57 return (lval < rval) ? rval : lval;
63 template <
typename NumberL,
typename NumberR>
64 constexpr
typename std::common_type<NumberL, NumberR>::type (min)(NumberL lval, NumberR rval)
66 return (lval < rval) ? lval : rval;
78 template <
typename EpsilonType = float,
79 typename LNumber,
typename RNumber>
80 bool float_equals(
const LNumber &lhs,
const RNumber &rhs,
81 int epsilon_scale = 20)
84 using common_t =
typename std::common_type<LNumber, RNumber>::type;
86 static_assert(std::is_floating_point<LNumber>::value || std::is_floating_point<RNumber>::value,
87 "Using this function with two integers is just wasting time. Use ==");
88 static_assert(std::numeric_limits<EpsilonType>::epsilon() < EpsilonType{1},
89 "epsilon >= 1.0 will cause all comparisons to return true");
92 if (std::isnan(lhs) || std::isnan(rhs))
99 constexpr common_t epsilon =
static_cast<common_t
>(std::numeric_limits<EpsilonType>::epsilon());
104 common_t scaled_fuzz = epsilon_scale * epsilon * max(max(xlnt::detail::abs<common_t>(lhs),
105 xlnt::detail::abs<common_t>(rhs)),
107 return ((lhs + scaled_fuzz) >= rhs) && ((rhs + scaled_fuzz) >= lhs);
112 static constexpr
int Excel_Digit_Precision = 15;
113 bool should_convert_comma;
115 static void convert_comma_to_pt(
char *buf,
int len)
117 char *buf_end = buf + len;
118 char *decimal = std::find(buf, buf_end,
',');
119 if (decimal != buf_end)
125 static void convert_pt_to_comma(
char *buf,
size_t len)
127 char *buf_end = buf + len;
128 char *decimal = std::find(buf, buf_end,
'.');
129 if (decimal != buf_end)
137 : should_convert_comma(localeconv()->decimal_point[0] ==
',')
143 std::string serialise(
double d)
const 146 int len = snprintf(buf,
sizeof(buf),
"%.15g", d);
147 if (should_convert_comma)
149 convert_comma_to_pt(buf, len);
151 return std::string(buf, static_cast<size_t>(len));
156 std::string serialise_short(
double d)
const 159 int len = snprintf(buf,
sizeof(buf),
"%f", d);
160 if (should_convert_comma)
162 convert_comma_to_pt(buf, len);
164 return std::string(buf, static_cast<size_t>(len));
167 double deserialise(
const std::string &s, ptrdiff_t *len_converted)
const 170 assert(len_converted !=
nullptr);
171 char *end_of_convert;
172 if (!should_convert_comma)
174 double d = strtod(s.c_str(), &end_of_convert);
175 *len_converted = end_of_convert - s.c_str();
179 assert(s.size() + 1 <
sizeof(buf));
180 const char *cstr = s.c_str();
181 auto copy_end = std::copy(cstr, cstr + s.size() + 1, buf);
182 convert_pt_to_comma(buf, static_cast<size_t>(copy_end - buf));
183 double d = strtod(buf, &end_of_convert);
184 *len_converted = end_of_convert - buf;
188 double deserialise(
const std::string &s)
const 191 return deserialise(s, &ignore);
Enumerates the possible types a cell can be determined by it's current value.
Definition: cell.hpp:37
Definition: numeric.hpp:110