diff --git a/CMakeLists.txt b/CMakeLists.txt index 8bba709..df01084 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/include/blt/math/math.h b/include/blt/math/math.h index 708d6b0..32041b2 100644 --- a/include/blt/math/math.h +++ b/include/blt/math/math.h @@ -56,8 +56,8 @@ namespace blt #ifdef __GNUC__ #pragma GCC diagnostic pop #endif - - + + template static inline constexpr R pow(B b, P p) { @@ -67,22 +67,61 @@ namespace blt return collection; } + template + 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(value); + auto f_value = value - static_cast(i_value); + if (f_value > 0) + return ((static_cast(i_value) * multiplier + 1) / multiplier); + else + return static_cast(i_value); + } + } + }; + + template + 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(value * multiplier)) / multiplier; + } + } + }; + /** * This is a fast rounding function and is not guaranteed to be 100% correct * @tparam decimal_places * @param value * @return */ - template + template 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 round_func; + return round_func(value); + } + + template + constexpr static inline double round_down(double value) + { + + round_down_t round_func; + return round_func(value); } /*inline std::ostream& operator<<(std::ostream& out, const mat4x4& v) { diff --git a/include/blt/std/format.h b/include/blt/std/format.h index a22b517..47cd739 100644 --- a/include/blt/std/format.h +++ b/include/blt/std/format.h @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include "memory.h" @@ -19,17 +20,27 @@ namespace blt::string { - template static inline std::string withGrouping(T t, size_t group = 3) { // TODO: all this + make it faster - static_assert(std::is_integral_v, "Must be integer type! (Floats currently not supported!)"); + static_assert(std::is_arithmetic_v && "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(str.size() - 1); + for (auto i = start_pos; i >= 0; i--) + { + if (str[i] == '.') + { + start_pos = i - 1; + break; + } + } + for (auto i = static_cast(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 - static inline std::string fromBytes(unsigned long bytes) +} + +namespace blt +{ + class byte_convert_t { - if (bytes > 1073741824) - { - // gigabyte - return std::to_string(round_up((double) bytes / 1024.0 / 1024.0 / 1024.0)) += "gb"; - } else if (bytes > 1048576) - { - // megabyte - return std::to_string(round_up((double) bytes / 1024.0 / 1024.0)) += "mb"; - } else if (bytes > 1024) - { - // kilobyte - return std::to_string(round_up((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(bytes) / static_cast(static_cast(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(bytes) / static_cast(static_cast(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 typename round_function = round_up_t> + [[nodiscard]] double getConvertedRound() const + { + round_function convert{}; + return convert(converted); + } + + template typename round_function = round_up_t> + [[nodiscard]] std::string to_pretty_string() const + { + auto str = string::withGrouping(getConvertedRound(), 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 + static inline std::string fromBytes(blt::u64 bytes) + { + byte_convert_t convert(bytes); + convert.convert_to_nearest_type(); + return std::to_string(convert.getConvertedRound()) + convert.type_string(); } // TODO: update table formatter to use these! diff --git a/libraries/parallel-hashmap b/libraries/parallel-hashmap index 8a889d3..d88c5e1 160000 --- a/libraries/parallel-hashmap +++ b/libraries/parallel-hashmap @@ -1 +1 @@ -Subproject commit 8a889d3699b3c09ade435641fb034427f3fd12b6 +Subproject commit d88c5e15079047777b418132ece5879e7c9aaa2b