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) cmake_minimum_required(VERSION 3.20)
include(cmake/color.cmake) 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_TEST_VERSION 0.0.1)
set(BLT_TARGET BLT) set(BLT_TARGET BLT)

View File

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

View File

@ -11,6 +11,7 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <blt/math/math.h> #include <blt/math/math.h>
#include <blt/std/types.h>
#include <algorithm> #include <algorithm>
#include <string_view> #include <string_view>
#include "memory.h" #include "memory.h"
@ -19,17 +20,27 @@
namespace blt::string namespace blt::string
{ {
template<typename T> template<typename T>
static inline std::string withGrouping(T t, size_t group = 3) static inline std::string withGrouping(T t, size_t group = 3)
{ {
// TODO: all this + make it faster // 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); auto str = std::to_string(t);
std::string ret; std::string ret;
ret.reserve(str.size()); ret.reserve(str.size());
size_t count = 0; blt::size_t count = 0;
for (int64_t i = str.size() - 1; i >= 0; i--) 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]; ret += str[i];
if (count++ % (group) == group - 1 && i != 0) if (count++ % (group) == group - 1 && i != 0)
@ -38,27 +49,113 @@ namespace blt::string
std::reverse(ret.begin(), ret.end()); std::reverse(ret.begin(), ret.end());
return ret; return ret;
} }
}
// negative decimal places will not round.
template<int decimal_places = -1> namespace blt
static inline std::string fromBytes(unsigned long bytes) {
class byte_convert_t
{ {
if (bytes > 1073741824) public:
{ enum class byte_t : blt::u64
// gigabyte {
return std::to_string(round_up<decimal_places>((double) bytes / 1024.0 / 1024.0 / 1024.0)) += "gb"; Bytes = 1,
} else if (bytes > 1048576) Kilobyte = 1024,
{ Megabyte = 1024 * 1024,
// megabyte Gigabyte = 1024 * 1024 * 1024,
return std::to_string(round_up<decimal_places>((double) bytes / 1024.0 / 1024.0)) += "mb"; };
} else if (bytes > 1024)
{ explicit byte_convert_t(blt::u64 bytes): bytes(bytes)
// kilobyte {}
return std::to_string(round_up<decimal_places>((double) bytes / 1024.0)) += "kb";
} else byte_convert_t(blt::u64 bytes, byte_t convert_type): bytes(bytes), type(convert_type)
{ {
return std::to_string(bytes) += "b"; 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! // TODO: update table formatter to use these!

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