Clean up basic_format_args

This commit is contained in:
Victor Zverovich
2020-04-11 08:22:53 -07:00
parent 7645ca0724
commit 3aab2171ed

View File

@@ -1331,7 +1331,7 @@ class format_arg_store
{ {
private: private:
static const size_t num_args = sizeof...(Args); static const size_t num_args = sizeof...(Args);
static const bool is_packed = num_args < internal::max_packed_args; static const bool is_packed = num_args <= internal::max_packed_args;
using value_type = conditional_t<is_packed, internal::value<Context>, using value_type = conditional_t<is_packed, internal::value<Context>,
basic_format_arg<Context>>; basic_format_arg<Context>>;
@@ -1481,25 +1481,27 @@ template <typename Context> class basic_format_args {
using format_arg = basic_format_arg<Context>; using format_arg = basic_format_arg<Context>;
private: private:
// To reduce compiled code size per formatting function call, types of first // A descriptor that contains information about formatting arguments.
// max_packed_args arguments are passed in the types_ field. // If the number of arguments is less or equal to max_packed_args then
unsigned long long types_; // argument types are passed in the descriptor. This reduces binary code size
// per formatting function call.
unsigned long long desc_;
union { union {
// If the number of arguments is less than max_packed_args, the argument // If is_packed() returns true then argument values are stored in values_;
// values are stored in values_, otherwise they are stored in args_. // otherwise they are stored in args_. This is done to improve cache
// This is done to reduce compiled code size as storing larger objects // 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 // 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. // data is actually copied to stack. It saves ~10% on the bloat test.
const internal::value<Context>* values_; const internal::value<Context>* values_;
const format_arg* args_; const format_arg* args_;
}; };
bool is_packed() const { return (types_ & internal::is_unpacked_bit) == 0; } bool is_packed() const { return (desc_ & internal::is_unpacked_bit) == 0; }
internal::type type(int index) const { internal::type type(int index) const {
int shift = index * internal::packed_arg_bits; int shift = index * internal::packed_arg_bits;
unsigned int mask = (1 << internal::packed_arg_bits) - 1; unsigned int mask = (1 << internal::packed_arg_bits) - 1;
return static_cast<internal::type>((types_ >> shift) & mask); return static_cast<internal::type>((desc_ >> shift) & mask);
} }
friend class internal::arg_map<Context>; friend class internal::arg_map<Context>;
@@ -1523,7 +1525,7 @@ template <typename Context> class basic_format_args {
} }
public: public:
basic_format_args() : types_(0) {} basic_format_args() : desc_(0) {}
/** /**
\rst \rst
@@ -1532,7 +1534,7 @@ template <typename Context> class basic_format_args {
*/ */
template <typename... Args> template <typename... Args>
basic_format_args(const format_arg_store<Context, Args...>& store) basic_format_args(const format_arg_store<Context, Args...>& store)
: types_(store.types) { : desc_(store.types) {
set_data(store.data_); set_data(store.data_);
} }
@@ -1543,7 +1545,7 @@ template <typename Context> class basic_format_args {
\endrst \endrst
*/ */
basic_format_args(const dynamic_format_arg_store<Context>& store) basic_format_args(const dynamic_format_arg_store<Context>& store)
: types_(store.get_types()) { : desc_(store.get_types()) {
set_data(store.data_.data()); set_data(store.data_.data());
} }
@@ -1553,7 +1555,7 @@ template <typename Context> class basic_format_args {
\endrst \endrst
*/ */
basic_format_args(const format_arg* args, int count) basic_format_args(const format_arg* args, int count)
: types_(internal::is_unpacked_bit | internal::to_unsigned(count)) { : desc_(internal::is_unpacked_bit | internal::to_unsigned(count)) {
set_data(args); set_data(args);
} }
@@ -1568,7 +1570,7 @@ template <typename Context> class basic_format_args {
int max_size() const { int max_size() const {
unsigned long long max_packed = internal::max_packed_args; unsigned long long max_packed = internal::max_packed_args;
return static_cast<int>(is_packed() ? max_packed return static_cast<int>(is_packed() ? max_packed
: types_ & ~internal::is_unpacked_bit); : desc_ & ~internal::is_unpacked_bit);
} }
}; };