From ed56206c302dbc4f69e7b6115b2ca02d3952e0d6 Mon Sep 17 00:00:00 2001 From: SChernykh Date: Sun, 17 Sep 2023 10:38:46 +0200 Subject: [PATCH] More log tests --- src/log.h | 3 +-- src/util.h | 6 ++++++ tests/src/log_tests.cpp | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/src/log.h b/src/log.h index a83f9bb..c8977e4 100644 --- a/src/log.h +++ b/src/log.h @@ -80,13 +80,12 @@ struct Stream static_assert(1 < base && base <= 64, "Invalid base"); const bool negative = is_negative(data); + std::make_unsigned_t udata = abs(data); char buf[32]; size_t k = sizeof(buf); int w = m_numberWidth; - std::make_unsigned_t udata = static_cast>(data); - do { buf[--k] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/"[udata % base]; udata /= base; diff --git a/src/util.h b/src/util.h index 21fdbb0..bb373f3 100644 --- a/src/util.h +++ b/src/util.h @@ -97,6 +97,12 @@ template struct is_negative_helper { static FORCEINLINE bo template FORCEINLINE bool is_negative(T x) { return is_negative_helper::value>::value(x); } +template struct abs_helper {}; +template struct abs_helper { static FORCEINLINE T value(T x) { return x; } }; +template struct abs_helper { static FORCEINLINE std::make_unsigned_t value(T x) { return (x < 0) ? -x : x; } }; + +template FORCEINLINE std::make_unsigned_t abs(T x) { return abs_helper::value>::value(x); } + template FORCEINLINE void writeVarint(T value, U&& callback) { diff --git a/tests/src/log_tests.cpp b/tests/src/log_tests.cpp index 3598699..4a15635 100644 --- a/tests/src/log_tests.cpp +++ b/tests/src/log_tests.cpp @@ -73,4 +73,41 @@ TEST(log, pad_right) ASSERT_EQ(buf[N], '\0'); } +template +void check_number(T value) +{ + constexpr size_t N = 64; + + char buf[N]; + memset(buf, -1, N); + log::Stream s(buf); + s << log::BasedValue(value) << '\0'; + + char buf2[N]; + memset(buf2, -1, N); + snprintf(buf2, N, hex ? "%llx" : (std::is_signed::value ? "%lld" : "%llu"), value); + + ASSERT_EQ(memcmp(buf, buf2, N), 0); +} + +TEST(log, numbers) +{ + for (int64_t i = -1024; i <= 1024; ++i) { + check_number(i); + + if (i >= 0) { + check_number(i); + check_number(i); + check_number(i); + } + } + + check_number(std::numeric_limits::min()); + check_number(std::numeric_limits::max()); + check_number(std::numeric_limits::max()); + + check_number(std::numeric_limits::max()); + check_number(std::numeric_limits::max()); +} + }