Add support for size_t and unsigned long to etl::format (#1290)

* Remove AppVeyor build status badge

Removed AppVeyor build status badge from README.

* Update README.md

* Update CONTRIBUTING.md

Updated the instructions for contributing.

* Fix for issue 1276 "Data corruption in the etl::bip_buffer_spsc_atomic" (#1277)

* Reproduce data corruption bug in the `etl::bip_buffer_spsc_atomic`.

* Fix data corruption bug in the `etl::bip_buffer_spsc_atomic`.

* Add support for size_t and unsigned long to etl::format

* Document list of supported types in etl::supported_format_types

* Add further types and tests for etl::format

---------

Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com>
Co-authored-by: Sergei <sergej.shirokov@gmail.com>
This commit is contained in:
Roland Reichwein 2026-02-06 11:08:17 +01:00 committed by GitHub
parent 2a79845dd5
commit 10fd81c2be
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 175 additions and 3 deletions

View File

@ -123,7 +123,13 @@ namespace etl
template<class... Args>
using format_string = basic_format_string<type_identity_t<Args>...>;
// supported types to format
// Supported types to format
//
// This is the limited number of types as defined in std::basic_format_arg
// https://en.cppreference.com/w/cpp/utility/format/basic_format_arg.html
//
// Further types to be supported are added via converting constructors in
// etl::basic_format_arg
using supported_format_types = etl::variant<
etl::monostate,
bool,
@ -239,6 +245,21 @@ namespace etl
{
}
basic_format_arg(const short v)
: data(static_cast<int>(v))
{
}
basic_format_arg(const unsigned short v)
: data(static_cast<unsigned int>(v))
{
}
basic_format_arg(const long int v)
: data(static_cast<long long int>(v))
{
}
basic_format_arg(const unsigned int v)
: data(v)
{
@ -254,6 +275,13 @@ namespace etl
{
}
// Additional type to list of basic types as defined for std::basic_format_arg:
// Mapping unsigned long to unsigned long long int
basic_format_arg(const unsigned long v)
: data(static_cast<unsigned long long int>(v))
{
}
basic_format_arg(const char* v)
: data(v)
{
@ -264,6 +292,16 @@ namespace etl
{
}
basic_format_arg(const signed char v)
: data(static_cast<char>(v))
{
}
basic_format_arg(const unsigned char v)
: data(static_cast<char>(v))
{
}
basic_format_arg(const float v)
: data(v)
{

View File

@ -86,6 +86,62 @@ namespace
CHECK_EQUAL("-1", test_format(s, "{}", -1));
}
//*************************************************************************
TEST(test_format_short)
{
etl::string<100> s;
CHECK_EQUAL("1", test_format(s, "{}", static_cast<short>(1)));
CHECK_EQUAL("123", test_format(s, "{}", static_cast<short>(123)));
CHECK_EQUAL("4123", test_format(s, "{}", static_cast<short>(4123)));
CHECK_EQUAL("1 2", test_format(s, "{} {}", static_cast<short>(1), static_cast<short>(2)));
CHECK_EQUAL("-123", test_format(s, "{}", static_cast<short>(-123)));
CHECK_EQUAL("0", test_format(s, "{}", static_cast<short>(0)));
CHECK_EQUAL("-1", test_format(s, "{}", static_cast<short>(-1)));
}
//*************************************************************************
TEST(test_format_unsigned_short)
{
etl::string<100> s;
CHECK_EQUAL("1", test_format(s, "{}", static_cast<unsigned short>(1)));
CHECK_EQUAL("123", test_format(s, "{}", static_cast<unsigned short>(123)));
CHECK_EQUAL("4123", test_format(s, "{}", static_cast<unsigned short>(4123)));
CHECK_EQUAL("1 2", test_format(s, "{} {}", static_cast<unsigned short>(1), static_cast<unsigned short>(2)));
CHECK_EQUAL("60123", test_format(s, "{}", static_cast<unsigned short>(60123)));
CHECK_EQUAL("0", test_format(s, "{}", static_cast<unsigned short>(0)));
CHECK_EQUAL("65500", test_format(s, "{}", static_cast<unsigned short>(65500)));
}
//*************************************************************************
TEST(test_format_long_int)
{
etl::string<100> s;
CHECK_EQUAL("1", test_format(s, "{}", static_cast<long int>(1)));
CHECK_EQUAL("123", test_format(s, "{}", static_cast<long int>(123)));
CHECK_EQUAL("4123", test_format(s, "{}", static_cast<long int>(4123)));
CHECK_EQUAL("1 2", test_format(s, "{} {}", static_cast<long int>(1), static_cast<long int>(2)));
CHECK_EQUAL("-123", test_format(s, "{}", static_cast<long int>(-123)));
CHECK_EQUAL("0", test_format(s, "{}", static_cast<long int>(0)));
CHECK_EQUAL("-1", test_format(s, "{}", static_cast<long int>(-1)));
}
//*************************************************************************
TEST(test_format_unsigned_long_int)
{
etl::string<100> s;
CHECK_EQUAL("1", test_format(s, "{}", static_cast<unsigned long int>(1)));
CHECK_EQUAL("123", test_format(s, "{}", static_cast<unsigned long int>(123)));
CHECK_EQUAL("4123", test_format(s, "{}", static_cast<unsigned long int>(4123)));
CHECK_EQUAL("1 2", test_format(s, "{} {}", static_cast<unsigned long int>(1), static_cast<unsigned long int>(2)));
CHECK_EQUAL("60123", test_format(s, "{}", static_cast<unsigned long int>(60123)));
CHECK_EQUAL("0", test_format(s, "{}", static_cast<unsigned long int>(0)));
CHECK_EQUAL("65500", test_format(s, "{}", static_cast<unsigned long int>(65500)));
}
//*************************************************************************
TEST(test_format_unsigned_int)
{
@ -131,8 +187,10 @@ namespace
{
etl::string<100> s;
CHECK_EQUAL("34", test_format(s, "{}", static_cast<uint8_t>(34)));
CHECK_EQUAL("-14", test_format(s, "{}", static_cast<int8_t>(-14)));
// mapped to unsigned char
//CHECK_EQUAL("34", test_format(s, "{}", static_cast<uint8_t>(34)));
// mapped to signed char
//CHECK_EQUAL("-14", test_format(s, "{}", static_cast<int8_t>(-14)));
CHECK_EQUAL("6534", test_format(s, "{}", static_cast<uint16_t>(6534)));
CHECK_EQUAL("-9414", test_format(s, "{}", static_cast<int16_t>(-9414)));
CHECK_EQUAL("236534", test_format(s, "{}", static_cast<uint32_t>(236534)));
@ -398,6 +456,82 @@ namespace
}
}
//*************************************************************************
TEST(test_format_size_t)
{
etl::string<100> s;
CHECK_EQUAL("0", test_format(s, "{}", static_cast<size_t>(0LL)));
CHECK_EQUAL("1", test_format(s, "{}", static_cast<size_t>(1LL)));
CHECK_EQUAL("12345678", test_format(s, "{}", static_cast<size_t>(12345678LL)));
CHECK_EQUAL("4123456780", test_format(s, "{}", static_cast<size_t>(4123456780LL)));
#if ETL_PLATFORM_64BIT
static_assert(sizeof(size_t) == 8, "size_t is expected to be 64 bit on 64 bit platforms");
CHECK_EQUAL("18446744073709551615", test_format(s, "{}", static_cast<size_t>(18446744073709551615ULL)));
CHECK_EQUAL("1311768467463790320", test_format(s, "{}", static_cast<size_t>(0x123456789ABCDEF0ULL)));
#endif
}
//*************************************************************************
TEST(test_format_unsigned_long)
{
etl::string<100> s;
CHECK_EQUAL("0", test_format(s, "{}", static_cast<unsigned long>(0LL)));
CHECK_EQUAL("1", test_format(s, "{}", static_cast<unsigned long>(1LL)));
CHECK_EQUAL("12345678", test_format(s, "{}", static_cast<unsigned long>(12345678LL)));
CHECK_EQUAL("4123456780", test_format(s, "{}", static_cast<unsigned long>(4123456780LL)));
#if ETL_PLATFORM_64BIT
static_assert(sizeof(unsigned long) == 8, "size_t is expected to be 64 bit on 64 bit platforms");
CHECK_EQUAL("18446744073709551615", test_format(s, "{}", static_cast<unsigned long>(18446744073709551615ULL)));
CHECK_EQUAL("1311768467463790320", test_format(s, "{}", static_cast<unsigned long>(0x123456789ABCDEF0ULL)));
#endif
}
//*************************************************************************
TEST(test_format_signed_char)
{
etl::string<100> s;
CHECK_EQUAL("a s b", test_format(s, "a {} b", static_cast<signed char>('s')));
CHECK_EQUAL("a s b", test_format(s, "a {:c} b", static_cast<signed char>('s')));
CHECK_EQUAL("a 's' b", test_format(s, "a {:?} b", static_cast<signed char>('s')));
CHECK_EQUAL("a \t b", test_format(s, "a {} b", static_cast<signed char>('\t')));
CHECK_EQUAL("a '\\t' b", test_format(s, "a {:?} b", static_cast<signed char>('\t')));
CHECK_EQUAL("a '\\n' b", test_format(s, "a {:?} b", static_cast<signed char>('\n')));
CHECK_EQUAL("a '\\r' b", test_format(s, "a {:?} b", static_cast<signed char>('\r')));
CHECK_EQUAL("a '\\\"' b", test_format(s, "a {:?} b", static_cast<signed char>('"')));
CHECK_EQUAL("a '\\'' b", test_format(s, "a {:?} b", static_cast<signed char>('\'')));
CHECK_EQUAL("a '\\\\' b", test_format(s, "a {:?} b", static_cast<signed char>('\\')));
CHECK_EQUAL("a '\\\\' b", test_format(s, "a {:?} b", static_cast<signed char>('\\')));
CHECK_EQUAL("a 97 b", test_format(s, "a {:d} b", static_cast<signed char>('a')));
CHECK_EQUAL("a 61 b", test_format(s, "a {:X} b", static_cast<signed char>('a')));
CHECK_EQUAL("a 61 b", test_format(s, "a {:x} b", static_cast<signed char>('a')));
CHECK_EQUAL("a 0x61 b", test_format(s, "a {:#x} b", static_cast<signed char>('a')));
}
//*************************************************************************
TEST(test_format_unsigned_char)
{
etl::string<100> s;
CHECK_EQUAL("a s b", test_format(s, "a {} b", static_cast<unsigned char>('s')));
CHECK_EQUAL("a s b", test_format(s, "a {:c} b", static_cast<unsigned char>('s')));
CHECK_EQUAL("a 's' b", test_format(s, "a {:?} b", static_cast<unsigned char>('s')));
CHECK_EQUAL("a \t b", test_format(s, "a {} b", static_cast<unsigned char>('\t')));
CHECK_EQUAL("a '\\t' b", test_format(s, "a {:?} b", static_cast<unsigned char>('\t')));
CHECK_EQUAL("a '\\n' b", test_format(s, "a {:?} b", static_cast<unsigned char>('\n')));
CHECK_EQUAL("a '\\r' b", test_format(s, "a {:?} b", static_cast<unsigned char>('\r')));
CHECK_EQUAL("a '\\\"' b", test_format(s, "a {:?} b", static_cast<unsigned char>('"')));
CHECK_EQUAL("a '\\'' b", test_format(s, "a {:?} b", static_cast<unsigned char>('\'')));
CHECK_EQUAL("a '\\\\' b", test_format(s, "a {:?} b", static_cast<unsigned char>('\\')));
CHECK_EQUAL("a '\\\\' b", test_format(s, "a {:?} b", static_cast<unsigned char>('\\')));
CHECK_EQUAL("a 97 b", test_format(s, "a {:d} b", static_cast<unsigned char>('a')));
CHECK_EQUAL("a 61 b", test_format(s, "a {:X} b", static_cast<unsigned char>('a')));
CHECK_EQUAL("a 61 b", test_format(s, "a {:x} b", static_cast<unsigned char>('a')));
CHECK_EQUAL("a 0x61 b", test_format(s, "a {:#x} b", static_cast<unsigned char>('a')));
}
//*************************************************************************
TEST(test_format_limit)
{