Skip to content

Commit

Permalink
Merge pull request #22 from MichaelMiller-/memory-class
Browse files Browse the repository at this point in the history
ensure compatibility with MSVC
  • Loading branch information
MichaelMiller- authored Jan 19, 2025
2 parents c7dcd07 + 1ae8566 commit 7c54467
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 16 deletions.
24 changes: 15 additions & 9 deletions include/sec21/memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,20 +68,30 @@ namespace sec21
}
} // namespace sec21

#if __cpp_lib_constexpr_charconv >= 202207L
template <>
struct std::formatter<sec21::memory>
class std::formatter<sec21::memory>
{
bool human_readable{false};
std::size_t precision{0};

public:
constexpr auto parse(std::format_parse_context& ctx)
{
auto pos = ctx.begin();
while (pos != ctx.end() and *pos != '}') {
if (*pos == 'h' or *pos == 'H') {
human_readable = true;
}
#ifndef WIN32
if (*pos == '.') {
//! \todo some issues with MSVC compiler
// maybe should work if proposal 'std::from_chars should work with std::string_view' is approved
// https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2007r0.html
pos = std::from_chars(++pos, ctx.end(), precision).ptr;
--pos;
}
#endif
++pos;
}
return pos;
Expand All @@ -90,25 +100,21 @@ struct std::formatter<sec21::memory>
auto format(sec21::memory const& obj, std::format_context& ctx) const
{
constexpr auto units = std::array{"B", "kB", "MB", "GB", "TB", "PB"};
auto value = static_cast<double>(obj.bytes);
auto unit = units[0];

if (human_readable) {
constexpr auto factor = 1000;
//! \todo constexpr auto factorIEC = 1024;

auto value = static_cast<double>(obj.bytes);
auto unit = units[0];

for (decltype(units.size()) i = 0; i < units.size(); ++i) {
if (obj.bytes >= std::pow(factor, i)) {
value = static_cast<double>(obj.bytes) / std::pow(factor, i);
unit = units[i];
}
}
return std::format_to(ctx.out(), "{:.{}f}{}", value, precision, unit);
}
return std::format_to(ctx.out(), "{}{}", obj.bytes, units[0]);
return std::format_to(ctx.out(), "{:.{}f}{}", value, precision, unit);
}

bool human_readable{false};
std::size_t precision{2};
};
#endif
25 changes: 18 additions & 7 deletions tests/memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,32 +20,43 @@ TEST_CASE("memory class", "[sec21]")
}
SECTION("test safety check of subtraction operator")
{
REQUIRE_THROWS([] { auto result = memory{2} - memory{10}; }());
REQUIRE_THROWS([] { [[maybe_unused]] auto result = memory{2} - memory{10}; }());
// REQUIRE_THROWS([] { auto result = memory{2} - std::byte{10}; }());
}
SECTION("multiplication")
{
REQUIRE(memory{2} * memory{1} == 2_B);
REQUIRE(4_kiB * std::byte{2} == memory{8192});
}
#if __cpp_lib_constexpr_charconv >= 202207L
SECTION("test formatter")
{
SECTION("default") { REQUIRE(std::format("{}", memory{1024}) == "1024B"); }

SECTION("format output to a human readable format")
{
REQUIRE(std::format("{:h}", memory{1_kiB}) == "1.02kB");
REQUIRE(std::format("{:h}", memory{1_MiB}) == "1.05MB");
REQUIRE(std::format("{:h}", memory{1_GiB}) == "1.07GB");
REQUIRE(std::format("{:h}", memory{1_TiB}) == "1.10TB");
REQUIRE(std::format("{:h}", memory{1_PiB}) == "1.13PB");
REQUIRE(std::format("{:h}", memory{1_kiB}) == "1kB");
REQUIRE(std::format("{:h}", memory{1_MiB}) == "1MB");
REQUIRE(std::format("{:h}", memory{1_GiB}) == "1GB");
REQUIRE(std::format("{:h}", memory{1_TiB}) == "1TB");
REQUIRE(std::format("{:h}", memory{1_PiB}) == "1PB");
}
#ifndef WIN32
SECTION("human readable format with precision")
{
REQUIRE(std::format("{:.0h}", memory{1024 * 1024}) == "1MB");
REQUIRE(std::format("{:.1h}", memory{1024 * 1024}) == "1.0MB");
REQUIRE(std::format("{:.2h}", memory{1024 * 1024}) == "1.05MB");
REQUIRE(std::format("{:.4h}", memory{1024 * 1024}) == "1.0486MB");
REQUIRE(std::format("{:.h}", memory{1024 * 1024}) == "1.05MB");
REQUIRE(std::format("{:.h}", memory{1024 * 1024}) == "1MB");
}
SECTION("format with precision")
{
REQUIRE(std::format("{:.0}", memory{1}) == "1B");
REQUIRE(std::format("{:.1}", memory{1}) == "1.0B");
REQUIRE(std::format("{:.4}", memory{1}) == "1.0000B");
}
#endif
}
#endif
}

0 comments on commit 7c54467

Please sign in to comment.