cpp : fixed format_time, format_time_ns and thousand_sep
This commit is contained in:
parent
598fdc383c
commit
d0493890f1
113
cpp/toolbox.cpp
113
cpp/toolbox.cpp
@ -1,13 +1,13 @@
|
||||
#include "toolbox.hpp"
|
||||
#include <numeric>
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <algorithm>
|
||||
|
||||
static constexpr size_t N_TIMES = 10;
|
||||
static const std::array<const char*, N_TIMES> time_formats = { "ns", "us", "ms", "s", "m", "h", "j", "w", "M", "y" };
|
||||
static constexpr std::array<uint16_t, N_TIMES> time_numbers = { 1, 1000, 1000, 1000, 60, 60, 24, 7, 4, 12 };
|
||||
static const uint64_t total_time = std::accumulate(time_numbers.begin(), time_numbers.end(), (uint64_t)1, std::multiplies<uint64_t>());
|
||||
static constexpr uint64_t u64(const double& n) noexcept { return static_cast<uint64_t>(n); }
|
||||
|
||||
static const constexpr size_t N_TIMES = 11;
|
||||
static const constexpr std::array<const char*, N_TIMES> time_formats = { "ns", "us", "ms", "s", "m", "h", "j", "w", "M", "y", "c" };
|
||||
static const constexpr std::array<uint64_t, N_TIMES> time_numbers = { 1, u64(1e3), u64(1e6), u64(1e9), u64(6e10), u64(36e11), u64(864e11),
|
||||
u64(6048e11), u64(26784e11), u64(31536e12), u64(31536e14) };
|
||||
|
||||
/**
|
||||
* @brief Format the time in seconds in human readable format.
|
||||
@ -16,7 +16,24 @@ static const uint64_t total_time = std::accumulate(time_numbers.begin(), time_nu
|
||||
* @return std::string The formatted human readable string.
|
||||
*/
|
||||
std::string format_time(uint64_t time) noexcept {
|
||||
return time < 2 ? std::to_string(time) + "s" : format_time_ns(time * (uint64_t)1e9);
|
||||
if (time == 0)
|
||||
return "0s";
|
||||
|
||||
std::string s = "";
|
||||
uint64_t res;
|
||||
for (int i = N_TIMES - 1; i >= 3; --i) {
|
||||
const uint64_t time_number = time_numbers[i] / 1e9; // Converting nanosecond timestamp to second
|
||||
if (time >= time_number) {
|
||||
res = time / time_number;
|
||||
time %= time_number;
|
||||
s += std::to_string(res) + time_formats[i] + " ";
|
||||
}
|
||||
}
|
||||
|
||||
if (s.back() == ' ')
|
||||
s.pop_back();
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -28,17 +45,15 @@ std::string format_time(uint64_t time) noexcept {
|
||||
std::string format_time_ns(uint64_t time) noexcept {
|
||||
if (time == 0)
|
||||
return "0ns";
|
||||
uint64_t prod = total_time;
|
||||
|
||||
std::string s = "";
|
||||
uint64_t res;
|
||||
for (int i = N_TIMES - 1; i >= 0; --i) {
|
||||
if (time >= prod) {
|
||||
res = time / prod;
|
||||
time %= prod;
|
||||
if (time >= time_numbers[i]) {
|
||||
res = time / time_numbers[i];
|
||||
time %= time_numbers[i];
|
||||
s += std::to_string(res) + time_formats[i] + " ";
|
||||
}
|
||||
prod /= time_numbers[i];
|
||||
}
|
||||
|
||||
if (s.back() == ' ')
|
||||
@ -48,9 +63,16 @@ std::string format_time_ns(uint64_t time) noexcept {
|
||||
}
|
||||
|
||||
static const constexpr size_t N_BYTES = 7;
|
||||
static const constexpr std::array<const char*, N_BYTES> bytes_formats = { "", "K", "M", "G", "P", "E", "Z" }; //, "Y" };
|
||||
static const constexpr uint64_t total_bytes = static_cast<uint64_t>(1)<<(10 * (N_BYTES - 1));
|
||||
static const constexpr std::array<const char*, N_BYTES> bytes_formats = { "", "K", "M", "G", "T", "P", "E", }; //"Z", "Y" };
|
||||
static const constexpr uint64_t total_bytes = u64(1)<<(10 * (N_BYTES - 1));
|
||||
|
||||
/**
|
||||
* @brief Convert the number of byte in JEDEC standard form.
|
||||
* See more : https://en.wikipedia.org/wiki/JEDEC_memory_standards
|
||||
*
|
||||
* @param bytes Number of bytes
|
||||
* @return std::string JEDEC compliant formatted number of bytes
|
||||
*/
|
||||
std::string format_byte_size(uint64_t bytes) noexcept {
|
||||
if (bytes == 0)
|
||||
return "0B";
|
||||
@ -64,70 +86,29 @@ std::string format_byte_size(uint64_t bytes) noexcept {
|
||||
bytes %= prod;
|
||||
s += std::to_string(res) + bytes_formats[i - 1] + "B ";
|
||||
}
|
||||
prod /= static_cast<uint64_t>(1)<<10;
|
||||
prod /= u64(1)<<10; // 1024
|
||||
}
|
||||
|
||||
if (s.back() == ' ')
|
||||
// Remove trailing character
|
||||
s.pop_back();
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void toolbox_unit_test() noexcept {
|
||||
assert(std::string("0B") == format_byte_size(static_cast<uint64_t>(0)));
|
||||
assert(std::string("1B") == format_byte_size(static_cast<uint64_t>(1)));
|
||||
assert(std::string("1KB") == format_byte_size(static_cast<uint64_t>(1)<<10));
|
||||
assert(std::string("1MB") == format_byte_size(static_cast<uint64_t>(1)<<20));
|
||||
assert(std::string("1GB") == format_byte_size(static_cast<uint64_t>(1)<<30));
|
||||
assert(std::string("1PB") == format_byte_size(static_cast<uint64_t>(1)<<40));
|
||||
assert(std::string("1EB") == format_byte_size(static_cast<uint64_t>(1)<<50));
|
||||
assert(std::string("1ZB") == format_byte_size(static_cast<uint64_t>(1)<<60));
|
||||
//assert(std::string("1YB") == format_byte_size(static_cast<uint64_t>(1)<<70));
|
||||
// UINT64_MAX == 18446744073709551615I64u == -1
|
||||
assert(std::string("15ZB 1023EB 1023PB 1023GB 1023MB 1023KB 1023B") == format_byte_size(static_cast<uint64_t>(-1)));
|
||||
std::string thousand_sep(uint64_t k, const char& separator) noexcept {
|
||||
const std::string n = std::to_string(k);
|
||||
const uint64_t st_size = n.length() + (n.length() - 1) / 3;
|
||||
std::string s = std::string(st_size, ' ');
|
||||
|
||||
assert(std::string("0s") == format_time(static_cast<uint64_t>(0)));
|
||||
assert(std::string("1s") == format_time(static_cast<uint64_t>(1)));
|
||||
assert(std::string("1m") == format_time(static_cast<uint64_t>(60)));
|
||||
assert(std::string("1h") == format_time(static_cast<uint64_t>(3600)));
|
||||
assert(std::string("1j") == format_time(static_cast<uint64_t>(86400)));
|
||||
assert(std::string("1w") == format_time(static_cast<uint64_t>(604800)));
|
||||
assert(std::string("1M") == format_time(static_cast<uint64_t>(2419200)));
|
||||
assert(std::string("1y") == format_time(static_cast<uint64_t>(29030400)));
|
||||
|
||||
assert(std::string("0ns") == format_time_ns(static_cast<uint64_t>(0)));
|
||||
assert(std::string("1ns") == format_time_ns(static_cast<uint64_t>(1)));
|
||||
assert(std::string("1us") == format_time_ns(static_cast<uint64_t>(1e3)));
|
||||
assert(std::string("1ms") == format_time_ns(static_cast<uint64_t>(1e6)));
|
||||
assert(std::string("1s") == format_time_ns(static_cast<uint64_t>(1e9)));
|
||||
assert(std::string("1m") == format_time_ns(static_cast<uint64_t>(6e10)));
|
||||
assert(std::string("1h") == format_time_ns(static_cast<uint64_t>(36e11)));
|
||||
assert(std::string("1j") == format_time_ns(static_cast<uint64_t>(864e11)));
|
||||
assert(std::string("1w") == format_time_ns(static_cast<uint64_t>(6048e11)));
|
||||
assert(std::string("1M") == format_time_ns(static_cast<uint64_t>(24192e11)));
|
||||
assert(std::string("1y") == format_time_ns(static_cast<uint64_t>(290304e11)));
|
||||
// UINT64_MAX == 18446744073709551615I64u == -1
|
||||
assert(std::string("635y 5M 3j 23h 34m 33s 709ms 551us 615ns") == format_time_ns(static_cast<uint64_t>(-1)));
|
||||
}
|
||||
|
||||
std::string thousand_sep(uint64_t k) noexcept {
|
||||
std::string s = "", n = std::to_string(k);
|
||||
|
||||
uint8_t c = 0;
|
||||
for (const char& n_i : n) {
|
||||
++c;
|
||||
s.push_back(n_i);
|
||||
if (c == 3) {
|
||||
s.push_back(',');
|
||||
int8_t c = 0, n_i = n.length() - 1, j = st_size - 1;
|
||||
for(; n_i >= 0; --n_i) {
|
||||
s[j--] = n[n_i];
|
||||
if (++c == 3 && j >= 0) {
|
||||
s[j--] = separator;
|
||||
c = 0;
|
||||
}
|
||||
}
|
||||
|
||||
std::reverse(s.begin(), s.end());
|
||||
|
||||
if (s.size() % 4 == 0)
|
||||
s.erase(s.begin());
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user