DEV Community

Ryota Sasaki
Ryota Sasaki

Posted on • Updated on

I Made a C++ Version of Python print() Function

I like Python's print(obj...) since it can print variables of any type: numbers, strings, arrays, and objects, and is helpful for debugging.
I have been doing competitive programming recently, but the function helps me debug there, too.

But C++ doesn't have a function like this.
C++ is fast and suited for competitive programming, but every time you want to print a vector for debugging, you have to write a long code like for(int i = 0; i < N; ++i) std::cout << a[i] << std::endl;. Competitive programming is a race against time, so I want to avoid that.

Then why not make a C++ version of print(obj...) myself?
So I made one (with much effort)!

Table of Contents

 1. Let's try it first!
 2. How to Use?
 3. 7 (or more) Features of the cpp-dump Library

       3.1. 1. Python-Like String Representation

       3.2. 2. Auto Indent

       3.3. 3. Filename and line Can Be Printed Instead of [dump]

       3.4. 4. A Wide Range of Other Supported Types

       3.5. 5. User Types Can Also Be Printed

       3.6. 6. Customizable Output Colors

       3.7. 7-. Other Customizable and Useful Features

 4. For Competitive Programming Use
 5. Conclusion

Let's try it first!

GitHub logo philip82148 / cpp-dump

A C++ library for debugging purposes that can print any variable, even user-defined types.

cpp-dump

日本語記事はこちら!
I Made a C++ Version of Python print() Function (DEV article)

Overview

cpp-dump is a C++ library for debugging purposes that can print any variable, including user types.

This library has the following features:

  • Prints string representations of a wide variety of types to the standard error output (std::clog). This includes multidimensional arrays, (multi)maps, and (multi)sets, and even complex numbers, error objects, etc.
  • Automatically indents so that the output fits into the maximum line width.
  • Customizable output color.
  • The file name, line, and function name can also be attached to the log output.
  • Header-only library, no build or dependencies required.
  • Can print even user-defined types by using macros or defining operators.
  • The string representation of variables is similar to JavaScript, Python, and C++ syntax.

Introduction

You can print variables of a wide variety of types by passing them to the cpp_dump(expressions...) macro.
See Full Example Code

std::vector<std::vector<int
Enter fullscreen mode Exit fullscreen mode

First, let's run this command in the terminal.
(If you can't use the git command, download and unzip the source folder in Releases instead.)
git clone https://github.com/philip82148/cpp-dump
Enter fullscreen mode Exit fullscreen mode

Next, let's copy and paste this code and run it.

#include <bitset>
#include <complex>
#include <map>
#include <optional>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <utility>
#include <variant>
#include <vector>

#include "./cpp-dump/dump.hpp"

int main() {
  int my_int = 15;
  int *ptr = &my_int;
  void *void_ptr = &my_int;
  std::vector<std::vector<int>> my_vector{{3, 5, 8, 9, 7}, {9, 3, 2, 3, 8}};
  std::set<char> my_set{'A', 'p', 'p', 'l', 'e'};
  std::map<int, int> my_map{{2, 6}, {4, 6}, {5, 3}};
  std::multiset<char> my_multiset{'A', 'p', 'p', 'l', 'e'};
  std::multimap<int, int> my_multimap{{2, 4}, {4, 6}, {5, 3}, {4, 7}};
  std::pair<int, char> my_pair{8, 'a'};
  std::tuple<int, double, std::string> my_tuple{7, 4.5, "This is a string."};
  std::queue<int> my_queue;
  std::priority_queue<int> my_priority_queue;
  std::stack<int> my_stack;
  for (auto v : {1, 2, 3, 4, 5}) my_queue.push(v), my_priority_queue.push(v), my_stack.push(v);
  std::bitset<8> my_bitset(0x3a);
  std::complex<double> my_complex{1.0, 1.0};
  std::optional<int> my_optional{15};
  std::variant<int, std::string> my_variant{"1"};
  std::vector<std::pair<int, std::string>> vector_of_pairs{{1, "apple"}, {3, "banana"}};

  std::clog << "\n// Basic Type" << std::endl;
  cpp_dump(false, 0, 0.0, '0'), cpp_dump(true, 3.14, my_int, 9265);
  cpp_dump("This is a string."), cpp_dump(ptr, void_ptr, nullptr);

  std::clog << "\n// Container" << std::endl;
  cpp_dump(my_vector);

  std::clog << "\n// Set/Map" << std::endl;
  cpp_dump(my_set), cpp_dump(my_map);

  std::clog << "\n// Multiset/Multimap" << std::endl;
  cpp_dump(my_multiset), cpp_dump(my_multimap);

  std::clog << "\n// Tuple" << std::endl;
  cpp_dump(my_tuple), cpp_dump(my_pair);

  std::clog << "\n// FIFO/LIFO" << std::endl;
  cpp_dump(my_queue), cpp_dump(my_priority_queue), cpp_dump(my_stack);

  std::clog << "\n// Other" << std::endl;
  cpp_dump(my_bitset), cpp_dump(my_complex);
  cpp_dump(my_optional, std::nullopt), cpp_dump(my_variant);

  std::clog << "\n// Combination" << std::endl;
  cpp_dump(vector_of_pairs);

  std::clog << std::endl;
}
Enter fullscreen mode Exit fullscreen mode

Then, the output will be like this!
https://github.com/philip82148/cpp-dump/raw/main/readme/supports-various-types.png

How to Use?

You can print various variables by passing them to the cpp_dump(exprs...) macro!

Code:

// In main() or some function
std::vector<std::vector<int>> my_vector{{3, 5, 8, 9, 7}, {9, 3, 2, 3, 8}};
cpp_dump(my_vector);
Enter fullscreen mode Exit fullscreen mode

Output:
Output Example

7 (or more) Features of the cpp-dump Library

1. Python-Like String Representation

Like Python's print(), cpp-dump prints variables in a Python-like string representation.
Note: The examples are printed with the macro version.

Output of Iterables Like std::vector, std::array, C-style arrays:

Output Example

Output of std::map and std::unordered_map:

Output Example

Output of std::tuple and std::pair:

Output Example

Output of std::set and std::unordered_set:

Output Example

2. Auto Indent

If the content of a variable is large, cpp-dump automatically indents so that the output fits into the maximum line width.

Output of Iterables Like std::vector, std::array, C-style arrays:

Output ExampleThe output of std::tuple, std::pair, std::set, and std::unordered_set is also indented in the same way.

Output of std::map and std::unordered_map:

Output Example

3. Filename and line Can Be Printed Instead of [dump]

You can print the filename and the line instead of [dump], by using the following code.

cpp_dump::log_label_func = cpp_dump::log_label::filename();
Enter fullscreen mode Exit fullscreen mode

customize dump

4. A Wide Range of Other Supported Types

cpp-dump supports various other types like std::multimap, std::queue, std::complex, etc!
See the README in the repo for all supported types.

https://github.com/philip82148/cpp-dump/raw/main/readme/supports-various-types.png

5. User Types Can Also Be Printed

By using macros or defining operators, you can enable cpp-dump to print user-defined types!
See the README in the repo for details.

CPP_DUMP_DEFINE_DANGEROUS_EXPORT_OBJECT(i, str());
Enter fullscreen mode Exit fullscreen mode

user-defined

6. Customizable Output Colors

You can customize the colors of the output of cpp-dump!
The following image is an example.
See the README in the repo for details.
https://github.com/philip82148/cpp-dump/raw/main/readme/customizable-colors.png

7-. Other Customizable and Useful Features

In addition to the features above, there are some other customizable and useful features; for example, there are manipulators that change the display method!
See the README in the repo for details.

Manipulator to set which and how many elements of an array will be displayed

manipulators.png

Manipulator to change the base of integers

int-style.png

Manipulator to display array indices

cont-index

For Competitive Programming Use

cpp_dump(vars...) is long, so let's shorten it to dump(vars...) by macro.
Also, let's write like the following to remove dump(vars...) when submitting the code.

#ifdef DEFINED_ONLY_IN_LOCAL
#include "./cpp-dump/dump.hpp"
#define dump(...) cpp_dump(__VA_ARGS__)
namespace cp = cpp_dump;
#else
#define dump(...)
#define CPP_DUMP_SET_OPTION(...)
#define CPP_DUMP_DEFINE_EXPORT_OBJECT(...)
#define CPP_DUMP_DEFINE_EXPORT_ENUM(...)
#define CPP_DUMP_DEFINE_DANGEROUS_EXPORT_OBJECT(...)
#endif

#include <bits/stdc++.h>

#define rep(i, n) for (int i = 0; i < (int)(n); ++i)

using namespace std;

int main() {
  CPP_DUMP_SET_OPTION(max_line_width, 80);
  CPP_DUMP_SET_OPTION(log_label_func, cp::log_label::filename());
  CPP_DUMP_SET_OPTION(enable_asterisk, true);

  int N;
  cin >> N;

  vector<int> X(N);
  rep(i, N) { cin >> X[i]; }
  dump(X);

  // To be continued...
}
Enter fullscreen mode Exit fullscreen mode

Then, when compiling the source locally, the dump() macro will only work locally by running the following command!

g++ ./main.cpp -D DEFINED_ONLY_IN_LOCAL
Enter fullscreen mode Exit fullscreen mode

Conclusion

I hope this library helps.
And don't forget to give it a GitHub star!

Top comments (1)

Collapse
 
phylis profile image
Phylis Jepchumba

Hello Ryota Sasaki,

Welcome to the community! 🎉
We're excited to have you here and look forward to your future contributions. 😊👋🚀