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)
A simple website-based resource monitor for slurm system.

Slurm Web A simple website-based resource monitor for slurm system. Screenshot Required python packages flask, colored, humanize, humanfriendly, beart

Tengda Han 17 Nov 29, 2022
Create beautiful diagrams just by typing mathematical notation in plain text.

Penrose Penrose is an early-stage system that is still in development. Our system is not ready for contributions or public use yet, but hopefully will

Penrose 5.6k Jan 08, 2023
Check if Python package names are available on PyPI.

😻 isavailable Can I haz this Python package on PyPI? Check if Python package names are available on PyPI. Usage $ isavailable checks whether your des

Felipe S. S. Schneider 3 May 18, 2022
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

EDM 1.15 3 Dec 17, 2022
This program can calculate the Aerial Distance between two cities.

Aerial_Distance_Calculator This program can calculate the Aerial Distance between two cities. This repository include both Jupyter notebook and Python

InvisiblePro 1 Apr 08, 2022
Render to print for blender 2.9+

render_to_print_blender_addon ** render2print: Blender AddOn for Blender 2.90.0+ ** Calculates camera parameters to allow printing a rendered image to

5 Nov 19, 2021
The program calculates the BMI of people

Programmieren Einleitung: Das Programm berechnet den BMI von Menschen. Es ist sehr einfach zu handhaben, so kΓΆnnen alle Menschen ihren BMI berechnen.

2 Dec 16, 2021
A compiler for ARM, X86, MSP430, xtensa and more implemented in pure Python

A compiler for ARM, X86, MSP430, xtensa and more implemented in pure Python

Windel Bouwman 277 Dec 26, 2022
A minimalist starknet amm adapted from StarkWare's amm.

viscus β€’ A minimalist starknet amm adapted from StarkWare's amm. Directory Structure contracts

Alucard 4 Dec 27, 2021
A self contained invitation management system for gatekeeping.

Invitease Description A self contained invitation management system for gatekeeping. Purpose Serves as a focal point for inviting guests to a venue pr

ΧžΧ’Χ’ΧŸ ΧžΧ™Χ›ΧΧœ 7 Jul 19, 2022
My collection of mini-projects in various languages

Mini-Projects My collection of mini-projects in various languages About: This repository consists of a number of small projects. Most of these "mini-p

Siddhant Attavar 1 Jul 11, 2022
Install JetBrains Toolbox

ansible-role-jetbrains-toolbox Install JetBrains Toolbox Example Playbook This example is taken from molecule/default/converge.yml and is tested on ea

Antoine Mace 2 Feb 04, 2022
Chemical Analysis Calculator, with full solution display.

Chemicology Chemical Analysis Calculator, to solve problems efficiently by displaying whole solution. Go to releases for downloading .exe, .dmg, Linux

Muhammad Moazzam 2 Aug 06, 2022
Flexible constructor to create dynamic list of heterogeneous properties for some kind of entity

Flexible constructor to create dynamic list of heterogeneous properties for some kind of entity. This set of helpers useful to create properties like contacts or attributes for describe car/computer/

Django Stars 24 Jul 21, 2022
Store Simulation

Almacenes Para clonar el Repositorio: Vaya a la terminal de Linux o Mac, o a la cmd en Windows y ejecute:

Johan Posada 1 Nov 12, 2021
Hands-on machine learning workshop

emb-ntua-workshop This workshop discusses introductory concepts of machine learning and data mining following a hands-on approach using popular tools

ISSEL Soft Eng Team 12 Oct 30, 2022
An app about keyboards, originating from the design of u/Sonnenschirm

keebapp-backend An app about keyboards, originating from the design of u/Sonnenschirm Setup Firstly, ensure that the environment for python is install

8 Sep 04, 2022
My tools box script for sigma

sigma_python_toolbox My tools box script for sigma purpose My goal is not to replace sigma but to put at disposal the scripts that I think to help me

4 Jun 20, 2022
Project Faros is a reference implimentation of Red Hat OpenShift 4 on small footprint, bare-metal clusters.

Project Faros Project Faros is a reference implimentation of Red Hat OpenShift 4 on small footprint, bare-metal clusters. The project includes referen

project: Faros 9 Jul 18, 2022
Reproduction repository for the MDX 2021 Hybrid Demucs model

Submission This is the submission for MDX 2021 Track A, for Track B go to the track_b branch. Submission Summary Submission ID: 151378 Submitter: defo

Alexandre DΓ©fossez 62 Dec 18, 2022