mirror of
https://github.com/fmtlib/fmt.git
synced 2025-07-31 19:24:48 +02:00
Implement more efficient handling of large number of format arguments
This commit is contained in:
37
fmt/format.h
37
fmt/format.h
@@ -1534,7 +1534,7 @@ template <>
|
|||||||
constexpr uint64_t make_type<void>() { return 0; }
|
constexpr uint64_t make_type<void>() { return 0; }
|
||||||
|
|
||||||
// Maximum number of arguments with packed types.
|
// Maximum number of arguments with packed types.
|
||||||
enum { MAX_PACKED_ARGS = 16 };
|
enum { MAX_PACKED_ARGS = 15 };
|
||||||
|
|
||||||
template <bool IS_PACKED, typename Context, typename T>
|
template <bool IS_PACKED, typename Context, typename T>
|
||||||
inline typename std::enable_if<IS_PACKED, value<Context>>::type
|
inline typename std::enable_if<IS_PACKED, value<Context>>::type
|
||||||
@@ -1567,7 +1567,9 @@ class arg_store {
|
|||||||
Array data_;
|
Array data_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static const uint64_t TYPES = internal::make_type<Args..., void>();
|
static const uint64_t TYPES =
|
||||||
|
NUM_ARGS <= internal::MAX_PACKED_ARGS ?
|
||||||
|
internal::make_type<Args..., void>() : -NUM_ARGS;
|
||||||
|
|
||||||
arg_store(const Args &... args)
|
arg_store(const Args &... args)
|
||||||
: data_(Array{{internal::make_arg<IS_PACKED, Context>(args)...}}) {}
|
: data_(Array{{internal::make_arg<IS_PACKED, Context>(args)...}}) {}
|
||||||
@@ -1619,27 +1621,18 @@ class basic_args {
|
|||||||
void set_data(const format_arg *args) { args_ = args; }
|
void set_data(const format_arg *args) { args_ = args; }
|
||||||
|
|
||||||
format_arg get(size_type index) const {
|
format_arg get(size_type index) const {
|
||||||
|
int64_t signed_types = static_cast<int64_t>(types_);
|
||||||
|
if (signed_types < 0) {
|
||||||
|
uint64_t num_args = -signed_types;
|
||||||
|
return index < num_args ? args_[index] : format_arg();
|
||||||
|
}
|
||||||
|
if (index > internal::MAX_PACKED_ARGS)
|
||||||
|
return format_arg();
|
||||||
format_arg arg;
|
format_arg arg;
|
||||||
bool use_values = type(internal::MAX_PACKED_ARGS - 1) == internal::NONE;
|
arg.type_ = type(index);
|
||||||
if (index < internal::MAX_PACKED_ARGS) {
|
internal::value<Context> &val = arg.value_;
|
||||||
typename internal::Type arg_type = type(index);
|
val = values_[index];
|
||||||
internal::value<Context> &val = arg.value_;
|
return arg;
|
||||||
if (arg_type != internal::NONE)
|
|
||||||
val = use_values ? values_[index] : args_[index].value_;
|
|
||||||
arg.type_ = arg_type;
|
|
||||||
return arg;
|
|
||||||
}
|
|
||||||
if (use_values) {
|
|
||||||
// The index is greater than the number of arguments that can be stored
|
|
||||||
// in values, so return a "none" argument.
|
|
||||||
arg.type_ = internal::NONE;
|
|
||||||
return arg;
|
|
||||||
}
|
|
||||||
for (unsigned i = internal::MAX_PACKED_ARGS; i <= index; ++i) {
|
|
||||||
if (args_[i].type_ == internal::NONE)
|
|
||||||
return args_[i];
|
|
||||||
}
|
|
||||||
return args_[index];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
Reference in New Issue
Block a user