#pragma once #include #include #include #include "wide_integer.h" namespace wide { template inline std::string to_string(const integer & n) { std::string res; if (integer::_impl::operator_eq(n, 0U)) return "0"; integer t; bool is_neg = integer::_impl::is_negative(n); if (is_neg) t = integer::_impl::operator_unary_minus(n); else t = n; while (!integer::_impl::operator_eq(t, 0U)) { res.insert(res.begin(), '0' + char(integer::_impl::operator_percent(t, 10U))); t = integer::_impl::operator_slash(t, 10U); } if (is_neg) res.insert(res.begin(), '-'); return res; } } template std::ostream & operator<<(std::ostream & out, const wide::integer & value) { return out << to_string(value); } /// See https://fmt.dev/latest/api.html#formatting-user-defined-types template struct fmt::formatter> { constexpr auto parse(format_parse_context & ctx) { auto it = ctx.begin(); auto end = ctx.end(); /// Only support {}. if (it != end && *it != '}') throw format_error("invalid format"); return it; } template auto format(const wide::integer & value, FormatContext & ctx) { return format_to(ctx.out(), "{}", to_string(value)); } };