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!
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
…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
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;
}
Then, the output will be like this!
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);
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 of std::map and std::unordered_map:
Output of std::tuple and std::pair:
Output of std::set and std::unordered_set:
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:
The 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:
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();
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.
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());
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.
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
Manipulator to change the base of integers
Manipulator to display array indices
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...
}
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
Conclusion
I hope this library helps.
And don't forget to give it a GitHub star!
Top comments (1)
Hello Ryota Sasaki,
Welcome to the community! 🎉
We're excited to have you here and look forward to your future contributions. 😊👋🚀