diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index c9d56e09..79ca1814 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -15,21 +15,16 @@ jobs: # https://github.com/actions/virtual-environments. os: [windows-2019] platform: [Win32, x64] - toolset: [v140, v141, v142] + toolset: [v141, v142] standard: [14, 17, 20] shared: ["", -DBUILD_SHARED_LIBS=ON] build_type: [Debug, Release] exclude: - - { toolset: v140, standard: 17 } - - { toolset: v140, standard: 20 } - - { toolset: v141, standard: 14 } - { toolset: v141, standard: 20 } - { toolset: v142, standard: 14 } - - { platform: Win32, toolset: v140 } - { platform: Win32, toolset: v141 } - { platform: Win32, standard: 14 } - { platform: Win32, standard: 20 } - - { platform: x64, toolset: v140, shared: -DBUILD_SHARED_LIBS=ON } - { platform: x64, toolset: v141, shared: -DBUILD_SHARED_LIBS=ON } - { platform: x64, standard: 14, shared: -DBUILD_SHARED_LIBS=ON } - { platform: x64, standard: 20, shared: -DBUILD_SHARED_LIBS=ON } diff --git a/include/fmt/base.h b/include/fmt/base.h index 72cac7c4..cb2a36a4 100644 --- a/include/fmt/base.h +++ b/include/fmt/base.h @@ -2238,8 +2238,19 @@ template class value { } FMT_ALWAYS_INLINE value(const void* val) : pointer(val) {} - template - FMT_CONSTEXPR20 FMT_ALWAYS_INLINE value(T&& val, custom_tag = {}) { + template ::map( + std::declval()))>::value)> + FMT_CONSTEXPR20 FMT_ALWAYS_INLINE value(T&& val) { + *this = arg_mapper::map(val); + } + + template < + typename T, + FMT_ENABLE_IF(std::is_same::map( + std::declval()))>::value)> + FMT_CONSTEXPR20 FMT_ALWAYS_INLINE value(T&& val) { // Use enum instead of constexpr because the latter may generate code. enum { formattable_char = !std::is_same::value }; static_assert(formattable_char, "mixing character types is disallowed"); @@ -2374,8 +2385,7 @@ struct named_arg_store { template FMT_CONSTEXPR FMT_ALWAYS_INLINE named_arg_store(T&... values) - : args{{named_args, NUM_NAMED_ARGS}, - arg_mapper::map(values)...} { + : args{{named_args, NUM_NAMED_ARGS}, values...} { int arg_index = 0, named_arg_index = 0; FMT_APPLY_VARIADIC( init_named_arg(named_args, arg_index, named_arg_index, values)); @@ -2636,6 +2646,10 @@ template class basic_format_args { return static_cast((desc_ >> shift) & mask); } + template + using store = + detail::format_arg_store; + public: using format_arg = basic_format_arg; @@ -2646,33 +2660,26 @@ template class basic_format_args { FMT_ENABLE_IF(NUM_ARGS <= detail::max_packed_args && NUM_NAMED_ARGS == 0)> constexpr FMT_ALWAYS_INLINE basic_format_args( - const detail::format_arg_store& - store) - : desc_(DESC), values_(store.args) {} + const store& s) + : desc_(DESC), values_(s.args) {} template - constexpr FMT_ALWAYS_INLINE basic_format_args( - const detail::format_arg_store& - store) - : desc_(DESC), values_(store.args.args + 1) {} + constexpr basic_format_args(const store& s) + : desc_(DESC | detail::has_named_args_bit), values_(s.args.args + 1) {} template detail::max_packed_args && NUM_NAMED_ARGS == 0)> - constexpr basic_format_args( - const detail::format_arg_store& - store) - : desc_(DESC), args_(store.args + (NUM_NAMED_ARGS != 0 ? 1 : 0)) {} + constexpr basic_format_args(const store& s) + : desc_(DESC), args_(s.args) {} template detail::max_packed_args && NUM_NAMED_ARGS != 0)> - constexpr basic_format_args( - const detail::format_arg_store& - store) - : desc_(DESC), args_(store.args.args + 1) {} + constexpr basic_format_args(const store& s) + : desc_(DESC | detail::has_named_args_bit), args_(s.args.args + 1) {} /// Constructs a `basic_format_args` object from a dynamic list of arguments. constexpr basic_format_args(const format_arg* args, int count, @@ -2870,6 +2877,8 @@ struct formatter constexpr T& identity(T& x) { return x; } + /** * Constructs an object that stores references to arguments and can be * implicitly converted to `format_args`. `Context` can be omitted in which case @@ -2901,6 +2910,12 @@ constexpr auto make_format_args(T&... args) } #endif +template +using vargs = + detail::format_arg_store(), + detail::make_descriptor()>; + /** * Returns a named argument to be used in a formatting function. * It should only be used in a call to a formatting function.