diff --git a/include/fmt/core.h b/include/fmt/core.h index 1a75100a..01804f87 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -760,6 +760,62 @@ using has_fallback_formatter = template struct named_arg_base; template struct named_arg; +template struct named_arg_info { + const Char* name; + int arg_id; +}; + +template +struct arg_data { + T args[NUM_ARGS != 0 ? NUM_ARGS : 1]; + named_arg_info named_args[NUM_NAMED_ARGS]; + template arg_data(const U&... init) : args{init...} {} +}; + +template +struct arg_data { + T args[NUM_ARGS != 0 ? NUM_ARGS : 1]; + static constexpr std::nullptr_t named_args = nullptr; + template arg_data(const U&... init) : args{init...} {} +}; + +template +constexpr std::nullptr_t arg_data::named_args; + +template +inline void init_named_args(named_arg_info*, int, int) {} + +template +void init_named_args(named_arg_info* named_args, int arg_count, + int named_arg_count, const T&, const Tail&... args) { + init_named_args(named_args, arg_count + 1, named_arg_count, args...); +} + +template +void init_named_args(named_arg_info* named_args, int arg_count, + int named_arg_count, const named_arg& arg, + const Tail&... args) { + named_args[named_arg_count++] = {arg.name.data(), arg_count}; + init_named_args(named_args, arg_count + 1, named_arg_count, args...); +} + +template +void init_named_args(std::nullptr_t, int, int, const Args&...) {} + +template struct is_named_arg : std::false_type {}; + +template +struct is_named_arg> : std::true_type {}; + +template constexpr size_t count() { return B ? 1 : 0; } +template constexpr size_t count() { + return (B1 ? 1 : 0) + count(); +} + +template constexpr size_t count_named_args() { + return count::value...>(); +} + enum class type { none_type, named_arg_type, @@ -1338,22 +1394,26 @@ class format_arg_store using value_type = conditional_t, basic_format_arg>; - // If the arguments are not packed, add one more element to mark the end. - value_type data_[num_args + (num_args == 0 ? 1 : 0)]; + internal::arg_data()> + data_; friend class basic_format_args; - public: - static constexpr unsigned long long types = + static constexpr unsigned long long desc = is_packed ? internal::encode_types() : internal::is_unpacked_bit | num_args; + public: + FMT_DEPRECATED static constexpr unsigned long long types = desc; + format_arg_store(const Args&... args) : #if FMT_GCC_VERSION && FMT_GCC_VERSION < 409 basic_format_args(*this), #endif data_{internal::make_arg(args)...} { + internal::init_named_args(data_.named_args, 0, 0, args...); } }; @@ -1536,8 +1596,8 @@ template class basic_format_args { */ template basic_format_args(const format_arg_store& store) - : desc_(store.types) { - set_data(store.data_); + : desc_(store.desc) { + set_data(store.data_.args); } /**