Clean up bit fiddling for argument packing

This commit is contained in:
Victor Zverovich 2018-11-30 15:48:09 -08:00
parent 9dcf127fa5
commit bcf3fcd673
2 changed files with 17 additions and 19 deletions

View File

@ -765,6 +765,7 @@ FMT_CONSTEXPR11 typename std::enable_if<
// Maximum number of arguments with packed types. // Maximum number of arguments with packed types.
enum { max_packed_args = 15 }; enum { max_packed_args = 15 };
enum : unsigned long long { is_unpacked_bit = 1ull << 63 };
template <typename Context> template <typename Context>
class arg_map; class arg_map;
@ -1150,17 +1151,17 @@ class format_arg_store {
friend class basic_format_args<Context>; friend class basic_format_args<Context>;
static FMT_CONSTEXPR11 long long get_types() { static FMT_CONSTEXPR11 unsigned long long get_types() {
return IS_PACKED ? return IS_PACKED ?
static_cast<long long>(internal::get_types<Context, Args...>()) : internal::get_types<Context, Args...>() :
-static_cast<long long>(NUM_ARGS); internal::is_unpacked_bit | NUM_ARGS;
} }
public: public:
#if FMT_USE_CONSTEXPR11 #if FMT_USE_CONSTEXPR11
static FMT_CONSTEXPR11 long long TYPES = get_types(); static FMT_CONSTEXPR11 unsigned long long TYPES = get_types();
#else #else
static const long long TYPES; static const unsigned long long TYPES;
#endif #endif
#if (FMT_GCC_VERSION && FMT_GCC_VERSION <= 405) || \ #if (FMT_GCC_VERSION && FMT_GCC_VERSION <= 405) || \
@ -1179,7 +1180,8 @@ class format_arg_store {
#if !FMT_USE_CONSTEXPR11 #if !FMT_USE_CONSTEXPR11
template <typename Context, typename ...Args> template <typename Context, typename ...Args>
const long long format_arg_store<Context, Args...>::TYPES = get_types(); const unsigned long long format_arg_store<Context, Args...>::TYPES =
get_types();
#endif #endif
/** /**
@ -1214,11 +1216,12 @@ class basic_format_args {
const format_arg *args_; const format_arg *args_;
}; };
bool is_packed() const { return (types_ & internal::is_unpacked_bit) == 0; }
typename internal::type type(unsigned index) const { typename internal::type type(unsigned index) const {
unsigned shift = index * 4; unsigned shift = index * 4;
unsigned long long mask = 0xf;
return static_cast<typename internal::type>( return static_cast<typename internal::type>(
(types_ & (mask << shift)) >> shift); (types_ & (0xfull << shift)) >> shift);
} }
friend class internal::arg_map<Context>; friend class internal::arg_map<Context>;
@ -1228,10 +1231,8 @@ class basic_format_args {
format_arg do_get(size_type index) const { format_arg do_get(size_type index) const {
format_arg arg; format_arg arg;
long long signed_types = static_cast<long long>(types_); if (!is_packed()) {
if (signed_types < 0) { auto num_args = max_size();
unsigned long long num_args =
static_cast<unsigned long long>(-signed_types);
if (index < num_args) if (index < num_args)
arg = args_[index]; arg = args_[index];
return arg; return arg;
@ -1266,7 +1267,7 @@ class basic_format_args {
\endrst \endrst
*/ */
basic_format_args(const format_arg *args, size_type count) basic_format_args(const format_arg *args, size_type count)
: types_(-static_cast<int64_t>(count)) { : types_(internal::is_unpacked_bit | count) {
set_data(args); set_data(args);
} }
@ -1279,10 +1280,8 @@ class basic_format_args {
} }
unsigned max_size() const { unsigned max_size() const {
long long signed_types = static_cast<long long>(types_); unsigned long long max_packed = internal::max_packed_args;
return static_cast<unsigned>( return is_packed() ? max_packed : types_ & ~internal::is_unpacked_bit;
signed_types < 0 ?
-signed_types : static_cast<long long>(internal::max_packed_args));
} }
}; };

View File

@ -1364,8 +1364,7 @@ void arg_map<Context>::init(const basic_format_args<Context> &args) {
if (map_) if (map_)
return; return;
map_ = new entry[args.max_size()]; map_ = new entry[args.max_size()];
bool use_values = args.type(max_packed_args - 1) == internal::none_type; if (args.is_packed()) {
if (use_values) {
for (unsigned i = 0;/*nothing*/; ++i) { for (unsigned i = 0;/*nothing*/; ++i) {
internal::type arg_type = args.type(i); internal::type arg_type = args.type(i);
switch (arg_type) { switch (arg_type) {