mirror of
https://github.com/fmtlib/fmt.git
synced 2026-07-30 16:26:27 +08:00
Handle const-qualified named arguments
A named argument that arrives const-qualified was not recognized by is_named_arg, silently dropping its name. This happens both when a named argument is passed through an intermediate function returning const T& (https://github.com/fmtlib/fmt/issues/4866) and in fmt's own compiled format path, which passes arguments as const T&. Make is_named_arg and is_static_named_arg see through top-level const so the name is preserved instead of dropped.
This commit is contained in:
parent
caf5e48b1c
commit
26c01df3bd
15
.github/workflows/linux.yml
vendored
15
.github/workflows/linux.yml
vendored
@ -13,6 +13,10 @@ jobs:
|
|||||||
${{matrix.shared && 'Shared' || ''}}
|
${{matrix.shared && 'Shared' || ''}}
|
||||||
${{matrix.cxxflags_extra && 'Sanitize' || ''}}
|
${{matrix.cxxflags_extra && 'Sanitize' || ''}}
|
||||||
runs-on: ${{ matrix.os || 'ubuntu-22.04' }}
|
runs-on: ${{ matrix.os || 'ubuntu-22.04' }}
|
||||||
|
env:
|
||||||
|
# Run tests in a non-UTC timezone. glibc localtime/strftime honor TZ, so
|
||||||
|
# there is no need for timedatectl, which fails without systemd-timedated.
|
||||||
|
TZ: Europe/Kyiv
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
cxx: [g++-4.9, g++-11, clang++-3.6, clang++-11]
|
cxx: [g++-4.9, g++-11, clang++-3.6, clang++-11]
|
||||||
@ -75,15 +79,14 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||||
|
|
||||||
- name: Set timezone
|
|
||||||
run: sudo timedatectl set-timezone 'Europe/Kyiv'
|
|
||||||
|
|
||||||
- name: Install GCC 4.9
|
- name: Install GCC 4.9
|
||||||
run: |
|
run: |
|
||||||
sudo apt update
|
sudo apt update
|
||||||
sudo apt install libatomic1 libc6-dev libgomp1 libitm1 libmpc3
|
sudo apt install libatomic1 libc6-dev libgomp1 libitm1 libmpc3
|
||||||
# https://launchpad.net/ubuntu/xenial/amd64/g++-4.9/4.9.3-13ubuntu2
|
# https://launchpad.net/ubuntu/xenial/amd64/g++-4.9/4.9.3-13ubuntu2
|
||||||
wget --no-verbose \
|
# launchpad periodically returns 503s, so retry to avoid flaky CI.
|
||||||
|
wget --no-verbose --tries=5 --waitretry=10 \
|
||||||
|
--retry-connrefused --retry-on-http-error=503 \
|
||||||
http://launchpadlibrarian.net/230069137/libmpfr4_3.1.3-2_amd64.deb \
|
http://launchpadlibrarian.net/230069137/libmpfr4_3.1.3-2_amd64.deb \
|
||||||
http://launchpadlibrarian.net/253728424/libasan1_4.9.3-13ubuntu2_amd64.deb \
|
http://launchpadlibrarian.net/253728424/libasan1_4.9.3-13ubuntu2_amd64.deb \
|
||||||
http://launchpadlibrarian.net/445346135/libubsan0_5.4.0-6ubuntu1~16.04.12_amd64.deb \
|
http://launchpadlibrarian.net/445346135/libubsan0_5.4.0-6ubuntu1~16.04.12_amd64.deb \
|
||||||
@ -114,7 +117,9 @@ jobs:
|
|||||||
sudo apt update
|
sudo apt update
|
||||||
sudo apt install libtinfo5
|
sudo apt install libtinfo5
|
||||||
# https://code.launchpad.net/ubuntu/xenial/amd64/clang-3.6/1:3.6.2-3ubuntu2
|
# https://code.launchpad.net/ubuntu/xenial/amd64/clang-3.6/1:3.6.2-3ubuntu2
|
||||||
wget --no-verbose \
|
# launchpad periodically returns 503s, so retry to avoid flaky CI.
|
||||||
|
wget --no-verbose --tries=5 --waitretry=10 \
|
||||||
|
--retry-connrefused --retry-on-http-error=503 \
|
||||||
http://launchpadlibrarian.net/230019046/libffi6_3.2.1-4_amd64.deb \
|
http://launchpadlibrarian.net/230019046/libffi6_3.2.1-4_amd64.deb \
|
||||||
http://launchpadlibrarian.net/445346109/libasan2_5.4.0-6ubuntu1~16.04.12_amd64.deb \
|
http://launchpadlibrarian.net/445346109/libasan2_5.4.0-6ubuntu1~16.04.12_amd64.deb \
|
||||||
http://launchpadlibrarian.net/445346135/libubsan0_5.4.0-6ubuntu1~16.04.12_amd64.deb \
|
http://launchpadlibrarian.net/445346135/libubsan0_5.4.0-6ubuntu1~16.04.12_amd64.deb \
|
||||||
|
|||||||
@ -1059,6 +1059,10 @@ template <typename T> struct is_static_named_arg : std::false_type {};
|
|||||||
template <typename T, typename Char>
|
template <typename T, typename Char>
|
||||||
struct is_named_arg<named_arg<T, Char>> : std::true_type {};
|
struct is_named_arg<named_arg<T, Char>> : std::true_type {};
|
||||||
|
|
||||||
|
template <typename T> struct is_named_arg<const T> : is_named_arg<T> {};
|
||||||
|
template <typename T>
|
||||||
|
struct is_static_named_arg<const T> : is_static_named_arg<T> {};
|
||||||
|
|
||||||
template <typename T, typename Char = char> struct named_arg : view {
|
template <typename T, typename Char = char> struct named_arg : view {
|
||||||
const Char* name;
|
const Char* name;
|
||||||
const T& value;
|
const T& value;
|
||||||
|
|||||||
@ -163,6 +163,10 @@ TEST(compile_test, named) {
|
|||||||
fmt::format(FMT_COMPILE("{a0} {a1}"), "a0"_a = 41, "a1"_a = 43));
|
fmt::format(FMT_COMPILE("{a0} {a1}"), "a0"_a = 41, "a1"_a = 43));
|
||||||
EXPECT_EQ("41 43",
|
EXPECT_EQ("41 43",
|
||||||
fmt::format(FMT_COMPILE("{a1} {a0}"), "a0"_a = 43, "a1"_a = 41));
|
fmt::format(FMT_COMPILE("{a1} {a0}"), "a0"_a = 43, "a1"_a = 41));
|
||||||
|
|
||||||
|
// A statically-named argument with a format spec compiles to spec_field,
|
||||||
|
// which passes the argument to make_format_args as const (#4866).
|
||||||
|
EXPECT_EQ("4.2", fmt::format(FMT_COMPILE("{arg:3.1f}"), "arg"_a = 4.2));
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user