mirror of
https://github.com/ETLCPP/etl.git
synced 2026-10-28 18:07:10 +08:00
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:
parent
06e54f6b23
commit
c896d2d7dd
@ -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"
|
||||
@ -627,7 +626,7 @@ namespace etl
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct has_formatter_parse<T, etl::void_t<decltype(etl::declval<etl::formatter<T>&>().parse(etl::declval<format_parse_context&>()))> >
|
||||
struct has_formatter_parse<T, etl::void_t<decltype(etl::declval<etl::formatter<T>&>().parse(etl::declval<format_parse_context&>()))>>
|
||||
: etl::true_type
|
||||
{
|
||||
};
|
||||
@ -642,7 +641,7 @@ namespace etl
|
||||
|
||||
template <typename T>
|
||||
struct has_formatter_format<T, etl::void_t<decltype(etl::declval<etl::formatter<T>&>().format(
|
||||
etl::declval<const T&>(), etl::declval<etl::basic_format_context<char*, char>&>()))> > : etl::true_type
|
||||
etl::declval<const T&>(), etl::declval<etl::basic_format_context<char*, char>&>()))>> : etl::true_type
|
||||
{
|
||||
};
|
||||
|
||||
@ -806,7 +805,7 @@ namespace etl
|
||||
// Converting constructor for user-defined types that provide an
|
||||
// etl::formatter<T> specialisation. The value is stored type-erased in a
|
||||
// handle, matching the std::basic_format_arg behaviour for custom types.
|
||||
template <typename T, typename = etl::enable_if_t<private_format::is_formattable<T>::value> >
|
||||
template <typename T, typename = etl::enable_if_t<private_format::is_formattable<T>::value>>
|
||||
basic_format_arg(const T& v)
|
||||
: data(handle(v))
|
||||
{
|
||||
@ -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
|
||||
@ -2019,7 +2027,7 @@ namespace etl
|
||||
}
|
||||
|
||||
// for user-defined types routed through basic_format_arg::handle
|
||||
void operator()(typename basic_format_arg<format_context<OutputIt> >::handle h)
|
||||
void operator()(typename basic_format_arg<format_context<OutputIt>>::handle h)
|
||||
{
|
||||
h.format(parse_ctx, fmt_ctx);
|
||||
}
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user