{"id":16889787,"url":"https://github.com/viatorus/compile-time-printer","last_synced_at":"2025-03-17T06:31:45.973Z","repository":{"id":54625318,"uuid":"326248985","full_name":"Viatorus/compile-time-printer","owner":"Viatorus","description":"Prints values and types during compilation!","archived":false,"fork":false,"pushed_at":"2022-11-07T20:21:17.000Z","size":4185,"stargazers_count":56,"open_issues_count":10,"forks_count":0,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-02-27T19:04:54.410Z","etag":null,"topics":["compile-time","cpp","print","printf","tool"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsl-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Viatorus.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGELOG.rst","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-01-02T18:45:18.000Z","updated_at":"2025-01-18T03:32:32.000Z","dependencies_parsed_at":"2022-08-13T22:00:18.059Z","dependency_job_id":null,"html_url":"https://github.com/Viatorus/compile-time-printer","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Viatorus%2Fcompile-time-printer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Viatorus%2Fcompile-time-printer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Viatorus%2Fcompile-time-printer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Viatorus%2Fcompile-time-printer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Viatorus","download_url":"https://codeload.github.com/Viatorus/compile-time-printer/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243847062,"owners_count":20357317,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["compile-time","cpp","print","printf","tool"],"created_at":"2024-10-13T16:58:56.740Z","updated_at":"2025-03-17T06:31:45.174Z","avatar_url":"https://github.com/Viatorus.png","language":"Python","readme":".. image:: https://raw.githubusercontent.com/Viatorus/compile-time-printer/main/web/static/banner-web.svg\n    :alt: compile-time printer\n\n.. image :: https://img.shields.io/github/release/viatorus/compile-time-printer.svg\n    :alt: Github Releases\n    :target: https://github.com/viatorus/compile-time-printer/releases\n.. image :: https://img.shields.io/pypi/v/compile-time-printer.svg\n    :alt: PyPI\n    :target: https://pypi.org/project/compile-time-printer/\n.. image :: https://api.bintray.com/packages/viatorus/compile-time-printer/compile-time-printer%3Aviatorus/images/download.svg\n    :alt: Conan\n    :target: https://bintray.com/viatorus/compile-time-printer/compile-time-printer%3Aviatorus/_latestVersion\n.. image :: https://github.com/Viatorus/compile-time-printer/workflows/Testing/badge.svg\n    :alt: Build Status\n    :target: https://github.com/viatorus/compile-time-printer/releases\n.. image :: https://img.shields.io/badge/try-online-blue.svg\n    :alt: Try online\n    :target: https://viatorus.github.io/compile-time-printer/\n\nCompile-Time Printer\n====================\n\n**Compile-Time Printer** prints values and types at compile-time in C++.\n\nTeaser\n------\n\n+-------------------------------------------------+-------------------------------------------------+\n|                       test.cpp                  |    ``compile-time-printer -- make test.cpp``    |\n+-------------------------------------------------+-------------------------------------------------+\n| .. code-block:: cpp                             | .. code-block::                                 |\n|                                                 |                                                 |\n|     #include \u003cctp/ctp.hpp\u003e                      |     .                                           |\n|                                                 |                                                 |\n|     template\u003cauto I\u003e                            |                                                 |\n|     constexpr auto func(int i) {                |                                                 |\n|                                                 |                                                 |\n|       // Formatted output.                      |                                                 |\n|       ctp::printf(\"Hello {}!\\n\", ctp::type{I}); |     Hello int!                                  |\n|                                                 |                                                 |\n|       // Standardized output.                   |                                                 |\n|       ctp::print(I + i, sizeof(I));             |     42 4                                        |\n|                                                 |                                                 |\n|       return true;                              |                                                 |\n|     }                                           |                                                 |\n|                                                 |                                                 |\n|     constexpr auto test = func\u003c22\u003e(20);         |                                               . |\n+-------------------------------------------------+-------------------------------------------------+\n\nTry it out online: https://viatorus.github.io/compile-time-printer/\n\nOverview\n--------\n\n* `Installation`_\n* `API`_\n* `How it works`_\n* `Known limitations`_\n* `License`_\n\nInstallation\n------------\n\nRequires:\n\n* Python \u003e=3.6\n* GCC \u003e=7.4 and STD \u003e=C++17\n\nTo get started, install the `python tool \u003chttps://pypi.org/project/compile-time-printer\u003e`__:\n\n.. code-block::\n\n    pip install compile-time-printer\n\nAfterwards, dump the CTP header file and include it in your project:\n\n.. code-block::\n\n    compile-time-printer --dump-header-file\n\nAlternative, you can install the header file via the\n`conan package \u003chttps://bintray.com/viatorus/compile-time-printer\u003e`__.\n\nFinally, run CTP with your build command.\n\n*E.g. with g++ directly:*\n\n.. code-block::\n\n    compile-time-printer -- g++ -I. -fsyntax-only -std=c++17 -fpermissive test.cpp\n\n*E.g. with make:*\n\n.. code-block::\n\n    compile-time-printer -- make test.cpp\n\nYou have to set the compiler flag *-fpermissive* in order to make it work.\n\nAPI\n---\n\nctp.hpp\n+++++++\n\n* **ctp::print(** *[file descriptor,] arguments* **)**\n\nPrints all arguments in a simple, standardized format. Each argument is separated by one space, ending with a line\nbreak.\n\n.. code-block:: cpp\n\n    int x = 42;\n    ctp::print(\"Hello\", 2.72, x);  // \"Hello 2.72 42\\n\"\n\n* **ctp::printf(** *[file descriptor,] format, arguments* **)**\n\nFormats and prints all arguments in the desired format without implicit line break.\nUses the `pythons format string syntax \u003chttps://docs.python.org/3/library/string.html#format-string-syntax\u003e`__.\n\n.. code-block:: cpp\n\n    int x = 42;\n    ctp::printf(\"{:.1f}\", 3.14);  // \"3.1\"\n    ctp::printf(\"int: {0:d}; hex: {0:x};\\n\"    // \"int: 42; hex: 2a;\\n\"\n                \"oct: {0:o}; bin: {0:b}\", x);  // \"oct: 52; bin: 101010\"\n\n* **ctp::stdout** or **ctp::stderr**\n\nAvailable file descriptor to print to standard output stream or standard error stream.\n\n.. code-block:: cpp\n\n    ctp::print(ctp::stdout, \"Info\");  // stdout: \"Info\\n\"\n    ctp::printf(ctp::stderr, \"Warning!\\n\");  // stderr: \"Warning!\\n\"\n\n* **ctp::type\u003c** *Types* **\u003e{}** or **ctp::type{** *variables* **}**\n\nHelper object which can be passed as an argument to **print/printf** to output the type of the variables rather then\ntheir values.\n\n.. code-block:: cpp\n\n    int x = 42;\n    ctp::print(ctp::type\u003cfloat\u003e{}, ctp::type{x});  // \"float int\u0026\\n\"\n\n* **ctp::view(** *data begin, data end* **)** or **ctp::view(** *data begin, data length* **)**\n  or **ctp::view(** *contiguous range* **)** (implicit constructed)\n\nHelper object which can be passed as an argument to **print/printf** to output a contiguous range.\n\n.. code-block:: cpp\n\n    int a[] = {1, 2, 3};\n    ctp::print(ctp::view{a, 1}, ctp::view{a + 1, a + 3}, a);  // \"[1] [2, 3] [1, 2, 3]\\n\"\n\n* **ctp::formatter\u003c** *Type* **\u003e**\n\nSpecialize struct **ctp::formatter** for *Type*. Provide a function **constexpr auto format(** *Type* **);**\nreturning a tuple like object. The first element must be a format string followed by the arguments.\n\n.. code-block:: cpp\n\n    struct FooBar {\n        int i;\n    };\n\n    template\u003c\u003e\n    struct ctp::formatter\u003cFooBar\u003e {\n        static constexpr auto format(const FooBar\u0026 obj) {\n            return std::tuple{\".i = {}\", obj.i};\n        }\n    };\n\n    constexpr auto test = ctp::print(FooBar{42});  // \".i = 42\"\n\n* **ctp::forward(** *value* **)** or **ctp::forward(** *function, arguments...* **)**\n\nHelper to use **print/printf** in ``static_assert`` and template parameters. See `Known limitations`_.\n\ncompile-time-printer\n++++++++++++++++++++\n\n.. code-block::\n\n    usage: compile-time-parser [optionals] [-- program args...]\n\n    Compile-time printer - prints variables and types at compile time in C++.\n\n    positional arguments:\n      program               the program to compile the source (default: read from stdin)\n      args                  the arguments for the command (default: [])\n\n    optional arguments:\n      -h, --help            show this help message and exit\n      --version             show program's version number and exit\n      -r REMOVE, --remove REMOVE\n                            removes matching regex from type info (default: [])\n      -cr CAPTURE_REMOVE, --capture-remove CAPTURE_REMOVE\n                            removes matching regex but keeps first capture-group from type info (default: [])\n      --time-point          prints time point of each print statement (default: False)\n      --no-color            disables colored error output stream (default: False)\n      --hide-compiler-log   don't print unparsed compiler log (default: False)\n      --dump-header-file    dumps the C++ header file to ctp/ctp.hpp (default: False)\n\nHighlights\n~~~~~~~~~~\n\n* Use ``--time-point`` to get the time when the print statement has been reached. This can be used for benchmarking.\n\n.. code-block::\n\n    0:00:00.236446 - Function one evaluated.\n    0:00:01.238051 - Function two evaluated.\n\n* Use ``-r`` and ``-cr`` to remove unnecessary information from types:\n\n.. code-block:: cpp\n\n    namespace abc::def {\n        template\u003ctypename T\u003e\n        struct holder {};\n    }\n\n    using H = abc::def::holder\u003cint\u003e;\n    constexpr auto i = ctp::print(ctp::type\u003cH\u003e{});  // \"abc::def::holder\u003cint\u003e\"\n\nOutput with ``-r \"abc::def::\"``:\n\n.. code-block::\n\n    holder\u003cint\u003e\n\nOutput with ``-cr \".+\u003c(.+)\u003e\"``:\n\n.. code-block::\n\n    int\n\nHow it works\n------------\n\nThe implementation of **print/printf** does nothing more than forcing the compiler to generate warnings\ndepending on the passed arguments. The python tool parses the warnings and converts them back to the actually\nC++ arguments and outputs them (standardized or formatted) to stdout or stderr.\n\nSo what does *-fpermissive* do and why do we use it?\n\n    -fpermissive\n\n    Downgrade some diagnostics about nonconformant code from errors to warnings. Thus, using -fpermissive will allow\n    some nonconforming code to compile.\n\nThe nonconformant code we use in in the implementation is:\n\n.. code-block:: cpp\n\n    constexpr bool print(int i, int j) {\n        int unused = i \u003c\u003c j;\n        return true;\n    }\n\n    constexpr auto test = print(10, 34);\n\n``10 \u003c\u003c 34`` will cause an integer overflow which is not allowed, especially in a constant expression.\nGCC will output the following interesting diagnostic error:\n\n    \u003csource\u003e:2:20: error: right operand of shift expression '(10 \u003c\u003c 34)' is greater than or equal to the precision 32\n    of the left operand [-fpermissive]\n\nGCC evaluates the expression ``i \u003c\u003c j`` and gives a detailed message about the value of ``i`` and ``j``.\nMoreover, the error will recur, even for the same input. Let us all thank GCC for supporting old broken legacy code.\nWith *-fpermissive* this error becomes a warning and we can `continue compiling \u003chttps://gcc.godbolt.org/z/3G8h7M\u003e`__.\n\nSo everything we like to print at compile-time and can be broken down to fundamental types, can be outputted.\n\nIs it undefined behavior? Certainly. Will it format erase your hard drive? Probably not.\n\nUse it only for development and not in production!\n\nKnown limitations\n-----------------\n\nCompiler\n++++++++\n\nSince GCC is the only compiler I am aware of with detailed diagnostic warnings to recur, this tool can only work with\nGCC. `Prove me wrong. \u003chttps://github.com/Viatorus/compile-time-printer/issues/new\u003e`__\n\nInstantiation of static_assert or template parameter\n++++++++++++++++++++++++++++++++++++++++++++++++++++\n\nIf a CTP statement is used while instantiate an expression triggered by a ``static_assert`` or a `template parameter`,\nthe compilation will fail without a meaningful error message:\n\n.. code-block::\n\n    \u003csource\u003e:55:19: error: non-constant condition for static assertion\n        55 | static_assert(test());\n           |               ~~~~^~\n\nBecause *-fpermissive* is a legacy option, it is not fully maintained anymore to work across all compile-time\ninstantiation.\n\nOne workaround is to forward the expression to a constexpr variable instantiation:\n\n.. code-block:: cpp\n\n    static_assert(ctp::forward\u003cfunc()\u003e);\n\nCheck out this `example \u003chttps://git.io/JLhaX\u003e`__.\n\nCaching\n+++++++\n\nThe result of a constexpr functions could get cached. If this happens, a CTP statement will only be evaluated once.\nTry to generate additional noise to prevent this. Especially if this happens in unevaluated context.\nAdd additional changing input to the function call as (template) parameter. Also, GCC \u003e=10 added\n``-fconstexpr-cache-depth=8``. Maybe a smaller value solves the issue.\n\nCheck out this `example \u003chttps://git.io/JLhVT\u003e`__.\n\nLicense\n-------\n\n`BSD-1 LICENSE \u003chttps://github.com/viatorus/compile-time-printer/blob/main/LICENSE.txt\u003e`__\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fviatorus%2Fcompile-time-printer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fviatorus%2Fcompile-time-printer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fviatorus%2Fcompile-time-printer/lists"}