Pretty Printer for Modern C++

Overview

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.

Comments
  • [SOLVED] Printing hex numbers

    [SOLVED] Printing hex numbers

    Tried to define a specific operator for uint to be printed as hex in my client code:

    std::ostream& operator<<(std::ostream& os, const uint64_t& uNum) {
      os << std::hex << uNum << std::dec;
      return os;
    }
    

    But it fails with

    src/ext/pprint/pprint.hpp:526:43: error: ambiguous overload for 'operator<<' (operand types are 'std::basic_ostream<char>' and 'long unsigned int')
      526 |       stream_ << std::string(indent, ' ') << value << line_terminator;
          |       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~
    

    Is there maybe already a way to print integers in hex format?

    opened by pyramid3d 2
  • Doesn't compile when printing std::unordered_set

    Doesn't compile when printing std::unordered_set

    This test case can't compile w/ Apple clang version 11.0.0 or gcc 8.3.0.

    TEST_CASE("Print empty set (line_terminator = '\n', indent = 2)",
    	  "[std::unordered_set]") {
      std::unordered_set<int> foo {};
    
      std::stringstream stream;
      pprint::PrettyPrinter printer(stream);
      printer.print(foo);
    
      const std::string expected = "{}\n";
    
      REQUIRE(stream.str() == expected);
    }
    
    opened by ncihnegn 1
  • Enable CMake release

    Enable CMake release

    1. Include CMakeLists.txt in the archive
    2. Add pprintConfigVersion.cmake
    3. Fix inconsistency: CMake install to <pprint/pprint.hpp>, not <pprint.hpp>.
    opened by ncihnegn 1
  • Add canon support

    Add canon support

    The title says it all...

    Using this lib in corporate invironments requires using packaging instead of copy pasting code due to software clearing... so conan and cmake would be great...

    opened by gocarlos 1
  • Newlines, quotes, escape characters, etc in strings?

    Newlines, quotes, escape characters, etc in strings?

    I'm not sure what's the intended behavior, but this library doesn't seem to do anything special to handle quotes or newlines or other "special" characters within strings.

    int main() {
      pprint::PrettyPrinter printer;
      printer.print("x'x\"x");
      printer.print("x\nx\nx");
    }
    

    It produces just the contents of the string with quotes. Is this intended behavior?

    opened by kccqzy 1
  • CMake fixes

    CMake fixes

    1. use CPack to create source packages: this should make it easy and fast to create a new release. Simply run mkdir build && cd build && cmake .. && make --build . --target package_source. To create the release, cmake copies all files in the source directory except those in the ignore list, which I've created from the .gitignore file. So it is important to keep the source tree clean when doing a source release.
    2. create+install a pprint.pc pkg-config file
    3. optionally use catch2 from the system repositories 4.. only enable install+cpack when pprint is built as a main project
    4. test install + packaging on ci
    5. add appveyor script: sample output: https://ci.appveyor.com/project/madebr/pprint/builds/30827828
    opened by madebr 0
  • conan: conan 'create .' will now build the recipe

    conan: conan 'create .' will now build the recipe

    My previous pr broke conan in that it the version of the conanfile was not set properly. Also, conan build did not work at all.. This is fixed in this pr. It is now possible to create a conan package using:

    conan create .
    
    opened by madebr 0
  • CMake updates + ci

    CMake updates + ci

    • create & install pprintConfigVersion.cmake
    • add .travis.yml file: sample ci result: https://travis-ci.com/madebr/pprint/builds/149076286
    • update conanfile.py
    • enable ctest support
    opened by madebr 0
  • added inline so pprint can be included in multiple translation units …

    added inline so pprint can be included in multiple translation units …

    …of larger codebases

    This allows various header files can include pprint and with no conflict of multiple redefinition. Maybe I missed more, but this fixes it for my needs at the moment.

    opened by JorySchossau 0
  • Fix incorrect setting of INTERFACE_INCLUDE_DIRECTORIES

    Fix incorrect setting of INTERFACE_INCLUDE_DIRECTORIES

    Currently, the INTERFACE_INCLUDE_DIRECTORIES property in pprintConfig.cmake is set as:

    set_target_properties(pprint::pprint PROPERTIES
      INTERFACE_COMPILE_FEATURES "cxx_std_17"
      INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include;/include"
    )
    

    and it causes building error for some users: https://github.com/microsoft/vcpkg/issues/7301 .

    opened by myd7349 0
  • Enable warnings as errors in tests and fix warning

    Enable warnings as errors in tests and fix warning

    Great library, I have warnings as errors which I'd like to not exempt dependencies from. I think this helps improve the quality of this project. Thanks.

    opened by wrayste 0
  • Compiling with structopt fails

    Compiling with structopt fails

    It seems like including both <pprint.hpp> and <structopt/structopt.hpp> will lead to conflicts, as magic_enum gets redefined. Is there a standard way to use both pprint and structopt or am I missing something obvious?

    opened by GaniAliguzhinov 1
Owner
Pranav
Pranav
The lightweight and modern Map SDK for Android and iOS

Open Mobile Maps The lightweight and modern Map SDK for Android (6.0+) and iOS (10+) openmobilemaps.io Getting started Readme Android Readme iOS Featu

Open Mobile Maps 95 Dec 23, 2022
An attempt to restore and adapt to modern Win10 version the Rootkit Arsenal original code samples

rootkit-arsenal-guacamole An attempt to restore and adapt to modern Win10 version the Rootkit Arsenal original code samples All projects have been por

Matteo Malvica 51 Nov 6, 2022
A Template Engine for Modern C++

Inja is a template engine for modern C++, loosely inspired by jinja for python. It has an easy and yet powerful template syntax with all variables, lo

pantor 1.2k Jan 8, 2023
Mustache text templates for modern C++

About Mustache implementation for modern C++ (requires C++11) Header only Zero dependencies Templated string type for compatibility with any STL-like

Kevin Wojniak 307 Dec 11, 2022
The C++ REST SDK is a Microsoft project for cloud-based client-server communication in native code using a modern asynchronous C++ API design. This project aims to help C++ developers connect to and interact with services.

The C++ REST SDK is a Microsoft project for cloud-based client-server communication in native code using a modern asynchronous C++ API design. This project aims to help C++ developers connect to and interact with services.

Microsoft 7.2k Jan 2, 2023
LibOS is a modern C++17 library that makes OS-specific features cross-platform.

LibOS is a modern C++17 library that makes OS-specific features cross-platform. Ever tried to get Windows version after Windows 8? Or to send ke

Gavrilikhin Daniil 27 Sep 13, 2022
A compile-time enabled Modern C++ library that provides compile-time dimensional analysis and unit/quantity manipulation.

mp-units - A Units Library for C++ The mp-units library is the subject of ISO standardization for C++23/26. More on this can be found in ISO C++ paper

Mateusz Pusz 679 Dec 29, 2022
The most powerful and customizable binary pattern scanner written on modern C++

Sig The most powerful and customizable binary pattern scanner written on modern C++ ✔ Capabilities: Support for all common pattern formats: Pattern +

Александр 153 Dec 21, 2022
Pretty Printer for Modern C++

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 p

Pranav 879 Dec 22, 2022
A beautiful stack trace pretty printer for C++

Backward-cpp Backward is a beautiful stack trace pretty printer for C++. If you are bored to see this: Backward will spice it up for you: There is not

François-Xavier Bourlet 2.8k Jan 4, 2023
NeoGB Printer an SD card-based standalone Game Boy Printer emulator.

An open-source and standalone Gameboy Printer emulator 100% compatible with all officially released games (110 in total) that support the accessory. Just print and save the images as BMP

Rafael Zenaro 85 Dec 22, 2022
A Game Boy Printer emulator that supports the Phomemo T02 printer

ESP32 + Phomemo T02 Game Boy Printer This project lets you print Game Boy Printer images via Bluetooth using a Phomemo T02 thermal printer and an ESP3

Jack Gaino 11 Aug 25, 2022
A header-only library for C++(0x) that allows automagic pretty-printing of any container.

cxx-prettyprint =============== A pretty printing library for C++ containers. Synopsis: Simply by including this header-only library in your sourc

Louis Delacroix 535 Nov 26, 2022
Juice the carrots from ウマ娘プリティーダービー (Umamusume Pretty Derby) - Android implementation

Riru-CarrotJuicer Hooks the decryption function in libnative.so of ウマ娘プリティーダービー (Umamusume Pretty Derby), to allow inspecting the packets. For Windows

Huang Yue 27 Aug 9, 2022
Localify "ウマ娘: Pretty Derby" DMM client

中文 赛马娘 (DMM版) 本地化补丁 使用方法: 将 version.dll 和 config.json 以及 config.json 中引用的字典放置于 umamusume.exe 边上 启动游戏 设置选项: enableConsole 启用用来输出调试信息的控制台 (true/false) e

GEEKiDoS 218 Dec 30, 2022
Juice the carrots from ウマ娘プリティーダービー (Umamusume Pretty Derby) - Windows implementation

Hooks the decryption function in libnative.dll of ウマ娘プリティーダービー (Umamusume Pretty Derby), to allow inspecting the packets (and provide some useful information during the game).

Huang Yue 81 Dec 16, 2022
Pretty much the repo name sums it up.

?? Console_Calculator Version Supported Date Ended Support v.1.0 ✔️ ?? Features The ?? Console_Calculator can do basic arithmatic, and yes there is no

Angelo Petrai 3 Dec 31, 2021
This project is pretty straightforward, you have to recode printf. You will learn what is and how to implement variadic functions. Once you validate it, you will reuse this function in your future projects.

100/100 Introduction to ft_printf This is the third project in the 1337 Curriculum #42network . This project is pretty straight forward, recode the pr

Zakaria Yacoubi 4 May 27, 2022
its a pretty dodo 0.1% os

Dodo OS why did i make this os? idk im bored and i wanted to learn alot of new stuff. so i decided to make dodo os. i will see for how far i will go i

Voidy Devleoper 5 Jan 4, 2022
Generate code for pretty-printing C++ enums

enums Generate code for pretty-printing C++ enums. Supported platforms Only Linux x86/x86_64 systems are supported. For the missing platforms, the too

Andrei Burdulescu 0 Jan 31, 2022