7#if defined(__cpp_lib_format)
25 || std::is_same_v<T, int128_t> || std::is_same_v<T, int256_t>;
60 template <decimal_
integer_type T>
137 constexpr explicit operator float() const
155 constexpr explicit operator
double() const
173 constexpr explicit operator
long double() const
191 [[nodiscard]] explicit operator
std::
string() const
212 [[nodiscard]] constexpr
int scale() const;
231 template <class FLOAT_TYPE>
232 [[nodiscard]] constexpr FLOAT_TYPE convert_to_floating_point() const
244 template <typename T>
255 template <typename T>
266 template <decimal_
integer_type T>
274 template <decimal_
integer_type T>
281 template <decimal_
integer_type T>
284 return m_value == other.m_value && m_scale == other.m_scale;
287 template <decimal_
integer_type T>
291 return convert_to_floating_point<float>();
294 template <decimal_
integer_type T>
298 return convert_to_floating_point<double>();
301 template <decimal_
integer_type T>
305 return convert_to_floating_point<long double>();
308 template <decimal_
integer_type T>
312 std::stringstream ss;
314 std::string result = ss.str();
319 if (result[0] ==
'0')
324 if (result[0] ==
'-')
326 result = result.substr(1);
331 if (result.length() <=
static_cast<std::size_t
>(m_scale))
335 std::string(
static_cast<std::size_t
>(m_scale) + 1 - result.length(),
'0')
338 std::size_t int_part_len = result.length() -
static_cast<std::size_t
>(m_scale);
339 std::string int_part = result.substr(0, int_part_len);
340 std::string frac_part = result.substr(int_part_len);
341 result = int_part +
"." + frac_part;
345 result += std::string(
static_cast<std::size_t
>(-m_scale),
'0');
350 result.insert(0, 1,
'-');
355 template <decimal_
integer_type T>
361 template <decimal_
integer_type T>
367 template <decimal_
integer_type T>
368 template <
class FLOAT_TYPE>
369 constexpr FLOAT_TYPE decimal<T>::convert_to_floating_point() const
372 using to_type = FLOAT_TYPE;
373 if constexpr (std::is_same_v<T, int256_t>)
376 auto val =
static_cast<int128_t>(m_value);
377 return static_cast<to_type
>(val) /
static_cast<to_type
>(std::pow(10, m_scale));
381 return static_cast<to_type
>(m_value) /
static_cast<to_type
>(std::pow(10, m_scale));
387#if defined(__cpp_lib_format)
390struct std::formatter<
sparrow::decimal<T>>
392 constexpr auto parse(std::format_parse_context& ctx)
397 auto format(
const sparrow::decimal<T>& d, std::format_context& ctx)
const
399 return std::format_to(ctx.out(),
"Decimal({}, {})", d.
storage(), d.
scale());
406 os << std::format(
"{}", value);
constexpr decimal()
Default constructor for placeholder integer types.
constexpr decimal(T value, int scale)
Constructor from value and scale.
constexpr int scale() const
constexpr bool operator==(const decimal &other) const
Equality comparison operator.
constexpr T storage() const
constexpr decimal()
Default constructor for non-placeholder integer types.
Concept for valid decimal integer backing types.
Concept for valid decimal types.
primesum::int128_t int128_t
constexpr bool is_int_placeholder_v
constexpr bool is_decimal_v
Type trait to check if a type is a decimal instantiation.
std::ostream & operator<<(std::ostream &os, const sparrow::nullval_t &)