Skip to content

Commit

Permalink
Simplify basic_format_args
Browse files Browse the repository at this point in the history
  • Loading branch information
vitaut committed Jan 9, 2024
1 parent 545d37a commit 973af31
Showing 1 changed file with 21 additions and 24 deletions.
45 changes: 21 additions & 24 deletions include/fmt/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -1727,15 +1727,19 @@ template <typename Context> class basic_format_args {
// argument types are passed in the descriptor. This reduces binary code size
// per formatting function call.
unsigned long long desc_;
union {
// If is_packed() returns true then argument values are stored in values_;
// otherwise they are stored in args_. This is done to improve cache
// locality and reduce compiled code size since storing larger objects
// may require more code (at least on x86-64) even if the same amount of
// data is actually copied to stack. It saves ~10% on the bloat test.
const detail::value<Context>* values_;
const format_arg* args_;
};

// If is_packed() returns true then arguments are stored as `detail::value`;
// otherwise they are stored as `format_arg` objects. This is done to improve
// cache locality and reduce compiled code size since storing larger objects
// may require more code (at least on x86-64) even if the same amount of
// data is actually copied to stack. It saves ~10% on the bloat test.
const void* args_;

auto get_value(int index) const -> const detail::value<Context>& {
return is_packed()
? static_cast<const detail::value<Context>*>(args_)[index]
: static_cast<const format_arg*>(args_)[index].value_;
}

constexpr auto is_packed() const -> bool {
return (desc_ & detail::is_unpacked_bit) == 0;
Expand All @@ -1750,12 +1754,6 @@ template <typename Context> class basic_format_args {
return static_cast<detail::type>((desc_ >> shift) & mask);
}

constexpr FMT_INLINE basic_format_args(unsigned long long desc,
const detail::value<Context>* values)
: desc_(desc), values_(values) {}
constexpr basic_format_args(unsigned long long desc, const format_arg* args)
: desc_(desc), args_(args) {}

public:
constexpr basic_format_args() : desc_(0), args_(nullptr) {}

Expand All @@ -1767,8 +1765,8 @@ template <typename Context> class basic_format_args {
template <size_t N, typename... Args>
constexpr FMT_INLINE basic_format_args(
const format_arg_store_impl<Context, N, Args...>& store)
: basic_format_args(format_arg_store_impl<Context, N, Args...>::desc,
store.args()) {}
: desc_(format_arg_store_impl<Context, N, Args...>::desc),
args_(store.args()) {}

/**
\rst
Expand All @@ -1778,28 +1776,28 @@ template <typename Context> class basic_format_args {
*/
constexpr FMT_INLINE basic_format_args(
const dynamic_format_arg_store<Context>& store)
: basic_format_args(store.get_types(), store.data()) {}
: desc_(store.get_types()), args_(store.data()) {}

/**
\rst
Constructs a `basic_format_args` object from a dynamic set of arguments.
\endrst
*/
constexpr basic_format_args(const format_arg* args, int count)
: basic_format_args(detail::is_unpacked_bit | detail::to_unsigned(count),
args) {}
: desc_(detail::is_unpacked_bit | detail::to_unsigned(count)),
args_(args) {}

/** Returns the argument with the specified id. */
FMT_CONSTEXPR auto get(int id) const -> format_arg {
format_arg arg;
if (!is_packed()) {
if (id < max_size()) arg = args_[id];
if (id < max_size()) arg = static_cast<const format_arg*>(args_)[id];
return arg;
}
if (id >= detail::max_packed_args) return arg;
arg.type_ = type(id);
if (arg.type_ == detail::type::none_type) return arg;
arg.value_ = values_[id];
arg.value_ = static_cast<const detail::value<Context>*>(args_)[id];
return arg;
}

Expand All @@ -1812,8 +1810,7 @@ template <typename Context> class basic_format_args {
template <typename Char>
FMT_CONSTEXPR auto get_id(basic_string_view<Char> name) const -> int {
if (!has_named_args()) return -1;
const auto& named_args =
(is_packed() ? values_[-1] : args_[-1].value_).named_args;
const auto& named_args = get_value(-1).named_args;
for (size_t i = 0; i < named_args.size; ++i) {
if (named_args.data[i].name == name) return named_args.data[i].id;
}
Expand Down

0 comments on commit 973af31

Please sign in to comment.