mirror of
https://github.com/fmtlib/fmt.git
synced 2025-02-28 06:39:50 +00:00
Optimize pointer formatting
This commit is contained in:
parent
bb6842ba35
commit
0302927f56
@ -314,6 +314,8 @@ class numeric_limits<fmt::internal::uintptr_t>
|
|||||||
static uintptr_t to_uint(const void* p) {
|
static uintptr_t to_uint(const void* p) {
|
||||||
return fmt::internal::bit_cast<uintptr_t>(p);
|
return fmt::internal::bit_cast<uintptr_t>(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef uintptr_t uintptr_type;
|
||||||
};
|
};
|
||||||
} // namespace std
|
} // namespace std
|
||||||
|
|
||||||
@ -780,6 +782,15 @@ inline int count_digits(uint64_t n) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Counts the number of digits in n. BITS = log2(radix).
|
||||||
|
template <unsigned BITS, typename UInt> inline int count_digits(UInt n) {
|
||||||
|
int num_digits = 0;
|
||||||
|
do {
|
||||||
|
++num_digits;
|
||||||
|
} while ((n >>= BITS) != 0);
|
||||||
|
return num_digits;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
inline size_t count_code_points(basic_string_view<Char> s) {
|
inline size_t count_code_points(basic_string_view<Char> s) {
|
||||||
return s.size();
|
return s.size();
|
||||||
@ -1409,10 +1420,7 @@ template <typename Range> class arg_formatter_base {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void write_pointer(const void* p) {
|
void write_pointer(const void* p) {
|
||||||
format_specs specs = specs_ ? *specs_ : format_specs();
|
writer_.write(p, specs_);
|
||||||
specs.flags = HASH_FLAG;
|
|
||||||
specs.type = 'x';
|
|
||||||
writer_.write_int(internal::numutil::to_uint(p), specs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -2486,16 +2494,6 @@ template <typename Range> class basic_writer {
|
|||||||
|
|
||||||
string_view get_prefix() const { return string_view(prefix, prefix_size); }
|
string_view get_prefix() const { return string_view(prefix, prefix_size); }
|
||||||
|
|
||||||
// Counts the number of digits in abs_value. BITS = log2(radix).
|
|
||||||
template <unsigned BITS> int count_digits() const {
|
|
||||||
unsigned_type n = abs_value;
|
|
||||||
int num_digits = 0;
|
|
||||||
do {
|
|
||||||
++num_digits;
|
|
||||||
} while ((n >>= BITS) != 0);
|
|
||||||
return num_digits;
|
|
||||||
}
|
|
||||||
|
|
||||||
int_writer(basic_writer<Range>& w, Int value, const Spec& s)
|
int_writer(basic_writer<Range>& w, Int value, const Spec& s)
|
||||||
: writer(w),
|
: writer(w),
|
||||||
spec(s),
|
spec(s),
|
||||||
@ -2541,7 +2539,7 @@ template <typename Range> class basic_writer {
|
|||||||
prefix[prefix_size++] = '0';
|
prefix[prefix_size++] = '0';
|
||||||
prefix[prefix_size++] = static_cast<char>(spec.type);
|
prefix[prefix_size++] = static_cast<char>(spec.type);
|
||||||
}
|
}
|
||||||
int num_digits = count_digits<4>();
|
int num_digits = internal::count_digits<4>(abs_value);
|
||||||
writer.write_int(num_digits, get_prefix(), spec,
|
writer.write_int(num_digits, get_prefix(), spec,
|
||||||
hex_writer{*this, num_digits});
|
hex_writer{*this, num_digits});
|
||||||
}
|
}
|
||||||
@ -2560,13 +2558,13 @@ template <typename Range> class basic_writer {
|
|||||||
prefix[prefix_size++] = '0';
|
prefix[prefix_size++] = '0';
|
||||||
prefix[prefix_size++] = static_cast<char>(spec.type);
|
prefix[prefix_size++] = static_cast<char>(spec.type);
|
||||||
}
|
}
|
||||||
int num_digits = count_digits<1>();
|
int num_digits = internal::count_digits<1>(abs_value);
|
||||||
writer.write_int(num_digits, get_prefix(), spec,
|
writer.write_int(num_digits, get_prefix(), spec,
|
||||||
bin_writer<1>{abs_value, num_digits});
|
bin_writer<1>{abs_value, num_digits});
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_oct() {
|
void on_oct() {
|
||||||
int num_digits = count_digits<3>();
|
int num_digits = internal::count_digits<3>(abs_value);
|
||||||
if (spec.has(HASH_FLAG) && spec.precision <= num_digits) {
|
if (spec.has(HASH_FLAG) && spec.precision <= num_digits) {
|
||||||
// Octal prefix '0' is counted as a digit, so only add it if precision
|
// Octal prefix '0' is counted as a digit, so only add it if precision
|
||||||
// is not greater than the number of digits.
|
// is not greater than the number of digits.
|
||||||
@ -2692,6 +2690,20 @@ template <typename Range> class basic_writer {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct pointer_writer {
|
||||||
|
internal::numutil::uintptr_type value;
|
||||||
|
int num_digits;
|
||||||
|
|
||||||
|
size_t size() const { return num_digits + 2; }
|
||||||
|
size_t width() const { return size(); }
|
||||||
|
|
||||||
|
template <typename It> void operator()(It&& it) const {
|
||||||
|
*it++ = static_cast<char_type>('0');
|
||||||
|
*it++ = static_cast<char_type>('x');
|
||||||
|
it = internal::format_uint<4, char_type>(it, value, num_digits, false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template <typename Char> friend class internal::arg_formatter_base;
|
template <typename Char> friend class internal::arg_formatter_base;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -2780,11 +2792,14 @@ template <typename Range> class basic_writer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, FMT_ENABLE_IF(std::is_same<T, void>::value)>
|
template <typename T, FMT_ENABLE_IF(std::is_same<T, void>::value)>
|
||||||
void write(const T* p) {
|
void write(const T* p, const align_spec* spec) {
|
||||||
format_specs specs;
|
auto value = internal::numutil::to_uint(p);
|
||||||
specs.flags = HASH_FLAG;
|
int num_digits = internal::count_digits<4>(value);
|
||||||
specs.type = 'x';
|
auto pw = pointer_writer{value, num_digits};
|
||||||
write_int(internal::numutil::to_uint(p), specs);
|
if (!spec) return pw(reserve(num_digits + 2));
|
||||||
|
align_spec as = *spec;
|
||||||
|
if (as.align() == ALIGN_DEFAULT) as.align_ = ALIGN_RIGHT;
|
||||||
|
write_padded(as, pw);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user