Prints values and types during compilation!

Overview

compile-time printer

Github Releases PyPI Conan Build Status Try online

Compile-Time Printer

Compile-Time Printer prints values and types at compile-time in C++.

Teaser

test.cpp compile-time-printer -- make test.cpp
#include <ctp/ctp.hpp>

template<auto I>
constexpr auto func(int i) {

  // Formatted output.
  ctp::printf("Hello {}!\n", ctp::type{I});

  // Standardized output.
  ctp::print(I + i, sizeof(I));

  return true;
}

constexpr auto test = func<22>(20);
.





Hello int!


42 4




                                          .

Try it out online: https://viatorus.github.io/compile-time-printer/

Overview

Installation

Requires:

  • Python >=3.6
  • GCC >=7.4 and STD >=C++17

To get started, install the python tool:

pip install compile-time-printer

Afterwards, dump the CTP header file and include it in your project:

compile-time-printer --dump-header-file

Alternative, you can install the header file via the conan package.

Finally, run CTP with your build command.

E.g. with g++ directly:

compile-time-printer -- g++ -I. -fsyntax-only -std=c++17 -fpermissive test.cpp

E.g. with make:

compile-time-printer -- make test.cpp

You have to set the compiler flag -fpermissive in order to make it work.

API

ctp.hpp

  • ctp::print( [file descriptor,] arguments )

Prints all arguments in a simple, standardized format. Each argument is separated by one space, ending with a line break.

int x = 42;
ctp::print("Hello", 2.72, x);  // "Hello 2.72 42\n"
  • ctp::printf( [file descriptor,] format, arguments )

Formats and prints all arguments in the desired format without implicit line break. Uses the pythons format string syntax.

int x = 42;
ctp::printf("{:.1f}", 3.14);  // "3.1"
ctp::printf("int: {0:d}; hex: {0:x};\n"    // "int: 42; hex: 2a;\n"
            "oct: {0:o}; bin: {0:b}", x);  // "oct: 52; bin: 101010"
  • ctp::stdout or ctp::stderr

Available file descriptor to print to standard output stream or standard error stream.

ctp::print(ctp::stdout, "Info");  // stdout: "Info\n"
ctp::printf(ctp::stderr, "Warning!\n");  // stderr: "Warning!\n"
  • ctp::type< Types >{} or ctp::type{ variables }

Helper object which can be passed as an argument to print/printf to output the type of the variables rather then their values.

int x = 42;
ctp::print(ctp::type<float>{}, ctp::type{x});  // "float int&\n"
  • ctp::view( data begin, data end ) or ctp::view( data begin, data length ) or ctp::view( contiguous range ) (implicit constructed)

Helper object which can be passed as an argument to print/printf to output a contiguous range.

int a[] = {1, 2, 3};
ctp::print(ctp::view{a, 1}, ctp::view{a + 1, a + 3}, a);  // "[1] [2, 3] [1, 2, 3]\n"
  • ctp::formatter< Type >

Specialize struct ctp::formatter for Type. Provide a function constexpr auto format( Type ); returning a tuple like object. The first element must be a format string followed by the arguments.

struct FooBar {
    int i;
};

template<>
struct ctp::formatter {
    static constexpr auto format(const FooBar& obj) {
        return std::tuple{".i = {}", obj.i};
    }
};

constexpr auto test = ctp::print(FooBar{42});  // ".i = 42"
  • ctp::forward( value ) or ctp::forward( function, arguments... )

Helper to use print/printf in static_assert and template parameters. See Known limitations.

compile-time-printer

usage: compile-time-parser [optionals] [-- program args...]

Compile-time printer - prints variables and types at compile time in C++.

positional arguments:
  program               the program to compile the source (default: read from stdin)
  args                  the arguments for the command (default: [])

optional arguments:
  -h, --help            show this help message and exit
  --version             show program's version number and exit
  -r REMOVE, --remove REMOVE
                        removes matching regex from type info (default: [])
  -cr CAPTURE_REMOVE, --capture-remove CAPTURE_REMOVE
                        removes matching regex but keeps first capture-group from type info (default: [])
  --time-point          prints time point of each print statement (default: False)
  --no-color            disables colored error output stream (default: False)
  --hide-compiler-log   don't print unparsed compiler log (default: False)
  --dump-header-file    dumps the C++ header file to ctp/ctp.hpp (default: False)
Highlights
  • Use --time-point to get the time when the print statement has been reached. This can be used for benchmarking.
0:00:00.236446 - Function one evaluated.
0:00:01.238051 - Function two evaluated.
  • Use -r and -cr to remove unnecessary information from types:
namespace abc::def {
    template<typename T>
    struct holder {};
}

using H = abc::def::holder<int>;
constexpr auto i = ctp::print(ctp::type{});  // "abc::def::holder"

Output with -r "abc::def::":

holder

Output with -cr ".+<(.+)>":

int

How it works

The implementation of print/printf does nothing more than forcing the compiler to generate warnings depending on the passed arguments. The python tool parses the warnings and converts them back to the actually C++ arguments and outputs them (standardized or formatted) to stdout or stderr.

So what does -fpermissive do and why do we use it?

-fpermissive

Downgrade some diagnostics about nonconformant code from errors to warnings. Thus, using -fpermissive will allow some nonconforming code to compile.

The nonconformant code we use in in the implementation is:

constexpr bool print(int i, int j) {
    int unused = i << j;
    return true;
}

constexpr auto test = print(10, 34);

10 << 34 will cause an integer overflow which is not allowed, especially in a constant expression. GCC will output the following interesting diagnostic error:

:2:20: error: right operand of shift expression '(10 << 34)' is greater than or equal to the precision 32 of the left operand [-fpermissive]

GCC evaluates the expression i << j and gives a detailed message about the value of i and j. Moreover, the error will recur, even for the same input. Let us all thank GCC for supporting old broken legacy code. With -fpermissive this error becomes a warning and we can continue compiling.

So everything we like to print at compile-time and can be broken down to fundamental types, can be outputted.

Is it undefined behavior? Certainly. Will it format erase your hard drive? Probably not.

Use it only for development and not in production!

Known limitations

Compiler

Since GCC is the only compiler I am aware of with detailed diagnostic warnings to recur, this tool can only work with GCC. Prove me wrong.

Instantiation of static_assert or template parameter

If a CTP statement is used while instantiate an expression triggered by a static_assert or a template parameter, the compilation will fail without a meaningful error message:

:55:19: error: non-constant condition for static assertion
    55 | static_assert(test());
       |               ~~~~^~

Because -fpermissive is a legacy option, it is not fully maintained anymore to work across all compile-time instantiation.

One workaround is to forward the expression to a constexpr variable instantiation:

static_assert(ctp::forward);

Check out this example.

Caching

The result of a constexpr functions could get cached. If this happens, a CTP statement will only be evaluated once. Try to generate additional noise to prevent this. Especially if this happens in unevaluated context. Add additional changing input to the function call as (template) parameter. Also, GCC >=10 added -fconstexpr-cache-depth=8. Maybe a smaller value solves the issue.

Check out this example.

License

BSD-1 LICENSE

You might also like...
On this repo, you'll find every codes I made during my NSI classes (informatical courses)

πŸ‘¨β€πŸ’» πŸ‘©β€πŸ’» school-codes On this repo, you'll find every codes I made during my NSI classes (informatical courses) French for now since this repo is d

PressurePlate is a multi-agent environment that requires agents to cooperate during the traversal of a gridworld.
PressurePlate is a multi-agent environment that requires agents to cooperate during the traversal of a gridworld.

PressurePlate is a multi-agent environment that requires agents to cooperate during the traversal of a gridworld. The grid is partitioned into several rooms, and each room contains a plate and a closed doorway.

Convert three types of color in your clipboard and paste it to the color property (gamma correct)
Convert three types of color in your clipboard and paste it to the color property (gamma correct)

ColorPaster [Blender Addon] Convert three types of color in your clipboard and paste it to the color property (gamma correct) How to Use Hover your mo

Types for the Rasterio package

types-rasterio Types for the rasterio package A work in progress Install Not yet published to PyPI pip install types-rasterio These type definitions

Statistics Calculator module for all types of Stats calculations.

Statistics-Calculator This Calculator user the formulas and methods to find the statistical values listed. Statistics Calculator module for all types

An awesome list of AI for art and design - resources, and popular datasets and how we may apply computer vision tasks to art and design.
An awesome list of AI for art and design - resources, and popular datasets and how we may apply computer vision tasks to art and design.

Awesome AI for Art & Design An awesome list of AI for art and design - resources, and popular datasets and how we may apply computer vision tasks to a

Built with Python programming language and QT library and Guess the number in three easy, medium and hard rolls
Built with Python programming language and QT library and Guess the number in three easy, medium and hard rolls

guess-the-numbers Built with Python programming language and QT library and Guess the number in three easy, medium and hard rolls Number guessing game

Built with Python programming language and QT library and Guess the number in three easy, medium and hard rolls
Built with Python programming language and QT library and Guess the number in three easy, medium and hard rolls

password-generator Built with Python programming language and QT library and Guess the number in three easy, medium and hard rolls Password generator

Cirq is a Python library for writing, manipulating, and optimizing quantum circuits and running them against quantum computers and simulators
Cirq is a Python library for writing, manipulating, and optimizing quantum circuits and running them against quantum computers and simulators

Cirq is a Python library for writing, manipulating, and optimizing quantum circuits and running them against quantum computers and simulators. Install

Comments
  • Add documentation (if possible) on how to integrate CTP C++ code into reStructuredText documents compiled by Sphinx

    Add documentation (if possible) on how to integrate CTP C++ code into reStructuredText documents compiled by Sphinx

    I think I briefly saw somewhere use of this project as a way to include limited C++ snippets that are "run" at text generation time without the need for some meta-level build system nonsense. How does one do this?

    I also can't get the following to work: compile-time-printer -- g++ -std=c++20 -I ../include/ -fsyntax-only -fpermissive examples/compile_time_examples.cpp for https://gitlab.com/anadon/prime_generator_header/-/blob/master/examples/compile_time_examples.cpp

    question 
    opened by anadon 2
  • Support unicode

    Support unicode

    constexpr auto test = ctp::printf(
      "β”Œ{0:─^{2}}┐\n"
      "β”‚{1: ^{2}}β”‚\n"
      "β””{0:─^{2}}β”˜\n", "", "Hello, world!", 20);
    

    Should print:

    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚   Hello, world!    β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
    
    enhancement cpp python 
    opened by Viatorus 0
Releases(1.1.0)
Simplified web browser made in python for a college project

Python browser Simplified web browser made in python for a college project. Web browser has bookmarks, history, multiple tabs, toolbar. It was made on

AmirHossein Mohammadi 9 Jul 25, 2022
Reconhecimento de voz, em portuguΓͺs, com python

Speech_recognizer Reconhecimento de voz, em portuguΓͺs, com python O ato de falar nada mais Γ© que criar vibraΓ§Γ΅es no ar. Por meio de um conversor analΓ³

Marcus VinΓ­cius Ribeiro Andrade 1 Dec 14, 2021
InverterApi - This project has been designed to take monitoring data from Voltronic, Axpert, Mppsolar PIP, Voltacon, Effekta

InverterApi - This project has been designed to take monitoring data from Voltronic, Axpert, Mppsolar PIP, Voltacon, Effekta

Josep Escobar 2 Sep 03, 2022
Data on Free Food at MIT

MIT Free Food Timing Procrastinating research by plotting data on how long it takes emails on the free-food at mit edu mailing list to go through. Dat

Peter Sharpe 2 Nov 01, 2021
LanguageCreator - Simple library for easy creation transpilator.

LanguageCreator - Simple library for easy creation transpilator. Create transpilators in one hour! Install. Download code, rename folder to "LanguageC

Ivan Perzhinsky. 2 Dec 31, 2021
Automated rop chain generation

This is the accompanying code to the blog post talking about automated rop chain generation. Build the test file with: make Install the dependencies:

Christopher Roberts 14 Nov 22, 2022
Just some mtk tool for exploitation, reading/writing flash and doing crazy stuff

Just some mtk tool for exploitation, reading/writing flash and doing crazy stuff. For linux, a patched kernel is needed (see Setup folder) (except for read/write flash). For windows, you need to inst

Bjoern Kerler 1.1k Dec 31, 2022
An early stage integration of Hotwire Turbo with Django

Note: This is not ready for production. APIs likely to change dramatically. Please drop by our Slack channel to discuss!

Hotwire for Django 352 Jan 06, 2023
Bad Apple printed out on the console with Python!

bad-apple Bad Apple printed out on the console with Python! Preface A word of disclaimer, while the final code is somewhat original, this project is a

CalvinLoke 186 Dec 01, 2022
A pairs trade is a market neutral trading strategy enabling traders to profit from virtually any market conditions.

A pairs trade is a market neutral trading strategy enabling traders to profit from virtually any market conditions. This strategy is categorized as a statistical arbitrage and convergence trading str

Kanupriya Anand 13 Nov 27, 2022
Amitkumar Mishra 2 Jan 14, 2022
Tc-python - A Python script to receive message from a twitch chat

Twitch-Chat πŸ“œ I did a script in Python to receive messages from a twitch chat.

miyucode 2 May 31, 2022
Convert your Gyrosco.pe travels to GPX files

gyroscope2gpx This little python joint will do you a favor of taking your "Travel" export from Gyroscope (https://gyrosco.pe) and turn it into a bunch

nick g 4 Oct 02, 2022
Resizing using nnedi3/znedi3/nnedi3cl with center alignment and correct chroma placement

nnedi3_resample A VapourSynth script for easy resizing using nnedi3/znedi3/nnedi3cl with center alignment and correct chroma placement. Requirements n

Home Of VapourSynth Evolution 12 Sep 08, 2022
A blazing fast mass certificate generator script for the community ⚑

A simple mass certificate generator script for the community ⚑ Source Code · Docs · Raw Script Docs All you need Certificate Design a simple template

Tushar Nankani 24 Jan 03, 2023
πŸŒπŸ’‰ Global COVID-19 vaccination data at the regional level.

COVID-19 vaccination data at subnational level. To ensure its officiality, the source data is carefully verified.

sociepy 61 Sep 21, 2022
⚑KiCad library containing footprints and symbols for inductive analog keyboard switches

Inductive Analog Switches This library contains footprints and symbols for inductive analog keyboard switches for use with the Texas Instruments LDC13

Elias SjΓΆgreen 3 Jun 30, 2022
An interactive tool with which to explore the possible imaging performance of candidate ngEHT architectures.

ngEHTexplorer An interactive tool with which to explore the possible imaging performance of candidate ngEHT architectures. Welcome! ngEHTexplorer is a

Avery Broderick 7 Jan 28, 2022
TurtleBot Control App - TurtleBot Control App With Python

TURTLEBOT CONTROL APP INDEX: 1. Introduction 2. Environments 2.1. Simulated Envi

Rafanton 4 Aug 03, 2022
Python script for the radio in the Junior float.

hoco radio 2021 Python script for the radio in the Junior float. Populate the ./music directory with 2 or more .wav files and run radio2.py. On the Ra

Kevin Yu 2 Jan 18, 2022