• This repository has been archived on 14/Dec/2021
  • Stars
    star
    907
  • Rank 48,350 (Top 1.0 %)
  • Language
    C++
  • License
    MIT License
  • Created about 5 years ago
  • Updated about 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Pretty Printer for Modern C++

pprint

Highlights

  • Single header file
  • Requires C++17
  • MIT License

Quick Start

Simply include pprint.hpp and you're good to go.

#include <pprint.hpp>

To start printing, create a PrettyPrinter

pprint::PrettyPrinter printer;

You can construct a PrettyPrinter with any stream that inherits from std::ostream , e.g, std::stringstream

std::stringstream stream;
pprint::PrettyPrinter printer(stream);

Fundamental Types

printer.print(5);
printer.print(3.14f);
printer.print(2.718);
printer.print(true);
printer.print('x');
printer.print("Hello, ไธ–็•Œ");
printer.print(nullptr);
5
3.14f
2.718
true
x
Hello, ไธ–็•Œ
nullptr

Strings

Maybe you want your strings to be quoted? Simply set printer.quotes(true)

printer.quotes(true);
printer.print("A", "B", "C");
"A" "B" "C"

Complex Numbers

using namespace std::complex_literals;
std::complex<double> foo = 1. + 2.5i;
std::complex<double> bar = 9. + 4i;
printer.print(foo, "*", bar, "=", (foo * bar));   // parameter packing
(1 + 2.5i) * (9 + 4i) = (-1 + 26.5i)

Enumeration Types

enum Color { RED = 2, BLUE = 4, GREEN = 8 };
Color color = BLUE;
printer.print(color);
4

If you compile with

  • Clang/LLVM >= 5
  • Visual C++ >= 15.3 / Visual Studio >= 2017
  • Xcode >= 10.2
  • GCC >= 9

then pprint will print the name of the enum for you (thanks to magic_enum)

enum Level { LOW, MEDIUM, HIGH };
Level current_level = MEDIUM;
std::cout << "Current level: ";
printer.print(current_level);
Current level: MEDIUM

STL Sequence Containers

pprint supports a variety of STL sequence containers including std::vector, std::list, std::deque, and std::array.

Here's an example pretty print of a simple 3x3 matrix:

typedef std::array<std::array<int, 3>, 3> Mat3x3;
Mat3x3 matrix;
matrix[0] = {1, 2, 3};
matrix[1] = {4, 5, 6};
matrix[2] = {7, 8, 9};
printer.print("Matrix =", matrix);
Matrix = [
  [1, 2, 3], 
  [4, 5, 6], 
  [7, 8, 9]
]

Compact Printing

pprint also supports compact printing of containers. Simply call printer.compact(true) to enable this:

std::vector<std::map<std::string, int>> foo {{{"a", 1}, {"b", 2}}, {{"c", 3}, {"d", 4}}};
printer.compact(true);
printer.print("Foo =", foo);
Foo = [{a : 1, b : 2}, {c : 3, d : 4}]

STL Associative Containers

Support for associative containers includes pretty printing of std::map, std::multimap, std::unordered_map, std::unordered_multimap, std::set, std::multiset, std::unordered_set and , std::unordered_multiset

printer.print(std::map<std::string, std::set<int>>{ 
    {"foo", {1, 2, 3, 3, 2, 1}}, {"bar", {7, 6, 5, 4}}});
{
  "bar" : {4, 5, 6, 7}, 
  "foo" : {1, 2, 3}
}

STL Container Adaptors

pprint can print container adaptors including std::queue, std::priority_queue and std::stack. Here's an example print of a priority queue:

std::priority_queue<int> queue;
for(int n : {1,8,5,6,3,4,0,9,7,2}) queue.push(n);
printer.print(queue);
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

Fixed-size Heterogeneous Tuples

auto get_student = [](int id) {
  if (id == 0) return std::make_tuple(3.8, 'A', "Lisa Simpson");
  if (id == 1) return std::make_tuple(2.9, 'C', "Milhouse Van Houten");
  if (id == 2) return std::make_tuple(1.7, 'D', "Ralph Wiggum");
  throw std::invalid_argument("id");
};
printer.print({ get_student(0), get_student(1), get_student(2) });
{(1.7, 'D', "Ralph Wiggum"), (2.9, 'C', "Milhouse Van Houten"), (3.8, 'A', "Lisa Simpson")}

Type-safe Unions

// Construct a vector of values
std::vector<std::variant<bool, int, int *, float, std::string, std::vector<int>,		      
       std::map<std::string, std::map<std::string, int>>, 
       std::pair<double, double>>> var;
var.push_back(5);
var.push_back(nullptr);
var.push_back(3.14f);
var.push_back(std::string{"Hello World"});
var.push_back(std::vector<int>{1, 2, 3, 4});
var.push_back(std::map<std::string, std::map<std::string, int>>{{"a",{{"b",1}}}, {"c",{{"d",2}, {"e",3}}}});
var.push_back(true);
var.push_back(std::pair<double, double>{1.1, 2.2});

// Print the vector
pprint::PrettyPrinter printer;
printer.indent(2);
printer.quotes(true);
printer.print(var);
[
  5, 
  nullptr,
  3.14f, 
  "Hello World", 
  [1, 2, 3, 4], 
  {"a" : {"b" : 1}, "c" : {"d" : 2, "e" : 3}}, 
  true, 
  (1.1, 2.2)
]

Optional Values

std::optional<int> opt = 5;
std::optional<int> opt2;

printer.print(opt);
printer.print(opt2);
5
nullopt

Class Objects

pprint print class objects with or without an overloaded << operator

class Foo {};
Foo foo;
printer.print(foo);
<Object main::Foo>

If an << operator is available, pprint will use it to print your object:

class Date {
  unsigned int month, day, year;
public:
  Date(unsigned int m, unsigned int d, unsigned int y) : month(m), day(d), year(y) {}
  friend std::ostream& operator<<(std::ostream& os, const Date& dt);
};

    
std::ostream& operator<<(std::ostream& os, const Date& dt) {
  os << dt.month << '/' << dt.day << '/' << dt.year;
  return os;
}
Date date(04, 07, 2019);
printer.print("Today's date is", date);
Today's date is 4/7/2019

User-defined types

Here's an example to print user-defined types. Let's say you want to print Mesh objects

struct Vector3 {
  float x, y, z;
};

struct Mesh {
  std::vector<Vector3> vertices;
};

First, overload the << operator for these structs:

std::ostream& operator<<(std::ostream& os, const Vector3& v) {
  pprint::PrettyPrinter printer(os);
  printer.print_inline(std::make_tuple(v.x, v.y, v.z));
  return os;
}

std::ostream& operator<<(std::ostream& os, const Mesh& mesh) {
  pprint::PrettyPrinter printer(os);
  printer.print("Mesh {");
  printer.indent(2);
  printer.print_inline("vertices:", mesh.vertices);
  printer.print("}");
  return os;
}

then simply call printer.print(Mesh)

Mesh quads = {{
  {0, 0, 0}, {1, 0, 0}, {1, 1, 0}, {0, 0, 0}, {1, 1, 0}, {0, 1, 0},
  {0, 0, 1}, {1, 0, 1}, {1, 1, 1}, {0, 0, 1}, {1, 1, 1}, {0, 1, 1},
  }};

pprint::PrettyPrinter printer;
printer.print(quads);
Mesh {
  vertices: [
      (0, 0, 0), 
      (1, 0, 0), 
      (1, 1, 0), 
      (0, 0, 0), 
      (1, 1, 0), 
      (0, 1, 0), 
      (0, 0, 1), 
      (1, 0, 1), 
      (1, 1, 1), 
      (0, 0, 1), 
      (1, 1, 1), 
      (0, 1, 1)
  ]
}

License

The project is available under the MIT license.

More Repositories

1

awesome-hpp

A curated list of awesome header-only C++ libraries
3,057
star
2

indicators

Activity Indicators for Modern C++
C++
2,736
star
3

argparse

Argument Parser for Modern C++
C++
2,224
star
4

tabulate

Table Maker for Modern C++
C++
1,726
star
5

csv2

Fast CSV parser and writer for Modern C++
C++
497
star
6

structopt

Parse command line arguments by defining a struct
C++
451
star
7

alpaca

Serialization library written in C++17 - Pack C++ structs into a compact byte-array without any macros or boilerplate code
C++
399
star
8

fccf

fccf: A command-line tool that quickly searches through C/C++ source code in a directory based on a search string and prints relevant code snippets that match the query.
C++
342
star
9

csv

[DEPRECATED] See https://github.com/p-ranav/csv2
C++
233
star
10

glob

Glob for C++17
C++
221
star
11

binary_log

Fast binary logger for C++
C++
207
star
12

criterion

Microbenchmarking for Modern C++
C++
202
star
13

hypergrep

Recursively search directories for a regex pattern
C++
158
star
14

saveddit

Bulk Downloader for Reddit
Python
156
star
15

PhotoLab

AI-Powered Photo Editor (Python, PyQt6, PyTorch)
Python
123
star
16

box

box is a text-based visual programming language inspired by Unreal Engine Blueprint function graphs.
Python
116
star
17

cppgit2

Git for Modern C++ (A libgit2 Wrapper Library)
C++
106
star
18

repr

repr for Modern C++: Return printable string representation of a value
C++
83
star
19

psched

Priority-based Task Scheduling for Modern C++
C++
80
star
20

fswatch

File/Directory Watcher for Modern C++
C++
70
star
21

envy

envy: Deserialize environment variables into type-safe structs
C++
66
star
22

iris

Lightweight Component Model and Messaging Framework based on ร˜MQ
C++
53
star
23

merged_depth

Monocular Depth Estimation - Weighted-average prediction from multiple pre-trained depth estimation models
Python
45
star
24

pipeline

Pipelines for Modern C++
C++
42
star
25

unicode_display_width

Displayed width of UTF-8 strings in Modern C++
C++
38
star
26

task_system

Task System presented in "Better Code: Concurrency - Sean Parent"
C++
38
star
27

cgol

Conway's Game of Life in the Terminal
C++
33
star
28

jsonlint

Lightweight command-line tool for validating JSON
C++
32
star
29

small_vector

"Small Vector" optimization for Modern C++: store up to a small number of items on the stack
C++
31
star
30

result

Result<T, E> for Modern C++
C++
29
star
31

container_traits

Container Traits for Modern C++
C++
24
star
32

lexer

Hackable Lexer with UTF-8 support
C++
21
star
33

lc

Fast multi-threaded line counter in Modern C++ (2-10x faster than `wc -l` for large files)
C++
17
star
34

oystr

oystr recursively searches directories for a substring.
C++
10
star
35

walnut.v1

The Walnut programming language
C++
8
star
36

line-detector

OpenCV-based Hough Transform Line Detection
C++
8
star
37

ttt

Terminal Typing Test
C++
6
star
38

wxPython-text-editor

wxPython Text Editor
Python
6
star
39

Vulkan-Earth

Vulkan-based 3D Rendering of Earth
HTML
6
star
40

DiverseDepth

The code and data of DiverseDepth
Python
6
star
41

strcpp.old

String Manipulation API for C++
C++
5
star
42

OpenGL-Engine

OpenGL 3D Rendering Engine
C++
5
star
43

zcm

A Lightweight Component Model using ZeroMQ
C++
4
star
44

any_of_trait

Type traits for any_of and any_but
C++
4
star
45

StaticAnalysis

GitHub action for C++ static analysis
Python
4
star
46

ImageViewer-Qt6

Minimalist image viewer in Qt6
C++
3
star
47

krpci

C++ client to kRPC for communication with Kerbal Space Program (KSP)
C++
2
star
48

activity-plotter

Linux Scheduler Thread Activity Plotter
Python
2
star
49

video_device_discovery

Find all video devices connected to Linux-based embedded platform
C++
2
star
50

python-zcm

ZeroMQ-based Component Model in Python
Python
2
star
51

emacs_config

Emacs configuration
Emacs Lisp
1
star
52

plexil-analysis

Timing Analysis for the Plan Interchange Language (Plexil)
Python
1
star
53

object-tracker

OpenCV-based Real-time Object Tracking
C++
1
star
54

json.old

JSON Manipulation Library for C++
C++
1
star
55

phd-dissertation

TeX
1
star
56

OpenGL-Engine-II

OpenGL 3D Rendering Engine II - Alternate Architecture
C++
1
star
57

arangit

Python program that can scan a .git folder and reconstruct a git version control property graph in ArangoDB
Python
1
star
58

ros-installer

Script to install ROS Indigo from source
Python
1
star