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
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
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;
}
Then, the output will look 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.
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_SET_OPTION(log_label_func, cp::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_EXPORT_OBJECT_GENERIC(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 omit part of a container
Manipulator to show indexes of an array
Manipulator to change the numerical base
Manipulator to escape strings
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...
}
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
or
clang++ ./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. 😊👋🚀