Skip to content

8.0.0

Compare
Choose a tag to compare
@vitaut vitaut released this 21 Jun 13:16
  • Enabled compile-time format string check by default. For example (godbolt):

    #include <fmt/core.h>
    
    int main() {
      fmt::print("{:d}", "I am not a number");
    }

    gives a compile-time error on compilers with C++20 consteval support (gcc 10+, clang 11+) because d is not a valid format specifier for a string.

    To pass a runtime string wrap it in fmt::runtime:

    fmt::print(fmt::runtime("{:d}"), "I am not a number");
  • Added compile-time formatting (#2019, #2044, #2056, #2072, #2075, #2078, #2129, #2326). For example (godbolt):

    #include <fmt/compile.h>
    
    consteval auto compile_time_itoa(int value) -> std::array<char, 10> {
      auto result = std::array<char, 10>();
      fmt::format_to(result.data(), FMT_COMPILE("{}"), value);
      return result;
    }
    
    constexpr auto answer = compile_time_itoa(42);

    Most of the formatting functionality is available at compile time with a notable exception of floating-point numbers and pointers. Thanks @alexezeder (Alexey Ochapov).

  • Optimized handling of format specifiers during format string compilation. For example, hexadecimal formatting ("{:x}") is now 3-7x faster than before when using format_to with format string compilation and a stack-allocated buffer (#1944).

    Before (7.1.3):

    ----------------------------------------------------------------------------
    Benchmark                                  Time             CPU   Iterations
    ----------------------------------------------------------------------------
    FMTCompileOld/0                         15.5 ns         15.5 ns     43302898
    FMTCompileOld/42                        16.6 ns         16.6 ns     43278267
    FMTCompileOld/273123                    18.7 ns         18.6 ns     37035861
    FMTCompileOld/9223372036854775807       19.4 ns         19.4 ns     35243000
    ----------------------------------------------------------------------------
    

    After (8.x):

    ----------------------------------------------------------------------------
    Benchmark                                  Time             CPU   Iterations
    ----------------------------------------------------------------------------
    FMTCompileNew/0                         1.99 ns         1.99 ns    360523686
    FMTCompileNew/42                        2.33 ns         2.33 ns    279865664
    FMTCompileNew/273123                    3.72 ns         3.71 ns    190230315
    FMTCompileNew/9223372036854775807       5.28 ns         5.26 ns    130711631
    ----------------------------------------------------------------------------
    

    It is even faster than std::to_chars from libc++ compiled with clang on macOS:

    ----------------------------------------------------------------------------
    Benchmark                                  Time             CPU   Iterations
    ----------------------------------------------------------------------------
    ToChars/0                               4.42 ns         4.41 ns    160196630
    ToChars/42                              5.00 ns         4.98 ns    140735201
    ToChars/273123                          7.26 ns         7.24 ns     95784130
    ToChars/9223372036854775807             8.77 ns         8.75 ns     75872534
    ----------------------------------------------------------------------------
    

    In other cases, especially involving std::string construction, the speed up is usually lower because handling format specifiers takes a smaller fraction of the total time.

  • Added the _cf user-defined literal to represent a compiled format string. It can be used instead of the FMT_COMPILE macro (#2043, #2242):

    #include <fmt/compile.h>
    
    using namespace fmt::literals;
    auto s = fmt::format(FMT_COMPILE("{}"), 42); // 🙁 not modern
    auto s = fmt::format("{}"_cf, 42);           // 🙂 modern as hell

    It requires compiler support for class types in non-type template parameters (a C++20 feature) which is available in GCC 9.3+. Thanks @alexezeder (Alexey Ochapov).

  • Format string compilation now requires format functions of formatter specializations for user-defined types to be const:

    template <> struct fmt::formatter<my_type>: formatter<string_view> {
      template <typename FormatContext>
      auto format(my_type obj, FormatContext& ctx) const {  // Note const here.
        // ...
      }
    };
  • Added UDL-based named argument support to format string compilation (#2243, #2281). For example:

    #include <fmt/compile.h>
    
    using namespace fmt::literals;
    auto s = fmt::format(FMT_COMPILE("{answer}"), "answer"_a = 42);

    Here the argument named "answer" is resolved at compile time with no runtime overhead. Thanks @alexezeder (Alexey Ochapov).

  • Added format string compilation support to fmt::print (#2280, #2304). Thanks @alexezeder (Alexey Ochapov).

  • Added initial support for compiling {fmt} as a C++20 module (#2235, #2240, #2260, #2282, #2283, #2288, #2298, #2306, #2307, #2309, #2318, #2324, #2332, #2340). Thanks @DanielaE (Daniela Engert).

  • Made symbols private by default reducing shared library size (#2301). For example there was a ~15% reported reduction on one platform. Thanks @sergiud (Sergiu Deitsch).

  • Optimized includes making the result of preprocessing fmt/format.h ~20% smaller with libstdc++/C++20 and slightly improving build times (#1998).

  • Added support of ranges with non-const begin / end (#1953). Thanks @kitegi (sarah).

  • Added support of std::byte and other formattable types to fmt::join (#1981, #2040, #2050, #2262). For example:

    #include <fmt/format.h>
    #include <cstddef>
    #include <vector>
    
    int main() {
      auto bytes = std::vector{std::byte(4), std::byte(2)};
      fmt::print("{}", fmt::join(bytes, ""));
    }

    prints "42".

    Thanks @kamibo (Camille Bordignon).

  • Implemented the default format for std::chrono::system_clock (#2319, #2345). For example:

    #include <fmt/chrono.h>
    
    int main() {
      fmt::print("{}", std::chrono::system_clock::now());
    }

    prints "2021-06-18 15:22:00" (the output depends on the current date and time). Thanks @sunmy2019.

  • Made more chrono specifiers locale independent by default. Use the 'L' specifier to get localized formatting. For example:

    #include <fmt/chrono.h>
    
    int main() {
      std::locale::global(std::locale("ru_RU.UTF-8"));
      auto monday = std::chrono::weekday(1);
      fmt::print("{}\n", monday);   // prints "Mon"
      fmt::print("{:L}\n", monday); // prints "пн"
    }
  • Improved locale handling in chrono formatting (#2337, #2349, #2350). Thanks @phprus (Vladislav Shchapov).

  • Deprecated fmt/locale.h moving the formatting functions that take a locale to fmt/format.h (char) and fmt/xchar (other overloads). This doesn't introduce a dependency on <locale> so there is virtually no compile time effect.

  • Made parameter order in vformat_to consistent with format_to (#2327).

  • Added support for time points with arbitrary durations (#2208). For example:

    #include <fmt/chrono.h>
    
    int main() {
      using tp = std::chrono::time_point<
        std::chrono::system_clock, std::chrono::seconds>;
      fmt::print("{:%S}", tp(std::chrono::seconds(42)));
    }

    prints "42".

  • Formatting floating-point numbers no longer produces trailing zeros by default for consistency with std::format. For example:

    #include <fmt/core.h>
    
    int main() {
      fmt::print("{0:.3}", 1.1);
    }

    prints "1.1". Use the '#' specifier to keep trailing zeros.

  • Dropped a limit on the number of elements in a range and replaced {} with [] as range delimiters for consistency with Python's str.format.

  • The 'L' specifier for locale-specific numeric formatting can now be combined with presentation specifiers as in std::format. For example:

    #include <fmt/core.h>
    #include <locale>
    
    int main() {
      std::locale::global(std::locale("fr_FR.UTF-8"));
      fmt::print("{0:.2Lf}", 0.42);
    }

    prints "0,42". The deprecated 'n' specifier has been removed.

  • Made the 0 specifier ignored for infinity and NaN (#2305, #2310). Thanks @Liedtke (Matthias Liedtke).

  • Made the hexfloat formatting use the right alignment by default (#2308, #2317). Thanks @Liedtke (Matthias Liedtke).

  • Removed the deprecated numeric alignment ('='). Use the '0' specifier instead.

  • Removed the deprecated fmt/posix.h header that has been replaced with fmt/os.h.

  • Removed the deprecated format_to_n_context, format_to_n_args and make_format_to_n_args. They have been replaced with format_context, format_args and make_format_args respectively.

  • Moved wchar_t-specific functions and types to fmt/xchar.h. You can define FMT_DEPRECATED_INCLUDE_XCHAR to automatically include fmt/xchar.h from fmt/format.h but this will be disabled in the next major release.

  • Fixed handling of the '+' specifier in localized formatting (#2133).

  • Added support for the 's' format specifier that gives textual representation of bool (#2094, #2109). For example:

    #include <fmt/core.h>
    
    int main() {
      fmt::print("{:s}", true);
    }

    prints "true". Thanks @powercoderlol (Ivan Polyakov).

  • Made fmt::ptr work with function pointers (#2131). For example:

    #include <fmt/format.h>
    
    int main() {
      fmt::print("My main: {}\n", fmt::ptr(main));
    }

    Thanks @mikecrowe (Mike Crowe).

  • Fixed fmt::formatted_size with format string compilation (#2141, #2161). Thanks @alexezeder (Alexey Ochapov).

  • Fixed handling of empty format strings during format string compilation (#2042):

    auto s = fmt::format(FMT_COMPILE(""));

    Thanks @alexezeder (Alexey Ochapov).

  • Fixed handling of enums in fmt::to_string (#2036).

  • Improved width computation (#2033, #2091). For example:

    #include <fmt/core.h>
    
    int main() {
      fmt::print("{:-<10}{}\n", "你好", "世界");
      fmt::print("{:-<10}{}\n", "hello", "world");
    }

    prints

    on a modern terminal.

  • The experimental fast output stream (fmt::ostream) is now truncated by default for consistency with fopen (#2018). For example:

    #include <fmt/os.h>
    
    int main() {
      fmt::ostream out1 = fmt::output_file("guide");
      out1.print("Zaphod");
      out1.close();
      fmt::ostream out2 = fmt::output_file("guide");
      out2.print("Ford");
    }

    writes "Ford" to the file "guide". To preserve the old file content if any pass fmt::file::WRONLY | fmt::file::CREATE flags to fmt::output_file.

  • Fixed moving of fmt::ostream that holds buffered data (#2197, #2198). Thanks @vtta.

  • Replaced the fmt::system_error exception with a function of the same name that constructs std::system_error (#2266).

  • Replaced the fmt::windows_error exception with a function of the same name that constructs std::system_error with the category returned by fmt::system_category() (#2274, #2275). The latter is similar to std::sytem_category but correctly handles UTF-8. Thanks @phprus (Vladislav Shchapov).

  • Replaced fmt::error_code with std::error_code and made it formattable (#2269, #2270, #2273). Thanks @phprus (Vladislav Shchapov).

  • Added speech synthesis support (#2206).

  • Made format_to work with a memory buffer that has a custom allocator (#2300). Thanks @voxmea.

  • Added Allocator::max_size support to basic_memory_buffer. (#1960). Thanks @phprus (Vladislav Shchapov).

  • Added wide string support to fmt::join (#2236). Thanks @crbrz.

  • Made iterators passed to formatter specializations via a format context satisfy C++20 std::output_iterator requirements (#2156, #2158, #2195, #2204). Thanks @randomnetcat (Jason Cobb).

  • Optimized the printf implementation (#1982, #1984, #2016, #2164). Thanks @rimathia and @moiwi.

  • Improved detection of constexpr char_traits (#2246, #2257). Thanks @phprus (Vladislav Shchapov).

  • Fixed writing to stdout when it is redirected to NUL on Windows (#2080).

  • Fixed exception propagation from iterators (#2097).

  • Improved strftime error handling (#2238, #2244). Thanks @yumeyao.

  • Stopped using deprecated GCC UDL template extension.

  • Added fmt/args.h to the install target (#2096).

  • Error messages are now passed to assert when exceptions are disabled (#2145). Thanks @NobodyXu (Jiahao XU).

  • Added the FMT_MASTER_PROJECT CMake option to control build and install targets when {fmt} is included via add_subdirectory (#2098, #2100). Thanks @randomizedthinking.

  • Improved build configuration (#2026, #2122). Thanks @luncliff (Park DongHa) and @ibaned (Dan Ibanez).

  • Fixed various warnings and compilation issues (#1947, #1959, #1963, #1965, #1966, #1974, #1975, #1990, #2000, #2001, #2002, #2004, #2006, #2009, #2010, #2038, #2039, #2047, #2053, #2059, #2065, #2067, #2068, #2073, #2103 #2105 #2106, #2107, #2116 #2117, #2118 #2119, #2127, #2128, #2140, #2142, #2143, #2144, #2147, #2148, #2149, #2152, #2160, #2170, #2175, #2176, #2177, #2178, #2179, #2180, #2181, #2183, #2184, #2185, #2186, #2187, #2190, #2192, #2194, #2205, #2210, #2211, #2215, #2216, #2218, #2220, #2228, #2229, #2230, #2233, #2239, #2248, #2252, #2253, #2255, #2261, #2278, #2284, #2287, #2289, #2290, #2293, #2295, #2296, #2297, #2311, #2313, #2315, #2320, #2321, #2323, #2328, #2329, #2333, #2338, #2341). Thanks @darklukee, @fagg (Ashton Fagg), @killerbot242 (Lieven de Cock), @jgopel (Jonathan Gopel), @yeswalrus (Walter Gray), @Finkman, @HazardyKnusperkeks (Björn Schäpers), @dkavolis (Daumantas Kavolis) @concatime (Issam Maghni), @chronoxor (Ivan Shynkarenka), @summivox (Yin Zhong), @yNeo, @Apache-HB (Elliot), @alexezeder (Alexey Ochapov), @toojays (John Steele Scott), @Brainy0207, @vadz (VZ), @imsherlock (Ryan Sherlock), @phprus (Vladislav Shchapov), @white238 (Chris White), @yafshar (Yaser Afshar), @BillyDonahue (Billy Donahue), @jstaahl, @denchat, @DanielaE (Daniela Engert), @ilyakurdyukov (Ilya Kurdyukov), @ilmai, @JessyDL (Jessy De Lannoit), @sergiud (Sergiu Deitsch), @mwinterb, @sven-herrmann, @jmelas (John Melas), @twoixter (Jose Miguel Pérez), @crbrz, @upsj (Tobias Ribizel).

  • Improved documentation (#1986, #2051, #2057, #2081, #2084, #2312). Thanks @imba-tjd (谭九鼎), @0x416c69 (AlιAѕѕaѕѕιN), @mordante.

  • Continuous integration and test improvements (#1969, #1991, #2020, #2110, #2114, #2196, #2217, #2247, #2256, #2336, #2346). Thanks @jgopel (Jonathan Gopel), @alexezeder (Alexey Ochapov) and @DanielaE (Daniela Engert).