forked from scylladb/scylladb
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpretty_printers.hh
95 lines (83 loc) · 2.84 KB
/
pretty_printers.hh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/*
* Copyright (C) 2023-present ScyllaDB
*/
/*
* SPDX-License-Identifier: LicenseRef-ScyllaDB-Source-Available-1.0
*/
#pragma once
#include <chrono>
#include <fmt/format.h>
namespace utils {
class pretty_printed_data_size {
uint64_t _size;
public:
pretty_printed_data_size(uint64_t size) : _size(size) {}
friend fmt::formatter<pretty_printed_data_size>;
};
class pretty_printed_throughput {
uint64_t _size;
std::chrono::duration<float> _duration;
public:
pretty_printed_throughput(uint64_t size, std::chrono::duration<float> dur) : _size(size), _duration(std::move(dur)) {}
friend fmt::formatter<pretty_printed_throughput>;
};
}
// print data_size using IEC or SI binary prefix annotation with optional "B"
// or " bytes" unit postfix.
//
// usage:
// fmt::print("{}", 10'024); // prints "10kB", using SI and add the "B" unit
// // postfix by default
// fmt::print("{:i}", 42); // prints "42 bytes"
// fmt::print("{:ib}", 10'024); // prints "10Ki", IEC unit is used, without
// // the " bytes" or "B" unit
// fmt::print("{:I}", 1024); // prints "1K", IEC unit is used, but without
// // the "iB" postfix.
// fmt::print("{:s}", 10); // prints "10 bytes", SI unit is used
// fmt::print("{:sb}", 10'000); // prints "10k", SI unit is used, without
// // the unit postfix
template <>
struct fmt::formatter<utils::pretty_printed_data_size> {
enum class prefix_type {
SI,
IEC,
IEC_SANS_I,
};
prefix_type _prefix = prefix_type::SI;
bool _bytes = true;
constexpr auto parse(format_parse_context& ctx) {
auto it = ctx.begin();
auto end = ctx.end();
if (it != end) {
if (*it == 's') {
_prefix = prefix_type::SI;
++it;
} else if (*it == 'i') {
_prefix = prefix_type::IEC;
++it;
} else if (*it == 'I') {
_prefix = prefix_type::IEC_SANS_I;
++it;
}
if (*it == 'b') {
_bytes = false;
++it;
}
}
if (it != end && *it != '}') {
throw fmt::format_error("invalid format specifier");
}
return it;
}
template <typename FormatContext>
auto format(utils::pretty_printed_data_size, FormatContext& ctx) const -> decltype(ctx.out());
};
template <>
struct fmt::formatter<utils::pretty_printed_throughput>
: private fmt::formatter<utils::pretty_printed_data_size> {
using size_formatter = fmt::formatter<utils::pretty_printed_data_size>;
public:
using size_formatter::parse;
template <typename FormatContext>
auto format(const utils::pretty_printed_throughput&, FormatContext& ctx) const -> decltype(ctx.out());
};