new format for bytes, rounding functions / types, they don't work.

rounding up at least
v1
Brett 2024-08-23 21:13:16 -04:00
parent 675c4234bc
commit 1b09483af0
4 changed files with 172 additions and 36 deletions

View File

@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.20)
include(cmake/color.cmake)
set(BLT_VERSION 0.19.0)
set(BLT_VERSION 0.19.1)
set(BLT_TEST_VERSION 0.0.1)
set(BLT_TARGET BLT)

View File

@ -56,8 +56,8 @@ namespace blt
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
template<typename B, typename P, typename R = decltype(B() * P())>
static inline constexpr R pow(B b, P p)
{
@ -67,22 +67,61 @@ namespace blt
return collection;
}
template<blt::i64 decimal_places>
struct round_up_t
{
constexpr inline double operator()(double value)
{
if constexpr (decimal_places < 0)
return value;
else
{
constexpr double multiplier = pow(10.0, decimal_places);
auto i_value = static_cast<blt::i64>(value);
auto f_value = value - static_cast<double>(i_value);
if (f_value > 0)
return ((static_cast<double>(i_value) * multiplier + 1) / multiplier);
else
return static_cast<double>(i_value);
}
}
};
template<blt::i64 decimal_places>
struct round_down_t
{
constexpr inline double operator()(double value)
{
if constexpr (decimal_places < 0)
return value;
else
{
constexpr double multiplier = pow(10.0, decimal_places);
return (static_cast<blt::i64>(value * multiplier)) / multiplier;
}
}
};
/**
* This is a fast rounding function and is not guaranteed to be 100% correct
* @tparam decimal_places
* @param value
* @return
*/
template<int decimal_places>
template<blt::i64 decimal_places>
constexpr static inline double round_up(double value)
{
if constexpr (decimal_places < 0)
return value;
else
{
constexpr double multiplier = pow(10.0, decimal_places);
return ((int) (value * multiplier) + 1) / multiplier;
}
round_up_t<decimal_places> round_func;
return round_func(value);
}
template<blt::i64 decimal_places>
constexpr static inline double round_down(double value)
{
round_down_t<decimal_places> round_func;
return round_func(value);
}
/*inline std::ostream& operator<<(std::ostream& out, const mat4x4& v) {

View File

@ -11,6 +11,7 @@
#include <utility>
#include <vector>
#include <blt/math/math.h>
#include <blt/std/types.h>
#include <algorithm>
#include <string_view>
#include "memory.h"
@ -19,17 +20,27 @@
namespace blt::string
{
template<typename T>
static inline std::string withGrouping(T t, size_t group = 3)
{
// TODO: all this + make it faster
static_assert(std::is_integral_v<T>, "Must be integer type! (Floats currently not supported!)");
static_assert(std::is_arithmetic_v<T> && "Must be arithmetic type!");
auto str = std::to_string(t);
std::string ret;
ret.reserve(str.size());
size_t count = 0;
for (int64_t i = str.size() - 1; i >= 0; i--)
blt::size_t count = 0;
auto start_pos = static_cast<blt::i64>(str.size() - 1);
for (auto i = start_pos; i >= 0; i--)
{
if (str[i] == '.')
{
start_pos = i - 1;
break;
}
}
for (auto i = static_cast<blt::i64>(str.size() - 1); i > start_pos; i--)
ret += str[i];
for (auto i = start_pos; i >= 0; i--)
{
ret += str[i];
if (count++ % (group) == group - 1 && i != 0)
@ -38,27 +49,113 @@ namespace blt::string
std::reverse(ret.begin(), ret.end());
return ret;
}
// negative decimal places will not round.
template<int decimal_places = -1>
static inline std::string fromBytes(unsigned long bytes)
}
namespace blt
{
class byte_convert_t
{
if (bytes > 1073741824)
{
// gigabyte
return std::to_string(round_up<decimal_places>((double) bytes / 1024.0 / 1024.0 / 1024.0)) += "gb";
} else if (bytes > 1048576)
{
// megabyte
return std::to_string(round_up<decimal_places>((double) bytes / 1024.0 / 1024.0)) += "mb";
} else if (bytes > 1024)
{
// kilobyte
return std::to_string(round_up<decimal_places>((double) bytes / 1024.0)) += "kb";
} else
{
return std::to_string(bytes) += "b";
}
public:
enum class byte_t : blt::u64
{
Bytes = 1,
Kilobyte = 1024,
Megabyte = 1024 * 1024,
Gigabyte = 1024 * 1024 * 1024,
};
explicit byte_convert_t(blt::u64 bytes): bytes(bytes)
{}
byte_convert_t(blt::u64 bytes, byte_t convert_type): bytes(bytes), type(convert_type)
{
converted = static_cast<double>(bytes) / static_cast<double>(static_cast<blt::u64>(type));
}
byte_convert_t& convert_to_nearest_type()
{
if (bytes > 1073741824)
{
// gigabyte
type = byte_t::Gigabyte;
} else if (bytes > 1048576)
{
// megabyte
type = byte_t::Megabyte;
} else if (bytes > 1024)
{
// kilobyte
type = byte_t::Kilobyte;
} else
{
type = byte_t::Bytes;
}
converted = static_cast<double>(bytes) / static_cast<double>(static_cast<blt::u64>(type));
return *this;
}
[[nodiscard]] std::string_view type_string() const
{
switch (type)
{
case byte_t::Bytes:
return "b";
case byte_t::Kilobyte:
return "KiB";
case byte_t::Megabyte:
return "MiB";
case byte_t::Gigabyte:
return "GiB";
}
return "NotPossible!";
}
[[nodiscard]] double getConverted() const
{
return converted;
}
template<blt::i64 decimal_places = -1, template<blt::i64> typename round_function = round_up_t>
[[nodiscard]] double getConvertedRound() const
{
round_function<decimal_places> convert{};
return convert(converted);
}
template<blt::i64 decimal_places = -1, template<blt::i64> typename round_function = round_up_t>
[[nodiscard]] std::string to_pretty_string() const
{
auto str = string::withGrouping(getConvertedRound<decimal_places, round_function>(), 3);
str += type_string();
return str;
}
[[nodiscard]] blt::u64 getBytes() const
{
return bytes;
}
[[nodiscard]] byte_t getType() const
{
return type;
}
private:
blt::u64 bytes = 0;
byte_t type = byte_t::Bytes;
double converted = 0;
};
}
namespace blt::string
{
// negative decimal places will not round.
template<blt::i64 decimal_places = -1>
static inline std::string fromBytes(blt::u64 bytes)
{
byte_convert_t convert(bytes);
convert.convert_to_nearest_type();
return std::to_string(convert.getConvertedRound<decimal_places>()) + convert.type_string();
}
// TODO: update table formatter to use these!

@ -1 +1 @@
Subproject commit 8a889d3699b3c09ade435641fb034427f3fd12b6
Subproject commit d88c5e15079047777b418132ece5879e7c9aaa2b