Merge commit '5ff285a9ed91944b686cd1d77ff28bafa9975695' into dev
This commit is contained in:
6
external/fmt/.github/workflows/cifuzz.yml
vendored
6
external/fmt/.github/workflows/cifuzz.yml
vendored
@@ -10,18 +10,20 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Build fuzzers
|
- name: Build fuzzers
|
||||||
id: build
|
id: build
|
||||||
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@92182553173581f871130c71c71b17f003d47b0a # master
|
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@92182553173581f871130c71c71b17f003d47b0a
|
||||||
with:
|
with:
|
||||||
oss-fuzz-project-name: 'fmt'
|
oss-fuzz-project-name: 'fmt'
|
||||||
dry-run: false
|
dry-run: false
|
||||||
language: c++
|
language: c++
|
||||||
|
|
||||||
- name: Run fuzzers
|
- name: Run fuzzers
|
||||||
uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@92182553173581f871130c71c71b17f003d47b0a # master
|
uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@92182553173581f871130c71c71b17f003d47b0a
|
||||||
with:
|
with:
|
||||||
oss-fuzz-project-name: 'fmt'
|
oss-fuzz-project-name: 'fmt'
|
||||||
fuzz-seconds: 300
|
fuzz-seconds: 300
|
||||||
dry-run: false
|
dry-run: false
|
||||||
language: c++
|
language: c++
|
||||||
|
|
||||||
- name: Upload crash
|
- name: Upload crash
|
||||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
||||||
if: failure() && steps.build.outcome == 'success'
|
if: failure() && steps.build.outcome == 'success'
|
||||||
|
|||||||
2
external/fmt/.github/workflows/doc.yml
vendored
2
external/fmt/.github/workflows/doc.yml
vendored
@@ -11,7 +11,7 @@ jobs:
|
|||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
- uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
||||||
|
|
||||||
- name: Add Ubuntu mirrors
|
- name: Add Ubuntu mirrors
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
12
external/fmt/.github/workflows/lint.yml
vendored
12
external/fmt/.github/workflows/lint.yml
vendored
@@ -13,14 +13,16 @@ jobs:
|
|||||||
format_code:
|
format_code:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
- uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
||||||
|
|
||||||
- name: Install clang-format
|
- name: Install clang-format
|
||||||
uses: aminya/setup-cpp@290824452986e378826155f3379d31bce8753d76 # v0.37.0
|
run: |
|
||||||
with:
|
wget https://apt.llvm.org/llvm.sh
|
||||||
clangformat: 17.0.5
|
sudo bash ./llvm.sh 17
|
||||||
|
sudo apt install clang-format-17
|
||||||
|
|
||||||
- name: Run clang-format
|
- name: Run clang-format
|
||||||
run: |
|
run: |
|
||||||
find include src -name '*.h' -o -name '*.cc' | xargs clang-format -i -style=file -fallback-style=none
|
find include src -name '*.h' -o -name '*.cc' | \
|
||||||
|
xargs clang-format-17 -i -style=file -fallback-style=none
|
||||||
git diff --exit-code
|
git diff --exit-code
|
||||||
|
|||||||
2
external/fmt/.github/workflows/linux.yml
vendored
2
external/fmt/.github/workflows/linux.yml
vendored
@@ -62,7 +62,7 @@ jobs:
|
|||||||
shared: -DBUILD_SHARED_LIBS=ON
|
shared: -DBUILD_SHARED_LIBS=ON
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
- uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
||||||
|
|
||||||
- name: Set timezone
|
- name: Set timezone
|
||||||
run: sudo timedatectl set-timezone 'Asia/Yekaterinburg'
|
run: sudo timedatectl set-timezone 'Asia/Yekaterinburg'
|
||||||
|
|||||||
2
external/fmt/.github/workflows/macos.yml
vendored
2
external/fmt/.github/workflows/macos.yml
vendored
@@ -25,7 +25,7 @@ jobs:
|
|||||||
runs-on: '${{ matrix.os }}'
|
runs-on: '${{ matrix.os }}'
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
- uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
||||||
|
|
||||||
- name: Set timezone
|
- name: Set timezone
|
||||||
run: sudo systemsetup -settimezone 'Asia/Yekaterinburg'
|
run: sudo systemsetup -settimezone 'Asia/Yekaterinburg'
|
||||||
|
|||||||
4
external/fmt/.github/workflows/scorecard.yml
vendored
4
external/fmt/.github/workflows/scorecard.yml
vendored
@@ -29,7 +29,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: "Checkout code"
|
- name: "Checkout code"
|
||||||
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
@@ -60,6 +60,6 @@ jobs:
|
|||||||
|
|
||||||
# Upload the results to GitHub's code scanning dashboard.
|
# Upload the results to GitHub's code scanning dashboard.
|
||||||
- name: "Upload to code-scanning"
|
- name: "Upload to code-scanning"
|
||||||
uses: github/codeql-action/upload-sarif@4dd16135b69a43b6c8efb853346f8437d92d3c93 # v3.26.6
|
uses: github/codeql-action/upload-sarif@662472033e021d55d94146f66f6058822b0b39fd # v3.27.0
|
||||||
with:
|
with:
|
||||||
sarif_file: results.sarif
|
sarif_file: results.sarif
|
||||||
|
|||||||
6
external/fmt/.github/workflows/windows.yml
vendored
6
external/fmt/.github/workflows/windows.yml
vendored
@@ -36,7 +36,7 @@ jobs:
|
|||||||
standard: 20
|
standard: 20
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
- uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
||||||
|
|
||||||
- name: Set timezone
|
- name: Set timezone
|
||||||
run: tzutil /s "Ekaterinburg Standard Time"
|
run: tzutil /s "Ekaterinburg Standard Time"
|
||||||
@@ -78,12 +78,12 @@ jobs:
|
|||||||
- name: Set timezone
|
- name: Set timezone
|
||||||
run: tzutil /s "Ekaterinburg Standard Time"
|
run: tzutil /s "Ekaterinburg Standard Time"
|
||||||
shell: cmd
|
shell: cmd
|
||||||
- uses: msys2/setup-msys2@5df0ca6cbf14efcd08f8d5bd5e049a3cc8e07fd2 # v2.24.0
|
- uses: msys2/setup-msys2@c52d1fa9c7492275e60fe763540fb601f5f232a1 # v2.25.0
|
||||||
with:
|
with:
|
||||||
release: false
|
release: false
|
||||||
msystem: ${{matrix.sys}}
|
msystem: ${{matrix.sys}}
|
||||||
pacboy: cc:p cmake:p ninja:p lld:p
|
pacboy: cc:p cmake:p ninja:p lld:p
|
||||||
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
- uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
||||||
- name: Configure
|
- name: Configure
|
||||||
run: cmake -B ../build -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Debug
|
run: cmake -B ../build -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Debug
|
||||||
env: { LDFLAGS: -fuse-ld=lld }
|
env: { LDFLAGS: -fuse-ld=lld }
|
||||||
|
|||||||
19
external/fmt/CMakeLists.txt
vendored
19
external/fmt/CMakeLists.txt
vendored
@@ -426,7 +426,9 @@ if (FMT_INSTALL)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Install the library and headers.
|
# Install the library and headers.
|
||||||
install(TARGETS ${INSTALL_TARGETS} EXPORT ${targets_export_name}
|
install(TARGETS ${INSTALL_TARGETS}
|
||||||
|
COMPONENT core
|
||||||
|
EXPORT ${targets_export_name}
|
||||||
LIBRARY DESTINATION ${FMT_LIB_DIR}
|
LIBRARY DESTINATION ${FMT_LIB_DIR}
|
||||||
ARCHIVE DESTINATION ${FMT_LIB_DIR}
|
ARCHIVE DESTINATION ${FMT_LIB_DIR}
|
||||||
PUBLIC_HEADER DESTINATION "${FMT_INC_DIR}/fmt"
|
PUBLIC_HEADER DESTINATION "${FMT_INC_DIR}/fmt"
|
||||||
@@ -439,13 +441,15 @@ if (FMT_INSTALL)
|
|||||||
FILE ${PROJECT_BINARY_DIR}/${targets_export_name}.cmake)
|
FILE ${PROJECT_BINARY_DIR}/${targets_export_name}.cmake)
|
||||||
|
|
||||||
# Install version, config and target files.
|
# Install version, config and target files.
|
||||||
install(
|
install(FILES ${project_config} ${version_config}
|
||||||
FILES ${project_config} ${version_config}
|
DESTINATION ${FMT_CMAKE_DIR}
|
||||||
DESTINATION ${FMT_CMAKE_DIR})
|
COMPONENT core)
|
||||||
install(EXPORT ${targets_export_name} DESTINATION ${FMT_CMAKE_DIR}
|
install(EXPORT ${targets_export_name} DESTINATION ${FMT_CMAKE_DIR}
|
||||||
NAMESPACE fmt::)
|
NAMESPACE fmt::
|
||||||
|
COMPONENT core)
|
||||||
|
|
||||||
install(FILES "${pkgconfig}" DESTINATION "${FMT_PKGCONFIG_DIR}")
|
install(FILES "${pkgconfig}" DESTINATION "${FMT_PKGCONFIG_DIR}"
|
||||||
|
COMPONENT core)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
function(add_doc_target)
|
function(add_doc_target)
|
||||||
@@ -481,7 +485,8 @@ function(add_doc_target)
|
|||||||
|
|
||||||
include(GNUInstallDirs)
|
include(GNUInstallDirs)
|
||||||
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc-html/
|
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc-html/
|
||||||
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/doc/fmt OPTIONAL)
|
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/doc/fmt
|
||||||
|
COMPONENT doc OPTIONAL)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
if (FMT_DOC)
|
if (FMT_DOC)
|
||||||
|
|||||||
238
external/fmt/ChangeLog.md
vendored
238
external/fmt/ChangeLog.md
vendored
@@ -1,6 +1,237 @@
|
|||||||
# 11.1.0 - TBD
|
# 11.1.1 - 2024-12-27
|
||||||
|
|
||||||
- Improved debug codegen.
|
- Fixed ABI compatibility with earlier 11.x versions
|
||||||
|
(https://github.com/fmtlib/fmt/issues/4278).
|
||||||
|
|
||||||
|
- Defined CMake components (`core` and `doc`) to allow docs to be installed
|
||||||
|
separately (https://github.com/fmtlib/fmt/pull/4276).
|
||||||
|
Thanks @carlsmedstad.
|
||||||
|
|
||||||
|
# 11.1.0 - 2024-12-25
|
||||||
|
|
||||||
|
- Improved C++20 module support
|
||||||
|
(https://github.com/fmtlib/fmt/issues/4081,
|
||||||
|
https://github.com/fmtlib/fmt/pull/4083,
|
||||||
|
https://github.com/fmtlib/fmt/pull/4084,
|
||||||
|
https://github.com/fmtlib/fmt/pull/4152,
|
||||||
|
https://github.com/fmtlib/fmt/issues/4153,
|
||||||
|
https://github.com/fmtlib/fmt/pull/4169,
|
||||||
|
https://github.com/fmtlib/fmt/issues/4190,
|
||||||
|
https://github.com/fmtlib/fmt/issues/4234,
|
||||||
|
https://github.com/fmtlib/fmt/pull/4239).
|
||||||
|
Thanks @kamrann and @Arghnews.
|
||||||
|
|
||||||
|
- Reduced debug (unoptimized) binary code size and the number of template
|
||||||
|
instantiations when passing formatting arguments. For example, unoptimized
|
||||||
|
binary code size for `fmt::print("{}", 42)` was reduced by ~40% on GCC and
|
||||||
|
~60% on clang (x86-64).
|
||||||
|
|
||||||
|
GCC:
|
||||||
|
- Before: 161 instructions of which 105 are in reusable functions
|
||||||
|
([godbolt](https://www.godbolt.org/z/s9bGoo4ze)).
|
||||||
|
- After: 116 instructions of which 60 are in reusable functions
|
||||||
|
([godbolt](https://www.godbolt.org/z/r7GGGxMs6)).
|
||||||
|
|
||||||
|
Clang:
|
||||||
|
- Before: 310 instructions of which 251 are in reusable functions
|
||||||
|
([godbolt](https://www.godbolt.org/z/Ts88b7M9o)).
|
||||||
|
- After: 194 instructions of which 135 are in reusable functions
|
||||||
|
([godbolt](https://www.godbolt.org/z/vcrjP8ceW)).
|
||||||
|
|
||||||
|
- Added an experimental `fmt::writer` API that can be used for writing to
|
||||||
|
different destinations such as files or strings
|
||||||
|
(https://github.com/fmtlib/fmt/issues/2354).
|
||||||
|
For example ([godbolt](https://www.godbolt.org/z/rWoKfbP7e)):
|
||||||
|
|
||||||
|
```c++
|
||||||
|
#include <fmt/os.h>
|
||||||
|
|
||||||
|
void write_text(fmt::writer w) {
|
||||||
|
w.print("The answer is {}.", 42);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
// Write to FILE.
|
||||||
|
write_text(stdout);
|
||||||
|
|
||||||
|
// Write to fmt::ostream.
|
||||||
|
auto f = fmt::output_file("myfile");
|
||||||
|
write_text(f);
|
||||||
|
|
||||||
|
// Write to std::string.
|
||||||
|
auto sb = fmt::string_buffer();
|
||||||
|
write_text(sb);
|
||||||
|
std::string s = sb.str();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- Added width and alignment support to the formatter of `std::error_code`.
|
||||||
|
|
||||||
|
- Made `std::expected<void, E>` formattable
|
||||||
|
(https://github.com/fmtlib/fmt/issues/4145,
|
||||||
|
https://github.com/fmtlib/fmt/pull/4148).
|
||||||
|
For example ([godbolt](https://www.godbolt.org/z/hrj5c6G86)):
|
||||||
|
|
||||||
|
```c++
|
||||||
|
fmt::print("{}", std::expected<void, int>());
|
||||||
|
```
|
||||||
|
|
||||||
|
prints
|
||||||
|
|
||||||
|
```
|
||||||
|
expected()
|
||||||
|
```
|
||||||
|
|
||||||
|
Thanks @phprus.
|
||||||
|
|
||||||
|
- Made `fmt::is_formattable<void>` SFINAE-friendly
|
||||||
|
(https://github.com/fmtlib/fmt/issues/4147).
|
||||||
|
|
||||||
|
- Added support for `_BitInt` formatting when using clang
|
||||||
|
(https://github.com/fmtlib/fmt/issues/4007,
|
||||||
|
https://github.com/fmtlib/fmt/pull/4072,
|
||||||
|
https://github.com/fmtlib/fmt/issues/4140,
|
||||||
|
https://github.com/fmtlib/fmt/issues/4173,
|
||||||
|
https://github.com/fmtlib/fmt/pull/4176).
|
||||||
|
For example ([godbolt](https://www.godbolt.org/z/KWjbWec5z)):
|
||||||
|
|
||||||
|
```c++
|
||||||
|
using int42 = _BitInt(42);
|
||||||
|
fmt::print("{}", int42(100));
|
||||||
|
```
|
||||||
|
|
||||||
|
Thanks @Arghnews.
|
||||||
|
|
||||||
|
- Added the `n` specifier for tuples and pairs
|
||||||
|
(https://github.com/fmtlib/fmt/pull/4107). Thanks @someonewithpc.
|
||||||
|
|
||||||
|
- Added support for tuple-like types to `fmt::join`
|
||||||
|
(https://github.com/fmtlib/fmt/issues/4226,
|
||||||
|
https://github.com/fmtlib/fmt/pull/4230). Thanks @phprus.
|
||||||
|
|
||||||
|
- Made more types formattable at compile time
|
||||||
|
(https://github.com/fmtlib/fmt/pull/4127). Thanks @AnthonyVH.
|
||||||
|
|
||||||
|
- Implemented a more efficient compile-time `fmt::formatted_size`
|
||||||
|
(https://github.com/fmtlib/fmt/issues/4102,
|
||||||
|
https://github.com/fmtlib/fmt/pull/4103). Thanks @phprus.
|
||||||
|
|
||||||
|
- Fixed compile-time formatting of some string types
|
||||||
|
(https://github.com/fmtlib/fmt/pull/4065). Thanks @torshepherd.
|
||||||
|
|
||||||
|
- Made compiled version of `fmt::format_to` work with
|
||||||
|
`std::back_insert_iterator<std::vector<char>>`
|
||||||
|
(https://github.com/fmtlib/fmt/issues/4206,
|
||||||
|
https://github.com/fmtlib/fmt/pull/4211). Thanks @phprus.
|
||||||
|
|
||||||
|
- Added a formatter for `std::reference_wrapper`
|
||||||
|
(https://github.com/fmtlib/fmt/pull/4163,
|
||||||
|
https://github.com/fmtlib/fmt/pull/4164). Thanks @yfeldblum and @phprus.
|
||||||
|
|
||||||
|
- Added experimental padding support (glibc `strftime` extension) to `%m`, `%j`
|
||||||
|
and `%Y` (https://github.com/fmtlib/fmt/pull/4161). Thanks @KKhanhH.
|
||||||
|
|
||||||
|
- Made microseconds formatted as `us` instead of `µs` if the Unicode support is
|
||||||
|
disabled (https://github.com/fmtlib/fmt/issues/4088).
|
||||||
|
|
||||||
|
- Fixed an unreleased regression in transcoding of surrogate pairs
|
||||||
|
(https://github.com/fmtlib/fmt/issues/4094,
|
||||||
|
https://github.com/fmtlib/fmt/pull/4095). Thanks @phprus.
|
||||||
|
|
||||||
|
- Made `fmt::appender` satisfy `std::output_iterator` concept
|
||||||
|
(https://github.com/fmtlib/fmt/issues/4092,
|
||||||
|
https://github.com/fmtlib/fmt/pull/4093). Thanks @phprus.
|
||||||
|
|
||||||
|
- Made `std::iterator_traits<fmt::appender>` standard-conforming
|
||||||
|
(https://github.com/fmtlib/fmt/pull/4185). Thanks @CaseyCarter.
|
||||||
|
|
||||||
|
- Made it easier to reuse `fmt::formatter<std::string_view>` for types with
|
||||||
|
an implicit conversion to `std::string_view`
|
||||||
|
(https://github.com/fmtlib/fmt/issues/4036,
|
||||||
|
https://github.com/fmtlib/fmt/pull/4055). Thanks @Arghnews.
|
||||||
|
|
||||||
|
- Made it possible to disable `<filesystem>` use via `FMT_CPP_LIB_FILESYSTEM`
|
||||||
|
for compatibility with some video game console SDKs, e.g. Nintendo Switch SDK
|
||||||
|
(https://github.com/fmtlib/fmt/issues/4257,
|
||||||
|
https://github.com/fmtlib/fmt/pull/4258,
|
||||||
|
https://github.com/fmtlib/fmt/pull/4259). Thanks @W4RH4WK and @phprus.
|
||||||
|
|
||||||
|
- Fixed compatibility with platforms that use 80-bit `long double`
|
||||||
|
(https://github.com/fmtlib/fmt/issues/4245,
|
||||||
|
https://github.com/fmtlib/fmt/pull/4246). Thanks @jsirpoma.
|
||||||
|
|
||||||
|
- Added support for UTF-32 code units greater than `0xFFFF` in fill
|
||||||
|
(https://github.com/fmtlib/fmt/issues/4201).
|
||||||
|
|
||||||
|
- Fixed handling of legacy encodings on Windows with GCC
|
||||||
|
(https://github.com/fmtlib/fmt/issues/4162).
|
||||||
|
|
||||||
|
- Made `fmt::to_string` take `fmt::basic_memory_buffer` by const reference
|
||||||
|
(https://github.com/fmtlib/fmt/issues/4261,
|
||||||
|
https://github.com/fmtlib/fmt/pull/4262). Thanks @sascha-devel.
|
||||||
|
|
||||||
|
- Added `fmt::dynamic_format_arg_store::size`
|
||||||
|
(https://github.com/fmtlib/fmt/pull/4270). Thanks @hannes-harnisch.
|
||||||
|
|
||||||
|
- Removed the ability to control locale usage via an undocumented
|
||||||
|
`FMT_STATIC_THOUSANDS_SEPARATOR` in favor of `FMT_USE_LOCALE`.
|
||||||
|
|
||||||
|
- Renamed `FMT_EXCEPTIONS` to `FMT_USE_EXCEPTIONS` for consistency with other
|
||||||
|
similar macros.
|
||||||
|
|
||||||
|
- Improved include directory ordering to reduce the chance of including
|
||||||
|
incorrect headers when using multiple versions of {fmt}
|
||||||
|
(https://github.com/fmtlib/fmt/pull/4116). Thanks @cdzhan.
|
||||||
|
|
||||||
|
- Made it possible to compile a subset of {fmt} without the C++ runtime.
|
||||||
|
|
||||||
|
- Improved documentation and README
|
||||||
|
(https://github.com/fmtlib/fmt/pull/4066,
|
||||||
|
https://github.com/fmtlib/fmt/issues/4117,
|
||||||
|
https://github.com/fmtlib/fmt/issues/4203,
|
||||||
|
https://github.com/fmtlib/fmt/pull/4235). Thanks @zyctree and @nikola-sh.
|
||||||
|
|
||||||
|
- Improved the documentation generator (https://github.com/fmtlib/fmt/pull/4110,
|
||||||
|
https://github.com/fmtlib/fmt/pull/4115). Thanks @rturrado.
|
||||||
|
|
||||||
|
- Improved CI (https://github.com/fmtlib/fmt/pull/4155,
|
||||||
|
https://github.com/fmtlib/fmt/pull/4151). Thanks @phprus.
|
||||||
|
|
||||||
|
- Fixed various warnings and compilation issues
|
||||||
|
(https://github.com/fmtlib/fmt/issues/2708,
|
||||||
|
https://github.com/fmtlib/fmt/issues/4091,
|
||||||
|
https://github.com/fmtlib/fmt/issues/4109,
|
||||||
|
https://github.com/fmtlib/fmt/issues/4113,
|
||||||
|
https://github.com/fmtlib/fmt/issues/4125,
|
||||||
|
https://github.com/fmtlib/fmt/issues/4129,
|
||||||
|
https://github.com/fmtlib/fmt/pull/4130,
|
||||||
|
https://github.com/fmtlib/fmt/pull/4131,
|
||||||
|
https://github.com/fmtlib/fmt/pull/4132,
|
||||||
|
https://github.com/fmtlib/fmt/issues/4133,
|
||||||
|
https://github.com/fmtlib/fmt/issues/4144,
|
||||||
|
https://github.com/fmtlib/fmt/issues/4150,
|
||||||
|
https://github.com/fmtlib/fmt/issues/4158,
|
||||||
|
https://github.com/fmtlib/fmt/pull/4159,
|
||||||
|
https://github.com/fmtlib/fmt/issues/4160,
|
||||||
|
https://github.com/fmtlib/fmt/pull/4170,
|
||||||
|
https://github.com/fmtlib/fmt/issues/4177,
|
||||||
|
https://github.com/fmtlib/fmt/pull/4187,
|
||||||
|
https://github.com/fmtlib/fmt/pull/4188,
|
||||||
|
https://github.com/fmtlib/fmt/pull/4194,
|
||||||
|
https://github.com/fmtlib/fmt/pull/4200,
|
||||||
|
https://github.com/fmtlib/fmt/issues/4205,
|
||||||
|
https://github.com/fmtlib/fmt/issues/4207,
|
||||||
|
https://github.com/fmtlib/fmt/pull/4208,
|
||||||
|
https://github.com/fmtlib/fmt/pull/4210,
|
||||||
|
https://github.com/fmtlib/fmt/issues/4220,
|
||||||
|
https://github.com/fmtlib/fmt/issues/4231,
|
||||||
|
https://github.com/fmtlib/fmt/issues/4232,
|
||||||
|
https://github.com/fmtlib/fmt/pull/4233,
|
||||||
|
https://github.com/fmtlib/fmt/pull/4236,
|
||||||
|
https://github.com/fmtlib/fmt/pull/4267,
|
||||||
|
https://github.com/fmtlib/fmt/pull/4271).
|
||||||
|
Thanks @torsten48, @Arghnews, @tinfoilboy, @aminya, @Ottani, @zeroomega,
|
||||||
|
@c4v4, @kongy, @vinayyadav3016, @sergio-nsk, @phprus and @YexuanXiao.
|
||||||
|
|
||||||
# 11.0.2 - 2024-07-20
|
# 11.0.2 - 2024-07-20
|
||||||
|
|
||||||
@@ -272,6 +503,9 @@
|
|||||||
- Fixed handling of negative ids in `fmt::basic_format_args::get`
|
- Fixed handling of negative ids in `fmt::basic_format_args::get`
|
||||||
(https://github.com/fmtlib/fmt/pull/3945). Thanks @marlenecota.
|
(https://github.com/fmtlib/fmt/pull/3945). Thanks @marlenecota.
|
||||||
|
|
||||||
|
- Fixed handling of a buffer boundary on flush
|
||||||
|
(https://github.com/fmtlib/fmt/issues/4229).
|
||||||
|
|
||||||
- Improved named argument validation
|
- Improved named argument validation
|
||||||
(https://github.com/fmtlib/fmt/issues/3817).
|
(https://github.com/fmtlib/fmt/issues/3817).
|
||||||
|
|
||||||
|
|||||||
1
external/fmt/README.md
vendored
1
external/fmt/README.md
vendored
@@ -291,6 +291,7 @@ converts to `std::print`.)
|
|||||||
- [ccache](https://ccache.dev/): a compiler cache
|
- [ccache](https://ccache.dev/): a compiler cache
|
||||||
- [ClickHouse](https://github.com/ClickHouse/ClickHouse): an
|
- [ClickHouse](https://github.com/ClickHouse/ClickHouse): an
|
||||||
analytical database management system
|
analytical database management system
|
||||||
|
- [ContextVision](https://www.contextvision.com/): medical imaging software
|
||||||
- [Contour](https://github.com/contour-terminal/contour/): a modern
|
- [Contour](https://github.com/contour-terminal/contour/): a modern
|
||||||
terminal emulator
|
terminal emulator
|
||||||
- [CUAUV](https://cuauv.org/): Cornell University\'s autonomous
|
- [CUAUV](https://cuauv.org/): Cornell University\'s autonomous
|
||||||
|
|||||||
75
external/fmt/doc/api.md
vendored
75
external/fmt/doc/api.md
vendored
@@ -269,18 +269,16 @@ that support C++20 `consteval`. On older compilers you can use the
|
|||||||
|
|
||||||
Unused arguments are allowed as in Python's `str.format` and ordinary functions.
|
Unused arguments are allowed as in Python's `str.format` and ordinary functions.
|
||||||
|
|
||||||
::: basic_format_string
|
See [Type Erasure](#type-erasure) for an example of how to enable compile-time
|
||||||
|
checks in your own functions with `fmt::format_string` while avoiding template
|
||||||
|
bloat.
|
||||||
|
|
||||||
|
::: fstring
|
||||||
|
|
||||||
::: format_string
|
::: format_string
|
||||||
|
|
||||||
::: runtime(string_view)
|
::: runtime(string_view)
|
||||||
|
|
||||||
### Named Arguments
|
|
||||||
|
|
||||||
::: arg(const Char*, const T&)
|
|
||||||
|
|
||||||
Named arguments are not supported in compile-time checks at the moment.
|
|
||||||
|
|
||||||
### Type Erasure
|
### Type Erasure
|
||||||
|
|
||||||
You can create your own formatting function with compile-time checks and
|
You can create your own formatting function with compile-time checks and
|
||||||
@@ -317,6 +315,12 @@ parameterized version.
|
|||||||
|
|
||||||
::: basic_format_arg
|
::: basic_format_arg
|
||||||
|
|
||||||
|
### Named Arguments
|
||||||
|
|
||||||
|
::: arg(const Char*, const T&)
|
||||||
|
|
||||||
|
Named arguments are not supported in compile-time checks at the moment.
|
||||||
|
|
||||||
### Compatibility
|
### Compatibility
|
||||||
|
|
||||||
::: basic_string_view
|
::: basic_string_view
|
||||||
@@ -375,18 +379,17 @@ allocator:
|
|||||||
using custom_string =
|
using custom_string =
|
||||||
std::basic_string<char, std::char_traits<char>, custom_allocator>;
|
std::basic_string<char, std::char_traits<char>, custom_allocator>;
|
||||||
|
|
||||||
custom_string vformat(custom_allocator alloc, fmt::string_view format_str,
|
auto vformat(custom_allocator alloc, fmt::string_view fmt,
|
||||||
fmt::format_args args) {
|
fmt::format_args args) -> custom_string {
|
||||||
auto buf = custom_memory_buffer(alloc);
|
auto buf = custom_memory_buffer(alloc);
|
||||||
fmt::vformat_to(std::back_inserter(buf), format_str, args);
|
fmt::vformat_to(std::back_inserter(buf), fmt, args);
|
||||||
return custom_string(buf.data(), buf.size(), alloc);
|
return custom_string(buf.data(), buf.size(), alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ...Args>
|
template <typename ...Args>
|
||||||
inline custom_string format(custom_allocator alloc,
|
auto format(custom_allocator alloc, fmt::string_view fmt,
|
||||||
fmt::string_view format_str,
|
const Args& ... args) -> custom_string {
|
||||||
const Args& ... args) {
|
return vformat(alloc, fmt, fmt::make_format_args(args...));
|
||||||
return vformat(alloc, format_str, fmt::make_format_args(args...));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
The allocator will be used for the output container only. Formatting
|
The allocator will be used for the output container only. Formatting
|
||||||
@@ -410,11 +413,11 @@ locale:
|
|||||||
that take `std::locale` as a parameter. The locale type is a template
|
that take `std::locale` as a parameter. The locale type is a template
|
||||||
parameter to avoid the expensive `<locale>` include.
|
parameter to avoid the expensive `<locale>` include.
|
||||||
|
|
||||||
::: format(const Locale&, format_string<T...>, T&&...)
|
::: format(detail::locale_ref, format_string<T...>, T&&...)
|
||||||
|
|
||||||
::: format_to(OutputIt, const Locale&, format_string<T...>, T&&...)
|
::: format_to(OutputIt, detail::locale_ref, format_string<T...>, T&&...)
|
||||||
|
|
||||||
::: formatted_size(const Locale&, format_string<T...>, T&&...)
|
::: formatted_size(detail::locale_ref, format_string<T...>, T&&...)
|
||||||
|
|
||||||
<a id="legacy-checks"></a>
|
<a id="legacy-checks"></a>
|
||||||
### Legacy Compile-Time Checks
|
### Legacy Compile-Time Checks
|
||||||
@@ -498,10 +501,13 @@ chrono-format-specifications).
|
|||||||
- [`std::atomic_flag`](https://en.cppreference.com/w/cpp/atomic/atomic_flag)
|
- [`std::atomic_flag`](https://en.cppreference.com/w/cpp/atomic/atomic_flag)
|
||||||
- [`std::bitset`](https://en.cppreference.com/w/cpp/utility/bitset)
|
- [`std::bitset`](https://en.cppreference.com/w/cpp/utility/bitset)
|
||||||
- [`std::error_code`](https://en.cppreference.com/w/cpp/error/error_code)
|
- [`std::error_code`](https://en.cppreference.com/w/cpp/error/error_code)
|
||||||
|
- [`std::exception`](https://en.cppreference.com/w/cpp/error/exception)
|
||||||
- [`std::filesystem::path`](https://en.cppreference.com/w/cpp/filesystem/path)
|
- [`std::filesystem::path`](https://en.cppreference.com/w/cpp/filesystem/path)
|
||||||
- [`std::monostate`](https://en.cppreference.com/w/cpp/utility/variant/monostate)
|
- [`std::monostate`](
|
||||||
|
https://en.cppreference.com/w/cpp/utility/variant/monostate)
|
||||||
- [`std::optional`](https://en.cppreference.com/w/cpp/utility/optional)
|
- [`std::optional`](https://en.cppreference.com/w/cpp/utility/optional)
|
||||||
- [`std::source_location`](https://en.cppreference.com/w/cpp/utility/source_location)
|
- [`std::source_location`](
|
||||||
|
https://en.cppreference.com/w/cpp/utility/source_location)
|
||||||
- [`std::thread::id`](https://en.cppreference.com/w/cpp/thread/thread/id)
|
- [`std::thread::id`](https://en.cppreference.com/w/cpp/thread/thread/id)
|
||||||
- [`std::variant`](https://en.cppreference.com/w/cpp/utility/variant/variant)
|
- [`std::variant`](https://en.cppreference.com/w/cpp/utility/variant/variant)
|
||||||
|
|
||||||
@@ -509,7 +515,7 @@ chrono-format-specifications).
|
|||||||
|
|
||||||
::: ptr(const std::shared_ptr<T>&)
|
::: ptr(const std::shared_ptr<T>&)
|
||||||
|
|
||||||
### Formatting Variants
|
### Variants
|
||||||
|
|
||||||
A `std::variant` is only formattable if every variant alternative is
|
A `std::variant` is only formattable if every variant alternative is
|
||||||
formattable, and requires the `__cpp_lib_variant` [library
|
formattable, and requires the `__cpp_lib_variant` [library
|
||||||
@@ -525,15 +531,32 @@ feature](https://en.cppreference.com/w/cpp/feature_test).
|
|||||||
fmt::print("{}", std::variant<std::monostate, char>());
|
fmt::print("{}", std::variant<std::monostate, char>());
|
||||||
// Output: variant(monostate)
|
// Output: variant(monostate)
|
||||||
|
|
||||||
|
## Bit-Fields and Packed Structs
|
||||||
|
|
||||||
|
To format a bit-field or a field of a struct with `__attribute__((packed))`
|
||||||
|
applied to it, you need to convert it to the underlying or compatible type via
|
||||||
|
a cast or a unary `+` ([godbolt](https://www.godbolt.org/z/3qKKs6T5Y)):
|
||||||
|
|
||||||
|
```c++
|
||||||
|
struct smol {
|
||||||
|
int bit : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto s = smol();
|
||||||
|
fmt::print("{}", +s.bit);
|
||||||
|
```
|
||||||
|
|
||||||
|
This is a known limitation of "perfect" forwarding in C++.
|
||||||
|
|
||||||
<a id="compile-api"></a>
|
<a id="compile-api"></a>
|
||||||
## Format String Compilation
|
## Format String Compilation
|
||||||
|
|
||||||
`fmt/compile.h` provides format string compilation enabled via the
|
`fmt/compile.h` provides format string compilation and compile-time
|
||||||
`FMT_COMPILE` macro or the `_cf` user-defined literal defined in
|
(`constexpr`) formatting enabled via the `FMT_COMPILE` macro or the `_cf`
|
||||||
namespace `fmt::literals`. Format strings marked with `FMT_COMPILE`
|
user-defined literal defined in namespace `fmt::literals`. Format strings
|
||||||
or `_cf` are parsed, checked and converted into efficient formatting
|
marked with `FMT_COMPILE` or `_cf` are parsed, checked and converted into
|
||||||
code at compile-time. This supports arguments of built-in and string
|
efficient formatting code at compile-time. This supports arguments of built-in
|
||||||
types as well as user-defined types with `format` functions taking
|
and string types as well as user-defined types with `format` functions taking
|
||||||
the format context type as a template parameter in their `formatter`
|
the format context type as a template parameter in their `formatter`
|
||||||
specializations. For example:
|
specializations. For example:
|
||||||
|
|
||||||
|
|||||||
2
external/fmt/doc/get-started.md
vendored
2
external/fmt/doc/get-started.md
vendored
@@ -202,7 +202,7 @@ For a static build, use the following subproject definition:
|
|||||||
|
|
||||||
For the header-only version, use:
|
For the header-only version, use:
|
||||||
|
|
||||||
fmt = subproject('fmt')
|
fmt = subproject('fmt', default_options: ['header-only=true'])
|
||||||
fmt_dep = fmt.get_variable('fmt_header_only_dep')
|
fmt_dep = fmt.get_variable('fmt_header_only_dep')
|
||||||
|
|
||||||
### Android NDK
|
### Android NDK
|
||||||
|
|||||||
4
external/fmt/doc/index.md
vendored
4
external/fmt/doc/index.md
vendored
@@ -122,8 +122,8 @@ hide:
|
|||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
The library is highly portable and requires only a minimal <b>subset of
|
The library is highly portable and requires only a minimal <b>subset of
|
||||||
C++11</b> features which are available in GCC 4.9, Clang 3.4, MSVC 19.0
|
C++11</b> features which are available in GCC 4.9, Clang 3.4, MSVC 19.10
|
||||||
(2015) and later. Newer compiler and standard library features are used
|
(2017) and later. Newer compiler and standard library features are used
|
||||||
if available, and enable additional functionality.
|
if available, and enable additional functionality.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
|
|||||||
6
external/fmt/doc/syntax.md
vendored
6
external/fmt/doc/syntax.md
vendored
@@ -706,12 +706,12 @@ The available padding modifiers (*padding_modifier*) are:
|
|||||||
|
|
||||||
| Type | Meaning |
|
| Type | Meaning |
|
||||||
|-------|-----------------------------------------|
|
|-------|-----------------------------------------|
|
||||||
| `'-'` | Pad a numeric result with spaces. |
|
| `'_'` | Pad a numeric result with spaces. |
|
||||||
| `'_'` | Do not pad a numeric result string. |
|
| `'-'` | Do not pad a numeric result string. |
|
||||||
| `'0'` | Pad a numeric result string with zeros. |
|
| `'0'` | Pad a numeric result string with zeros. |
|
||||||
|
|
||||||
These modifiers are only supported for the `'H'`, `'I'`, `'M'`, `'S'`, `'U'`,
|
These modifiers are only supported for the `'H'`, `'I'`, `'M'`, `'S'`, `'U'`,
|
||||||
`'V'`, `'W'`, `'m'`, `'j'`, `'Y'` presentation types.
|
`'V'`, `'W'`, `'Y'`, `'d'`, `'j'` and `'m'` presentation types.
|
||||||
|
|
||||||
## Range Format Specifications
|
## Range Format Specifications
|
||||||
|
|
||||||
|
|||||||
3
external/fmt/include/fmt/args.h
vendored
3
external/fmt/include/fmt/args.h
vendored
@@ -210,6 +210,9 @@ template <typename Context> class dynamic_format_arg_store {
|
|||||||
data_.reserve(new_cap);
|
data_.reserve(new_cap);
|
||||||
named_info_.reserve(new_cap_named);
|
named_info_.reserve(new_cap_named);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the number of elements in the store.
|
||||||
|
size_t size() const noexcept { return data_.size(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
FMT_END_NAMESPACE
|
FMT_END_NAMESPACE
|
||||||
|
|||||||
180
external/fmt/include/fmt/base.h
vendored
180
external/fmt/include/fmt/base.h
vendored
@@ -21,7 +21,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// The fmt library version in the form major * 10000 + minor * 100 + patch.
|
// The fmt library version in the form major * 10000 + minor * 100 + patch.
|
||||||
#define FMT_VERSION 110002
|
#define FMT_VERSION 110101
|
||||||
|
|
||||||
// Detect compiler versions.
|
// Detect compiler versions.
|
||||||
#if defined(__clang__) && !defined(__ibmxl__)
|
#if defined(__clang__) && !defined(__ibmxl__)
|
||||||
@@ -146,6 +146,8 @@
|
|||||||
// Use the provided definition.
|
// Use the provided definition.
|
||||||
#elif defined(__GNUC__) && !defined(__EXCEPTIONS)
|
#elif defined(__GNUC__) && !defined(__EXCEPTIONS)
|
||||||
# define FMT_USE_EXCEPTIONS 0
|
# define FMT_USE_EXCEPTIONS 0
|
||||||
|
#elif defined(__clang__) && !defined(__cpp_exceptions)
|
||||||
|
# define FMT_USE_EXCEPTIONS 0
|
||||||
#elif FMT_MSC_VERSION && !_HAS_EXCEPTIONS
|
#elif FMT_MSC_VERSION && !_HAS_EXCEPTIONS
|
||||||
# define FMT_USE_EXCEPTIONS 0
|
# define FMT_USE_EXCEPTIONS 0
|
||||||
#else
|
#else
|
||||||
@@ -159,6 +161,20 @@
|
|||||||
# define FMT_CATCH(x) if (false)
|
# define FMT_CATCH(x) if (false)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef FMT_NO_UNIQUE_ADDRESS
|
||||||
|
// Use the provided definition.
|
||||||
|
#elif FMT_CPLUSPLUS < 202002L
|
||||||
|
// Not supported.
|
||||||
|
#elif FMT_HAS_CPP_ATTRIBUTE(no_unique_address)
|
||||||
|
# define FMT_NO_UNIQUE_ADDRESS [[no_unique_address]]
|
||||||
|
// VS2019 v16.10 and later except clang-cl (https://reviews.llvm.org/D110485).
|
||||||
|
#elif FMT_MSC_VERSION >= 1929 && !FMT_CLANG_VERSION
|
||||||
|
# define FMT_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]]
|
||||||
|
#endif
|
||||||
|
#ifndef FMT_NO_UNIQUE_ADDRESS
|
||||||
|
# define FMT_NO_UNIQUE_ADDRESS
|
||||||
|
#endif
|
||||||
|
|
||||||
#if FMT_HAS_CPP17_ATTRIBUTE(fallthrough)
|
#if FMT_HAS_CPP17_ATTRIBUTE(fallthrough)
|
||||||
# define FMT_FALLTHROUGH [[fallthrough]]
|
# define FMT_FALLTHROUGH [[fallthrough]]
|
||||||
#elif defined(__clang__)
|
#elif defined(__clang__)
|
||||||
@@ -332,6 +348,13 @@ struct monostate {
|
|||||||
# define FMT_ENABLE_IF(...) fmt::enable_if_t<(__VA_ARGS__), int> = 0
|
# define FMT_ENABLE_IF(...) fmt::enable_if_t<(__VA_ARGS__), int> = 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
template <typename T> constexpr auto min_of(T a, T b) -> T {
|
||||||
|
return a < b ? a : b;
|
||||||
|
}
|
||||||
|
template <typename T> constexpr auto max_of(T a, T b) -> T {
|
||||||
|
return a > b ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
// Suppresses "unused variable" warnings with the method described in
|
// Suppresses "unused variable" warnings with the method described in
|
||||||
// https://herbsutter.com/2009/10/18/mailbag-shutting-up-compiler-warnings/.
|
// https://herbsutter.com/2009/10/18/mailbag-shutting-up-compiler-warnings/.
|
||||||
@@ -355,7 +378,9 @@ constexpr auto is_constant_evaluated(bool default_value = false) noexcept
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Suppresses "conditional expression is constant" warnings.
|
// Suppresses "conditional expression is constant" warnings.
|
||||||
template <typename T> constexpr auto const_check(T value) -> T { return value; }
|
template <typename T> FMT_ALWAYS_INLINE constexpr auto const_check(T val) -> T {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
FMT_NORETURN FMT_API void assert_fail(const char* file, int line,
|
FMT_NORETURN FMT_API void assert_fail(const char* file, int line,
|
||||||
const char* message);
|
const char* message);
|
||||||
@@ -394,7 +419,7 @@ inline auto map(uint128_opt) -> monostate { return {}; }
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef FMT_USE_BITINT
|
#ifndef FMT_USE_BITINT
|
||||||
# define FMT_USE_BITINT (FMT_CLANG_VERSION >= 1400)
|
# define FMT_USE_BITINT (FMT_CLANG_VERSION >= 1500)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if FMT_USE_BITINT
|
#if FMT_USE_BITINT
|
||||||
@@ -562,8 +587,8 @@ template <typename Char> class basic_string_view {
|
|||||||
|
|
||||||
// Lexicographically compare this string reference to other.
|
// Lexicographically compare this string reference to other.
|
||||||
FMT_CONSTEXPR auto compare(basic_string_view other) const -> int {
|
FMT_CONSTEXPR auto compare(basic_string_view other) const -> int {
|
||||||
size_t str_size = size_ < other.size_ ? size_ : other.size_;
|
int result =
|
||||||
int result = detail::compare(data_, other.data_, str_size);
|
detail::compare(data_, other.data_, min_of(size_, other.size_));
|
||||||
if (result != 0) return result;
|
if (result != 0) return result;
|
||||||
return size_ == other.size_ ? 0 : (size_ < other.size_ ? -1 : 1);
|
return size_ == other.size_ ? 0 : (size_ < other.size_ ? -1 : 1);
|
||||||
}
|
}
|
||||||
@@ -714,7 +739,7 @@ class basic_specs {
|
|||||||
max_fill_size = 4
|
max_fill_size = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned long data_ = 1 << fill_size_shift;
|
size_t data_ = 1 << fill_size_shift;
|
||||||
|
|
||||||
// Character (code unit) type is erased to prevent template bloat.
|
// Character (code unit) type is erased to prevent template bloat.
|
||||||
char fill_data_[max_fill_size] = {' '};
|
char fill_data_[max_fill_size] = {' '};
|
||||||
@@ -793,7 +818,8 @@ class basic_specs {
|
|||||||
template <typename Char> constexpr auto fill_unit() const -> Char {
|
template <typename Char> constexpr auto fill_unit() const -> Char {
|
||||||
using uchar = unsigned char;
|
using uchar = unsigned char;
|
||||||
return static_cast<Char>(static_cast<uchar>(fill_data_[0]) |
|
return static_cast<Char>(static_cast<uchar>(fill_data_[0]) |
|
||||||
(static_cast<uchar>(fill_data_[1]) << 8));
|
(static_cast<uchar>(fill_data_[1]) << 8) |
|
||||||
|
(static_cast<uchar>(fill_data_[2]) << 16));
|
||||||
}
|
}
|
||||||
|
|
||||||
FMT_CONSTEXPR void set_fill(char c) {
|
FMT_CONSTEXPR void set_fill(char c) {
|
||||||
@@ -809,12 +835,19 @@ class basic_specs {
|
|||||||
unsigned uchar = static_cast<detail::unsigned_char<Char>>(s[0]);
|
unsigned uchar = static_cast<detail::unsigned_char<Char>>(s[0]);
|
||||||
fill_data_[0] = static_cast<char>(uchar);
|
fill_data_[0] = static_cast<char>(uchar);
|
||||||
fill_data_[1] = static_cast<char>(uchar >> 8);
|
fill_data_[1] = static_cast<char>(uchar >> 8);
|
||||||
|
fill_data_[2] = static_cast<char>(uchar >> 16);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
FMT_ASSERT(size <= max_fill_size, "invalid fill");
|
FMT_ASSERT(size <= max_fill_size, "invalid fill");
|
||||||
for (size_t i = 0; i < size; ++i)
|
for (size_t i = 0; i < size; ++i)
|
||||||
fill_data_[i & 3] = static_cast<char>(s[i]);
|
fill_data_[i & 3] = static_cast<char>(s[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FMT_CONSTEXPR void set_fill(const basic_specs& specs) {
|
||||||
|
set_fill_size(specs.fill_size());
|
||||||
|
for (size_t i = 0; i < max_fill_size; ++i)
|
||||||
|
fill_data_[i] = specs.fill_data_[i];
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Format specifiers for built-in and string types.
|
// Format specifiers for built-in and string types.
|
||||||
@@ -842,7 +875,7 @@ template <typename Char = char> class parse_context {
|
|||||||
using char_type = Char;
|
using char_type = Char;
|
||||||
using iterator = const Char*;
|
using iterator = const Char*;
|
||||||
|
|
||||||
explicit constexpr parse_context(basic_string_view<Char> fmt,
|
constexpr explicit parse_context(basic_string_view<Char> fmt,
|
||||||
int next_arg_id = 0)
|
int next_arg_id = 0)
|
||||||
: fmt_(fmt), next_arg_id_(next_arg_id) {}
|
: fmt_(fmt), next_arg_id_(next_arg_id) {}
|
||||||
|
|
||||||
@@ -1012,15 +1045,15 @@ template <typename Char, typename T> struct named_arg : view {
|
|||||||
static_assert(!is_named_arg<T>::value, "nested named arguments");
|
static_assert(!is_named_arg<T>::value, "nested named arguments");
|
||||||
};
|
};
|
||||||
|
|
||||||
template <bool B = false> constexpr auto count() -> size_t { return B ? 1 : 0; }
|
template <bool B = false> constexpr auto count() -> int { 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() -> int {
|
||||||
return (B1 ? 1 : 0) + count<B2, Tail...>();
|
return (B1 ? 1 : 0) + count<B2, Tail...>();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... Args> constexpr auto count_named_args() -> size_t {
|
template <typename... Args> constexpr auto count_named_args() -> int {
|
||||||
return count<is_named_arg<Args>::value...>();
|
return count<is_named_arg<Args>::value...>();
|
||||||
}
|
}
|
||||||
template <typename... Args> constexpr auto count_static_named_args() -> size_t {
|
template <typename... Args> constexpr auto count_static_named_args() -> int {
|
||||||
return count<is_static_named_arg<Args>::value...>();
|
return count<is_static_named_arg<Args>::value...>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1180,7 +1213,7 @@ class compile_parse_context : public parse_context<Char> {
|
|||||||
using base = parse_context<Char>;
|
using base = parse_context<Char>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit FMT_CONSTEXPR compile_parse_context(basic_string_view<Char> fmt,
|
FMT_CONSTEXPR explicit compile_parse_context(basic_string_view<Char> fmt,
|
||||||
int num_args, const type* types,
|
int num_args, const type* types,
|
||||||
int next_arg_id = 0)
|
int next_arg_id = 0)
|
||||||
: base(fmt, next_arg_id), num_args_(num_args), types_(types) {}
|
: base(fmt, next_arg_id), num_args_(num_args), types_(types) {}
|
||||||
@@ -1627,16 +1660,16 @@ template <typename... T> struct arg_pack {};
|
|||||||
template <typename Char, int NUM_ARGS, int NUM_NAMED_ARGS, bool DYNAMIC_NAMES>
|
template <typename Char, int NUM_ARGS, int NUM_NAMED_ARGS, bool DYNAMIC_NAMES>
|
||||||
class format_string_checker {
|
class format_string_checker {
|
||||||
private:
|
private:
|
||||||
type types_[NUM_ARGS > 0 ? NUM_ARGS : 1];
|
type types_[max_of(1, NUM_ARGS)];
|
||||||
named_arg_info<Char> named_args_[NUM_NAMED_ARGS > 0 ? NUM_NAMED_ARGS : 1];
|
named_arg_info<Char> named_args_[max_of(1, NUM_NAMED_ARGS)];
|
||||||
compile_parse_context<Char> context_;
|
compile_parse_context<Char> context_;
|
||||||
|
|
||||||
using parse_func = auto (*)(parse_context<Char>&) -> const Char*;
|
using parse_func = auto (*)(parse_context<Char>&) -> const Char*;
|
||||||
parse_func parse_funcs_[NUM_ARGS > 0 ? NUM_ARGS : 1];
|
parse_func parse_funcs_[max_of(1, NUM_ARGS)];
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template <typename... T>
|
template <typename... T>
|
||||||
explicit FMT_CONSTEXPR format_string_checker(basic_string_view<Char> fmt,
|
FMT_CONSTEXPR explicit format_string_checker(basic_string_view<Char> fmt,
|
||||||
arg_pack<T...>)
|
arg_pack<T...>)
|
||||||
: types_{mapped_type_constant<T, Char>::value...},
|
: types_{mapped_type_constant<T, Char>::value...},
|
||||||
named_args_{},
|
named_args_{},
|
||||||
@@ -1694,7 +1727,7 @@ template <typename T> class buffer {
|
|||||||
protected:
|
protected:
|
||||||
// Don't initialize ptr_ since it is not accessed to save a few cycles.
|
// Don't initialize ptr_ since it is not accessed to save a few cycles.
|
||||||
FMT_MSC_WARNING(suppress : 26495)
|
FMT_MSC_WARNING(suppress : 26495)
|
||||||
FMT_CONSTEXPR20 buffer(grow_fun grow, size_t sz) noexcept
|
FMT_CONSTEXPR buffer(grow_fun grow, size_t sz) noexcept
|
||||||
: size_(sz), capacity_(sz), grow_(grow) {}
|
: size_(sz), capacity_(sz), grow_(grow) {}
|
||||||
|
|
||||||
constexpr buffer(grow_fun grow, T* p = nullptr, size_t sz = 0,
|
constexpr buffer(grow_fun grow, T* p = nullptr, size_t sz = 0,
|
||||||
@@ -1740,7 +1773,7 @@ template <typename T> class buffer {
|
|||||||
// the new elements may not be initialized.
|
// the new elements may not be initialized.
|
||||||
FMT_CONSTEXPR void try_resize(size_t count) {
|
FMT_CONSTEXPR void try_resize(size_t count) {
|
||||||
try_reserve(count);
|
try_reserve(count);
|
||||||
size_ = count <= capacity_ ? count : capacity_;
|
size_ = min_of(count, capacity_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tries increasing the buffer capacity to `new_capacity`. It can increase the
|
// Tries increasing the buffer capacity to `new_capacity`. It can increase the
|
||||||
@@ -1788,9 +1821,9 @@ template <typename T> class buffer {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct buffer_traits {
|
struct buffer_traits {
|
||||||
explicit buffer_traits(size_t) {}
|
constexpr explicit buffer_traits(size_t) {}
|
||||||
auto count() const -> size_t { return 0; }
|
constexpr auto count() const -> size_t { return 0; }
|
||||||
auto limit(size_t size) -> size_t { return size; }
|
constexpr auto limit(size_t size) const -> size_t { return size; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class fixed_buffer_traits {
|
class fixed_buffer_traits {
|
||||||
@@ -1799,12 +1832,12 @@ class fixed_buffer_traits {
|
|||||||
size_t limit_;
|
size_t limit_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit fixed_buffer_traits(size_t limit) : limit_(limit) {}
|
constexpr explicit fixed_buffer_traits(size_t limit) : limit_(limit) {}
|
||||||
auto count() const -> size_t { return count_; }
|
constexpr auto count() const -> size_t { return count_; }
|
||||||
auto limit(size_t size) -> size_t {
|
FMT_CONSTEXPR auto limit(size_t size) -> size_t {
|
||||||
size_t n = limit_ > count_ ? limit_ - count_ : 0;
|
size_t n = limit_ > count_ ? limit_ - count_ : 0;
|
||||||
count_ += size;
|
count_ += size;
|
||||||
return size < n ? size : n;
|
return min_of(size, n);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1962,15 +1995,37 @@ template <typename T = char> class counting_buffer : public buffer<T> {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
struct is_back_insert_iterator<basic_appender<T>> : std::true_type {};
|
struct is_back_insert_iterator<basic_appender<T>> : std::true_type {};
|
||||||
|
|
||||||
|
template <typename OutputIt, typename InputIt, typename = void>
|
||||||
|
struct has_back_insert_iterator_container_append : std::false_type {};
|
||||||
|
template <typename OutputIt, typename InputIt>
|
||||||
|
struct has_back_insert_iterator_container_append<
|
||||||
|
OutputIt, InputIt,
|
||||||
|
void_t<decltype(get_container(std::declval<OutputIt>())
|
||||||
|
.append(std::declval<InputIt>(),
|
||||||
|
std::declval<InputIt>()))>> : std::true_type {};
|
||||||
|
|
||||||
// An optimized version of std::copy with the output value type (T).
|
// An optimized version of std::copy with the output value type (T).
|
||||||
template <typename T, typename InputIt, typename OutputIt,
|
template <typename T, typename InputIt, typename OutputIt,
|
||||||
FMT_ENABLE_IF(is_back_insert_iterator<OutputIt>::value)>
|
FMT_ENABLE_IF(is_back_insert_iterator<OutputIt>::value&&
|
||||||
|
has_back_insert_iterator_container_append<
|
||||||
|
OutputIt, InputIt>::value)>
|
||||||
FMT_CONSTEXPR20 auto copy(InputIt begin, InputIt end, OutputIt out)
|
FMT_CONSTEXPR20 auto copy(InputIt begin, InputIt end, OutputIt out)
|
||||||
-> OutputIt {
|
-> OutputIt {
|
||||||
get_container(out).append(begin, end);
|
get_container(out).append(begin, end);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T, typename InputIt, typename OutputIt,
|
||||||
|
FMT_ENABLE_IF(is_back_insert_iterator<OutputIt>::value &&
|
||||||
|
!has_back_insert_iterator_container_append<
|
||||||
|
OutputIt, InputIt>::value)>
|
||||||
|
FMT_CONSTEXPR20 auto copy(InputIt begin, InputIt end, OutputIt out)
|
||||||
|
-> OutputIt {
|
||||||
|
auto& c = get_container(out);
|
||||||
|
c.insert(c.end(), begin, end);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T, typename InputIt, typename OutputIt,
|
template <typename T, typename InputIt, typename OutputIt,
|
||||||
FMT_ENABLE_IF(!is_back_insert_iterator<OutputIt>::value)>
|
FMT_ENABLE_IF(!is_back_insert_iterator<OutputIt>::value)>
|
||||||
FMT_CONSTEXPR auto copy(InputIt begin, InputIt end, OutputIt out) -> OutputIt {
|
FMT_CONSTEXPR auto copy(InputIt begin, InputIt end, OutputIt out) -> OutputIt {
|
||||||
@@ -2146,7 +2201,8 @@ template <typename Context> class value {
|
|||||||
template <typename T, FMT_ENABLE_IF(is_named_arg<T>::value)>
|
template <typename T, FMT_ENABLE_IF(is_named_arg<T>::value)>
|
||||||
value(const T& named_arg) : value(named_arg.value) {}
|
value(const T& named_arg) : value(named_arg.value) {}
|
||||||
|
|
||||||
template <typename T, FMT_ENABLE_IF(use_formatter<T>::value)>
|
template <typename T,
|
||||||
|
FMT_ENABLE_IF(use_formatter<T>::value || !FMT_BUILTIN_TYPES)>
|
||||||
FMT_CONSTEXPR20 FMT_INLINE value(T& x) : value(x, custom_tag()) {}
|
FMT_CONSTEXPR20 FMT_INLINE value(T& x) : value(x, custom_tag()) {}
|
||||||
|
|
||||||
FMT_ALWAYS_INLINE value(const named_arg_info<char_type>* args, size_t size)
|
FMT_ALWAYS_INLINE value(const named_arg_info<char_type>* args, size_t size)
|
||||||
@@ -2220,9 +2276,12 @@ struct locale_ref {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
constexpr locale_ref() : locale_(nullptr) {}
|
constexpr locale_ref() : locale_(nullptr) {}
|
||||||
template <typename Locale> explicit locale_ref(const Locale& loc);
|
|
||||||
explicit operator bool() const noexcept { return locale_ != nullptr; }
|
template <typename Locale, FMT_ENABLE_IF(sizeof(Locale::collate) != 0)>
|
||||||
#endif
|
locale_ref(const Locale& loc);
|
||||||
|
|
||||||
|
inline explicit operator bool() const noexcept { return locale_ != nullptr; }
|
||||||
|
#endif // FMT_USE_LOCALE
|
||||||
|
|
||||||
template <typename Locale> auto get() const -> Locale;
|
template <typename Locale> auto get() const -> Locale;
|
||||||
};
|
};
|
||||||
@@ -2243,16 +2302,15 @@ constexpr auto make_descriptor() -> unsigned long long {
|
|||||||
: is_unpacked_bit | NUM_ARGS;
|
: is_unpacked_bit | NUM_ARGS;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Context, size_t NUM_ARGS>
|
template <typename Context, int 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 Context, size_t NUM_ARGS, size_t NUM_NAMED_ARGS,
|
template <typename Context, int NUM_ARGS, int NUM_NAMED_ARGS,
|
||||||
unsigned long long DESC>
|
unsigned long long DESC>
|
||||||
struct named_arg_store {
|
struct named_arg_store {
|
||||||
// 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.
|
arg_t<Context, NUM_ARGS> args[1 + NUM_ARGS];
|
||||||
arg_t<Context, NUM_ARGS> args[1 + (NUM_ARGS != 0 ? NUM_ARGS : +1)];
|
|
||||||
named_arg_info<typename Context::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>
|
||||||
@@ -2280,13 +2338,13 @@ struct named_arg_store {
|
|||||||
// An array of references to arguments. It can be implicitly converted to
|
// An array of references to arguments. It can be implicitly converted to
|
||||||
// `basic_format_args` for passing into type-erased formatting functions
|
// `basic_format_args` for passing into type-erased formatting functions
|
||||||
// such as `vformat`. It is a plain struct to reduce binary size in debug mode.
|
// such as `vformat`. It is a plain struct to reduce binary size in debug mode.
|
||||||
template <typename Context, size_t NUM_ARGS, size_t NUM_NAMED_ARGS,
|
template <typename Context, int NUM_ARGS, int NUM_NAMED_ARGS,
|
||||||
unsigned long long DESC>
|
unsigned long long DESC>
|
||||||
struct format_arg_store {
|
struct format_arg_store {
|
||||||
// +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.
|
||||||
using type =
|
using type =
|
||||||
conditional_t<NUM_NAMED_ARGS == 0,
|
conditional_t<NUM_NAMED_ARGS == 0,
|
||||||
arg_t<Context, NUM_ARGS>[NUM_ARGS != 0 ? NUM_ARGS : +1],
|
arg_t<Context, NUM_ARGS>[max_of(1, NUM_ARGS)],
|
||||||
named_arg_store<Context, NUM_ARGS, NUM_NAMED_ARGS, DESC>>;
|
named_arg_store<Context, NUM_ARGS, NUM_NAMED_ARGS, DESC>>;
|
||||||
type args;
|
type args;
|
||||||
};
|
};
|
||||||
@@ -2372,11 +2430,6 @@ template <typename T> class basic_appender {
|
|||||||
detail::buffer<T>* container;
|
detail::buffer<T>* container;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using iterator_category = int;
|
|
||||||
using value_type = T;
|
|
||||||
using pointer = T*;
|
|
||||||
using reference = T&;
|
|
||||||
using difference_type = decltype(pointer() - pointer());
|
|
||||||
using container_type = detail::buffer<T>;
|
using container_type = detail::buffer<T>;
|
||||||
|
|
||||||
FMT_CONSTEXPR basic_appender(detail::buffer<T>& buf) : container(&buf) {}
|
FMT_CONSTEXPR basic_appender(detail::buffer<T>& buf) : container(&buf) {}
|
||||||
@@ -2503,7 +2556,7 @@ template <typename Context> class basic_format_args {
|
|||||||
return static_cast<detail::type>((desc_ >> shift) & mask);
|
return static_cast<detail::type>((desc_ >> shift) & mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <size_t NUM_ARGS, size_t NUM_NAMED_ARGS, unsigned long long DESC>
|
template <int NUM_ARGS, int NUM_NAMED_ARGS, unsigned long long DESC>
|
||||||
using store =
|
using store =
|
||||||
detail::format_arg_store<Context, NUM_ARGS, NUM_NAMED_ARGS, DESC>;
|
detail::format_arg_store<Context, NUM_ARGS, NUM_NAMED_ARGS, DESC>;
|
||||||
|
|
||||||
@@ -2513,14 +2566,14 @@ template <typename Context> class basic_format_args {
|
|||||||
constexpr basic_format_args() : desc_(0), args_(nullptr) {}
|
constexpr basic_format_args() : desc_(0), args_(nullptr) {}
|
||||||
|
|
||||||
/// Constructs a `basic_format_args` object from `format_arg_store`.
|
/// Constructs a `basic_format_args` object from `format_arg_store`.
|
||||||
template <size_t NUM_ARGS, size_t NUM_NAMED_ARGS, unsigned long long DESC,
|
template <int NUM_ARGS, int 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 FMT_ALWAYS_INLINE basic_format_args(
|
constexpr FMT_ALWAYS_INLINE basic_format_args(
|
||||||
const store<NUM_ARGS, NUM_NAMED_ARGS, DESC>& s)
|
const store<NUM_ARGS, NUM_NAMED_ARGS, DESC>& s)
|
||||||
: desc_(DESC | (NUM_NAMED_ARGS != 0 ? +detail::has_named_args_bit : 0)),
|
: desc_(DESC | (NUM_NAMED_ARGS != 0 ? +detail::has_named_args_bit : 0)),
|
||||||
values_(s.args) {}
|
values_(s.args) {}
|
||||||
|
|
||||||
template <size_t NUM_ARGS, size_t NUM_NAMED_ARGS, unsigned long long DESC,
|
template <int NUM_ARGS, int 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(const store<NUM_ARGS, NUM_NAMED_ARGS, DESC>& s)
|
constexpr basic_format_args(const store<NUM_ARGS, NUM_NAMED_ARGS, DESC>& s)
|
||||||
: desc_(DESC | (NUM_NAMED_ARGS != 0 ? +detail::has_named_args_bit : 0)),
|
: desc_(DESC | (NUM_NAMED_ARGS != 0 ? +detail::has_named_args_bit : 0)),
|
||||||
@@ -2571,10 +2624,11 @@ template <typename Context> class basic_format_args {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// A formatting context.
|
// A formatting context.
|
||||||
class context : private detail::locale_ref {
|
class context {
|
||||||
private:
|
private:
|
||||||
appender out_;
|
appender out_;
|
||||||
format_args args_;
|
format_args args_;
|
||||||
|
FMT_NO_UNIQUE_ADDRESS detail::locale_ref loc_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// The character type for the output.
|
/// The character type for the output.
|
||||||
@@ -2590,24 +2644,26 @@ class context : private detail::locale_ref {
|
|||||||
/// in the object so make sure they have appropriate lifetimes.
|
/// in the object so make sure they have appropriate lifetimes.
|
||||||
FMT_CONSTEXPR context(iterator out, format_args args,
|
FMT_CONSTEXPR context(iterator out, format_args args,
|
||||||
detail::locale_ref loc = {})
|
detail::locale_ref loc = {})
|
||||||
: locale_ref(loc), out_(out), args_(args) {}
|
: out_(out), args_(args), loc_(loc) {}
|
||||||
context(context&&) = default;
|
context(context&&) = default;
|
||||||
context(const context&) = delete;
|
context(const context&) = delete;
|
||||||
void operator=(const context&) = delete;
|
void operator=(const context&) = delete;
|
||||||
|
|
||||||
FMT_CONSTEXPR auto arg(int id) const -> format_arg { return args_.get(id); }
|
FMT_CONSTEXPR auto arg(int id) const -> format_arg { return args_.get(id); }
|
||||||
auto arg(string_view name) -> format_arg { return args_.get(name); }
|
inline auto arg(string_view name) const -> format_arg {
|
||||||
FMT_CONSTEXPR auto arg_id(string_view name) -> int {
|
return args_.get(name);
|
||||||
|
}
|
||||||
|
FMT_CONSTEXPR auto arg_id(string_view name) const -> int {
|
||||||
return args_.get_id(name);
|
return args_.get_id(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns an iterator to the beginning of the output range.
|
// Returns an iterator to the beginning of the output range.
|
||||||
FMT_CONSTEXPR auto out() -> iterator { return out_; }
|
FMT_CONSTEXPR auto out() const -> iterator { return out_; }
|
||||||
|
|
||||||
// Advances the begin iterator to `it`.
|
// Advances the begin iterator to `it`.
|
||||||
void advance_to(iterator) {}
|
FMT_CONSTEXPR void advance_to(iterator) {}
|
||||||
|
|
||||||
FMT_CONSTEXPR auto locale() -> detail::locale_ref { return *this; }
|
FMT_CONSTEXPR auto locale() const -> detail::locale_ref { return loc_; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Char = char> struct runtime_format_string {
|
template <typename Char = char> struct runtime_format_string {
|
||||||
@@ -2624,7 +2680,8 @@ template <typename Char = char> struct runtime_format_string {
|
|||||||
*/
|
*/
|
||||||
inline auto runtime(string_view s) -> runtime_format_string<> { return {{s}}; }
|
inline auto runtime(string_view s) -> runtime_format_string<> { return {{s}}; }
|
||||||
|
|
||||||
/// A compile-time format string.
|
/// A compile-time format string. Use `format_string` in the public API to
|
||||||
|
/// prevent type deduction.
|
||||||
template <typename... T> struct fstring {
|
template <typename... T> struct fstring {
|
||||||
private:
|
private:
|
||||||
static constexpr int num_static_named_args =
|
static constexpr int num_static_named_args =
|
||||||
@@ -2657,8 +2714,9 @@ template <typename... T> struct fstring {
|
|||||||
template <typename S,
|
template <typename S,
|
||||||
FMT_ENABLE_IF(std::is_convertible<const S&, string_view>::value)>
|
FMT_ENABLE_IF(std::is_convertible<const S&, string_view>::value)>
|
||||||
FMT_CONSTEVAL FMT_ALWAYS_INLINE fstring(const S& s) : str(s) {
|
FMT_CONSTEVAL FMT_ALWAYS_INLINE fstring(const S& s) : str(s) {
|
||||||
|
auto sv = string_view(str);
|
||||||
if (FMT_USE_CONSTEVAL)
|
if (FMT_USE_CONSTEVAL)
|
||||||
detail::parse_format_string<char>(s, checker(s, arg_pack()));
|
detail::parse_format_string<char>(sv, checker(sv, arg_pack()));
|
||||||
#ifdef FMT_ENFORCE_COMPILE_STRING
|
#ifdef FMT_ENFORCE_COMPILE_STRING
|
||||||
static_assert(
|
static_assert(
|
||||||
FMT_USE_CONSTEVAL && sizeof(s) != 0,
|
FMT_USE_CONSTEVAL && sizeof(s) != 0,
|
||||||
@@ -2711,8 +2769,8 @@ struct formatter<T, Char,
|
|||||||
// Take arguments by lvalue references to avoid some lifetime issues, e.g.
|
// Take arguments by lvalue references to avoid some lifetime issues, e.g.
|
||||||
// auto args = make_format_args(std::string());
|
// auto args = make_format_args(std::string());
|
||||||
template <typename Context = context, typename... T,
|
template <typename Context = context, typename... T,
|
||||||
size_t NUM_ARGS = sizeof...(T),
|
int NUM_ARGS = sizeof...(T),
|
||||||
size_t NUM_NAMED_ARGS = detail::count_named_args<T...>(),
|
int NUM_NAMED_ARGS = detail::count_named_args<T...>(),
|
||||||
unsigned long long DESC = detail::make_descriptor<Context, T...>()>
|
unsigned long long DESC = detail::make_descriptor<Context, T...>()>
|
||||||
constexpr FMT_ALWAYS_INLINE auto make_format_args(T&... args)
|
constexpr FMT_ALWAYS_INLINE auto make_format_args(T&... args)
|
||||||
-> detail::format_arg_store<Context, NUM_ARGS, NUM_NAMED_ARGS, DESC> {
|
-> detail::format_arg_store<Context, NUM_ARGS, NUM_NAMED_ARGS, DESC> {
|
||||||
@@ -2851,7 +2909,7 @@ FMT_API void vprint_buffered(FILE* f, string_view fmt, format_args args);
|
|||||||
template <typename... T>
|
template <typename... T>
|
||||||
FMT_INLINE void print(format_string<T...> fmt, T&&... args) {
|
FMT_INLINE void print(format_string<T...> fmt, T&&... args) {
|
||||||
vargs<T...> va = {{args...}};
|
vargs<T...> va = {{args...}};
|
||||||
if (!detail::use_utf8)
|
if (detail::const_check(!detail::use_utf8))
|
||||||
return detail::vprint_mojibake(stdout, fmt.str, va, false);
|
return detail::vprint_mojibake(stdout, fmt.str, va, false);
|
||||||
return detail::is_locking<T...>() ? vprint_buffered(stdout, fmt.str, va)
|
return detail::is_locking<T...>() ? vprint_buffered(stdout, fmt.str, va)
|
||||||
: vprint(fmt.str, va);
|
: vprint(fmt.str, va);
|
||||||
@@ -2868,7 +2926,8 @@ FMT_INLINE void print(format_string<T...> fmt, T&&... args) {
|
|||||||
template <typename... T>
|
template <typename... T>
|
||||||
FMT_INLINE void print(FILE* f, format_string<T...> fmt, T&&... args) {
|
FMT_INLINE void print(FILE* f, format_string<T...> fmt, T&&... args) {
|
||||||
vargs<T...> va = {{args...}};
|
vargs<T...> va = {{args...}};
|
||||||
if (!detail::use_utf8) return detail::vprint_mojibake(f, fmt.str, va, false);
|
if (detail::const_check(!detail::use_utf8))
|
||||||
|
return detail::vprint_mojibake(f, fmt.str, va, false);
|
||||||
return detail::is_locking<T...>() ? vprint_buffered(f, fmt.str, va)
|
return detail::is_locking<T...>() ? vprint_buffered(f, fmt.str, va)
|
||||||
: vprint(f, fmt.str, va);
|
: vprint(f, fmt.str, va);
|
||||||
}
|
}
|
||||||
@@ -2878,8 +2937,9 @@ FMT_INLINE void print(FILE* f, format_string<T...> fmt, T&&... args) {
|
|||||||
template <typename... T>
|
template <typename... T>
|
||||||
FMT_INLINE void println(FILE* f, format_string<T...> fmt, T&&... args) {
|
FMT_INLINE void println(FILE* f, format_string<T...> fmt, T&&... args) {
|
||||||
vargs<T...> va = {{args...}};
|
vargs<T...> va = {{args...}};
|
||||||
return detail::use_utf8 ? vprintln(f, fmt.str, va)
|
return detail::const_check(detail::use_utf8)
|
||||||
: detail::vprint_mojibake(f, fmt.str, va, true);
|
? vprintln(f, fmt.str, va)
|
||||||
|
: detail::vprint_mojibake(f, fmt.str, va, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Formats `args` according to specifications in `fmt` and writes the output
|
/// Formats `args` according to specifications in `fmt` and writes the output
|
||||||
|
|||||||
40
external/fmt/include/fmt/chrono.h
vendored
40
external/fmt/include/fmt/chrono.h
vendored
@@ -444,7 +444,7 @@ struct is_same_arithmetic_type
|
|||||||
std::is_floating_point<Rep2>::value)> {
|
std::is_floating_point<Rep2>::value)> {
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void throw_duration_error() {
|
FMT_NORETURN inline void throw_duration_error() {
|
||||||
FMT_THROW(format_error("cannot format duration"));
|
FMT_THROW(format_error("cannot format duration"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -540,24 +540,24 @@ inline auto localtime(std::time_t time) -> std::tm {
|
|||||||
std::time_t time_;
|
std::time_t time_;
|
||||||
std::tm tm_;
|
std::tm tm_;
|
||||||
|
|
||||||
dispatcher(std::time_t t) : time_(t) {}
|
inline dispatcher(std::time_t t) : time_(t) {}
|
||||||
|
|
||||||
auto run() -> bool {
|
inline auto run() -> bool {
|
||||||
using namespace fmt::detail;
|
using namespace fmt::detail;
|
||||||
return handle(localtime_r(&time_, &tm_));
|
return handle(localtime_r(&time_, &tm_));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto handle(std::tm* tm) -> bool { return tm != nullptr; }
|
inline auto handle(std::tm* tm) -> bool { return tm != nullptr; }
|
||||||
|
|
||||||
auto handle(detail::null<>) -> bool {
|
inline auto handle(detail::null<>) -> bool {
|
||||||
using namespace fmt::detail;
|
using namespace fmt::detail;
|
||||||
return fallback(localtime_s(&tm_, &time_));
|
return fallback(localtime_s(&tm_, &time_));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto fallback(int res) -> bool { return res == 0; }
|
inline auto fallback(int res) -> bool { return res == 0; }
|
||||||
|
|
||||||
#if !FMT_MSC_VERSION
|
#if !FMT_MSC_VERSION
|
||||||
auto fallback(detail::null<>) -> bool {
|
inline auto fallback(detail::null<>) -> bool {
|
||||||
using namespace fmt::detail;
|
using namespace fmt::detail;
|
||||||
std::tm* tm = std::localtime(&time_);
|
std::tm* tm = std::localtime(&time_);
|
||||||
if (tm) tm_ = *tm;
|
if (tm) tm_ = *tm;
|
||||||
@@ -591,24 +591,24 @@ inline auto gmtime(std::time_t time) -> std::tm {
|
|||||||
std::time_t time_;
|
std::time_t time_;
|
||||||
std::tm tm_;
|
std::tm tm_;
|
||||||
|
|
||||||
dispatcher(std::time_t t) : time_(t) {}
|
inline dispatcher(std::time_t t) : time_(t) {}
|
||||||
|
|
||||||
auto run() -> bool {
|
inline auto run() -> bool {
|
||||||
using namespace fmt::detail;
|
using namespace fmt::detail;
|
||||||
return handle(gmtime_r(&time_, &tm_));
|
return handle(gmtime_r(&time_, &tm_));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto handle(std::tm* tm) -> bool { return tm != nullptr; }
|
inline auto handle(std::tm* tm) -> bool { return tm != nullptr; }
|
||||||
|
|
||||||
auto handle(detail::null<>) -> bool {
|
inline auto handle(detail::null<>) -> bool {
|
||||||
using namespace fmt::detail;
|
using namespace fmt::detail;
|
||||||
return fallback(gmtime_s(&tm_, &time_));
|
return fallback(gmtime_s(&tm_, &time_));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto fallback(int res) -> bool { return res == 0; }
|
inline auto fallback(int res) -> bool { return res == 0; }
|
||||||
|
|
||||||
#if !FMT_MSC_VERSION
|
#if !FMT_MSC_VERSION
|
||||||
auto fallback(detail::null<>) -> bool {
|
inline auto fallback(detail::null<>) -> bool {
|
||||||
std::tm* tm = std::gmtime(&time_);
|
std::tm* tm = std::gmtime(&time_);
|
||||||
if (tm) tm_ = *tm;
|
if (tm) tm_ = *tm;
|
||||||
return tm != nullptr;
|
return tm != nullptr;
|
||||||
@@ -912,7 +912,9 @@ template <typename Derived> struct null_chrono_spec_handler {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct tm_format_checker : null_chrono_spec_handler<tm_format_checker> {
|
struct tm_format_checker : null_chrono_spec_handler<tm_format_checker> {
|
||||||
FMT_NORETURN void unsupported() { FMT_THROW(format_error("no format")); }
|
FMT_NORETURN inline void unsupported() {
|
||||||
|
FMT_THROW(format_error("no format"));
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
FMT_CONSTEXPR void on_text(const Char*, const Char*) {}
|
FMT_CONSTEXPR void on_text(const Char*, const Char*) {}
|
||||||
@@ -1069,7 +1071,7 @@ void write_fractional_seconds(OutputIt& out, Duration d, int precision = -1) {
|
|||||||
}
|
}
|
||||||
} else if (precision > 0) {
|
} else if (precision > 0) {
|
||||||
*out++ = '.';
|
*out++ = '.';
|
||||||
leading_zeroes = (std::min)(leading_zeroes, precision);
|
leading_zeroes = min_of(leading_zeroes, precision);
|
||||||
int remaining = precision - leading_zeroes;
|
int remaining = precision - leading_zeroes;
|
||||||
out = detail::fill_n(out, leading_zeroes, '0');
|
out = detail::fill_n(out, leading_zeroes, '0');
|
||||||
if (remaining < num_digits) {
|
if (remaining < num_digits) {
|
||||||
@@ -1572,7 +1574,7 @@ class tm_writer {
|
|||||||
struct chrono_format_checker : null_chrono_spec_handler<chrono_format_checker> {
|
struct chrono_format_checker : null_chrono_spec_handler<chrono_format_checker> {
|
||||||
bool has_precision_integral = false;
|
bool has_precision_integral = false;
|
||||||
|
|
||||||
FMT_NORETURN void unsupported() { FMT_THROW(format_error("no date")); }
|
FMT_NORETURN inline void unsupported() { FMT_THROW(format_error("no date")); }
|
||||||
|
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
FMT_CONSTEXPR void on_text(const Char*, const Char*) {}
|
FMT_CONSTEXPR void on_text(const Char*, const Char*) {}
|
||||||
@@ -1693,14 +1695,14 @@ class get_locale {
|
|||||||
bool has_locale_ = false;
|
bool has_locale_ = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
get_locale(bool localized, locale_ref loc) : has_locale_(localized) {
|
inline get_locale(bool localized, locale_ref loc) : has_locale_(localized) {
|
||||||
if (localized)
|
if (localized)
|
||||||
::new (&locale_) std::locale(loc.template get<std::locale>());
|
::new (&locale_) std::locale(loc.template get<std::locale>());
|
||||||
}
|
}
|
||||||
~get_locale() {
|
inline ~get_locale() {
|
||||||
if (has_locale_) locale_.~locale();
|
if (has_locale_) locale_.~locale();
|
||||||
}
|
}
|
||||||
operator const std::locale&() const {
|
inline operator const std::locale&() const {
|
||||||
return has_locale_ ? locale_ : get_classic_locale();
|
return has_locale_ ? locale_ : get_classic_locale();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
13
external/fmt/include/fmt/compile.h
vendored
13
external/fmt/include/fmt/compile.h
vendored
@@ -42,11 +42,10 @@ struct is_compiled_string : std::is_base_of<compiled_string, S> {};
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if FMT_USE_NONTYPE_TEMPLATE_ARGS
|
#if FMT_USE_NONTYPE_TEMPLATE_ARGS
|
||||||
template <typename Char, size_t N,
|
template <typename Char, size_t N, fmt::detail::fixed_string<Char, N> Str>
|
||||||
fmt::detail_exported::fixed_string<Char, N> Str>
|
|
||||||
struct udl_compiled_string : compiled_string {
|
struct udl_compiled_string : compiled_string {
|
||||||
using char_type = Char;
|
using char_type = Char;
|
||||||
explicit constexpr operator basic_string_view<char_type>() const {
|
constexpr explicit operator basic_string_view<char_type>() const {
|
||||||
return {Str.data, N - 1};
|
return {Str.data, N - 1};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -525,9 +524,9 @@ FMT_CONSTEXPR20 auto formatted_size(const S& fmt, const Args&... args)
|
|||||||
template <typename S, typename... Args,
|
template <typename S, typename... Args,
|
||||||
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
|
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
|
||||||
void print(std::FILE* f, const S& fmt, const Args&... args) {
|
void print(std::FILE* f, const S& fmt, const Args&... args) {
|
||||||
memory_buffer buffer;
|
auto buf = memory_buffer();
|
||||||
fmt::format_to(std::back_inserter(buffer), fmt, args...);
|
fmt::format_to(appender(buf), fmt, args...);
|
||||||
detail::print(f, {buffer.data(), buffer.size()});
|
detail::print(f, {buf.data(), buf.size()});
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename S, typename... Args,
|
template <typename S, typename... Args,
|
||||||
@@ -538,7 +537,7 @@ void print(const S& fmt, const Args&... args) {
|
|||||||
|
|
||||||
#if FMT_USE_NONTYPE_TEMPLATE_ARGS
|
#if FMT_USE_NONTYPE_TEMPLATE_ARGS
|
||||||
inline namespace literals {
|
inline namespace literals {
|
||||||
template <detail_exported::fixed_string Str> constexpr auto operator""_cf() {
|
template <detail::fixed_string Str> constexpr auto operator""_cf() {
|
||||||
using char_t = remove_cvref_t<decltype(Str.data[0])>;
|
using char_t = remove_cvref_t<decltype(Str.data[0])>;
|
||||||
return detail::udl_compiled_string<char_t, sizeof(Str.data) / sizeof(char_t),
|
return detail::udl_compiled_string<char_t, sizeof(Str.data) / sizeof(char_t),
|
||||||
Str>();
|
Str>();
|
||||||
|
|||||||
16
external/fmt/include/fmt/format-inl.h
vendored
16
external/fmt/include/fmt/format-inl.h
vendored
@@ -26,6 +26,10 @@
|
|||||||
# include <locale>
|
# include <locale>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef FMT_FUNC
|
||||||
|
# define FMT_FUNC
|
||||||
|
#endif
|
||||||
|
|
||||||
FMT_BEGIN_NAMESPACE
|
FMT_BEGIN_NAMESPACE
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
@@ -59,8 +63,8 @@ FMT_FUNC void format_error_code(detail::buffer<char>& out, int error_code,
|
|||||||
FMT_ASSERT(out.size() <= inline_buffer_size, "");
|
FMT_ASSERT(out.size() <= inline_buffer_size, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
FMT_FUNC void report_error(format_func func, int error_code,
|
FMT_FUNC void do_report_error(format_func func, int error_code,
|
||||||
const char* message) noexcept {
|
const char* message) noexcept {
|
||||||
memory_buffer full_message;
|
memory_buffer full_message;
|
||||||
func(full_message, error_code, message);
|
func(full_message, error_code, message);
|
||||||
// Don't use fwrite_all because the latter may throw.
|
// Don't use fwrite_all because the latter may throw.
|
||||||
@@ -80,7 +84,7 @@ using std::locale;
|
|||||||
using std::numpunct;
|
using std::numpunct;
|
||||||
using std::use_facet;
|
using std::use_facet;
|
||||||
|
|
||||||
template <typename Locale>
|
template <typename Locale, enable_if_t<(sizeof(Locale::collate) != 0), int>>
|
||||||
locale_ref::locale_ref(const Locale& loc) : locale_(&loc) {
|
locale_ref::locale_ref(const Locale& loc) : locale_(&loc) {
|
||||||
static_assert(std::is_same<Locale, locale>::value, "");
|
static_assert(std::is_same<Locale, locale>::value, "");
|
||||||
}
|
}
|
||||||
@@ -130,7 +134,9 @@ FMT_FUNC auto write_loc(appender out, loc_value value,
|
|||||||
|
|
||||||
FMT_FUNC void report_error(const char* message) {
|
FMT_FUNC void report_error(const char* message) {
|
||||||
#if FMT_USE_EXCEPTIONS
|
#if FMT_USE_EXCEPTIONS
|
||||||
throw format_error(message);
|
// Use FMT_THROW instead of throw to avoid bogus unreachable code warnings
|
||||||
|
// from MSVC.
|
||||||
|
FMT_THROW(format_error(message));
|
||||||
#else
|
#else
|
||||||
fputs(message, stderr);
|
fputs(message, stderr);
|
||||||
abort();
|
abort();
|
||||||
@@ -1430,7 +1436,7 @@ FMT_FUNC void format_system_error(detail::buffer<char>& out, int error_code,
|
|||||||
|
|
||||||
FMT_FUNC void report_system_error(int error_code,
|
FMT_FUNC void report_system_error(int error_code,
|
||||||
const char* message) noexcept {
|
const char* message) noexcept {
|
||||||
report_error(format_system_error, error_code, message);
|
do_report_error(format_system_error, error_code, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
FMT_FUNC auto vformat(string_view fmt, format_args args) -> std::string {
|
FMT_FUNC auto vformat(string_view fmt, format_args args) -> std::string {
|
||||||
|
|||||||
715
external/fmt/include/fmt/format.h
vendored
715
external/fmt/include/fmt/format.h
vendored
File diff suppressed because it is too large
Load Diff
28
external/fmt/include/fmt/os.h
vendored
28
external/fmt/include/fmt/os.h
vendored
@@ -176,24 +176,24 @@ class buffered_file {
|
|||||||
|
|
||||||
friend class file;
|
friend class file;
|
||||||
|
|
||||||
explicit buffered_file(FILE* f) : file_(f) {}
|
inline explicit buffered_file(FILE* f) : file_(f) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
buffered_file(const buffered_file&) = delete;
|
buffered_file(const buffered_file&) = delete;
|
||||||
void operator=(const buffered_file&) = delete;
|
void operator=(const buffered_file&) = delete;
|
||||||
|
|
||||||
// Constructs a buffered_file object which doesn't represent any file.
|
// Constructs a buffered_file object which doesn't represent any file.
|
||||||
buffered_file() noexcept : file_(nullptr) {}
|
inline buffered_file() noexcept : file_(nullptr) {}
|
||||||
|
|
||||||
// Destroys the object closing the file it represents if any.
|
// Destroys the object closing the file it represents if any.
|
||||||
FMT_API ~buffered_file() noexcept;
|
FMT_API ~buffered_file() noexcept;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
buffered_file(buffered_file&& other) noexcept : file_(other.file_) {
|
inline buffered_file(buffered_file&& other) noexcept : file_(other.file_) {
|
||||||
other.file_ = nullptr;
|
other.file_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto operator=(buffered_file&& other) -> buffered_file& {
|
inline auto operator=(buffered_file&& other) -> buffered_file& {
|
||||||
close();
|
close();
|
||||||
file_ = other.file_;
|
file_ = other.file_;
|
||||||
other.file_ = nullptr;
|
other.file_ = nullptr;
|
||||||
@@ -207,7 +207,7 @@ class buffered_file {
|
|||||||
FMT_API void close();
|
FMT_API void close();
|
||||||
|
|
||||||
// Returns the pointer to a FILE object representing this file.
|
// Returns the pointer to a FILE object representing this file.
|
||||||
auto get() const noexcept -> FILE* { return file_; }
|
inline auto get() const noexcept -> FILE* { return file_; }
|
||||||
|
|
||||||
FMT_API auto descriptor() const -> int;
|
FMT_API auto descriptor() const -> int;
|
||||||
|
|
||||||
@@ -248,7 +248,7 @@ class FMT_API file {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Constructs a file object which doesn't represent any file.
|
// Constructs a file object which doesn't represent any file.
|
||||||
file() noexcept : fd_(-1) {}
|
inline file() noexcept : fd_(-1) {}
|
||||||
|
|
||||||
// Opens a file and constructs a file object representing this file.
|
// Opens a file and constructs a file object representing this file.
|
||||||
file(cstring_view path, int oflag);
|
file(cstring_view path, int oflag);
|
||||||
@@ -257,10 +257,10 @@ class FMT_API file {
|
|||||||
file(const file&) = delete;
|
file(const file&) = delete;
|
||||||
void operator=(const file&) = delete;
|
void operator=(const file&) = delete;
|
||||||
|
|
||||||
file(file&& other) noexcept : fd_(other.fd_) { other.fd_ = -1; }
|
inline file(file&& other) noexcept : fd_(other.fd_) { other.fd_ = -1; }
|
||||||
|
|
||||||
// Move assignment is not noexcept because close may throw.
|
// Move assignment is not noexcept because close may throw.
|
||||||
auto operator=(file&& other) -> file& {
|
inline auto operator=(file&& other) -> file& {
|
||||||
close();
|
close();
|
||||||
fd_ = other.fd_;
|
fd_ = other.fd_;
|
||||||
other.fd_ = -1;
|
other.fd_ = -1;
|
||||||
@@ -271,7 +271,7 @@ class FMT_API file {
|
|||||||
~file() noexcept;
|
~file() noexcept;
|
||||||
|
|
||||||
// Returns the file descriptor.
|
// Returns the file descriptor.
|
||||||
auto descriptor() const noexcept -> int { return fd_; }
|
inline auto descriptor() const noexcept -> int { return fd_; }
|
||||||
|
|
||||||
// Closes the file.
|
// Closes the file.
|
||||||
void close();
|
void close();
|
||||||
@@ -324,9 +324,9 @@ auto getpagesize() -> long;
|
|||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
struct buffer_size {
|
struct buffer_size {
|
||||||
buffer_size() = default;
|
constexpr buffer_size() = default;
|
||||||
size_t value = 0;
|
size_t value = 0;
|
||||||
auto operator=(size_t val) const -> buffer_size {
|
FMT_CONSTEXPR auto operator=(size_t val) const -> buffer_size {
|
||||||
auto bs = buffer_size();
|
auto bs = buffer_size();
|
||||||
bs.value = val;
|
bs.value = val;
|
||||||
return bs;
|
return bs;
|
||||||
@@ -337,7 +337,7 @@ struct ostream_params {
|
|||||||
int oflag = file::WRONLY | file::CREATE | file::TRUNC;
|
int oflag = file::WRONLY | file::CREATE | file::TRUNC;
|
||||||
size_t buffer_size = BUFSIZ > 32768 ? BUFSIZ : 32768;
|
size_t buffer_size = BUFSIZ > 32768 ? BUFSIZ : 32768;
|
||||||
|
|
||||||
ostream_params() {}
|
constexpr ostream_params() {}
|
||||||
|
|
||||||
template <typename... T>
|
template <typename... T>
|
||||||
ostream_params(T... params, int new_oflag) : ostream_params(params...) {
|
ostream_params(T... params, int new_oflag) : ostream_params(params...) {
|
||||||
@@ -381,7 +381,7 @@ class FMT_API ostream : private detail::buffer<char> {
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void flush() {
|
inline void flush() {
|
||||||
if (size() == 0) return;
|
if (size() == 0) return;
|
||||||
file_.write(data(), size() * sizeof(data()[0]));
|
file_.write(data(), size() * sizeof(data()[0]));
|
||||||
clear();
|
clear();
|
||||||
@@ -390,7 +390,7 @@ class FMT_API ostream : private detail::buffer<char> {
|
|||||||
template <typename... T>
|
template <typename... T>
|
||||||
friend auto output_file(cstring_view path, T... params) -> ostream;
|
friend auto output_file(cstring_view path, T... params) -> ostream;
|
||||||
|
|
||||||
void close() {
|
inline void close() {
|
||||||
flush();
|
flush();
|
||||||
file_.close();
|
file_.close();
|
||||||
}
|
}
|
||||||
|
|||||||
12
external/fmt/include/fmt/ostream.h
vendored
12
external/fmt/include/fmt/ostream.h
vendored
@@ -22,6 +22,14 @@
|
|||||||
|
|
||||||
#include "chrono.h" // formatbuf
|
#include "chrono.h" // formatbuf
|
||||||
|
|
||||||
|
#ifdef _MSVC_STL_UPDATE
|
||||||
|
# define FMT_MSVC_STL_UPDATE _MSVC_STL_UPDATE
|
||||||
|
#elif defined(_MSC_VER) && _MSC_VER < 1912 // VS 15.5
|
||||||
|
# define FMT_MSVC_STL_UPDATE _MSVC_LANG
|
||||||
|
#else
|
||||||
|
# define FMT_MSVC_STL_UPDATE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
FMT_BEGIN_NAMESPACE
|
FMT_BEGIN_NAMESPACE
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
@@ -35,7 +43,7 @@ class file_access {
|
|||||||
friend auto get_file(BufType& obj) -> FILE* { return obj.*FileMemberPtr; }
|
friend auto get_file(BufType& obj) -> FILE* { return obj.*FileMemberPtr; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#if FMT_MSC_VERSION
|
#if FMT_MSVC_STL_UPDATE
|
||||||
template class file_access<file_access_tag, std::filebuf,
|
template class file_access<file_access_tag, std::filebuf,
|
||||||
&std::filebuf::_Myfile>;
|
&std::filebuf::_Myfile>;
|
||||||
auto get_file(std::filebuf&) -> FILE*;
|
auto get_file(std::filebuf&) -> FILE*;
|
||||||
@@ -109,7 +117,7 @@ inline void vprint(std::ostream& os, string_view fmt, format_args args) {
|
|||||||
auto buffer = memory_buffer();
|
auto buffer = memory_buffer();
|
||||||
detail::vformat_to(buffer, fmt, args);
|
detail::vformat_to(buffer, fmt, args);
|
||||||
FILE* f = nullptr;
|
FILE* f = nullptr;
|
||||||
#if FMT_MSC_VERSION && FMT_USE_RTTI
|
#if FMT_MSVC_STL_UPDATE && FMT_USE_RTTI
|
||||||
if (auto* buf = dynamic_cast<std::filebuf*>(os.rdbuf()))
|
if (auto* buf = dynamic_cast<std::filebuf*>(os.rdbuf()))
|
||||||
f = detail::get_file(*buf);
|
f = detail::get_file(*buf);
|
||||||
#elif defined(_WIN32) && defined(__GLIBCXX__) && FMT_USE_RTTI
|
#elif defined(_WIN32) && defined(__GLIBCXX__) && FMT_USE_RTTI
|
||||||
|
|||||||
6
external/fmt/include/fmt/printf.h
vendored
6
external/fmt/include/fmt/printf.h
vendored
@@ -79,7 +79,7 @@ template <bool IsSigned> struct int_checker {
|
|||||||
unsigned max = to_unsigned(max_value<int>());
|
unsigned max = to_unsigned(max_value<int>());
|
||||||
return value <= max;
|
return value <= max;
|
||||||
}
|
}
|
||||||
static auto fits_in_int(bool) -> bool { return true; }
|
inline static auto fits_in_int(bool) -> bool { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> struct int_checker<true> {
|
template <> struct int_checker<true> {
|
||||||
@@ -87,7 +87,7 @@ template <> struct int_checker<true> {
|
|||||||
return value >= (std::numeric_limits<int>::min)() &&
|
return value >= (std::numeric_limits<int>::min)() &&
|
||||||
value <= max_value<int>();
|
value <= max_value<int>();
|
||||||
}
|
}
|
||||||
static auto fits_in_int(int) -> bool { return true; }
|
inline static auto fits_in_int(int) -> bool { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct printf_precision_handler {
|
struct printf_precision_handler {
|
||||||
@@ -205,7 +205,7 @@ class printf_width_handler {
|
|||||||
format_specs& specs_;
|
format_specs& specs_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit printf_width_handler(format_specs& specs) : specs_(specs) {}
|
inline explicit printf_width_handler(format_specs& specs) : specs_(specs) {}
|
||||||
|
|
||||||
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
|
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
|
||||||
auto operator()(T value) -> unsigned {
|
auto operator()(T value) -> unsigned {
|
||||||
|
|||||||
120
external/fmt/include/fmt/ranges.h
vendored
120
external/fmt/include/fmt/ranges.h
vendored
@@ -357,12 +357,9 @@ template <typename R>
|
|||||||
using maybe_const_range =
|
using maybe_const_range =
|
||||||
conditional_t<has_const_begin_end<R>::value, const R, R>;
|
conditional_t<has_const_begin_end<R>::value, const R, R>;
|
||||||
|
|
||||||
// Workaround a bug in MSVC 2015 and earlier.
|
|
||||||
#if !FMT_MSC_VERSION || FMT_MSC_VERSION >= 1910
|
|
||||||
template <typename R, typename Char>
|
template <typename R, typename Char>
|
||||||
struct is_formattable_delayed
|
struct is_formattable_delayed
|
||||||
: is_formattable<uncvref_type<maybe_const_range<R>>, Char> {};
|
: is_formattable<uncvref_type<maybe_const_range<R>>, Char> {};
|
||||||
#endif
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
template <typename...> struct conjunction : std::true_type {};
|
template <typename...> struct conjunction : std::true_type {};
|
||||||
@@ -498,13 +495,8 @@ struct formatter<
|
|||||||
range_format_kind<R, Char>::value != range_format::disabled &&
|
range_format_kind<R, Char>::value != range_format::disabled &&
|
||||||
range_format_kind<R, Char>::value != range_format::map &&
|
range_format_kind<R, Char>::value != range_format::map &&
|
||||||
range_format_kind<R, Char>::value != range_format::string &&
|
range_format_kind<R, Char>::value != range_format::string &&
|
||||||
range_format_kind<R, Char>::value != range_format::debug_string>
|
range_format_kind<R, Char>::value != range_format::debug_string>,
|
||||||
// Workaround a bug in MSVC 2015 and earlier.
|
detail::is_formattable_delayed<R, Char>>::value>> {
|
||||||
#if !FMT_MSC_VERSION || FMT_MSC_VERSION >= 1910
|
|
||||||
,
|
|
||||||
detail::is_formattable_delayed<R, Char>
|
|
||||||
#endif
|
|
||||||
>::value>> {
|
|
||||||
private:
|
private:
|
||||||
using range_type = detail::maybe_const_range<R>;
|
using range_type = detail::maybe_const_range<R>;
|
||||||
range_formatter<detail::uncvref_type<range_type>, Char> range_formatter_;
|
range_formatter<detail::uncvref_type<range_type>, Char> range_formatter_;
|
||||||
@@ -646,9 +638,9 @@ struct formatter<join_view<It, Sentinel, Char>, Char> {
|
|||||||
#endif
|
#endif
|
||||||
formatter<remove_cvref_t<value_type>, Char> value_formatter_;
|
formatter<remove_cvref_t<value_type>, Char> value_formatter_;
|
||||||
|
|
||||||
using view_ref = conditional_t<std::is_copy_constructible<It>::value,
|
using view = conditional_t<std::is_copy_constructible<It>::value,
|
||||||
const join_view<It, Sentinel, Char>&,
|
const join_view<It, Sentinel, Char>,
|
||||||
join_view<It, Sentinel, Char>&&>;
|
join_view<It, Sentinel, Char>>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using nonlocking = void;
|
using nonlocking = void;
|
||||||
@@ -658,9 +650,10 @@ struct formatter<join_view<It, Sentinel, Char>, Char> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename FormatContext>
|
template <typename FormatContext>
|
||||||
auto format(view_ref& value, FormatContext& ctx) const
|
auto format(view& value, FormatContext& ctx) const -> decltype(ctx.out()) {
|
||||||
-> decltype(ctx.out()) {
|
using iter =
|
||||||
auto it = std::forward<view_ref>(value).begin;
|
conditional_t<std::is_copy_constructible<view>::value, It, It&>;
|
||||||
|
iter it = value.begin;
|
||||||
auto out = ctx.out();
|
auto out = ctx.out();
|
||||||
if (it == value.end) return out;
|
if (it == value.end) return out;
|
||||||
out = value_formatter_.format(*it, ctx);
|
out = value_formatter_.format(*it, ctx);
|
||||||
@@ -675,39 +668,11 @@ struct formatter<join_view<It, Sentinel, Char>, Char> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Returns a view that formats the iterator range `[begin, end)` with elements
|
template <typename Char, typename Tuple> struct tuple_join_view : detail::view {
|
||||||
/// separated by `sep`.
|
const Tuple& tuple;
|
||||||
template <typename It, typename Sentinel>
|
|
||||||
auto join(It begin, Sentinel end, string_view sep) -> join_view<It, Sentinel> {
|
|
||||||
return {std::move(begin), end, sep};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a view that formats `range` with elements separated by `sep`.
|
|
||||||
*
|
|
||||||
* **Example**:
|
|
||||||
*
|
|
||||||
* auto v = std::vector<int>{1, 2, 3};
|
|
||||||
* fmt::print("{}", fmt::join(v, ", "));
|
|
||||||
* // Output: 1, 2, 3
|
|
||||||
*
|
|
||||||
* `fmt::join` applies passed format specifiers to the range elements:
|
|
||||||
*
|
|
||||||
* fmt::print("{:02}", fmt::join(v, ", "));
|
|
||||||
* // Output: 01, 02, 03
|
|
||||||
*/
|
|
||||||
template <typename Range>
|
|
||||||
auto join(Range&& r, string_view sep)
|
|
||||||
-> join_view<decltype(detail::range_begin(r)),
|
|
||||||
decltype(detail::range_end(r))> {
|
|
||||||
return {detail::range_begin(r), detail::range_end(r), sep};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Char, typename... T> struct tuple_join_view : detail::view {
|
|
||||||
const std::tuple<T...>& tuple;
|
|
||||||
basic_string_view<Char> sep;
|
basic_string_view<Char> sep;
|
||||||
|
|
||||||
tuple_join_view(const std::tuple<T...>& t, basic_string_view<Char> s)
|
tuple_join_view(const Tuple& t, basic_string_view<Char> s)
|
||||||
: tuple(t), sep{s} {}
|
: tuple(t), sep{s} {}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -718,21 +683,22 @@ template <typename Char, typename... T> struct tuple_join_view : detail::view {
|
|||||||
# define FMT_TUPLE_JOIN_SPECIFIERS 0
|
# define FMT_TUPLE_JOIN_SPECIFIERS 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <typename Char, typename... T>
|
template <typename Char, typename Tuple>
|
||||||
struct formatter<tuple_join_view<Char, T...>, Char> {
|
struct formatter<tuple_join_view<Char, Tuple>, Char,
|
||||||
|
enable_if_t<is_tuple_like<Tuple>::value>> {
|
||||||
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
|
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
|
||||||
return do_parse(ctx, std::integral_constant<size_t, sizeof...(T)>());
|
return do_parse(ctx, std::tuple_size<Tuple>());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename FormatContext>
|
template <typename FormatContext>
|
||||||
auto format(const tuple_join_view<Char, T...>& value,
|
auto format(const tuple_join_view<Char, Tuple>& value,
|
||||||
FormatContext& ctx) const -> typename FormatContext::iterator {
|
FormatContext& ctx) const -> typename FormatContext::iterator {
|
||||||
return do_format(value, ctx,
|
return do_format(value, ctx, std::tuple_size<Tuple>());
|
||||||
std::integral_constant<size_t, sizeof...(T)>());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::tuple<formatter<typename std::decay<T>::type, Char>...> formatters_;
|
decltype(detail::tuple::get_formatters<Tuple, Char>(
|
||||||
|
detail::tuple_index_sequence<Tuple>())) formatters_;
|
||||||
|
|
||||||
FMT_CONSTEXPR auto do_parse(parse_context<Char>& ctx,
|
FMT_CONSTEXPR auto do_parse(parse_context<Char>& ctx,
|
||||||
std::integral_constant<size_t, 0>)
|
std::integral_constant<size_t, 0>)
|
||||||
@@ -746,7 +712,7 @@ struct formatter<tuple_join_view<Char, T...>, Char> {
|
|||||||
-> const Char* {
|
-> const Char* {
|
||||||
auto end = ctx.begin();
|
auto end = ctx.begin();
|
||||||
#if FMT_TUPLE_JOIN_SPECIFIERS
|
#if FMT_TUPLE_JOIN_SPECIFIERS
|
||||||
end = std::get<sizeof...(T) - N>(formatters_).parse(ctx);
|
end = std::get<std::tuple_size<Tuple>::value - N>(formatters_).parse(ctx);
|
||||||
if (N > 1) {
|
if (N > 1) {
|
||||||
auto end1 = do_parse(ctx, std::integral_constant<size_t, N - 1>());
|
auto end1 = do_parse(ctx, std::integral_constant<size_t, N - 1>());
|
||||||
if (end != end1)
|
if (end != end1)
|
||||||
@@ -757,18 +723,20 @@ struct formatter<tuple_join_view<Char, T...>, Char> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename FormatContext>
|
template <typename FormatContext>
|
||||||
auto do_format(const tuple_join_view<Char, T...>&, FormatContext& ctx,
|
auto do_format(const tuple_join_view<Char, Tuple>&, FormatContext& ctx,
|
||||||
std::integral_constant<size_t, 0>) const ->
|
std::integral_constant<size_t, 0>) const ->
|
||||||
typename FormatContext::iterator {
|
typename FormatContext::iterator {
|
||||||
return ctx.out();
|
return ctx.out();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename FormatContext, size_t N>
|
template <typename FormatContext, size_t N>
|
||||||
auto do_format(const tuple_join_view<Char, T...>& value, FormatContext& ctx,
|
auto do_format(const tuple_join_view<Char, Tuple>& value, FormatContext& ctx,
|
||||||
std::integral_constant<size_t, N>) const ->
|
std::integral_constant<size_t, N>) const ->
|
||||||
typename FormatContext::iterator {
|
typename FormatContext::iterator {
|
||||||
auto out = std::get<sizeof...(T) - N>(formatters_)
|
using std::get;
|
||||||
.format(std::get<sizeof...(T) - N>(value.tuple), ctx);
|
auto out =
|
||||||
|
std::get<std::tuple_size<Tuple>::value - N>(formatters_)
|
||||||
|
.format(get<std::tuple_size<Tuple>::value - N>(value.tuple), ctx);
|
||||||
if (N <= 1) return out;
|
if (N <= 1) return out;
|
||||||
out = detail::copy<Char>(value.sep, out);
|
out = detail::copy<Char>(value.sep, out);
|
||||||
ctx.advance_to(out);
|
ctx.advance_to(out);
|
||||||
@@ -816,6 +784,34 @@ struct formatter<
|
|||||||
|
|
||||||
FMT_BEGIN_EXPORT
|
FMT_BEGIN_EXPORT
|
||||||
|
|
||||||
|
/// Returns a view that formats the iterator range `[begin, end)` with elements
|
||||||
|
/// separated by `sep`.
|
||||||
|
template <typename It, typename Sentinel>
|
||||||
|
auto join(It begin, Sentinel end, string_view sep) -> join_view<It, Sentinel> {
|
||||||
|
return {std::move(begin), end, sep};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a view that formats `range` with elements separated by `sep`.
|
||||||
|
*
|
||||||
|
* **Example**:
|
||||||
|
*
|
||||||
|
* auto v = std::vector<int>{1, 2, 3};
|
||||||
|
* fmt::print("{}", fmt::join(v, ", "));
|
||||||
|
* // Output: 1, 2, 3
|
||||||
|
*
|
||||||
|
* `fmt::join` applies passed format specifiers to the range elements:
|
||||||
|
*
|
||||||
|
* fmt::print("{:02}", fmt::join(v, ", "));
|
||||||
|
* // Output: 01, 02, 03
|
||||||
|
*/
|
||||||
|
template <typename Range, FMT_ENABLE_IF(!is_tuple_like<Range>::value)>
|
||||||
|
auto join(Range&& r, string_view sep)
|
||||||
|
-> join_view<decltype(detail::range_begin(r)),
|
||||||
|
decltype(detail::range_end(r))> {
|
||||||
|
return {detail::range_begin(r), detail::range_end(r), sep};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an object that formats `std::tuple` with elements separated by `sep`.
|
* Returns an object that formats `std::tuple` with elements separated by `sep`.
|
||||||
*
|
*
|
||||||
@@ -825,9 +821,9 @@ FMT_BEGIN_EXPORT
|
|||||||
* fmt::print("{}", fmt::join(t, ", "));
|
* fmt::print("{}", fmt::join(t, ", "));
|
||||||
* // Output: 1, a
|
* // Output: 1, a
|
||||||
*/
|
*/
|
||||||
template <typename... T>
|
template <typename Tuple, FMT_ENABLE_IF(is_tuple_like<Tuple>::value)>
|
||||||
FMT_CONSTEXPR auto join(const std::tuple<T...>& tuple, string_view sep)
|
FMT_CONSTEXPR auto join(const Tuple& tuple, string_view sep)
|
||||||
-> tuple_join_view<char, T...> {
|
-> tuple_join_view<char, Tuple> {
|
||||||
return {tuple, sep};
|
return {tuple, sep};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
16
external/fmt/include/fmt/std.h
vendored
16
external/fmt/include/fmt/std.h
vendored
@@ -27,7 +27,8 @@
|
|||||||
|
|
||||||
// Check FMT_CPLUSPLUS to suppress a bogus warning in MSVC.
|
// Check FMT_CPLUSPLUS to suppress a bogus warning in MSVC.
|
||||||
# if FMT_CPLUSPLUS >= 201703L
|
# if FMT_CPLUSPLUS >= 201703L
|
||||||
# if FMT_HAS_INCLUDE(<filesystem>)
|
# if FMT_HAS_INCLUDE(<filesystem>) && \
|
||||||
|
(!defined(FMT_CPP_LIB_FILESYSTEM) || FMT_CPP_LIB_FILESYSTEM != 0)
|
||||||
# include <filesystem>
|
# include <filesystem>
|
||||||
# endif
|
# endif
|
||||||
# if FMT_HAS_INCLUDE(<variant>)
|
# if FMT_HAS_INCLUDE(<variant>)
|
||||||
@@ -183,7 +184,8 @@ FMT_END_NAMESPACE
|
|||||||
FMT_BEGIN_NAMESPACE
|
FMT_BEGIN_NAMESPACE
|
||||||
FMT_EXPORT
|
FMT_EXPORT
|
||||||
template <std::size_t N, typename Char>
|
template <std::size_t N, typename Char>
|
||||||
struct formatter<std::bitset<N>, Char> : nested_formatter<string_view> {
|
struct formatter<std::bitset<N>, Char>
|
||||||
|
: nested_formatter<basic_string_view<Char>, Char> {
|
||||||
private:
|
private:
|
||||||
// Functor because C++11 doesn't support generic lambdas.
|
// Functor because C++11 doesn't support generic lambdas.
|
||||||
struct writer {
|
struct writer {
|
||||||
@@ -203,7 +205,7 @@ struct formatter<std::bitset<N>, Char> : nested_formatter<string_view> {
|
|||||||
template <typename FormatContext>
|
template <typename FormatContext>
|
||||||
auto format(const std::bitset<N>& bs, FormatContext& ctx) const
|
auto format(const std::bitset<N>& bs, FormatContext& ctx) const
|
||||||
-> decltype(ctx.out()) {
|
-> decltype(ctx.out()) {
|
||||||
return write_padded(ctx, writer{bs});
|
return this->write_padded(ctx, writer{bs});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -433,8 +435,8 @@ template <> struct formatter<std::error_code> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename FormatContext>
|
template <typename FormatContext>
|
||||||
FMT_CONSTEXPR20 auto format(const std::error_code& ec, FormatContext& ctx) const
|
FMT_CONSTEXPR20 auto format(const std::error_code& ec,
|
||||||
-> decltype(ctx.out()) {
|
FormatContext& ctx) const -> decltype(ctx.out()) {
|
||||||
auto specs = specs_;
|
auto specs = specs_;
|
||||||
detail::handle_dynamic_spec(specs.dynamic_width(), specs.width, width_ref_,
|
detail::handle_dynamic_spec(specs.dynamic_width(), specs.width, width_ref_,
|
||||||
ctx);
|
ctx);
|
||||||
@@ -694,9 +696,7 @@ template <typename T, typename Char> struct formatter<std::complex<T>, Char> {
|
|||||||
|
|
||||||
auto outer_specs = format_specs();
|
auto outer_specs = format_specs();
|
||||||
outer_specs.width = specs.width;
|
outer_specs.width = specs.width;
|
||||||
auto fill = specs.template fill<Char>();
|
outer_specs.set_fill(specs);
|
||||||
if (fill)
|
|
||||||
outer_specs.set_fill(basic_string_view<Char>(fill, specs.fill_size()));
|
|
||||||
outer_specs.set_align(specs.align());
|
outer_specs.set_align(specs.align());
|
||||||
|
|
||||||
specs.width = 0;
|
specs.width = 0;
|
||||||
|
|||||||
35
external/fmt/include/fmt/xchar.h
vendored
35
external/fmt/include/fmt/xchar.h
vendored
@@ -140,7 +140,7 @@ auto join(It begin, Sentinel end, wstring_view sep)
|
|||||||
return {begin, end, sep};
|
return {begin, end, sep};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Range>
|
template <typename Range, FMT_ENABLE_IF(!is_tuple_like<Range>::value)>
|
||||||
auto join(Range&& range, wstring_view sep)
|
auto join(Range&& range, wstring_view sep)
|
||||||
-> join_view<decltype(std::begin(range)), decltype(std::end(range)),
|
-> join_view<decltype(std::begin(range)), decltype(std::end(range)),
|
||||||
wchar_t> {
|
wchar_t> {
|
||||||
@@ -153,9 +153,9 @@ auto join(std::initializer_list<T> list, wstring_view sep)
|
|||||||
return join(std::begin(list), std::end(list), sep);
|
return join(std::begin(list), std::end(list), sep);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... T>
|
template <typename Tuple, FMT_ENABLE_IF(is_tuple_like<Tuple>::value)>
|
||||||
auto join(const std::tuple<T...>& tuple, basic_string_view<wchar_t> sep)
|
auto join(const Tuple& tuple, basic_string_view<wchar_t> sep)
|
||||||
-> tuple_join_view<wchar_t, T...> {
|
-> tuple_join_view<wchar_t, Tuple> {
|
||||||
return {tuple, sep};
|
return {tuple, sep};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,11 +191,9 @@ auto format(const S& fmt, T&&... args) -> std::basic_string<Char> {
|
|||||||
fmt::make_format_args<buffered_context<Char>>(args...));
|
fmt::make_format_args<buffered_context<Char>>(args...));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Locale, typename S,
|
template <typename S, typename Char = detail::format_string_char_t<S>,
|
||||||
typename Char = detail::format_string_char_t<S>,
|
FMT_ENABLE_IF(detail::is_exotic_char<Char>::value)>
|
||||||
FMT_ENABLE_IF(detail::is_locale<Locale>::value&&
|
inline auto vformat(detail::locale_ref loc, const S& fmt,
|
||||||
detail::is_exotic_char<Char>::value)>
|
|
||||||
inline auto vformat(const Locale& loc, const S& fmt,
|
|
||||||
typename detail::vformat_args<Char>::type args)
|
typename detail::vformat_args<Char>::type args)
|
||||||
-> std::basic_string<Char> {
|
-> std::basic_string<Char> {
|
||||||
auto buf = basic_memory_buffer<Char>();
|
auto buf = basic_memory_buffer<Char>();
|
||||||
@@ -204,11 +202,10 @@ inline auto vformat(const Locale& loc, const S& fmt,
|
|||||||
return {buf.data(), buf.size()};
|
return {buf.data(), buf.size()};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Locale, typename S, typename... T,
|
template <typename S, typename... T,
|
||||||
typename Char = detail::format_string_char_t<S>,
|
typename Char = detail::format_string_char_t<S>,
|
||||||
FMT_ENABLE_IF(detail::is_locale<Locale>::value&&
|
FMT_ENABLE_IF(detail::is_exotic_char<Char>::value)>
|
||||||
detail::is_exotic_char<Char>::value)>
|
inline auto format(detail::locale_ref loc, const S& fmt, T&&... args)
|
||||||
inline auto format(const Locale& loc, const S& fmt, T&&... args)
|
|
||||||
-> std::basic_string<Char> {
|
-> std::basic_string<Char> {
|
||||||
return vformat(loc, detail::to_string_view(fmt),
|
return vformat(loc, detail::to_string_view(fmt),
|
||||||
fmt::make_format_args<buffered_context<Char>>(args...));
|
fmt::make_format_args<buffered_context<Char>>(args...));
|
||||||
@@ -235,12 +232,11 @@ inline auto format_to(OutputIt out, const S& fmt, T&&... args) -> OutputIt {
|
|||||||
fmt::make_format_args<buffered_context<Char>>(args...));
|
fmt::make_format_args<buffered_context<Char>>(args...));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Locale, typename S, typename OutputIt, typename... Args,
|
template <typename S, typename OutputIt, typename... Args,
|
||||||
typename Char = detail::format_string_char_t<S>,
|
typename Char = detail::format_string_char_t<S>,
|
||||||
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&
|
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&
|
||||||
detail::is_locale<Locale>::value&&
|
detail::is_exotic_char<Char>::value)>
|
||||||
detail::is_exotic_char<Char>::value)>
|
inline auto vformat_to(OutputIt out, detail::locale_ref loc, const S& fmt,
|
||||||
inline auto vformat_to(OutputIt out, const Locale& loc, const S& fmt,
|
|
||||||
typename detail::vformat_args<Char>::type args)
|
typename detail::vformat_args<Char>::type args)
|
||||||
-> OutputIt {
|
-> OutputIt {
|
||||||
auto&& buf = detail::get_buffer<Char>(out);
|
auto&& buf = detail::get_buffer<Char>(out);
|
||||||
@@ -248,12 +244,11 @@ inline auto vformat_to(OutputIt out, const Locale& loc, const S& fmt,
|
|||||||
return detail::get_iterator(buf, out);
|
return detail::get_iterator(buf, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename OutputIt, typename Locale, typename S, typename... T,
|
template <typename OutputIt, typename S, typename... T,
|
||||||
typename Char = detail::format_string_char_t<S>,
|
typename Char = detail::format_string_char_t<S>,
|
||||||
bool enable = detail::is_output_iterator<OutputIt, Char>::value &&
|
bool enable = detail::is_output_iterator<OutputIt, Char>::value &&
|
||||||
detail::is_locale<Locale>::value &&
|
|
||||||
detail::is_exotic_char<Char>::value>
|
detail::is_exotic_char<Char>::value>
|
||||||
inline auto format_to(OutputIt out, const Locale& loc, const S& fmt,
|
inline auto format_to(OutputIt out, detail::locale_ref loc, const S& fmt,
|
||||||
T&&... args) ->
|
T&&... args) ->
|
||||||
typename std::enable_if<enable, OutputIt>::type {
|
typename std::enable_if<enable, OutputIt>::type {
|
||||||
return vformat_to(out, loc, detail::to_string_view(fmt),
|
return vformat_to(out, loc, detail::to_string_view(fmt),
|
||||||
|
|||||||
1
external/fmt/src/format.cc
vendored
1
external/fmt/src/format.cc
vendored
@@ -16,6 +16,7 @@ template FMT_API auto dragonbox::to_decimal(double x) noexcept
|
|||||||
-> dragonbox::decimal_fp<double>;
|
-> dragonbox::decimal_fp<double>;
|
||||||
|
|
||||||
#if FMT_USE_LOCALE
|
#if FMT_USE_LOCALE
|
||||||
|
// DEPRECATED! locale_ref in the detail namespace
|
||||||
template FMT_API locale_ref::locale_ref(const std::locale& loc);
|
template FMT_API locale_ref::locale_ref(const std::locale& loc);
|
||||||
template FMT_API auto locale_ref::get<std::locale>() const -> std::locale;
|
template FMT_API auto locale_ref::get<std::locale>() const -> std::locale;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
2
external/fmt/src/os.cc
vendored
2
external/fmt/src/os.cc
vendored
@@ -160,7 +160,7 @@ void detail::format_windows_error(detail::buffer<char>& out, int error_code,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void report_windows_error(int error_code, const char* message) noexcept {
|
void report_windows_error(int error_code, const char* message) noexcept {
|
||||||
report_error(detail::format_windows_error, error_code, message);
|
do_report_error(detail::format_windows_error, error_code, message);
|
||||||
}
|
}
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
"""Manage site and releases.
|
"""Make a release.
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
manage.py release [<branch>]
|
release.py [<branch>]
|
||||||
manage.py site
|
|
||||||
|
|
||||||
For the release command $FMT_TOKEN should contain a GitHub personal access token
|
For the release command $FMT_TOKEN should contain a GitHub personal access token
|
||||||
obtained from https://github.com/settings/tokens.
|
obtained from https://github.com/settings/tokens.
|
||||||
@@ -12,9 +11,9 @@ obtained from https://github.com/settings/tokens.
|
|||||||
|
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
import datetime, docopt, errno, fileinput, json, os
|
import datetime, docopt, errno, fileinput, json, os
|
||||||
import re, requests, shutil, sys
|
import re, shutil, sys
|
||||||
from contextlib import contextmanager
|
|
||||||
from subprocess import check_call
|
from subprocess import check_call
|
||||||
|
import urllib.request
|
||||||
|
|
||||||
|
|
||||||
class Git:
|
class Git:
|
||||||
@@ -81,46 +80,15 @@ def create_build_env():
|
|||||||
return env
|
return env
|
||||||
|
|
||||||
|
|
||||||
fmt_repo_url = 'git@github.com:fmtlib/fmt'
|
if __name__ == '__main__':
|
||||||
|
args = docopt.docopt(__doc__)
|
||||||
|
|
||||||
def update_site(env):
|
|
||||||
env.fmt_repo.update(fmt_repo_url)
|
|
||||||
|
|
||||||
doc_repo = Git(os.path.join(env.build_dir, 'fmt.dev'))
|
|
||||||
doc_repo.update('git@github.com:fmtlib/fmt.dev')
|
|
||||||
|
|
||||||
version = '11.0.0'
|
|
||||||
clean_checkout(env.fmt_repo, version)
|
|
||||||
target_doc_dir = os.path.join(env.fmt_repo.dir, 'doc')
|
|
||||||
|
|
||||||
# Build the docs.
|
|
||||||
html_dir = os.path.join(env.build_dir, 'html')
|
|
||||||
if os.path.exists(html_dir):
|
|
||||||
shutil.rmtree(html_dir)
|
|
||||||
include_dir = env.fmt_repo.dir
|
|
||||||
import build
|
|
||||||
build.build_docs(version, doc_dir=target_doc_dir,
|
|
||||||
include_dir=include_dir, work_dir=env.build_dir)
|
|
||||||
shutil.rmtree(os.path.join(html_dir, '.doctrees'))
|
|
||||||
# Copy docs to the website.
|
|
||||||
version_doc_dir = os.path.join(doc_repo.dir, version)
|
|
||||||
try:
|
|
||||||
shutil.rmtree(version_doc_dir)
|
|
||||||
except OSError as e:
|
|
||||||
if e.errno != errno.ENOENT:
|
|
||||||
raise
|
|
||||||
shutil.move(html_dir, version_doc_dir)
|
|
||||||
|
|
||||||
|
|
||||||
def release(args):
|
|
||||||
env = create_build_env()
|
env = create_build_env()
|
||||||
fmt_repo = env.fmt_repo
|
fmt_repo = env.fmt_repo
|
||||||
|
|
||||||
branch = args.get('<branch>')
|
branch = args.get('<branch>')
|
||||||
if branch is None:
|
if branch is None:
|
||||||
branch = 'master'
|
branch = 'master'
|
||||||
if not fmt_repo.update('-b', branch, fmt_repo_url):
|
if not fmt_repo.update('-b', branch, 'git@github.com:fmtlib/fmt'):
|
||||||
clean_checkout(fmt_repo, branch)
|
clean_checkout(fmt_repo, branch)
|
||||||
|
|
||||||
# Update the date in the changelog and extract the version and the first
|
# Update the date in the changelog and extract the version and the first
|
||||||
@@ -191,28 +159,30 @@ def release(args):
|
|||||||
# Create a release on GitHub.
|
# Create a release on GitHub.
|
||||||
fmt_repo.push('origin', 'release')
|
fmt_repo.push('origin', 'release')
|
||||||
auth_headers = {'Authorization': 'token ' + os.getenv('FMT_TOKEN')}
|
auth_headers = {'Authorization': 'token ' + os.getenv('FMT_TOKEN')}
|
||||||
r = requests.post('https://api.github.com/repos/fmtlib/fmt/releases',
|
req = urllib.request.Request(
|
||||||
headers=auth_headers,
|
'https://api.github.com/repos/fmtlib/fmt/releases',
|
||||||
data=json.dumps({'tag_name': version,
|
data=json.dumps({'tag_name': version,
|
||||||
'target_commitish': 'release',
|
'target_commitish': 'release',
|
||||||
'body': changes, 'draft': True}))
|
'body': changes, 'draft': True}).encode('utf-8'),
|
||||||
if r.status_code != 201:
|
headers=auth_headers, method='POST')
|
||||||
raise Exception('Failed to create a release ' + str(r))
|
with urllib.request.urlopen(req) as response:
|
||||||
id = r.json()['id']
|
if response.status != 201:
|
||||||
|
raise Exception(f'Failed to create a release ' +
|
||||||
|
'{response.status} {response.reason}')
|
||||||
|
response_data = json.loads(response.read().decode('utf-8'))
|
||||||
|
id = response_data['id']
|
||||||
|
|
||||||
|
# Upload the package.
|
||||||
uploads_url = 'https://uploads.github.com/repos/fmtlib/fmt/releases'
|
uploads_url = 'https://uploads.github.com/repos/fmtlib/fmt/releases'
|
||||||
package = 'fmt-{}.zip'.format(version)
|
package = 'fmt-{}.zip'.format(version)
|
||||||
r = requests.post(
|
req = urllib.request.Request(
|
||||||
'{}/{}/assets?name={}'.format(uploads_url, id, package),
|
f'{uploads_url}/{id}/assets?name={package}',
|
||||||
headers={'Content-Type': 'application/zip'} | auth_headers,
|
headers={'Content-Type': 'application/zip'} | auth_headers,
|
||||||
data=open('build/fmt/' + package, 'rb'))
|
data=open('build/fmt/' + package, 'rb').read(), method='POST')
|
||||||
if r.status_code != 201:
|
with urllib.request.urlopen(req) as response:
|
||||||
raise Exception('Failed to upload an asset ' + str(r))
|
if response.status != 201:
|
||||||
|
raise Exception(f'Failed to upload an asset '
|
||||||
|
'{response.status} {response.reason}')
|
||||||
|
|
||||||
update_site(env)
|
short_version = '.'.join(version.split('.')[:-1])
|
||||||
|
check_call(['./mkdocs', 'deploy', short_version])
|
||||||
if __name__ == '__main__':
|
|
||||||
args = docopt.docopt(__doc__)
|
|
||||||
if args.get('release'):
|
|
||||||
release(args)
|
|
||||||
elif args.get('site'):
|
|
||||||
update_site(create_build_env())
|
|
||||||
3
external/fmt/test/CMakeLists.txt
vendored
3
external/fmt/test/CMakeLists.txt
vendored
@@ -62,13 +62,14 @@ if (NOT (MSVC AND BUILD_SHARED_LIBS))
|
|||||||
endif ()
|
endif ()
|
||||||
add_fmt_test(ostream-test)
|
add_fmt_test(ostream-test)
|
||||||
add_fmt_test(compile-test)
|
add_fmt_test(compile-test)
|
||||||
add_fmt_test(compile-fp-test HEADER_ONLY)
|
add_fmt_test(compile-fp-test)
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
# Without this option, MSVC returns 199711L for the __cplusplus macro.
|
# Without this option, MSVC returns 199711L for the __cplusplus macro.
|
||||||
target_compile_options(compile-fp-test PRIVATE /Zc:__cplusplus)
|
target_compile_options(compile-fp-test PRIVATE /Zc:__cplusplus)
|
||||||
endif()
|
endif()
|
||||||
add_fmt_test(printf-test)
|
add_fmt_test(printf-test)
|
||||||
add_fmt_test(ranges-test ranges-odr-test.cc)
|
add_fmt_test(ranges-test ranges-odr-test.cc)
|
||||||
|
add_fmt_test(no-builtin-types-test HEADER_ONLY)
|
||||||
|
|
||||||
add_fmt_test(scan-test HEADER_ONLY)
|
add_fmt_test(scan-test HEADER_ONLY)
|
||||||
check_symbol_exists(strptime "time.h" HAVE_STRPTIME)
|
check_symbol_exists(strptime "time.h" HAVE_STRPTIME)
|
||||||
|
|||||||
14
external/fmt/test/args-test.cc
vendored
14
external/fmt/test/args-test.cc
vendored
@@ -186,3 +186,17 @@ TEST(args_test, move_constructor) {
|
|||||||
store.reset();
|
store.reset();
|
||||||
EXPECT_EQ(fmt::vformat("{} {} {a1}", moved_store), "42 foo foo");
|
EXPECT_EQ(fmt::vformat("{} {} {a1}", moved_store), "42 foo foo");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(args_test, size) {
|
||||||
|
fmt::dynamic_format_arg_store<fmt::format_context> store;
|
||||||
|
EXPECT_EQ(store.size(), 0);
|
||||||
|
|
||||||
|
store.push_back(42);
|
||||||
|
EXPECT_EQ(store.size(), 1);
|
||||||
|
|
||||||
|
store.push_back("Molybdenum");
|
||||||
|
EXPECT_EQ(store.size(), 2);
|
||||||
|
|
||||||
|
store.clear();
|
||||||
|
EXPECT_EQ(store.size(), 0);
|
||||||
|
}
|
||||||
|
|||||||
43
external/fmt/test/base-test.cc
vendored
43
external/fmt/test/base-test.cc
vendored
@@ -645,9 +645,7 @@ TEST(base_test, is_formattable) {
|
|||||||
EXPECT_TRUE(fmt::is_formattable<const const_formattable&>::value);
|
EXPECT_TRUE(fmt::is_formattable<const const_formattable&>::value);
|
||||||
|
|
||||||
EXPECT_TRUE(fmt::is_formattable<nonconst_formattable&>::value);
|
EXPECT_TRUE(fmt::is_formattable<nonconst_formattable&>::value);
|
||||||
#if !FMT_MSC_VERSION || FMT_MSC_VERSION >= 1910
|
|
||||||
EXPECT_FALSE(fmt::is_formattable<const nonconst_formattable&>::value);
|
EXPECT_FALSE(fmt::is_formattable<const nonconst_formattable&>::value);
|
||||||
#endif
|
|
||||||
|
|
||||||
EXPECT_FALSE(fmt::is_formattable<convertible_to_pointer>::value);
|
EXPECT_FALSE(fmt::is_formattable<convertible_to_pointer>::value);
|
||||||
const auto f = convertible_to_pointer_formattable();
|
const auto f = convertible_to_pointer_formattable();
|
||||||
@@ -745,19 +743,6 @@ TEST(base_test, no_implicit_conversion_to_string_view) {
|
|||||||
fmt::is_formattable<implicitly_convertible_to_string_view>::value);
|
fmt::is_formattable<implicitly_convertible_to_string_view>::value);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FMT_USE_STRING_VIEW
|
|
||||||
struct implicitly_convertible_to_std_string_view {
|
|
||||||
operator std::string_view() const { return "foo"; }
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST(base_test, no_implicit_conversion_to_std_string_view) {
|
|
||||||
EXPECT_FALSE(
|
|
||||||
fmt::is_formattable<implicitly_convertible_to_std_string_view>::value);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// std::is_constructible is broken in MSVC until version 2015.
|
|
||||||
#if !FMT_MSC_VERSION || FMT_MSC_VERSION >= 1900
|
|
||||||
struct explicitly_convertible_to_string_view {
|
struct explicitly_convertible_to_string_view {
|
||||||
explicit operator fmt::string_view() const { return "foo"; }
|
explicit operator fmt::string_view() const { return "foo"; }
|
||||||
};
|
};
|
||||||
@@ -769,7 +754,16 @@ TEST(base_test, format_explicitly_convertible_to_string_view) {
|
|||||||
!fmt::is_formattable<explicitly_convertible_to_string_view>::value, "");
|
!fmt::is_formattable<explicitly_convertible_to_string_view>::value, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
# ifdef FMT_USE_STRING_VIEW
|
#if FMT_CPLUSPLUS >= 201703L
|
||||||
|
struct implicitly_convertible_to_std_string_view {
|
||||||
|
operator std::string_view() const { return "foo"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST(base_test, no_implicit_conversion_to_std_string_view) {
|
||||||
|
EXPECT_FALSE(
|
||||||
|
fmt::is_formattable<implicitly_convertible_to_std_string_view>::value);
|
||||||
|
}
|
||||||
|
|
||||||
struct explicitly_convertible_to_std_string_view {
|
struct explicitly_convertible_to_std_string_view {
|
||||||
explicit operator std::string_view() const { return "foo"; }
|
explicit operator std::string_view() const { return "foo"; }
|
||||||
};
|
};
|
||||||
@@ -781,8 +775,7 @@ TEST(base_test, format_explicitly_convertible_to_std_string_view) {
|
|||||||
!fmt::is_formattable<explicitly_convertible_to_std_string_view>::value,
|
!fmt::is_formattable<explicitly_convertible_to_std_string_view>::value,
|
||||||
"");
|
"");
|
||||||
}
|
}
|
||||||
# endif
|
#endif // FMT_CPLUSPLUS >= 201703L
|
||||||
#endif
|
|
||||||
|
|
||||||
TEST(base_test, has_formatter) {
|
TEST(base_test, has_formatter) {
|
||||||
EXPECT_TRUE((fmt::detail::has_formatter<const const_formattable, char>()));
|
EXPECT_TRUE((fmt::detail::has_formatter<const const_formattable, char>()));
|
||||||
@@ -868,3 +861,17 @@ TEST(base_test, format_to_custom_container) {
|
|||||||
auto c = custom_container();
|
auto c = custom_container();
|
||||||
fmt::format_to(std::back_inserter(c), "");
|
fmt::format_to(std::back_inserter(c), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct nondeterministic_format_string {
|
||||||
|
mutable int i = 0;
|
||||||
|
FMT_CONSTEXPR operator string_view() const {
|
||||||
|
return string_view("{}", i++ != 0 ? 2 : 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST(base_test, no_repeated_format_string_conversions) {
|
||||||
|
#if !FMT_GCC_VERSION
|
||||||
|
char buf[10];
|
||||||
|
fmt::format_to(buf, nondeterministic_format_string());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|||||||
23
external/fmt/test/compile-test.cc
vendored
23
external/fmt/test/compile-test.cc
vendored
@@ -8,6 +8,7 @@
|
|||||||
#include "fmt/compile.h"
|
#include "fmt/compile.h"
|
||||||
|
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "fmt/chrono.h"
|
#include "fmt/chrono.h"
|
||||||
#include "fmt/ranges.h"
|
#include "fmt/ranges.h"
|
||||||
@@ -229,10 +230,14 @@ TEST(compile_test, unknown_format_fallback) {
|
|||||||
EXPECT_EQ(" 42 ",
|
EXPECT_EQ(" 42 ",
|
||||||
fmt::format(FMT_COMPILE("{name:^4}"), fmt::arg("name", 42)));
|
fmt::format(FMT_COMPILE("{name:^4}"), fmt::arg("name", 42)));
|
||||||
|
|
||||||
std::vector<char> v;
|
std::vector<char> v1;
|
||||||
fmt::format_to(std::back_inserter(v), FMT_COMPILE("{name:^4}"),
|
fmt::format_to(std::back_inserter(v1), FMT_COMPILE("{}"), 42);
|
||||||
|
EXPECT_EQ("42", fmt::string_view(v1.data(), v1.size()));
|
||||||
|
|
||||||
|
std::vector<char> v2;
|
||||||
|
fmt::format_to(std::back_inserter(v2), FMT_COMPILE("{name:^4}"),
|
||||||
fmt::arg("name", 42));
|
fmt::arg("name", 42));
|
||||||
EXPECT_EQ(" 42 ", fmt::string_view(v.data(), v.size()));
|
EXPECT_EQ(" 42 ", fmt::string_view(v2.data(), v2.size()));
|
||||||
|
|
||||||
char buffer[4];
|
char buffer[4];
|
||||||
auto result = fmt::format_to_n(buffer, 4, FMT_COMPILE("{name:^5}"),
|
auto result = fmt::format_to_n(buffer, 4, FMT_COMPILE("{name:^5}"),
|
||||||
@@ -265,11 +270,23 @@ TEST(compile_test, to_string_and_formatter) {
|
|||||||
fmt::format(FMT_COMPILE("{}"), to_stringable());
|
fmt::format(FMT_COMPILE("{}"), to_stringable());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct std_context_test {};
|
||||||
|
|
||||||
|
FMT_BEGIN_NAMESPACE
|
||||||
|
template <> struct formatter<std_context_test> : formatter<int> {
|
||||||
|
auto format(std_context_test, format_context& ctx) const
|
||||||
|
-> decltype(ctx.out()) {
|
||||||
|
return ctx.out();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
FMT_END_NAMESPACE
|
||||||
|
|
||||||
TEST(compile_test, print) {
|
TEST(compile_test, print) {
|
||||||
EXPECT_WRITE(stdout, fmt::print(FMT_COMPILE("Don't {}!"), "panic"),
|
EXPECT_WRITE(stdout, fmt::print(FMT_COMPILE("Don't {}!"), "panic"),
|
||||||
"Don't panic!");
|
"Don't panic!");
|
||||||
EXPECT_WRITE(stderr, fmt::print(stderr, FMT_COMPILE("Don't {}!"), "panic"),
|
EXPECT_WRITE(stderr, fmt::print(stderr, FMT_COMPILE("Don't {}!"), "panic"),
|
||||||
"Don't panic!");
|
"Don't panic!");
|
||||||
|
fmt::print(FMT_COMPILE("{}"), std_context_test());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
4
external/fmt/test/format-impl-test.cc
vendored
4
external/fmt/test/format-impl-test.cc
vendored
@@ -283,7 +283,7 @@ struct double_double {
|
|||||||
double a;
|
double a;
|
||||||
double b;
|
double b;
|
||||||
|
|
||||||
explicit constexpr double_double(double a_val = 0, double b_val = 0)
|
constexpr explicit double_double(double a_val = 0, double b_val = 0)
|
||||||
: a(a_val), b(b_val) {}
|
: a(a_val), b(b_val) {}
|
||||||
|
|
||||||
operator double() const { return a + b; }
|
operator double() const { return a + b; }
|
||||||
@@ -299,7 +299,7 @@ bool operator>=(const double_double& lhs, const double_double& rhs) {
|
|||||||
struct slow_float {
|
struct slow_float {
|
||||||
float value;
|
float value;
|
||||||
|
|
||||||
explicit constexpr slow_float(float val = 0) : value(val) {}
|
constexpr explicit slow_float(float val = 0) : value(val) {}
|
||||||
operator float() const { return value; }
|
operator float() const { return value; }
|
||||||
auto operator-() const -> slow_float { return slow_float(-value); }
|
auto operator-() const -> slow_float { return slow_float(-value); }
|
||||||
};
|
};
|
||||||
|
|||||||
25
external/fmt/test/format-test.cc
vendored
25
external/fmt/test/format-test.cc
vendored
@@ -1821,7 +1821,9 @@ TEST(format_test, big_print) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Windows CRT implements _IOLBF incorrectly (full buffering).
|
// Windows CRT implements _IOLBF incorrectly (full buffering).
|
||||||
#if FMT_USE_FCNTL && !defined(_WIN32)
|
#if FMT_USE_FCNTL
|
||||||
|
|
||||||
|
# ifndef _WIN32
|
||||||
TEST(format_test, line_buffering) {
|
TEST(format_test, line_buffering) {
|
||||||
auto pipe = fmt::pipe();
|
auto pipe = fmt::pipe();
|
||||||
|
|
||||||
@@ -1845,7 +1847,26 @@ TEST(format_test, line_buffering) {
|
|||||||
|
|
||||||
reader.join();
|
reader.join();
|
||||||
}
|
}
|
||||||
#endif
|
# endif
|
||||||
|
|
||||||
|
TEST(format_test, buffer_boundary) {
|
||||||
|
auto pipe = fmt::pipe();
|
||||||
|
|
||||||
|
auto write_end = pipe.write_end.fdopen("w");
|
||||||
|
setvbuf(write_end.get(), nullptr, _IOFBF, 4096);
|
||||||
|
for (int i = 3; i < 4094; i++)
|
||||||
|
write_end.print("{}", (i % 73) != 0 ? 'x' : '\n');
|
||||||
|
write_end.print("{} {}", 1234, 567);
|
||||||
|
write_end.close();
|
||||||
|
|
||||||
|
auto read_end = pipe.read_end.fdopen("r");
|
||||||
|
char buf[4091] = {};
|
||||||
|
size_t n = fread(buf, 1, sizeof(buf), read_end.get());
|
||||||
|
EXPECT_EQ(n, sizeof(buf));
|
||||||
|
EXPECT_STREQ(fgets(buf, sizeof(buf), read_end.get()), "1234 567");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // FMT_USE_FCNTL
|
||||||
|
|
||||||
struct deadlockable {
|
struct deadlockable {
|
||||||
int value = 0;
|
int value = 0;
|
||||||
|
|||||||
24
external/fmt/test/no-builtin-types-test.cc
vendored
Normal file
24
external/fmt/test/no-builtin-types-test.cc
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
// Formatting library for C++ - formatting library tests
|
||||||
|
//
|
||||||
|
// Copyright (c) 2012 - present, Victor Zverovich
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// For the license information refer to format.h.
|
||||||
|
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
#if !defined(__GNUC__) || __GNUC__ >= 5
|
||||||
|
#define FMT_BUILTIN_TYPES 0
|
||||||
|
#include "fmt/format.h"
|
||||||
|
|
||||||
|
TEST(no_builtin_types_test, format) {
|
||||||
|
EXPECT_EQ(fmt::format("{}", 42), "42");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(no_builtin_types_test, double_is_custom_type) {
|
||||||
|
double d = 42;
|
||||||
|
auto args = fmt::make_format_args(d);
|
||||||
|
EXPECT_EQ(fmt::format_args(args).get(0).type(),
|
||||||
|
fmt::detail::type::custom_type);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
14
external/fmt/test/ranges-test.cc
vendored
14
external/fmt/test/ranges-test.cc
vendored
@@ -28,11 +28,6 @@
|
|||||||
# define FMT_RANGES_TEST_ENABLE_C_STYLE_ARRAY
|
# define FMT_RANGES_TEST_ENABLE_C_STYLE_ARRAY
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !FMT_MSC_VERSION || FMT_MSC_VERSION > 1910
|
|
||||||
# define FMT_RANGES_TEST_ENABLE_JOIN
|
|
||||||
# define FMT_RANGES_TEST_ENABLE_FORMAT_STRUCT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef FMT_RANGES_TEST_ENABLE_C_STYLE_ARRAY
|
#ifdef FMT_RANGES_TEST_ENABLE_C_STYLE_ARRAY
|
||||||
TEST(ranges_test, format_array) {
|
TEST(ranges_test, format_array) {
|
||||||
int arr[] = {1, 2, 3, 5, 7, 11};
|
int arr[] = {1, 2, 3, 5, 7, 11};
|
||||||
@@ -213,7 +208,6 @@ TEST(ranges_test, tuple_parse_calls_element_parse) {
|
|||||||
EXPECT_THROW(f.parse(ctx), bad_format);
|
EXPECT_THROW(f.parse(ctx), bad_format);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FMT_RANGES_TEST_ENABLE_FORMAT_STRUCT
|
|
||||||
struct tuple_like {
|
struct tuple_like {
|
||||||
int i;
|
int i;
|
||||||
std::string str;
|
std::string str;
|
||||||
@@ -246,7 +240,6 @@ TEST(ranges_test, format_struct) {
|
|||||||
auto t = tuple_like{42, "foo"};
|
auto t = tuple_like{42, "foo"};
|
||||||
EXPECT_EQ(fmt::format("{}", t), "(42, \"foo\")");
|
EXPECT_EQ(fmt::format("{}", t), "(42, \"foo\")");
|
||||||
}
|
}
|
||||||
#endif // FMT_RANGES_TEST_ENABLE_FORMAT_STRUCT
|
|
||||||
|
|
||||||
TEST(ranges_test, format_to) {
|
TEST(ranges_test, format_to) {
|
||||||
char buf[10];
|
char buf[10];
|
||||||
@@ -401,7 +394,6 @@ TEST(ranges_test, join_bytes) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef FMT_RANGES_TEST_ENABLE_JOIN
|
|
||||||
TEST(ranges_test, join_tuple) {
|
TEST(ranges_test, join_tuple) {
|
||||||
// Value tuple args.
|
// Value tuple args.
|
||||||
auto t1 = std::tuple<char, int, float>('a', 1, 2.0f);
|
auto t1 = std::tuple<char, int, float>('a', 1, 2.0f);
|
||||||
@@ -420,6 +412,10 @@ TEST(ranges_test, join_tuple) {
|
|||||||
auto t4 = std::tuple<float>(4.0f);
|
auto t4 = std::tuple<float>(4.0f);
|
||||||
EXPECT_EQ(fmt::format("{}", fmt::join(t4, "/")), "4");
|
EXPECT_EQ(fmt::format("{}", fmt::join(t4, "/")), "4");
|
||||||
|
|
||||||
|
// Tuple-like.
|
||||||
|
auto t5 = tuple_like{42, "foo"};
|
||||||
|
EXPECT_EQ(fmt::format("{}", fmt::join(t5, ", ")), "42, foo");
|
||||||
|
|
||||||
# if FMT_TUPLE_JOIN_SPECIFIERS
|
# if FMT_TUPLE_JOIN_SPECIFIERS
|
||||||
// Specs applied to each element.
|
// Specs applied to each element.
|
||||||
auto t5 = std::tuple<int, int, long>(-3, 100, 1);
|
auto t5 = std::tuple<int, int, long>(-3, 100, 1);
|
||||||
@@ -533,8 +529,6 @@ TEST(ranges_test, format_join_adl_begin_end) {
|
|||||||
EXPECT_EQ(fmt::format("{}", fmt::join(adl::vec(), "/")), "42/43");
|
EXPECT_EQ(fmt::format("{}", fmt::join(adl::vec(), "/")), "42/43");
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // FMT_RANGES_TEST_ENABLE_JOIN
|
|
||||||
|
|
||||||
#if defined(__cpp_lib_ranges) && __cpp_lib_ranges >= 202207L
|
#if defined(__cpp_lib_ranges) && __cpp_lib_ranges >= 202207L
|
||||||
TEST(ranges_test, nested_ranges) {
|
TEST(ranges_test, nested_ranges) {
|
||||||
auto l = std::list{1, 2, 3};
|
auto l = std::list{1, 2, 3};
|
||||||
|
|||||||
4
external/fmt/test/scan.h
vendored
4
external/fmt/test/scan.h
vendored
@@ -211,7 +211,7 @@ class scan_parse_context {
|
|||||||
public:
|
public:
|
||||||
using iterator = string_view::iterator;
|
using iterator = string_view::iterator;
|
||||||
|
|
||||||
explicit FMT_CONSTEXPR scan_parse_context(string_view format)
|
FMT_CONSTEXPR explicit scan_parse_context(string_view format)
|
||||||
: format_(format) {}
|
: format_(format) {}
|
||||||
|
|
||||||
FMT_CONSTEXPR auto begin() const -> iterator { return format_.begin(); }
|
FMT_CONSTEXPR auto begin() const -> iterator { return format_.begin(); }
|
||||||
@@ -347,7 +347,7 @@ class scan_context {
|
|||||||
using iterator = detail::scan_iterator;
|
using iterator = detail::scan_iterator;
|
||||||
using sentinel = detail::scan_sentinel;
|
using sentinel = detail::scan_sentinel;
|
||||||
|
|
||||||
explicit FMT_CONSTEXPR scan_context(detail::scan_buffer& buf, scan_args args)
|
FMT_CONSTEXPR explicit scan_context(detail::scan_buffer& buf, scan_args args)
|
||||||
: buf_(buf), args_(args) {}
|
: buf_(buf), args_(args) {}
|
||||||
|
|
||||||
FMT_CONSTEXPR auto arg(int id) const -> scan_arg {
|
FMT_CONSTEXPR auto arg(int id) const -> scan_arg {
|
||||||
|
|||||||
3
external/fmt/test/std-test.cc
vendored
3
external/fmt/test/std-test.cc
vendored
@@ -91,6 +91,9 @@ TEST(std_test, complex) {
|
|||||||
EXPECT_EQ(fmt::format("{: }", std::complex<double>(1, 2.2)), "( 1+2.2i)");
|
EXPECT_EQ(fmt::format("{: }", std::complex<double>(1, 2.2)), "( 1+2.2i)");
|
||||||
EXPECT_EQ(fmt::format("{: }", std::complex<double>(1, -2.2)), "( 1-2.2i)");
|
EXPECT_EQ(fmt::format("{: }", std::complex<double>(1, -2.2)), "( 1-2.2i)");
|
||||||
|
|
||||||
|
EXPECT_EQ(fmt::format("{:8}", std::complex<double>(1, 2)), "(1+2i) ");
|
||||||
|
EXPECT_EQ(fmt::format("{:-<8}", std::complex<double>(1, 2)), "(1+2i)--");
|
||||||
|
|
||||||
EXPECT_EQ(fmt::format("{:>20.2f}", std::complex<double>(1, 2.2)),
|
EXPECT_EQ(fmt::format("{:>20.2f}", std::complex<double>(1, 2.2)),
|
||||||
" (1.00+2.20i)");
|
" (1.00+2.20i)");
|
||||||
EXPECT_EQ(fmt::format("{:<20.2f}", std::complex<double>(1, 2.2)),
|
EXPECT_EQ(fmt::format("{:<20.2f}", std::complex<double>(1, 2.2)),
|
||||||
|
|||||||
2
external/fmt/test/test-assert.h
vendored
2
external/fmt/test/test-assert.h
vendored
@@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
void throw_assertion_failure(const char* message);
|
void throw_assertion_failure(const char* message);
|
||||||
#define FMT_ASSERT(condition, message) \
|
#define FMT_ASSERT(condition, message) \
|
||||||
if (!(condition)) throw_assertion_failure(message);
|
((condition) ? (void)0 : throw_assertion_failure(message))
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
|||||||
27
external/fmt/test/xchar-test.cc
vendored
27
external/fmt/test/xchar-test.cc
vendored
@@ -72,16 +72,17 @@ TEST(xchar_test, format_explicitly_convertible_to_wstring_view) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
TEST(xchar_test, format) {
|
TEST(xchar_test, format) {
|
||||||
EXPECT_EQ(L"42", fmt::format(L"{}", 42));
|
EXPECT_EQ(fmt::format(L"{}", 42), L"42");
|
||||||
EXPECT_EQ(L"4.2", fmt::format(L"{}", 4.2));
|
EXPECT_EQ(fmt::format(L"{}", 4.2), L"4.2");
|
||||||
EXPECT_EQ(L"abc", fmt::format(L"{}", L"abc"));
|
EXPECT_EQ(fmt::format(L"{}", L"abc"), L"abc");
|
||||||
EXPECT_EQ(L"z", fmt::format(L"{}", L'z'));
|
EXPECT_EQ(fmt::format(L"{}", L'z'), L"z");
|
||||||
EXPECT_THROW(fmt::format(fmt::runtime(L"{:*\x343E}"), 42), fmt::format_error);
|
EXPECT_THROW(fmt::format(fmt::runtime(L"{:*\x343E}"), 42), fmt::format_error);
|
||||||
EXPECT_EQ(L"true", fmt::format(L"{}", true));
|
EXPECT_EQ(fmt::format(L"{}", true), L"true");
|
||||||
EXPECT_EQ(L"a", fmt::format(L"{0}", L'a'));
|
EXPECT_EQ(fmt::format(L"{0}", L'a'), L"a");
|
||||||
EXPECT_EQ(L"Cyrillic letter \x42e",
|
EXPECT_EQ(fmt::format(L"Letter {}", L'\x40e'), L"Letter \x40e"); // Ў
|
||||||
fmt::format(L"Cyrillic letter {}", L'\x42e'));
|
if (sizeof(wchar_t) == 4)
|
||||||
EXPECT_EQ(L"abc1", fmt::format(L"{}c{}", L"ab", 1));
|
EXPECT_EQ(fmt::format(fmt::runtime(L"{:𓀨>3}"), 42), L"𓀨42");
|
||||||
|
EXPECT_EQ(fmt::format(L"{}c{}", L"ab", 1), L"abc1");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(xchar_test, is_formattable) {
|
TEST(xchar_test, is_formattable) {
|
||||||
@@ -490,12 +491,20 @@ TEST(locale_test, sign) {
|
|||||||
EXPECT_EQ(fmt::format(std::locale(), L"{:L}", -50), L"-50");
|
EXPECT_EQ(fmt::format(std::locale(), L"{:L}", -50), L"-50");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(std_test_xchar, format_bitset) {
|
||||||
|
auto bs = std::bitset<6>(42);
|
||||||
|
EXPECT_EQ(fmt::format(L"{}", bs), L"101010");
|
||||||
|
EXPECT_EQ(fmt::format(L"{:0>8}", bs), L"00101010");
|
||||||
|
EXPECT_EQ(fmt::format(L"{:-^12}", bs), L"---101010---");
|
||||||
|
}
|
||||||
|
|
||||||
TEST(std_test_xchar, complex) {
|
TEST(std_test_xchar, complex) {
|
||||||
auto s = fmt::format(L"{}", std::complex<double>(1, 2));
|
auto s = fmt::format(L"{}", std::complex<double>(1, 2));
|
||||||
EXPECT_EQ(s, L"(1+2i)");
|
EXPECT_EQ(s, L"(1+2i)");
|
||||||
EXPECT_EQ(fmt::format(L"{:.2f}", std::complex<double>(1, 2)),
|
EXPECT_EQ(fmt::format(L"{:.2f}", std::complex<double>(1, 2)),
|
||||||
L"(1.00+2.00i)");
|
L"(1.00+2.00i)");
|
||||||
EXPECT_EQ(fmt::format(L"{:8}", std::complex<double>(1, 2)), L"(1+2i) ");
|
EXPECT_EQ(fmt::format(L"{:8}", std::complex<double>(1, 2)), L"(1+2i) ");
|
||||||
|
EXPECT_EQ(fmt::format(L"{:-<8}", std::complex<double>(1, 2)), L"(1+2i)--");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(std_test_xchar, optional) {
|
TEST(std_test_xchar, optional) {
|
||||||
|
|||||||
Reference in New Issue
Block a user