Optimize counting
This commit is contained in:
parent
6498bc6d31
commit
d39ebf3ff2
@ -582,8 +582,8 @@ struct chrono_formatter {
|
||||
void write(Rep value, int width) {
|
||||
write_sign();
|
||||
if (isnan(value)) return write_nan();
|
||||
uint32_or_64_or_128_t<int> n = to_unsigned(
|
||||
to_nonnegative_int(value, max_value<int>()));
|
||||
uint32_or_64_or_128_t<int> n =
|
||||
to_unsigned(to_nonnegative_int(value, max_value<int>()));
|
||||
int num_digits = internal::count_digits(n);
|
||||
if (width > num_digits) out = std::fill_n(out, width - num_digits, '0');
|
||||
out = format_decimal<char_type>(out, n, num_digits);
|
||||
|
@ -498,9 +498,9 @@ void vformat_to(basic_memory_buffer<Char>& buf, const text_style& ts,
|
||||
}
|
||||
} // namespace internal
|
||||
|
||||
template <typename S, typename Char = char_t<S> >
|
||||
template <typename S, typename Char = char_t<S>>
|
||||
void vprint(std::FILE* f, const text_style& ts, const S& format,
|
||||
basic_format_args<buffer_context<Char> > args) {
|
||||
basic_format_args<buffer_context<Char>> args) {
|
||||
basic_memory_buffer<Char> buf;
|
||||
internal::vformat_to(buf, ts, to_string_view(format), args);
|
||||
buf.push_back(Char(0));
|
||||
@ -519,7 +519,7 @@ template <typename S, typename... Args,
|
||||
void print(std::FILE* f, const text_style& ts, const S& format_str,
|
||||
const Args&... args) {
|
||||
internal::check_format_string<Args...>(format_str);
|
||||
using context = buffer_context<char_t<S> >;
|
||||
using context = buffer_context<char_t<S>>;
|
||||
format_arg_store<context, Args...> as{args...};
|
||||
vprint(f, ts, format_str, basic_format_args<context>(as));
|
||||
}
|
||||
@ -537,10 +537,10 @@ void print(const text_style& ts, const S& format_str, const Args&... args) {
|
||||
return print(stdout, ts, format_str, args...);
|
||||
}
|
||||
|
||||
template <typename S, typename Char = char_t<S> >
|
||||
template <typename S, typename Char = char_t<S>>
|
||||
inline std::basic_string<Char> vformat(
|
||||
const text_style& ts, const S& format_str,
|
||||
basic_format_args<buffer_context<Char> > args) {
|
||||
basic_format_args<buffer_context<Char>> args) {
|
||||
basic_memory_buffer<Char> buf;
|
||||
internal::vformat_to(buf, ts, to_string_view(format_str), args);
|
||||
return fmt::to_string(buf);
|
||||
@ -558,12 +558,11 @@ inline std::basic_string<Char> vformat(
|
||||
"The answer is {}", 42);
|
||||
\endrst
|
||||
*/
|
||||
template <typename S, typename... Args, typename Char = char_t<S> >
|
||||
template <typename S, typename... Args, typename Char = char_t<S>>
|
||||
inline std::basic_string<Char> format(const text_style& ts, const S& format_str,
|
||||
const Args&... args) {
|
||||
return vformat(
|
||||
ts, to_string_view(format_str),
|
||||
{internal::make_args_checked<Args...>(format_str, args...)});
|
||||
return vformat(ts, to_string_view(format_str),
|
||||
{internal::make_args_checked<Args...>(format_str, args...)});
|
||||
}
|
||||
|
||||
FMT_END_NAMESPACE
|
||||
|
@ -570,10 +570,7 @@ format_to_n_result<OutputIt> format_to_n(OutputIt out, size_t n,
|
||||
|
||||
template <typename CompiledFormat, typename... Args>
|
||||
std::size_t formatted_size(const CompiledFormat& cf, const Args&... args) {
|
||||
return format_to(
|
||||
internal::counting_iterator<typename CompiledFormat::char_type>(),
|
||||
cf, args...)
|
||||
.count();
|
||||
return format_to(internal::counting_iterator(), cf, args...).count();
|
||||
}
|
||||
|
||||
FMT_END_NAMESPACE
|
||||
|
@ -292,19 +292,21 @@ inline Iterator& reserve(Iterator& it, std::size_t) {
|
||||
|
||||
// An output iterator that counts the number of objects written to it and
|
||||
// discards them.
|
||||
template <typename T> class counting_iterator {
|
||||
class counting_iterator {
|
||||
private:
|
||||
std::size_t count_;
|
||||
mutable T blackhole_;
|
||||
|
||||
public:
|
||||
using iterator_category = std::output_iterator_tag;
|
||||
using value_type = T;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using pointer = T*;
|
||||
using reference = T&;
|
||||
using pointer = void;
|
||||
using reference = void;
|
||||
using _Unchecked_type = counting_iterator; // Mark iterator as checked.
|
||||
|
||||
struct value_type {
|
||||
template <typename T> void operator=(const T&) {}
|
||||
};
|
||||
|
||||
counting_iterator() : count_(0) {}
|
||||
|
||||
std::size_t count() const { return count_; }
|
||||
@ -320,7 +322,7 @@ template <typename T> class counting_iterator {
|
||||
return it;
|
||||
}
|
||||
|
||||
T& operator*() const { return blackhole_; }
|
||||
value_type operator*() const { return {}; }
|
||||
};
|
||||
|
||||
template <typename OutputIt> class truncating_iterator_base {
|
||||
@ -1132,7 +1134,7 @@ template <typename Char> class grisu_writer {
|
||||
int full_exp = num_digits + exp - 1;
|
||||
int precision = params.num_digits > 0 ? params.num_digits : 16;
|
||||
params_.fixed |= full_exp >= -4 && full_exp < precision;
|
||||
auto it = grisu_prettify(digits, num_digits, exp, counting_iterator<char>(),
|
||||
auto it = grisu_prettify(digits, num_digits, exp, counting_iterator(),
|
||||
params_, '\0');
|
||||
size_ = it.count();
|
||||
}
|
||||
@ -3482,7 +3484,7 @@ inline std::basic_string<Char> internal::vformat(
|
||||
*/
|
||||
template <typename... Args>
|
||||
inline std::size_t formatted_size(string_view format_str, const Args&... args) {
|
||||
auto it = format_to(internal::counting_iterator<char>(), format_str, args...);
|
||||
auto it = format_to(internal::counting_iterator(), format_str, args...);
|
||||
return it.count();
|
||||
}
|
||||
|
||||
|
@ -469,8 +469,7 @@ OutputIt basic_printf_context<OutputIt, Char>::format() {
|
||||
|
||||
// Parse argument index, flags and width.
|
||||
unsigned arg_index = parse_header(it, end, specs);
|
||||
if (arg_index == 0)
|
||||
on_error("argument index out of range");
|
||||
if (arg_index == 0) on_error("argument index out of range");
|
||||
|
||||
// Parse precision.
|
||||
if (it != end && *it == '.') {
|
||||
|
@ -182,7 +182,7 @@ TEST(UtilTest, ParseNonnegativeInt) {
|
||||
}
|
||||
|
||||
TEST(IteratorTest, CountingIterator) {
|
||||
fmt::internal::counting_iterator<char> it;
|
||||
fmt::internal::counting_iterator it;
|
||||
auto prev = it++;
|
||||
EXPECT_EQ(prev.count(), 0);
|
||||
EXPECT_EQ(it.count(), 1);
|
||||
|
Loading…
Reference in New Issue
Block a user