diff --git a/include/fmt/core.h b/include/fmt/core.h index 238a1f1b..b532fa83 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -765,6 +765,7 @@ FMT_CONSTEXPR11 typename std::enable_if< // Maximum number of arguments with packed types. enum { max_packed_args = 15 }; +enum : unsigned long long { is_unpacked_bit = 1ull << 63 }; template class arg_map; @@ -1150,17 +1151,17 @@ class format_arg_store { friend class basic_format_args; - static FMT_CONSTEXPR11 long long get_types() { + static FMT_CONSTEXPR11 unsigned long long get_types() { return IS_PACKED ? - static_cast(internal::get_types()) : - -static_cast(NUM_ARGS); + internal::get_types() : + internal::is_unpacked_bit | NUM_ARGS; } public: #if FMT_USE_CONSTEXPR11 - static FMT_CONSTEXPR11 long long TYPES = get_types(); + static FMT_CONSTEXPR11 unsigned long long TYPES = get_types(); #else - static const long long TYPES; + static const unsigned long long TYPES; #endif #if (FMT_GCC_VERSION && FMT_GCC_VERSION <= 405) || \ @@ -1179,7 +1180,8 @@ class format_arg_store { #if !FMT_USE_CONSTEXPR11 template -const long long format_arg_store::TYPES = get_types(); +const unsigned long long format_arg_store::TYPES = + get_types(); #endif /** @@ -1214,11 +1216,12 @@ class basic_format_args { const format_arg *args_; }; + bool is_packed() const { return (types_ & internal::is_unpacked_bit) == 0; } + typename internal::type type(unsigned index) const { unsigned shift = index * 4; - unsigned long long mask = 0xf; return static_cast( - (types_ & (mask << shift)) >> shift); + (types_ & (0xfull << shift)) >> shift); } friend class internal::arg_map; @@ -1228,10 +1231,8 @@ class basic_format_args { format_arg do_get(size_type index) const { format_arg arg; - long long signed_types = static_cast(types_); - if (signed_types < 0) { - unsigned long long num_args = - static_cast(-signed_types); + if (!is_packed()) { + auto num_args = max_size(); if (index < num_args) arg = args_[index]; return arg; @@ -1266,7 +1267,7 @@ class basic_format_args { \endrst */ basic_format_args(const format_arg *args, size_type count) - : types_(-static_cast(count)) { + : types_(internal::is_unpacked_bit | count) { set_data(args); } @@ -1279,10 +1280,8 @@ class basic_format_args { } unsigned max_size() const { - long long signed_types = static_cast(types_); - return static_cast( - signed_types < 0 ? - -signed_types : static_cast(internal::max_packed_args)); + unsigned long long max_packed = internal::max_packed_args; + return is_packed() ? max_packed : types_ & ~internal::is_unpacked_bit; } }; diff --git a/include/fmt/format.h b/include/fmt/format.h index f56a56bf..f0a6b6b3 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -1364,8 +1364,7 @@ void arg_map::init(const basic_format_args &args) { if (map_) return; map_ = new entry[args.max_size()]; - bool use_values = args.type(max_packed_args - 1) == internal::none_type; - if (use_values) { + if (args.is_packed()) { for (unsigned i = 0;/*nothing*/; ++i) { internal::type arg_type = args.type(i); switch (arg_type) {