mirror of
https://github.com/mpusz/mp-units.git
synced 2025-08-03 04:14:27 +02:00
Not needed stuff removed from fmt format (resolves #6)
This commit is contained in:
@@ -57,7 +57,7 @@ namespace units {
|
||||
++ptr;
|
||||
continue;
|
||||
}
|
||||
if (begin != ptr)
|
||||
if(begin != ptr)
|
||||
handler.on_text(begin, ptr);
|
||||
++ptr; // consume '%'
|
||||
if(ptr == end)
|
||||
@@ -94,8 +94,8 @@ namespace units {
|
||||
}
|
||||
|
||||
struct units_format_checker {
|
||||
template<typename Char>
|
||||
void on_text(const Char*, const Char*) {}
|
||||
template<typename CharT>
|
||||
void on_text(const CharT*, const CharT*) {}
|
||||
void on_quantity_value() {}
|
||||
void on_quantity_unit() {}
|
||||
};
|
||||
@@ -114,108 +114,25 @@ namespace units {
|
||||
return format_to(out, "{}", unit_text<Unit>().c_str());
|
||||
}
|
||||
|
||||
// If T is an integral type, maps T to its unsigned counterpart, otherwise
|
||||
// leaves it unchanged (unlike std::make_unsigned).
|
||||
template<typename T, bool Integral = std::is_integral_v<T>>
|
||||
struct make_unsigned_or_unchanged {
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct make_unsigned_or_unchanged<T, true> {
|
||||
using type = std::make_unsigned_t<T>;
|
||||
};
|
||||
|
||||
// converts value to int and checks that it's in the range [0, upper).
|
||||
template<typename T>
|
||||
requires std::is_integral_v<T>
|
||||
inline int to_nonnegative_int(T value, int upper)
|
||||
{
|
||||
FMT_ASSERT(value >= 0 && value <= upper, "invalid value");
|
||||
(void)upper;
|
||||
return static_cast<int>(value);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline int to_nonnegative_int(T value, int upper)
|
||||
{
|
||||
FMT_ASSERT(units::isnan(value) || (value >= 0 && value <= static_cast<T>(upper)), "invalid value");
|
||||
(void)upper;
|
||||
return static_cast<int>(value);
|
||||
}
|
||||
|
||||
template<typename FormatContext, typename OutputIt, typename Unit, typename Rep>
|
||||
template<typename OutputIt, typename Unit, typename Rep>
|
||||
struct units_formatter {
|
||||
FormatContext& context;
|
||||
OutputIt out;
|
||||
// rep is unsigned to avoid overflow.
|
||||
using rep = conditional<std::is_integral_v<Rep> && sizeof(Rep) < sizeof(int),
|
||||
unsigned, typename make_unsigned_or_unchanged<Rep>::type>;
|
||||
bool negative = false;
|
||||
rep val;
|
||||
Rep val;
|
||||
int precision;
|
||||
|
||||
using char_type = FormatContext::char_type;
|
||||
|
||||
explicit units_formatter(FormatContext& ctx, OutputIt o, quantity<Unit, Rep> q, int prec):
|
||||
context(ctx), out(o), negative(q.count() < 0), val(negative ? -q.count() : q.count()), precision(prec)
|
||||
explicit units_formatter(OutputIt o, quantity<Unit, Rep> q, int prec):
|
||||
out(o), val(q.count()), precision(prec)
|
||||
{
|
||||
}
|
||||
|
||||
// returns true if nan or inf, writes to out.
|
||||
bool handle_nan_inf()
|
||||
{
|
||||
if(units::isfinite(val)) {
|
||||
return false;
|
||||
}
|
||||
if(units::isnan(val)) {
|
||||
write_nan();
|
||||
return true;
|
||||
}
|
||||
// must be +-inf
|
||||
if(val > 0) {
|
||||
write_pinf();
|
||||
}
|
||||
else {
|
||||
write_ninf();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void write_sign()
|
||||
{
|
||||
if(negative) {
|
||||
*out++ = '-';
|
||||
negative = false;
|
||||
}
|
||||
}
|
||||
|
||||
void write(Rep value, int width)
|
||||
{
|
||||
write_sign();
|
||||
if(units::isnan(value))
|
||||
return write_nan();
|
||||
fmt::internal::uint32_or_64_t<int> n = fmt::internal::to_unsigned(to_nonnegative_int(value, std::numeric_limits<int>::max()));
|
||||
int num_digits = fmt::internal::count_digits(n);
|
||||
if(width > num_digits)
|
||||
out = std::fill_n(out, width - num_digits, '0');
|
||||
out = fmt::internal::format_decimal<char_type>(out, n, num_digits);
|
||||
}
|
||||
|
||||
void write_nan() { std::copy_n("nan", 3, out); }
|
||||
void write_pinf() { std::copy_n("inf", 3, out); }
|
||||
void write_ninf() { std::copy_n("-inf", 4, out); }
|
||||
|
||||
void on_text(const char_type* begin, const char_type* end)
|
||||
template<typename CharT>
|
||||
void on_text(const CharT* begin, const CharT* end)
|
||||
{
|
||||
std::copy(begin, end, out);
|
||||
}
|
||||
|
||||
void on_quantity_value()
|
||||
{
|
||||
if(handle_nan_inf())
|
||||
return;
|
||||
write_sign();
|
||||
out = format_units_quantity_value(out, val, precision);
|
||||
}
|
||||
|
||||
@@ -261,7 +178,7 @@ private:
|
||||
return arg_ref_type(str_val);
|
||||
}
|
||||
|
||||
constexpr arg_ref_type make_arg_ref(internal::auto_id)
|
||||
constexpr arg_ref_type make_arg_ref(fmt::internal::auto_id)
|
||||
{
|
||||
return arg_ref_type(context.next_arg_id());
|
||||
}
|
||||
@@ -279,7 +196,8 @@ private:
|
||||
f.width_ref = make_arg_ref(arg_id);
|
||||
}
|
||||
|
||||
template <typename Id> void on_dynamic_precision(Id arg_id)
|
||||
template<typename Id>
|
||||
void on_dynamic_precision(Id arg_id)
|
||||
{
|
||||
f.precision_ref = make_arg_ref(arg_id);
|
||||
}
|
||||
@@ -317,6 +235,7 @@ private:
|
||||
handler.on_error("precision not allowed for integral quantity representation");
|
||||
}
|
||||
|
||||
// parse units-specific specification
|
||||
end = parse_units_format(begin, end, units::detail::units_format_checker());
|
||||
|
||||
return {begin, end};
|
||||
@@ -352,7 +271,7 @@ public:
|
||||
}
|
||||
else {
|
||||
// user provided format
|
||||
units::detail::units_formatter<FormatContext, decltype(out), Unit, Rep> f(ctx, out, q, precision);
|
||||
units::detail::units_formatter f(out, q, precision);
|
||||
parse_units_format(begin, end, f);
|
||||
}
|
||||
|
||||
@@ -362,7 +281,5 @@ public:
|
||||
w.write(buf.data(), buf.size(), specs);
|
||||
|
||||
return w.out();
|
||||
|
||||
// return format_to(ctx.out(), "{} {}", q.count(), units::detail::unit_text<typename quantity::unit>().c_str());
|
||||
}
|
||||
};
|
||||
|
Reference in New Issue
Block a user