Optimize counting

This commit is contained in:
Victor Zverovich 2019-10-21 06:51:21 -07:00
parent 6498bc6d31
commit d39ebf3ff2
6 changed files with 23 additions and 26 deletions

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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();
}

View File

@ -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 == '.') {

View File

@ -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);