From 44f2c7ae018adca38ad266df471dc66b6a10ea6c Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Mon, 7 Sep 2026 17:11:35 -0700 Subject: [PATCH] Make base.h a compatibility header Complete the header swap by making core.h canonical and updating code, tests, documentation, and tooling. --- CMakeLists.txt | 8 ++++---- README.md | 4 ++-- doc/api.md | 8 ++++---- doc/get-started.md | 2 +- doc/index.md | 2 +- include/fmt/base-compat.h | 14 -------------- include/fmt/base.h | 8 ++++++++ include/fmt/core.h | 12 +++++++----- include/fmt/format.h | 2 +- src/fmt-c.cc | 2 +- .../python/mkdocstrings_handlers/cxx/__init__.py | 2 +- support/release.py | 4 ++-- test/CMakeLists.txt | 2 +- test/add-subdirectory-test/main.cc | 2 +- test/assert-test.cc | 2 +- test/{base-test.cc => core-test.cc} | 4 ++-- test/cuda-test/cpp14.cc | 2 +- test/cuda-test/cuda-cpp14.cu | 2 +- test/fuzzing/fuzzer-common.h | 2 +- test/header-only-test.cc | 2 +- test/module-test.cc | 2 +- test/noexception-test.cc | 2 +- 22 files changed, 43 insertions(+), 47 deletions(-) delete mode 100644 include/fmt/base-compat.h create mode 100644 include/fmt/base.h rename test/{base-test.cc => core-test.cc} (99%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 585d11b7..0496306b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -113,10 +113,10 @@ set(FMT_DEBUG_POSTFIX d CACHE STRING "Debug library postfix.") -# Get version from base.h. -file(READ include/fmt/base.h base_h) -if (NOT base_h MATCHES "FMT_VERSION ([0-9]+)([0-9][0-9])([0-9][0-9])") - message(FATAL_ERROR "Cannot get FMT_VERSION from base.h.") +# Get version from core.h. +file(READ include/fmt/core.h core_h) +if (NOT core_h MATCHES "FMT_VERSION ([0-9]+)([0-9][0-9])([0-9][0-9])") + message(FATAL_ERROR "Cannot get FMT_VERSION from core.h.") endif () # Use math to skip leading zeros if any. math(EXPR CPACK_PACKAGE_VERSION_MAJOR ${CMAKE_MATCH_1}) diff --git a/README.md b/README.md index dea49fbb..a8a56f17 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ Try {fmt} in [Compiler Explorer](https://godbolt.org/z/8Mx1EW73v). hundred million integers to strings per second](https://vitaut.net/posts/2020/fast-int-to-string-revisited/) - Small code size both in terms of source code with the minimum - configuration consisting of just three files, `base.h`, `format.h` + configuration consisting of just three files, `core.h`, `format.h` and `format-inl.h`, and compiled code; see [Compile time and code bloat](#compile-time-and-code-bloat) - Reliability: the library has an extensive set of @@ -83,7 +83,7 @@ See the [documentation](https://fmt.dev) for more details. **Print to stdout** ([run](https://godbolt.org/z/Tevcjh)) ``` c++ -#include +#include int main() { fmt::print("Hello, world!\n"); diff --git a/doc/api.md b/doc/api.md index 5ed975ec..4a49cdc4 100644 --- a/doc/api.md +++ b/doc/api.md @@ -2,7 +2,7 @@ The {fmt} library API consists of the following components: -- [`fmt/base.h`](#base-api): the base API providing main formatting functions +- [`fmt/core.h`](#core-api): the core API providing main formatting functions for `char`/UTF-8 with C++20 compile-time checks and minimal dependencies - [`fmt/format.h`](#format-api): `fmt::format` and other formatting functions as well as locale support @@ -27,9 +27,9 @@ With the C++ module API, the headers listed above don't need to be included. You can use the `import fmt;` statement instead. All other functionality, listed below, remains the same. -## Base API +## Core API -`fmt/base.h` defines the base API which provides main formatting functions +`fmt/core.h` defines the core API which provides main formatting functions for `char`/UTF-8 with C++20 compile-time checks. It has minimal include dependencies for better compile times. This header is only beneficial when using {fmt} as a library (the default) and not in the header-only mode. @@ -127,7 +127,7 @@ format specifiers without implementing them yourself. For example: ```c++ // color.h: -#include +#include enum class color {red, green, blue}; diff --git a/doc/get-started.md b/doc/get-started.md index d2590d91..23ccd8d3 100644 --- a/doc/get-started.md +++ b/doc/get-started.md @@ -265,7 +265,7 @@ https://developer.android.com/tools/sdk/ndk/index.html). ### Other To use the {fmt} library with any other build system, add -`include/fmt/base.h`, `include/fmt/format.h`, `include/fmt/format-inl.h`, +`include/fmt/core.h`, `include/fmt/format.h`, `include/fmt/format-inl.h`, `src/format.cc` and optionally other headers from a [release archive]( https://github.com/fmtlib/fmt/releases) or the [git repository]( https://github.com/fmtlib/fmt) to your project, add `include` to include diff --git a/doc/index.md b/doc/index.md index 217ade6b..9731cbba 100644 --- a/doc/index.md +++ b/doc/index.md @@ -84,7 +84,7 @@ hide:

Fast compilation

The library makes extensive use of type erasure to achieve fast - compilation. fmt/base.h provides a subset of the API with + compilation. fmt/core.h provides a subset of the API with minimal include dependencies and enough functionality to replace all uses of *printf.

diff --git a/include/fmt/base-compat.h b/include/fmt/base-compat.h deleted file mode 100644 index eff2ae89..00000000 --- a/include/fmt/base-compat.h +++ /dev/null @@ -1,14 +0,0 @@ -// Formatting library for C++ - core API -// -// Copyright (c) 2012 - present, Victor Zverovich and {fmt} contributors -// All rights reserved. -// -// For the license information refer to format.h. - -#include "base.h" - -// Using fmt::format via fmt/core.h has been deprecated since version 11 -// and now requires an explicit opt in. -#ifdef FMT_DEPRECATED_HEAVY_CORE -# include "format.h" -#endif diff --git a/include/fmt/base.h b/include/fmt/base.h new file mode 100644 index 00000000..e4de404c --- /dev/null +++ b/include/fmt/base.h @@ -0,0 +1,8 @@ +// Formatting library for C++ - base API compatibility header +// +// Copyright (c) 2012 - present, Victor Zverovich and {fmt} contributors +// All rights reserved. +// +// For the license information refer to format.h. + +#include "core.h" diff --git a/include/fmt/core.h b/include/fmt/core.h index 1c006dae..8d36f75f 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -1,12 +1,12 @@ -// Formatting library for C++ - the base API for char/UTF-8 +// Formatting library for C++ - the core API for char/UTF-8 // // Copyright (c) 2012 - present, Victor Zverovich and {fmt} contributors // All rights reserved. // // For the license information refer to format.h. -#ifndef FMT_BASE_H_ -#define FMT_BASE_H_ +#ifndef FMT_CORE_H_ +#define FMT_CORE_H_ #if defined(FMT_IMPORT_STD) && !defined(FMT_MODULE) # define FMT_MODULE @@ -2952,7 +2952,9 @@ FMT_PRAGMA_MSVC(warning(pop)) FMT_END_EXPORT FMT_END_NAMESPACE -#ifdef FMT_HEADER_ONLY +// Using fmt::format via fmt/core.h has been deprecated since version 11 +// and now requires an explicit opt in. +#if defined(FMT_HEADER_ONLY) || defined(FMT_DEPRECATED_HEAVY_CORE) # include "format.h" #endif -#endif // FMT_BASE_H_ +#endif // FMT_CORE_H_ diff --git a/include/fmt/format.h b/include/fmt/format.h index 045260e2..318ce814 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -38,7 +38,7 @@ # define FMT_REMOVE_TRANSITIVE_INCLUDES #endif -#include "base.h" +#include "core.h" // libc++ supports string_view in pre-c++17. #if FMT_HAS_INCLUDE() && \ diff --git a/src/fmt-c.cc b/src/fmt-c.cc index d5945ea9..aec19072 100644 --- a/src/fmt-c.cc +++ b/src/fmt-c.cc @@ -7,7 +7,7 @@ #include "fmt/fmt-c.h" -#include +#include constexpr size_t max_c_format_args = 16; diff --git a/support/python/mkdocstrings_handlers/cxx/__init__.py b/support/python/mkdocstrings_handlers/cxx/__init__.py index a55e85b2..22df4c16 100644 --- a/support/python/mkdocstrings_handlers/cxx/__init__.py +++ b/support/python/mkdocstrings_handlers/cxx/__init__.py @@ -245,10 +245,10 @@ class CxxHandler(BaseHandler): headers = [ "args.h", - "base.h", "chrono.h", "color.h", "compile.h", + "core.h", "enum.h", "format.h", "os.h", diff --git a/support/release.py b/support/release.py index b3585b84..e7b1ba48 100755 --- a/support/release.py +++ b/support/release.py @@ -144,8 +144,8 @@ if __name__ == '__main__': first_section.pop(0) ns_version = None - base_h_path = os.path.join(fmt_repo.dir, 'include', 'fmt', 'base.h') - for line in fileinput.input(base_h_path): + core_h_path = os.path.join(fmt_repo.dir, 'include', 'fmt', 'core.h') + for line in fileinput.input(core_h_path): m = re.match(r'\s*inline namespace v(.*) .*', line) if m: ns_version = m.group(1) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 446261d8..0ac690f5 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -41,7 +41,7 @@ function (add_fmt_test name) endfunction () add_fmt_test(args-test) -add_fmt_test(base-test) +add_fmt_test(core-test) add_fmt_test(assert-test) add_fmt_test(chrono-test) add_fmt_test(color-test) diff --git a/test/add-subdirectory-test/main.cc b/test/add-subdirectory-test/main.cc index 1d31cb90..fcdf232e 100644 --- a/test/add-subdirectory-test/main.cc +++ b/test/add-subdirectory-test/main.cc @@ -1,4 +1,4 @@ -#include "fmt/base.h" +#include "fmt/core.h" int main(int argc, char** argv) { for (int i = 0; i < argc; ++i) fmt::print("{}: {}\n", i, argv[i]); diff --git a/test/assert-test.cc b/test/assert-test.cc index e0588184..30ce7051 100644 --- a/test/assert-test.cc +++ b/test/assert-test.cc @@ -9,7 +9,7 @@ // // For the license information refer to format.h. -#include "fmt/base.h" +#include "fmt/core.h" #include "gtest/gtest.h" TEST(assert_test, fail) { diff --git a/test/base-test.cc b/test/core-test.cc similarity index 99% rename from test/base-test.cc rename to test/core-test.cc index 837c4e5e..8c3651c2 100644 --- a/test/base-test.cc +++ b/test/core-test.cc @@ -13,7 +13,7 @@ // Suppress warnings for pathological types convertible to detail::value. #pragma GCC diagnostic ignored "-Wconversion" -#include "fmt/base.h" +#include "fmt/core.h" #include // INT_MAX #include // strlen @@ -29,7 +29,7 @@ #include "gmock/gmock.h" #ifdef FMT_FORMAT_H_ -# error base-test includes format.h +# error core-test includes format.h #endif using testing::_; diff --git a/test/cuda-test/cpp14.cc b/test/cuda-test/cpp14.cc index 59db442e..ad846396 100644 --- a/test/cuda-test/cpp14.cc +++ b/test/cuda-test/cpp14.cc @@ -1,4 +1,4 @@ -#include +#include // The purpose of this part is to ensure NVCC's host compiler also supports // the standard version. See 'cuda-cpp14.cu'. diff --git a/test/cuda-test/cuda-cpp14.cu b/test/cuda-test/cuda-cpp14.cu index 9fc36c93..76a9d088 100644 --- a/test/cuda-test/cuda-cpp14.cu +++ b/test/cuda-test/cuda-cpp14.cu @@ -10,7 +10,7 @@ // https://en.cppreference.com/w/cpp/preprocessor/replace#Predefined_macros static_assert(__cplusplus >= 201402L, "expect C++ 2014 for nvcc"); -#include +#include #include #include diff --git a/test/fuzzing/fuzzer-common.h b/test/fuzzing/fuzzer-common.h index 89178205..4ea1c59b 100644 --- a/test/fuzzing/fuzzer-common.h +++ b/test/fuzzing/fuzzer-common.h @@ -4,7 +4,7 @@ #ifndef FUZZER_COMMON_H #define FUZZER_COMMON_H -#include +#include #include // std::uint8_t #include // memcpy diff --git a/test/header-only-test.cc b/test/header-only-test.cc index 8c99f857..98be1b3f 100644 --- a/test/header-only-test.cc +++ b/test/header-only-test.cc @@ -1,6 +1,6 @@ // Header-only configuration test -#include "fmt/base.h" +#include "fmt/base.h" // Test the compatibility header. #include "fmt/ostream.h" #include "gtest/gtest.h" diff --git a/test/module-test.cc b/test/module-test.cc index e266a879..ea13dedc 100644 --- a/test/module-test.cc +++ b/test/module-test.cc @@ -49,7 +49,7 @@ TEST(module_test, namespace) { // Macros must not be imported from a named module [cpp.import]/5.1. TEST(module_test, macros) { -#if defined(FMT_BASE_H_) || defined(FMT_FORMAT_H_) +#if defined(FMT_CORE_H_) || defined(FMT_FORMAT_H_) FAIL() << "Macros are leaking from a named module"; #endif } diff --git a/test/noexception-test.cc b/test/noexception-test.cc index 2bf9605b..1351a45f 100644 --- a/test/noexception-test.cc +++ b/test/noexception-test.cc @@ -6,7 +6,7 @@ // For the license information refer to format.h. #include "fmt/args.h" -#include "fmt/base.h" +#include "fmt/core.h" #include "fmt/chrono.h" #include "fmt/color.h" #include "fmt/compile.h"