Support variable number of arguments to inject at runtime (#1580)

Further, switching internal member from array_view to span to
be closer to standard, and more constexpr friendly.

Also adjusting to C++11 template syntax.

Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com>
This commit is contained in:
Roland Reichwein 2026-09-01 20:16:24 +02:00 committed by GitHub
parent 06e54f6b23
commit c896d2d7dd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 38 additions and 7 deletions

View File

@ -35,7 +35,6 @@ SOFTWARE.
#include "algorithm.h"
#include "array.h"
#include "array_view.h"
#include "error_handler.h"
#include "limits.h"
#include "math.h"
@ -863,7 +862,7 @@ namespace etl
return _args.get(i);
}
etl::array_view<basic_format_arg<Context>> get()
etl::span<basic_format_arg<Context>> get()
{
return _args;
}
@ -884,6 +883,15 @@ namespace etl
{
}
// non-standard
// Constructs from externally owned storage, for cases where the number of
// arguments is only known at runtime and so no format_arg_store<Context, Args...>
// can be formed. The referenced storage must outlive this object.
explicit basic_format_args(etl::span<basic_format_arg<Context>> args_)
: _args(args_)
{
}
basic_format_args(const basic_format_args<Context>& other)
: _args(other._args)
{
@ -908,7 +916,7 @@ namespace etl
private:
etl::array_view<basic_format_arg<Context>> _args;
etl::span<basic_format_arg<Context>> _args;
};
namespace private_format

View File

@ -950,6 +950,29 @@ namespace
CHECK_EQUAL("010", test_format(s, "{:#o}", 8));
}
//*************************************************************************
// Arguments whose count is only known at runtime cannot be held in a
// format_arg_store<Context, Args...>, so basic_format_args can also be built
// directly over caller owned storage.
TEST(test_vformat_to_runtime_sized_args)
{
etl::string<100> s;
using iterator_t = etl::back_insert_iterator<etl::string<100>>;
using arg_t = etl::format_arg<iterator_t>;
etl::array<arg_t, 4> storage = {arg_t(1), arg_t("two"), arg_t(3), arg_t('x')};
// Only the first three of the four slots are used.
etl::vformat_to(etl::back_inserter(s), "{} {} {}", etl::format_args<iterator_t>(etl::span<arg_t>(storage.data(), 3U)));
CHECK_EQUAL("1 two 3", s);
// An empty argument list is also valid.
s.clear();
etl::vformat_to(etl::back_inserter(s), "no args", etl::format_args<iterator_t>(etl::span<arg_t>()));
CHECK_EQUAL("no args", s);
}
//*************************************************************************
TEST(test_format_custom_type)
{