1 | // |
---|
2 | // Created by gabi on 6/15/18. |
---|
3 | // |
---|
4 | |
---|
5 | #pragma once |
---|
6 | |
---|
7 | #include <chrono> |
---|
8 | #include <type_traits> |
---|
9 | #include "spdlog/fmt/fmt.h" |
---|
10 | |
---|
11 | // Some fmt helpers to efficiently format and pad ints and strings |
---|
12 | namespace spdlog { |
---|
13 | namespace details { |
---|
14 | namespace fmt_helper { |
---|
15 | |
---|
16 | template<size_t Buffer_Size> |
---|
17 | inline spdlog::string_view_t to_string_view(const fmt::basic_memory_buffer<char, Buffer_Size> &buf) SPDLOG_NOEXCEPT |
---|
18 | { |
---|
19 | return spdlog::string_view_t(buf.data(), buf.size()); |
---|
20 | } |
---|
21 | |
---|
22 | template<size_t Buffer_Size1, size_t Buffer_Size2> |
---|
23 | inline void append_buf(const fmt::basic_memory_buffer<char, Buffer_Size1> &buf, fmt::basic_memory_buffer<char, Buffer_Size2> &dest) |
---|
24 | { |
---|
25 | auto *buf_ptr = buf.data(); |
---|
26 | dest.append(buf_ptr, buf_ptr + buf.size()); |
---|
27 | } |
---|
28 | |
---|
29 | template<size_t Buffer_Size> |
---|
30 | inline void append_string_view(spdlog::string_view_t view, fmt::basic_memory_buffer<char, Buffer_Size> &dest) |
---|
31 | { |
---|
32 | auto *buf_ptr = view.data(); |
---|
33 | if (buf_ptr != nullptr) |
---|
34 | { |
---|
35 | dest.append(buf_ptr, buf_ptr + view.size()); |
---|
36 | } |
---|
37 | } |
---|
38 | |
---|
39 | template<typename T, size_t Buffer_Size> |
---|
40 | inline void append_int(T n, fmt::basic_memory_buffer<char, Buffer_Size> &dest) |
---|
41 | { |
---|
42 | fmt::format_int i(n); |
---|
43 | dest.append(i.data(), i.data() + i.size()); |
---|
44 | } |
---|
45 | |
---|
46 | template<typename T> |
---|
47 | inline unsigned count_digits(T n) |
---|
48 | { |
---|
49 | using count_type = typename std::conditional<(sizeof(T) > sizeof(uint32_t)), uint64_t, uint32_t>::type; |
---|
50 | return static_cast<unsigned>(fmt::internal::count_digits(static_cast<count_type>(n))); |
---|
51 | } |
---|
52 | |
---|
53 | template<size_t Buffer_Size> |
---|
54 | inline void pad2(int n, fmt::basic_memory_buffer<char, Buffer_Size> &dest) |
---|
55 | { |
---|
56 | if (n > 99) |
---|
57 | { |
---|
58 | append_int(n, dest); |
---|
59 | } |
---|
60 | else if (n > 9) // 10-99 |
---|
61 | { |
---|
62 | dest.push_back(static_cast<char>('0' + n / 10)); |
---|
63 | dest.push_back(static_cast<char>('0' + n % 10)); |
---|
64 | } |
---|
65 | else if (n >= 0) // 0-9 |
---|
66 | { |
---|
67 | dest.push_back('0'); |
---|
68 | dest.push_back(static_cast<char>('0' + n)); |
---|
69 | } |
---|
70 | else // negatives (unlikely, but just in case, let fmt deal with it) |
---|
71 | { |
---|
72 | fmt::format_to(dest, "{:02}", n); |
---|
73 | } |
---|
74 | } |
---|
75 | |
---|
76 | template<typename T, size_t Buffer_Size> |
---|
77 | inline void pad_uint(T n, unsigned int width, fmt::basic_memory_buffer<char, Buffer_Size> &dest) |
---|
78 | { |
---|
79 | static_assert(std::is_unsigned<T>::value, "pad_uint must get unsigned T"); |
---|
80 | auto digits = count_digits(n); |
---|
81 | if (width > digits) |
---|
82 | { |
---|
83 | const char *zeroes = "0000000000000000000"; |
---|
84 | dest.append(zeroes, zeroes + width - digits); |
---|
85 | } |
---|
86 | append_int(n, dest); |
---|
87 | } |
---|
88 | |
---|
89 | template<typename T, size_t Buffer_Size> |
---|
90 | inline void pad3(T n, fmt::basic_memory_buffer<char, Buffer_Size> &dest) |
---|
91 | { |
---|
92 | pad_uint(n, 3, dest); |
---|
93 | } |
---|
94 | |
---|
95 | template<typename T, size_t Buffer_Size> |
---|
96 | inline void pad6(T n, fmt::basic_memory_buffer<char, Buffer_Size> &dest) |
---|
97 | { |
---|
98 | pad_uint(n, 6, dest); |
---|
99 | } |
---|
100 | |
---|
101 | template<typename T, size_t Buffer_Size> |
---|
102 | inline void pad9(T n, fmt::basic_memory_buffer<char, Buffer_Size> &dest) |
---|
103 | { |
---|
104 | pad_uint(n, 9, dest); |
---|
105 | } |
---|
106 | |
---|
107 | // return fraction of a second of the given time_point. |
---|
108 | // e.g. |
---|
109 | // fraction<std::milliseconds>(tp) -> will return the millis part of the second |
---|
110 | template<typename ToDuration> |
---|
111 | inline ToDuration time_fraction(const log_clock::time_point &tp) |
---|
112 | { |
---|
113 | using std::chrono::duration_cast; |
---|
114 | using std::chrono::seconds; |
---|
115 | auto duration = tp.time_since_epoch(); |
---|
116 | auto secs = duration_cast<seconds>(duration); |
---|
117 | return duration_cast<ToDuration>(duration) - duration_cast<ToDuration>(secs); |
---|
118 | } |
---|
119 | |
---|
120 | } // namespace fmt_helper |
---|
121 | } // namespace details |
---|
122 | } // namespace spdlog |
---|