DEV Community

Ryota Sasaki
Ryota Sasaki

Posted on • Edited on

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

cpp-dump.gif

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

cpp-dump.gif
This is an animated GIF.

cpp-dump is a C++ library for printing variables of any type for debugging.

Python has print(), JavaScript has console.log(), and PHP has var_dump() — functions that print variables of any type and are useful for debugging when you want a quick way to inspect variables. But what about C++? Enter cpp_dump(...). cpp-dump is a library that automatically formats and prints variables of any type. With features like auto-indentation, colored output, string representations similar to JavaScript, Python, and C++, and over 20 manipulators, cpp-dump is equipped with everything you need to effortlessly and clearly print variables.

Key points:

  • cpp-dump can print a wide variety of types, including multi-D vectors, (multi)maps, (multi)sets, and tuples.
  • cpp-dump has an auto-indentation feature. The output fits into the maximum line width, and nested containers are formatted for readability.
  • The string representation of variables is similar to JavaScript…

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

Next, 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/cpp-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 look 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.

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_SET_OPTION(log_label_func, cp::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_EXPORT_OBJECT_GENERIC(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 omit part of a container

manipulator-front-etc.png

Manipulator to show indexes of an array

manipulator-index.png

Manipulator to change the numerical base

manipulator-ubin-etc.png

Manipulator to escape strings

manipulator-stresc.png

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/cpp-dump.hpp"
#define dump(...) cpp_dump(__VA_ARGS__)
namespace cp = cpp_dump;
CPP_DUMP_SET_OPTION_GLOBAL(max_line_width, 80);
CPP_DUMP_SET_OPTION_GLOBAL(log_label_func, cp::log_label::filename());
CPP_DUMP_SET_OPTION_GLOBAL(enable_asterisk, true);
#else
#define dump(...)
#define CPP_DUMP_SET_OPTION(...)
#define CPP_DUMP_DEFINE_EXPORT_OBJECT(...)
#define CPP_DUMP_DEFINE_EXPORT_ENUM(...)
#define CPP_DUMP_DEFINE_EXPORT_OBJECT_GENERIC(...)
#endif

#include <bits/stdc++.h>

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

using namespace std;

int main() {
  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

or

clang++ ./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, MSc

Hello Ryota Sasaki,

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