Files

140 lines
4.4 KiB
C++
Raw Permalink Normal View History

2025-09-01 19:33:55 +09:00
/*
* SPDX-FileCopyrightText: 2025 M5Stack Technology CO LTD
*
* SPDX-License-Identifier: MIT
*/
/*
UnitTest for M5Utility
*/
#include <gtest/gtest.h>
#include <M5Utility.hpp>
#include <M5Unified.hpp>
#include <limits>
#if defined(__SIZEOF_INT128__)
#pragma message "Support I128"
namespace {
using u128_t = unsigned __int128;
using i128_t = __int128;
constexpr u128_t make_u128(uint64_t hi, uint64_t lo)
{
return ((u128_t)hi << 64) | (u128_t)lo;
}
constexpr i128_t make_i128(int64_t hi, uint64_t lo)
{
return (i128_t)(((u128_t)((uint64_t)hi) << 64) | (u128_t)lo);
}
} // namespace
#endif
2025-09-01 19:42:48 +09:00
TEST(Utility, Byteswap)
2025-09-01 19:33:55 +09:00
{
constexpr uint8_t u8{127};
constexpr int8_t i8{-128};
constexpr uint16_t u16{0x1234};
constexpr int16_t i16{-0x1234}; // 0xEDCC
constexpr uint32_t u32{0x12345678};
constexpr int32_t i32{-0x12345678}; // 0xEDCBA988
constexpr uint64_t u64{0x123456789ABCDEF0};
constexpr int64_t i64{-0x123456789ABCDEF0}; // 0xEDCBA98765432110
{
constexpr auto a = m5::stl::byteswap(u8);
EXPECT_EQ(a, u8);
constexpr auto b = m5::stl::byteswap(i8);
EXPECT_EQ(b, i8);
EXPECT_EQ(m5::stl::byteswap(a), u8);
EXPECT_EQ(m5::stl::byteswap(b), i8);
}
{
constexpr auto a = m5::stl::byteswap(u16);
EXPECT_EQ(a, 0x3412);
constexpr auto b = m5::stl::byteswap(i16);
EXPECT_EQ(b, (int16_t)0xCCED);
EXPECT_EQ(m5::stl::byteswap(a), u16);
EXPECT_EQ(m5::stl::byteswap(b), i16);
}
{
constexpr auto a = m5::stl::byteswap(u32);
EXPECT_EQ(a, 0x78563412);
constexpr auto b = m5::stl::byteswap(i32);
EXPECT_EQ(b, (int32_t)0x88A9CBED);
EXPECT_EQ(m5::stl::byteswap(a), u32);
EXPECT_EQ(m5::stl::byteswap(b), i32);
}
{
constexpr auto a = m5::stl::byteswap(u64);
EXPECT_EQ(a, 0xF0DEBC9A78563412);
constexpr auto b = m5::stl::byteswap(i64);
EXPECT_EQ(b, (int64_t)0x1021436587A9CBED);
EXPECT_EQ(m5::stl::byteswap(a), u64);
EXPECT_EQ(m5::stl::byteswap(b), i64);
}
#if defined(__SIZEOF_INT128__)
constexpr u128_t u128 = make_u128(u64, u64);
constexpr i128_t i128 = make_i128(i64, (uint64_t)i64);
{
constexpr u128_t expect_u = make_u128(0xF0DEBC9A78563412ULL, 0xF0DEBC9A78563412ULL);
constexpr i128_t expect_i = (i128_t)make_u128(0x1021436587A9CBEDULL, 0x1021436587A9CBEDULL);
constexpr auto a = m5::stl::byteswap(u128);
EXPECT_EQ(a, expect_u);
constexpr auto b = m5::stl::byteswap(i128);
EXPECT_EQ(b, expect_i);
EXPECT_EQ(m5::stl::byteswap(a), u128);
EXPECT_EQ(m5::stl::byteswap(b), i128);
}
#endif
}
// Verify portable and default (builtin on GCC/Clang) implementations produce identical results
TEST(Utility, ByteswapPortable)
{
constexpr uint8_t u8{127};
constexpr int8_t i8{-128};
constexpr uint16_t u16{0x1234};
constexpr int16_t i16{-0x1234};
constexpr uint32_t u32{0x12345678};
constexpr int32_t i32{-0x12345678};
constexpr uint64_t u64{0x123456789ABCDEF0};
constexpr int64_t i64{-0x123456789ABCDEF0};
EXPECT_EQ(m5::stl::byteswap_with_portable(u8), m5::stl::byteswap(u8));
EXPECT_EQ(m5::stl::byteswap_with_portable(i8), m5::stl::byteswap(i8));
EXPECT_EQ(m5::stl::byteswap_with_portable(u16), m5::stl::byteswap(u16));
EXPECT_EQ(m5::stl::byteswap_with_portable(i16), m5::stl::byteswap(i16));
EXPECT_EQ(m5::stl::byteswap_with_portable(u32), m5::stl::byteswap(u32));
EXPECT_EQ(m5::stl::byteswap_with_portable(i32), m5::stl::byteswap(i32));
EXPECT_EQ(m5::stl::byteswap_with_portable(u64), m5::stl::byteswap(u64));
EXPECT_EQ(m5::stl::byteswap_with_portable(i64), m5::stl::byteswap(i64));
// Also verify round-trip with portable
EXPECT_EQ(m5::stl::byteswap_with_portable(m5::stl::byteswap_with_portable(u16)), u16);
EXPECT_EQ(m5::stl::byteswap_with_portable(m5::stl::byteswap_with_portable(u32)), u32);
EXPECT_EQ(m5::stl::byteswap_with_portable(m5::stl::byteswap_with_portable(u64)), u64);
#if defined(__SIZEOF_INT128__)
constexpr u128_t u128 = make_u128(u64, u64);
constexpr i128_t i128 = make_i128(i64, (uint64_t)i64);
EXPECT_EQ(m5::stl::byteswap_with_portable(u128), m5::stl::byteswap(u128));
EXPECT_EQ(m5::stl::byteswap_with_portable(i128), m5::stl::byteswap(i128));
EXPECT_EQ(m5::stl::byteswap_with_portable(m5::stl::byteswap_with_portable(u128)), u128);
#endif
}