Ustring format_int(T t, uint64_t flags, int prec) { static constexpr auto float_flags = Format::digits | Format::exp | Format::fixed | Format::general | Format::stripz; static constexpr auto int_flags = Format::binary | Format::decimal | Format::hex | Format::roman; static constexpr auto sign_flags = Format::sign | Format::signz; if ((flags & float_flags) && ! (flags & int_flags)) return format_float(t, flags, prec); if (ibits(flags & int_flags) > 1 || ibits(flags & sign_flags) > 1) throw std::invalid_argument("Inconsistent integer formatting flags"); char sign = 0; if (t > static_cast<T>(0)) { if (flags & (Format::sign | Format::signz)) sign = '+'; } else if (t == static_cast<T>(0)) { if (flags & Format::sign) sign = '+'; } else { t = RS_Detail::SimpleAbs<T>()(t); sign = '-'; } Ustring s; if (flags & Format::binary) s = format_radix(t, 2, prec); else if (flags & Format::roman) s = roman(unsigned(t)); else if (flags & Format::hex) s = format_radix(t, 16, prec); else s = format_radix(t, 10, prec); if (sign) s.insert(s.begin(), sign); return s; }
Ustring format_radix(T t, int base, int prec) { // Argument will never be negative Ustring s; auto b = static_cast<T>(base); prec = std::max(prec, 1); while (t > 0 || int(s.size()) < prec) { auto d = t % b; s += char(d + (d <= 9 ? '0' : 'a' - 10)); t /= b; } std::reverse(s.begin(), s.end()); return s; }