mirror of
https://github.com/fmtlib/fmt.git
synced 2025-07-30 10:47:35 +02:00
Reduce template instantiations
This commit is contained in:
@ -2870,11 +2870,12 @@ FMT_CONSTEXPR inline auto check_char_specs(const format_specs& specs) -> bool {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Char, typename... Args> class format_string_checker {
|
template <typename... T> struct arg_pack {};
|
||||||
|
|
||||||
|
template <typename Char, int NUM_ARGS, int NUM_NAMED_ARGS>
|
||||||
|
class format_string_checker {
|
||||||
private:
|
private:
|
||||||
using parse_context_type = compile_parse_context<Char>;
|
using parse_context_type = compile_parse_context<Char>;
|
||||||
static constexpr int num_args = sizeof...(Args);
|
|
||||||
static constexpr int num_named_args = count_statically_named_args<Args...>();
|
|
||||||
|
|
||||||
// Format specifiers parsing function.
|
// Format specifiers parsing function.
|
||||||
// In the future basic_format_parse_context will replace compile_parse_context
|
// In the future basic_format_parse_context will replace compile_parse_context
|
||||||
@ -2882,21 +2883,23 @@ template <typename Char, typename... Args> class format_string_checker {
|
|||||||
// needed for compile-time checks: https://godbolt.org/z/GvWzcTjh1.
|
// needed for compile-time checks: https://godbolt.org/z/GvWzcTjh1.
|
||||||
using parse_func = const Char* (*)(parse_context_type&);
|
using parse_func = const Char* (*)(parse_context_type&);
|
||||||
|
|
||||||
type types_[num_args > 0 ? static_cast<size_t>(num_args) : 1];
|
type types_[NUM_ARGS > 0 ? NUM_ARGS : 1];
|
||||||
parse_context_type context_;
|
parse_context_type context_;
|
||||||
parse_func parse_funcs_[num_args > 0 ? static_cast<size_t>(num_args) : 1];
|
parse_func parse_funcs_[NUM_ARGS > 0 ? NUM_ARGS : 1];
|
||||||
named_arg_info<Char> named_args_[num_named_args > 0 ? num_named_args : 1];
|
named_arg_info<Char> named_args_[NUM_NAMED_ARGS > 0 ? NUM_NAMED_ARGS : 1];
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit FMT_CONSTEXPR format_string_checker(basic_string_view<Char> fmt)
|
template <typename... T>
|
||||||
: types_{mapped_type_constant<Args, buffered_context<Char>>::value...},
|
explicit FMT_CONSTEXPR format_string_checker(basic_string_view<Char> fmt,
|
||||||
context_(fmt, num_args, types_),
|
arg_pack<T...>)
|
||||||
parse_funcs_{&parse_format_specs<Args, parse_context_type>...},
|
: types_{mapped_type_constant<T, buffered_context<Char>>::value...},
|
||||||
|
context_(fmt, NUM_ARGS, types_),
|
||||||
|
parse_funcs_{&parse_format_specs<T, parse_context_type>...},
|
||||||
named_args_{} {
|
named_args_{} {
|
||||||
using dummy = int[];
|
using dummy = int[];
|
||||||
int arg_index = 0, named_arg_index = 0;
|
int arg_index = 0, named_arg_index = 0;
|
||||||
(void)dummy{0, (init_statically_named_arg<Args>(named_args_, arg_index,
|
(void)dummy{0, (init_statically_named_arg<T>(named_args_, arg_index,
|
||||||
named_arg_index),
|
named_arg_index),
|
||||||
0)...};
|
0)...};
|
||||||
ignore_unused(arg_index, named_arg_index);
|
ignore_unused(arg_index, named_arg_index);
|
||||||
}
|
}
|
||||||
@ -2908,7 +2911,7 @@ template <typename Char, typename... Args> class format_string_checker {
|
|||||||
return context_.check_arg_id(id), id;
|
return context_.check_arg_id(id), id;
|
||||||
}
|
}
|
||||||
FMT_CONSTEXPR auto on_arg_id(basic_string_view<Char> id) -> int {
|
FMT_CONSTEXPR auto on_arg_id(basic_string_view<Char> id) -> int {
|
||||||
for (int i = 0; i < num_named_args; ++i) {
|
for (int i = 0; i < NUM_NAMED_ARGS; ++i) {
|
||||||
if (named_args_[i].name == id) return i;
|
if (named_args_[i].name == id) return i;
|
||||||
}
|
}
|
||||||
on_error("named argument is not found");
|
on_error("named argument is not found");
|
||||||
@ -2923,7 +2926,7 @@ template <typename Char, typename... Args> class format_string_checker {
|
|||||||
-> const Char* {
|
-> const Char* {
|
||||||
context_.advance_to(begin);
|
context_.advance_to(begin);
|
||||||
// id >= 0 check is a workaround for gcc 10 bug (#2065).
|
// id >= 0 check is a workaround for gcc 10 bug (#2065).
|
||||||
return id >= 0 && id < num_args ? parse_funcs_[id](context_) : begin;
|
return id >= 0 && id < NUM_ARGS ? parse_funcs_[id](context_) : begin;
|
||||||
}
|
}
|
||||||
|
|
||||||
FMT_NORETURN FMT_CONSTEXPR void on_error(const char* message) {
|
FMT_NORETURN FMT_CONSTEXPR void on_error(const char* message) {
|
||||||
@ -3009,7 +3012,9 @@ template <typename Char, typename... Args> class basic_format_string {
|
|||||||
private:
|
private:
|
||||||
basic_string_view<Char> str_;
|
basic_string_view<Char> str_;
|
||||||
|
|
||||||
using checker = detail::format_string_checker<Char, remove_cvref_t<Args>...>;
|
using checker = detail::format_string_checker<
|
||||||
|
Char, static_cast<int>(sizeof...(Args)),
|
||||||
|
detail::count_statically_named_args<Args...>()>;
|
||||||
|
|
||||||
FMT_CONSTEXPR FMT_ALWAYS_INLINE static void check(
|
FMT_CONSTEXPR FMT_ALWAYS_INLINE static void check(
|
||||||
basic_string_view<Char> fmt) {
|
basic_string_view<Char> fmt) {
|
||||||
@ -3019,7 +3024,7 @@ template <typename Char, typename... Args> class basic_format_string {
|
|||||||
std::is_reference<Args>::value)...>() == 0,
|
std::is_reference<Args>::value)...>() == 0,
|
||||||
"passing views as lvalues is disallowed");
|
"passing views as lvalues is disallowed");
|
||||||
if (count_named_args<Args...>() == count_statically_named_args<Args...>())
|
if (count_named_args<Args...>() == count_statically_named_args<Args...>())
|
||||||
parse_format_string(fmt, checker(fmt));
|
parse_format_string(fmt, checker(fmt, arg_pack<Args...>()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
Reference in New Issue
Block a user