duckstation

duckstation, but archived from the revision just before upstream changed it to a proprietary software project, this version is the libre one
git clone https://git.neptards.moe/u3shit/duckstation.git
Log | Files | Refs | README | LICENSE

README.rst (20274B)


      1 .. image:: https://user-images.githubusercontent.com/
      2            576385/156254208-f5b743a9-88cf-439d-b0c0-923d53e8d551.png
      3    :width: 25%
      4    :alt: {fmt}
      5 
      6 .. image:: https://github.com/fmtlib/fmt/workflows/linux/badge.svg
      7    :target: https://github.com/fmtlib/fmt/actions?query=workflow%3Alinux
      8 
      9 .. image:: https://github.com/fmtlib/fmt/workflows/macos/badge.svg
     10    :target: https://github.com/fmtlib/fmt/actions?query=workflow%3Amacos
     11 
     12 .. image:: https://github.com/fmtlib/fmt/workflows/windows/badge.svg
     13    :target: https://github.com/fmtlib/fmt/actions?query=workflow%3Awindows
     14 
     15 .. image:: https://oss-fuzz-build-logs.storage.googleapis.com/badges/fmt.svg
     16    :alt: fmt is continuously fuzzed at oss-fuzz
     17    :target: https://bugs.chromium.org/p/oss-fuzz/issues/list?\
     18             colspec=ID%20Type%20Component%20Status%20Proj%20Reported%20Owner%20\
     19             Summary&q=proj%3Dfmt&can=1
     20 
     21 .. image:: https://img.shields.io/badge/stackoverflow-fmt-blue.svg
     22    :alt: Ask questions at StackOverflow with the tag fmt
     23    :target: https://stackoverflow.com/questions/tagged/fmt
     24 
     25 .. image:: https://api.securityscorecards.dev/projects/github.com/fmtlib/fmt/badge
     26    :target: https://securityscorecards.dev/viewer/?uri=github.com/fmtlib/fmt
     27 
     28 **{fmt}** is an open-source formatting library providing a fast and safe
     29 alternative to C stdio and C++ iostreams.
     30 
     31 If you like this project, please consider donating to one of the funds that
     32 help victims of the war in Ukraine: https://www.stopputin.net/.
     33 
     34 `Documentation <https://fmt.dev>`__
     35 
     36 `Cheat Sheets <https://hackingcpp.com/cpp/libs/fmt.html>`__
     37 
     38 Q&A: ask questions on `StackOverflow with the tag fmt
     39 <https://stackoverflow.com/questions/tagged/fmt>`_.
     40 
     41 Try {fmt} in `Compiler Explorer <https://godbolt.org/z/Eq5763>`_.
     42 
     43 Features
     44 --------
     45 
     46 * Simple `format API <https://fmt.dev/latest/api.html>`_ with positional arguments
     47   for localization
     48 * Implementation of `C++20 std::format
     49   <https://en.cppreference.com/w/cpp/utility/format>`__
     50 * `Format string syntax <https://fmt.dev/latest/syntax.html>`_ similar to Python's
     51   `format <https://docs.python.org/3/library/stdtypes.html#str.format>`_
     52 * Fast IEEE 754 floating-point formatter with correct rounding, shortness and
     53   round-trip guarantees using the `Dragonbox <https://github.com/jk-jeon/dragonbox>`_
     54   algorithm
     55 * Portable Unicode support
     56 * Safe `printf implementation
     57   <https://fmt.dev/latest/api.html#printf-formatting>`_ including the POSIX
     58   extension for positional arguments
     59 * Extensibility: `support for user-defined types
     60   <https://fmt.dev/latest/api.html#formatting-user-defined-types>`_
     61 * High performance: faster than common standard library implementations of
     62   ``(s)printf``, iostreams, ``to_string`` and ``to_chars``, see `Speed tests`_
     63   and `Converting a hundred million integers to strings per second
     64   <http://www.zverovich.net/2020/06/13/fast-int-to-string-revisited.html>`_
     65 * Small code size both in terms of source code with the minimum configuration
     66   consisting of just three files, ``core.h``, ``format.h`` and ``format-inl.h``,
     67   and compiled code; see `Compile time and code bloat`_
     68 * Reliability: the library has an extensive set of `tests
     69   <https://github.com/fmtlib/fmt/tree/master/test>`_ and is `continuously fuzzed
     70   <https://bugs.chromium.org/p/oss-fuzz/issues/list?colspec=ID%20Type%20
     71   Component%20Status%20Proj%20Reported%20Owner%20Summary&q=proj%3Dfmt&can=1>`_
     72 * Safety: the library is fully type-safe, errors in format strings can be
     73   reported at compile time, automatic memory management prevents buffer overflow
     74   errors
     75 * Ease of use: small self-contained code base, no external dependencies,
     76   permissive MIT `license
     77   <https://github.com/fmtlib/fmt/blob/master/LICENSE.rst>`_
     78 * `Portability <https://fmt.dev/latest/index.html#portability>`_ with
     79   consistent output across platforms and support for older compilers
     80 * Clean warning-free codebase even on high warning levels such as
     81   ``-Wall -Wextra -pedantic``
     82 * Locale independence by default
     83 * Optional header-only configuration enabled with the ``FMT_HEADER_ONLY`` macro
     84 
     85 See the `documentation <https://fmt.dev>`_ for more details.
     86 
     87 Examples
     88 --------
     89 
     90 **Print to stdout** (`run <https://godbolt.org/z/Tevcjh>`_)
     91 
     92 .. code:: c++
     93 
     94     #include <fmt/core.h>
     95     
     96     int main() {
     97       fmt::print("Hello, world!\n");
     98     }
     99 
    100 **Format a string** (`run <https://godbolt.org/z/oK8h33>`_)
    101 
    102 .. code:: c++
    103 
    104     std::string s = fmt::format("The answer is {}.", 42);
    105     // s == "The answer is 42."
    106 
    107 **Format a string using positional arguments** (`run <https://godbolt.org/z/Yn7Txe>`_)
    108 
    109 .. code:: c++
    110 
    111     std::string s = fmt::format("I'd rather be {1} than {0}.", "right", "happy");
    112     // s == "I'd rather be happy than right."
    113 
    114 **Print chrono durations** (`run <https://godbolt.org/z/K8s4Mc>`_)
    115 
    116 .. code:: c++
    117 
    118     #include <fmt/chrono.h>
    119 
    120     int main() {
    121       using namespace std::literals::chrono_literals;
    122       fmt::print("Default format: {} {}\n", 42s, 100ms);
    123       fmt::print("strftime-like format: {:%H:%M:%S}\n", 3h + 15min + 30s);
    124     }
    125 
    126 Output::
    127 
    128     Default format: 42s 100ms
    129     strftime-like format: 03:15:30
    130 
    131 **Print a container** (`run <https://godbolt.org/z/MxM1YqjE7>`_)
    132 
    133 .. code:: c++
    134 
    135     #include <vector>
    136     #include <fmt/ranges.h>
    137 
    138     int main() {
    139       std::vector<int> v = {1, 2, 3};
    140       fmt::print("{}\n", v);
    141     }
    142 
    143 Output::
    144 
    145     [1, 2, 3]
    146 
    147 **Check a format string at compile time**
    148 
    149 .. code:: c++
    150 
    151     std::string s = fmt::format("{:d}", "I am not a number");
    152 
    153 This gives a compile-time error in C++20 because ``d`` is an invalid format
    154 specifier for a string.
    155 
    156 **Write a file from a single thread**
    157 
    158 .. code:: c++
    159 
    160     #include <fmt/os.h>
    161 
    162     int main() {
    163       auto out = fmt::output_file("guide.txt");
    164       out.print("Don't {}", "Panic");
    165     }
    166 
    167 This can be `5 to 9 times faster than fprintf
    168 <http://www.zverovich.net/2020/08/04/optimal-file-buffer-size.html>`_.
    169 
    170 **Print with colors and text styles**
    171 
    172 .. code:: c++
    173 
    174     #include <fmt/color.h>
    175 
    176     int main() {
    177       fmt::print(fg(fmt::color::crimson) | fmt::emphasis::bold,
    178                  "Hello, {}!\n", "world");
    179       fmt::print(fg(fmt::color::floral_white) | bg(fmt::color::slate_gray) |
    180                  fmt::emphasis::underline, "Hello, {}!\n", "мир");
    181       fmt::print(fg(fmt::color::steel_blue) | fmt::emphasis::italic,
    182                  "Hello, {}!\n", "世界");
    183     }
    184 
    185 Output on a modern terminal:
    186 
    187 .. image:: https://user-images.githubusercontent.com/
    188            576385/88485597-d312f600-cf2b-11ea-9cbe-61f535a86e28.png
    189 
    190 Benchmarks
    191 ----------
    192 
    193 Speed tests
    194 ~~~~~~~~~~~
    195 
    196 ================= ============= ===========
    197 Library           Method        Run Time, s
    198 ================= ============= ===========
    199 libc              printf          0.91
    200 libc++            std::ostream    2.49
    201 {fmt} 9.1         fmt::print      0.74
    202 Boost Format 1.80 boost::format   6.26
    203 Folly Format      folly::format   1.87
    204 ================= ============= ===========
    205 
    206 {fmt} is the fastest of the benchmarked methods, ~20% faster than ``printf``.
    207 
    208 The above results were generated by building ``tinyformat_test.cpp`` on macOS
    209 12.6.1 with ``clang++ -O3 -DNDEBUG -DSPEED_TEST -DHAVE_FORMAT``, and taking the
    210 best of three runs. In the test, the format string ``"%0.10f:%04d:%+g:%s:%p:%c:%%\n"``
    211 or equivalent is filled 2,000,000 times with output sent to ``/dev/null``; for
    212 further details refer to the `source
    213 <https://github.com/fmtlib/format-benchmark/blob/master/src/tinyformat-test.cc>`_.
    214 
    215 {fmt} is up to 20-30x faster than ``std::ostringstream`` and ``sprintf`` on
    216 IEEE754 ``float`` and ``double`` formatting (`dtoa-benchmark <https://github.com/fmtlib/dtoa-benchmark>`_)
    217 and faster than `double-conversion <https://github.com/google/double-conversion>`_ and
    218 `ryu <https://github.com/ulfjack/ryu>`_:
    219 
    220 .. image:: https://user-images.githubusercontent.com/576385/
    221            95684665-11719600-0ba8-11eb-8e5b-972ff4e49428.png
    222    :target: https://fmt.dev/unknown_mac64_clang12.0.html
    223 
    224 Compile time and code bloat
    225 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    226 
    227 The script `bloat-test.py
    228 <https://github.com/fmtlib/format-benchmark/blob/master/bloat-test.py>`_
    229 from `format-benchmark <https://github.com/fmtlib/format-benchmark>`_
    230 tests compile time and code bloat for nontrivial projects.
    231 It generates 100 translation units and uses ``printf()`` or its alternative
    232 five times in each to simulate a medium-sized project.  The resulting
    233 executable size and compile time (Apple LLVM version 8.1.0 (clang-802.0.42),
    234 macOS Sierra, best of three) is shown in the following tables.
    235 
    236 **Optimized build (-O3)**
    237 
    238 ============= =============== ==================== ==================
    239 Method        Compile Time, s Executable size, KiB Stripped size, KiB
    240 ============= =============== ==================== ==================
    241 printf                    2.6                   29                 26
    242 printf+string            16.4                   29                 26
    243 iostreams                31.1                   59                 55
    244 {fmt}                    19.0                   37                 34
    245 Boost Format             91.9                  226                203
    246 Folly Format            115.7                  101                 88
    247 ============= =============== ==================== ==================
    248 
    249 As you can see, {fmt} has 60% less overhead in terms of resulting binary code
    250 size compared to iostreams and comes pretty close to ``printf``. Boost Format
    251 and Folly Format have the largest overheads.
    252 
    253 ``printf+string`` is the same as ``printf`` but with an extra ``<string>``
    254 include to measure the overhead of the latter.
    255 
    256 **Non-optimized build**
    257 
    258 ============= =============== ==================== ==================
    259 Method        Compile Time, s Executable size, KiB Stripped size, KiB
    260 ============= =============== ==================== ==================
    261 printf                    2.2                   33                 30
    262 printf+string            16.0                   33                 30
    263 iostreams                28.3                   56                 52
    264 {fmt}                    18.2                   59                 50
    265 Boost Format             54.1                  365                303
    266 Folly Format             79.9                  445                430
    267 ============= =============== ==================== ==================
    268 
    269 ``libc``, ``lib(std)c++``, and ``libfmt`` are all linked as shared libraries to
    270 compare formatting function overhead only. Boost Format is a
    271 header-only library so it doesn't provide any linkage options.
    272 
    273 Running the tests
    274 ~~~~~~~~~~~~~~~~~
    275 
    276 Please refer to `Building the library`__ for instructions on how to build
    277 the library and run the unit tests.
    278 
    279 __ https://fmt.dev/latest/usage.html#building-the-library
    280 
    281 Benchmarks reside in a separate repository,
    282 `format-benchmarks <https://github.com/fmtlib/format-benchmark>`_,
    283 so to run the benchmarks you first need to clone this repository and
    284 generate Makefiles with CMake::
    285 
    286     $ git clone --recursive https://github.com/fmtlib/format-benchmark.git
    287     $ cd format-benchmark
    288     $ cmake .
    289 
    290 Then you can run the speed test::
    291 
    292     $ make speed-test
    293 
    294 or the bloat test::
    295 
    296     $ make bloat-test
    297     
    298 Migrating code
    299 --------------
    300 
    301 `clang-tidy <https://clang.llvm.org/extra/clang-tidy/>`_ v17 (not yet
    302 released) provides the `modernize-use-std-print
    303 <https://clang.llvm.org/extra/clang-tidy/checks/modernize/use-std-print.html>`_
    304 check that is capable of converting occurrences of ``printf`` and
    305 ``fprintf`` to ``fmt::print`` if configured to do so. (By default it
    306 converts to ``std::print``.)
    307 
    308 Projects using this library
    309 ---------------------------
    310 
    311 * `0 A.D. <https://play0ad.com/>`_: a free, open-source, cross-platform
    312   real-time strategy game
    313 
    314 * `AMPL/MP <https://github.com/ampl/mp>`_:
    315   an open-source library for mathematical programming
    316 
    317 * `Aseprite <https://github.com/aseprite/aseprite>`_:
    318   animated sprite editor & pixel art tool 
    319 
    320 * `AvioBook <https://www.aviobook.aero/en>`_: a comprehensive aircraft
    321   operations suite
    322   
    323 * `Blizzard Battle.net <https://battle.net/>`_: an online gaming platform
    324   
    325 * `Celestia <https://celestia.space/>`_: real-time 3D visualization of space
    326 
    327 * `Ceph <https://ceph.com/>`_: a scalable distributed storage system
    328 
    329 * `ccache <https://ccache.dev/>`_: a compiler cache
    330 
    331 * `ClickHouse <https://github.com/ClickHouse/ClickHouse>`_: an analytical database
    332   management system
    333   
    334 * `Contour <https://github.com/contour-terminal/contour/>`_: a modern terminal emulator
    335 
    336 * `CUAUV <https://cuauv.org/>`_: Cornell University's autonomous underwater
    337   vehicle
    338 
    339 * `Drake <https://drake.mit.edu/>`_: a planning, control, and analysis toolbox
    340   for nonlinear dynamical systems (MIT)
    341 
    342 * `Envoy <https://lyft.github.io/envoy/>`_: C++ L7 proxy and communication bus
    343   (Lyft)
    344 
    345 * `FiveM <https://fivem.net/>`_: a modification framework for GTA V
    346 
    347 * `fmtlog <https://github.com/MengRao/fmtlog>`_: a performant fmtlib-style
    348   logging library with latency in nanoseconds
    349 
    350 * `Folly <https://github.com/facebook/folly>`_: Facebook open-source library
    351 
    352 * `GemRB <https://gemrb.org/>`_: a portable open-source implementation of
    353   Bioware’s Infinity Engine
    354 
    355 * `Grand Mountain Adventure
    356   <https://store.steampowered.com/app/1247360/Grand_Mountain_Adventure/>`_:
    357   a beautiful open-world ski & snowboarding game
    358 
    359 * `HarpyWar/pvpgn <https://github.com/pvpgn/pvpgn-server>`_:
    360   Player vs Player Gaming Network with tweaks
    361 
    362 * `KBEngine <https://github.com/kbengine/kbengine>`_: an open-source MMOG server
    363   engine
    364 
    365 * `Keypirinha <https://keypirinha.com/>`_: a semantic launcher for Windows
    366 
    367 * `Kodi <https://kodi.tv/>`_ (formerly xbmc): home theater software
    368 
    369 * `Knuth <https://kth.cash/>`_: high-performance Bitcoin full-node
    370 
    371 * `libunicode <https://github.com/contour-terminal/libunicode/>`_: a modern C++17 Unicode library
    372 
    373 * `MariaDB <https://mariadb.org/>`_: relational database management system
    374 
    375 * `Microsoft Verona <https://github.com/microsoft/verona>`_:
    376   research programming language for concurrent ownership
    377 
    378 * `MongoDB <https://mongodb.com/>`_: distributed document database
    379 
    380 * `MongoDB Smasher <https://github.com/duckie/mongo_smasher>`_: a small tool to
    381   generate randomized datasets
    382 
    383 * `OpenSpace <https://openspaceproject.com/>`_: an open-source
    384   astrovisualization framework
    385 
    386 * `PenUltima Online (POL) <https://www.polserver.com/>`_:
    387   an MMO server, compatible with most Ultima Online clients
    388 
    389 * `PyTorch <https://github.com/pytorch/pytorch>`_: an open-source machine
    390   learning library
    391 
    392 * `quasardb <https://www.quasardb.net/>`_: a distributed, high-performance,
    393   associative database
    394   
    395 * `Quill <https://github.com/odygrd/quill>`_: asynchronous low-latency logging library
    396 
    397 * `QKW <https://github.com/ravijanjam/qkw>`_: generalizing aliasing to simplify
    398   navigation, and executing complex multi-line terminal command sequences
    399 
    400 * `redis-cerberus <https://github.com/HunanTV/redis-cerberus>`_: a Redis cluster
    401   proxy
    402 
    403 * `redpanda <https://vectorized.io/redpanda>`_: a 10x faster Kafka® replacement
    404   for mission-critical systems written in C++
    405 
    406 * `rpclib <http://rpclib.net/>`_: a modern C++ msgpack-RPC server and client
    407   library
    408 
    409 * `Salesforce Analytics Cloud
    410   <https://www.salesforce.com/analytics-cloud/overview/>`_:
    411   business intelligence software
    412 
    413 * `Scylla <https://www.scylladb.com/>`_: a Cassandra-compatible NoSQL data store
    414   that can handle 1 million transactions per second on a single server
    415 
    416 * `Seastar <http://www.seastar-project.org/>`_: an advanced, open-source C++
    417   framework for high-performance server applications on modern hardware
    418 
    419 * `spdlog <https://github.com/gabime/spdlog>`_: super fast C++ logging library
    420 
    421 * `Stellar <https://www.stellar.org/>`_: financial platform
    422 
    423 * `Touch Surgery <https://www.touchsurgery.com/>`_: surgery simulator
    424 
    425 * `TrinityCore <https://github.com/TrinityCore/TrinityCore>`_: open-source
    426   MMORPG framework
    427 
    428 * `🐙 userver framework <https://userver.tech/>`_: open-source asynchronous
    429   framework with a rich set of abstractions and database drivers
    430 
    431 * `Windows Terminal <https://github.com/microsoft/terminal>`_: the new Windows
    432   terminal
    433 
    434 `More... <https://github.com/search?q=fmtlib&type=Code>`_
    435 
    436 If you are aware of other projects using this library, please let me know
    437 by `email <mailto:victor.zverovich@gmail.com>`_ or by submitting an
    438 `issue <https://github.com/fmtlib/fmt/issues>`_.
    439 
    440 Motivation
    441 ----------
    442 
    443 So why yet another formatting library?
    444 
    445 There are plenty of methods for doing this task, from standard ones like
    446 the printf family of function and iostreams to Boost Format and FastFormat
    447 libraries. The reason for creating a new library is that every existing
    448 solution that I found either had serious issues or didn't provide
    449 all the features I needed.
    450 
    451 printf
    452 ~~~~~~
    453 
    454 The good thing about ``printf`` is that it is pretty fast and readily available
    455 being a part of the C standard library. The main drawback is that it
    456 doesn't support user-defined types. ``printf`` also has safety issues although
    457 they are somewhat mitigated with `__attribute__ ((format (printf, ...))
    458 <https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html>`_ in GCC.
    459 There is a POSIX extension that adds positional arguments required for
    460 `i18n <https://en.wikipedia.org/wiki/Internationalization_and_localization>`_
    461 to ``printf`` but it is not a part of C99 and may not be available on some
    462 platforms.
    463 
    464 iostreams
    465 ~~~~~~~~~
    466 
    467 The main issue with iostreams is best illustrated with an example:
    468 
    469 .. code:: c++
    470 
    471     std::cout << std::setprecision(2) << std::fixed << 1.23456 << "\n";
    472 
    473 which is a lot of typing compared to printf:
    474 
    475 .. code:: c++
    476 
    477     printf("%.2f\n", 1.23456);
    478 
    479 Matthew Wilson, the author of FastFormat, called this "chevron hell". iostreams
    480 don't support positional arguments by design.
    481 
    482 The good part is that iostreams support user-defined types and are safe although
    483 error handling is awkward.
    484 
    485 Boost Format
    486 ~~~~~~~~~~~~
    487 
    488 This is a very powerful library that supports both ``printf``-like format
    489 strings and positional arguments. Its main drawback is performance. According to
    490 various benchmarks, it is much slower than other methods considered here. Boost
    491 Format also has excessive build times and severe code bloat issues (see
    492 `Benchmarks`_).
    493 
    494 FastFormat
    495 ~~~~~~~~~~
    496 
    497 This is an interesting library that is fast, safe, and has positional arguments.
    498 However, it has significant limitations, citing its author:
    499 
    500     Three features that have no hope of being accommodated within the
    501     current design are:
    502 
    503     * Leading zeros (or any other non-space padding)
    504     * Octal/hexadecimal encoding
    505     * Runtime width/alignment specification
    506 
    507 It is also quite big and has a heavy dependency, STLSoft, which might be too
    508 restrictive for using it in some projects.
    509 
    510 Boost Spirit.Karma
    511 ~~~~~~~~~~~~~~~~~~
    512 
    513 This is not a formatting library but I decided to include it here for
    514 completeness. As iostreams, it suffers from the problem of mixing verbatim text
    515 with arguments. The library is pretty fast, but slower on integer formatting
    516 than ``fmt::format_to`` with format string compilation on Karma's own benchmark,
    517 see `Converting a hundred million integers to strings per second
    518 <http://www.zverovich.net/2020/06/13/fast-int-to-string-revisited.html>`_.
    519 
    520 License
    521 -------
    522 
    523 {fmt} is distributed under the MIT `license
    524 <https://github.com/fmtlib/fmt/blob/master/LICENSE.rst>`_.
    525 
    526 Documentation License
    527 ---------------------
    528 
    529 The `Format String Syntax <https://fmt.dev/latest/syntax.html>`_
    530 section in the documentation is based on the one from Python `string module
    531 documentation <https://docs.python.org/3/library/string.html#module-string>`_.
    532 For this reason, the documentation is distributed under the Python Software
    533 Foundation license available in `doc/python-license.txt
    534 <https://raw.github.com/fmtlib/fmt/master/doc/python-license.txt>`_.
    535 It only applies if you distribute the documentation of {fmt}.
    536 
    537 Maintainers
    538 -----------
    539 
    540 The {fmt} library is maintained by Victor Zverovich (`vitaut
    541 <https://github.com/vitaut>`_) with contributions from many other people.
    542 See `Contributors <https://github.com/fmtlib/fmt/graphs/contributors>`_ and
    543 `Releases <https://github.com/fmtlib/fmt/releases>`_ for some of the names.
    544 Let us know if your contribution is not listed or mentioned incorrectly and
    545 we'll make it right.