mirror of
https://github.com/fmtlib/fmt.git
synced 2025-07-30 10:47:35 +02:00
Simplify format_arg_store
This commit is contained in:
@ -1191,34 +1191,12 @@ template <typename Char> struct named_arg_info {
|
|||||||
int id;
|
int id;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Char>
|
|
||||||
inline void init_named_args(named_arg_info<Char>*, int, int) {}
|
|
||||||
|
|
||||||
template <typename T> struct is_named_arg : std::false_type {};
|
template <typename T> struct is_named_arg : std::false_type {};
|
||||||
template <typename T> struct is_statically_named_arg : std::false_type {};
|
template <typename T> struct is_statically_named_arg : std::false_type {};
|
||||||
|
|
||||||
template <typename T, typename Char>
|
template <typename T, typename Char>
|
||||||
struct is_named_arg<named_arg<Char, T>> : std::true_type {};
|
struct is_named_arg<named_arg<Char, T>> : std::true_type {};
|
||||||
|
|
||||||
template <typename Char, typename T, typename... Tail,
|
|
||||||
FMT_ENABLE_IF(!is_named_arg<T>::value)>
|
|
||||||
void init_named_args(named_arg_info<Char>* 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 <typename Char, typename T, typename... Tail,
|
|
||||||
FMT_ENABLE_IF(is_named_arg<T>::value)>
|
|
||||||
void init_named_args(named_arg_info<Char>* named_args, int arg_count,
|
|
||||||
int named_arg_count, const T& arg, const Tail&... args) {
|
|
||||||
named_args[named_arg_count++] = {arg.name, arg_count};
|
|
||||||
init_named_args(named_args, arg_count + 1, named_arg_count, args...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename... Args>
|
|
||||||
FMT_CONSTEXPR FMT_INLINE void init_named_args(std::nullptr_t, int, int,
|
|
||||||
const Args&...) {}
|
|
||||||
|
|
||||||
template <bool B = false> constexpr auto count() -> size_t { return B ? 1 : 0; }
|
template <bool B = false> constexpr auto count() -> size_t { return B ? 1 : 0; }
|
||||||
template <bool B1, bool B2, bool... Tail> constexpr auto count() -> size_t {
|
template <bool B1, bool B2, bool... Tail> constexpr auto count() -> size_t {
|
||||||
return (B1 ? 1 : 0) + count<B2, Tail...>();
|
return (B1 ? 1 : 0) + count<B2, Tail...>();
|
||||||
@ -1596,46 +1574,47 @@ template <typename Context, size_t NUM_ARGS>
|
|||||||
using arg_t = conditional_t<NUM_ARGS <= max_packed_args, value<Context>,
|
using arg_t = conditional_t<NUM_ARGS <= max_packed_args, value<Context>,
|
||||||
basic_format_arg<Context>>;
|
basic_format_arg<Context>>;
|
||||||
|
|
||||||
|
template <typename Char, typename T, FMT_ENABLE_IF(!is_named_arg<T>::value)>
|
||||||
|
void init_named_arg(named_arg_info<Char>*, int& arg_index, int&, const T&) {
|
||||||
|
++arg_index;
|
||||||
|
}
|
||||||
|
template <typename Char, typename T, FMT_ENABLE_IF(is_named_arg<T>::value)>
|
||||||
|
void init_named_arg(named_arg_info<Char>* named_args, int& arg_index,
|
||||||
|
int& named_arg_index, const T& arg) {
|
||||||
|
named_args[named_arg_index++] = {arg.name, arg_index++};
|
||||||
|
}
|
||||||
|
|
||||||
// An array of references to arguments. It can be implicitly converted to
|
// An array of references to arguments. It can be implicitly converted to
|
||||||
// `fmt::basic_format_args` for passing into type-erased formatting functions
|
// `fmt::basic_format_args` for passing into type-erased formatting functions
|
||||||
// such as `fmt::vformat`.
|
// such as `fmt::vformat`.
|
||||||
template <typename Context, size_t NUM_ARGS, size_t NUM_NAMED_ARGS,
|
template <typename Context, size_t NUM_ARGS, size_t NUM_NAMED_ARGS,
|
||||||
unsigned long long DESC>
|
unsigned long long DESC>
|
||||||
struct format_arg_store {
|
struct format_arg_store {
|
||||||
static const bool is_packed = NUM_ARGS <= detail::max_packed_args;
|
|
||||||
|
|
||||||
using char_type = typename Context::char_type;
|
|
||||||
using value_type = arg_t<Context, NUM_ARGS>;
|
|
||||||
|
|
||||||
// args_[0].named_args points to named_args to avoid bloating format_args.
|
// args_[0].named_args points to named_args to avoid bloating format_args.
|
||||||
// +1 to workaround a bug in gcc 7.5 that causes duplicated-branches warning.
|
// +1 to workaround a bug in gcc 7.5 that causes duplicated-branches warning.
|
||||||
value_type args_[1 + (NUM_ARGS != 0 ? NUM_ARGS : +1)];
|
arg_t<Context, NUM_ARGS> args[1 + (NUM_ARGS != 0 ? NUM_ARGS : +1)];
|
||||||
detail::named_arg_info<char_type> named_args[NUM_NAMED_ARGS];
|
named_arg_info<typename Context::char_type> named_args[NUM_NAMED_ARGS];
|
||||||
|
|
||||||
template <typename... T>
|
template <typename... T>
|
||||||
FMT_CONSTEXPR FMT_INLINE format_arg_store(T&... args)
|
FMT_CONSTEXPR FMT_INLINE format_arg_store(T&... values)
|
||||||
: args_{{named_args, NUM_NAMED_ARGS},
|
: args{{named_args, NUM_NAMED_ARGS},
|
||||||
detail::make_arg<is_packed, Context>(args)...} {
|
make_arg<NUM_ARGS <= max_packed_args, Context>(values)...} {
|
||||||
detail::init_named_args(named_args, 0, 0, args...);
|
using dummy = int[];
|
||||||
}
|
int arg_index = 0, named_arg_index = 0;
|
||||||
|
(void)dummy{
|
||||||
FMT_CONSTEXPR FMT_INLINE auto args() const -> const value_type* {
|
0,
|
||||||
return args_ + 1;
|
(init_named_arg(named_args, arg_index, named_arg_index, values), 0)...};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// A specialization of format_arg_store without named arguments.
|
// A specialization of format_arg_store without named arguments.
|
||||||
|
// It is a plain struct to reduce binary size in debug mode.
|
||||||
template <typename Context, size_t NUM_ARGS, unsigned long long DESC>
|
template <typename Context, size_t NUM_ARGS, unsigned long long DESC>
|
||||||
struct format_arg_store<Context, NUM_ARGS, 0, DESC> {
|
struct format_arg_store<Context, NUM_ARGS, 0, DESC> {
|
||||||
using value_type = arg_t<Context, NUM_ARGS>;
|
|
||||||
|
|
||||||
// +1 to workaround a bug in gcc 7.5 that causes duplicated-branches warning.
|
// +1 to workaround a bug in gcc 7.5 that causes duplicated-branches warning.
|
||||||
value_type args_[NUM_ARGS != 0 ? NUM_ARGS : +1];
|
arg_t<Context, NUM_ARGS> args[NUM_ARGS != 0 ? NUM_ARGS : +1];
|
||||||
|
|
||||||
FMT_CONSTEXPR FMT_INLINE auto args() const -> const value_type* {
|
|
||||||
return args_;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
FMT_BEGIN_EXPORT
|
FMT_BEGIN_EXPORT
|
||||||
|
|
||||||
@ -1808,14 +1787,14 @@ template <typename Context> class basic_format_args {
|
|||||||
constexpr basic_format_args(
|
constexpr basic_format_args(
|
||||||
const detail::format_arg_store<Context, NUM_ARGS, NUM_NAMED_ARGS, DESC>&
|
const detail::format_arg_store<Context, NUM_ARGS, NUM_NAMED_ARGS, DESC>&
|
||||||
store)
|
store)
|
||||||
: desc_(DESC), values_(store.args()) {}
|
: desc_(DESC), values_(store.args + (NUM_NAMED_ARGS != 0 ? 1 : 0)) {}
|
||||||
|
|
||||||
template <size_t NUM_ARGS, size_t NUM_NAMED_ARGS, unsigned long long DESC,
|
template <size_t NUM_ARGS, size_t NUM_NAMED_ARGS, unsigned long long DESC,
|
||||||
FMT_ENABLE_IF(NUM_ARGS > detail::max_packed_args)>
|
FMT_ENABLE_IF(NUM_ARGS > detail::max_packed_args)>
|
||||||
constexpr basic_format_args(
|
constexpr basic_format_args(
|
||||||
const detail::format_arg_store<Context, NUM_ARGS, NUM_NAMED_ARGS, DESC>&
|
const detail::format_arg_store<Context, NUM_ARGS, NUM_NAMED_ARGS, DESC>&
|
||||||
store)
|
store)
|
||||||
: desc_(DESC), args_(store.args()) {}
|
: desc_(DESC), args_(store.args + (NUM_NAMED_ARGS != 0 ? 1 : 0)) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\rst
|
\rst
|
||||||
|
Reference in New Issue
Block a user