C++ アルゴリズムとデータ構造のライブラリ
#define PROBLEM \
"https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ITP1_1_A"
#include <bits/stdc++.h>
using namespace std;
#include "template/debug.hpp"
/**
* @brief debugのテスト
*/
int main() {
cout << "Hello World" << endl;
int a = 1ll;
char c = 'c';
string S = "sss";
pair<int, string> p = {a, S};
tuple<int, char, string> t = {a, c, S};
vector<int> A = {a};
vector<vector<string>> G = {{S, S}, {S, S}};
debug(a);
debug(c);
debug(S);
debug(p);
debug(t);
debug(A);
debug(G);
}#line 1 "tests/template.debug.test.cpp"
#define PROBLEM \
"https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ITP1_1_A"
#include <bits/stdc++.h>
using namespace std;
#line 2 "template/debug.hpp"
#include <cxxabi.h>
#line 8 "template/debug.hpp"
using std::cerr;
using std::deque;
using std::map;
using std::multiset;
using std::pair;
using std::priority_queue;
using std::queue;
using std::set;
using std::stack;
using std::string;
using std::tuple;
using std::vector;
// =====================================
// 区切り文字系
// =====================================
// array: インデックスで要素にアクセスできる系
inline void _print_a_start() {
cerr << "\033[32m"
<< "["
<< "\033[m";
}
inline void _print_a_end() {
cerr << "\033[32m"
<< "]"
<< "\033[m";
}
// brucet: その他の集合
inline void _print_b_start() {
cerr << "\033[32m"
<< "{"
<< "\033[m";
}
inline void _print_b_end() {
cerr << "\033[32m"
<< "}"
<< "\033[m";
}
// parentheses: タプル系
inline void _print_p_start() {
cerr << "\033[32m"
<< "("
<< "\033[m";
}
inline void _print_p_end() {
cerr << "\033[32m"
<< ")"
<< "\033[m";
}
// カンマ、改行
inline void _print_sep() {
cerr << "\033[32m"
<< ","
<< "\033[m";
}
inline void _print_LF() { cerr << "\n"; }
const int DEBUG_LIMIT_LOOP = 20;
// =====================================
// 型が入れ子になっているか判定
// =====================================
template <typename T> bool _is_nested(const T &v, int f = 3) {
// 型名をデマングルする
int res;
char *r = abi::__cxa_demangle(typeid(v).name(), nullptr, nullptr, &res);
if (res != 0) {
cerr << "demangle error"
<< "\n";
free(r);
return false;
}
string tmp = r;
free(r);
// stdうんたらを消す
const string prefix = "std::__1::";
const int presz = prefix.size();
auto p = tmp.find(prefix);
while (p != string::npos) {
tmp.erase(p, presz);
p = tmp.find(prefix, p + 1);
}
// stringはbasic_string<char ...
if (tmp == "basic_string<") {
tmp = "string";
}
int cnt = 0;
for (auto &&ch : tmp) {
if (ch == '<') ++cnt;
}
// 閾値fについて
// vector<int>はvector<int, allocator<int>>になる
// setではもっと多い
return cnt >= f;
}
// =====================================
// 対応型用のinterfaceを宣言しておく
// =====================================
template <typename T> void _print(const T &v);
template <typename T> void _print(const vector<T> &v);
template <typename T> void _print(const set<T> &v);
template <typename T> void _print(const multiset<T> &v);
template <typename T, typename U> void _print(const map<T, U> &v);
template <typename T, typename U> void _print(const pair<T, U> &v);
template <typename T, typename U, typename R>
void _print(const tuple<T, U, R> &v);
template <typename T, typename U, typename R, typename S>
void _print(const tuple<T, U, R, S> &v);
template <typename T> void _print(const stack<T> &v);
template <typename T> void _print(const queue<T> &v);
template <typename T> void _print(const priority_queue<T> &v);
template <typename T> void _print(const deque<T> &v);
// =====================================
// プリミティブ型用
// =====================================
inline void _print(const int &v) { cerr << v; }
inline void _print(const long long &v) { cerr << v; }
inline void _print(const double &v) { cerr << v; }
inline void _print(const char &v) {
cerr << "\033[32m'\033[m" << v << "\033[32m'\033[m";
}
inline void _print(const string &v) {
cerr << "\033[32m" << '"' << "\033[m" << v << "\033[32m" << '"' << "\033[m";
}
// 直接引数に入れたりとかした場合
template <typename T> void _print(const T &v) { cerr << v; }
// =====================================
// pair tuple3 tuple4
// =====================================
template <typename T, typename U> void _print(const pair<T, U> &v) {
_print_p_start();
_print(v.first);
_print_sep();
_print(v.second);
_print_p_end();
}
template <typename T, typename U, typename R>
void _print(const tuple<T, U, R> &v) {
_print_p_start();
_print(get<0>(v));
_print_sep();
_print(get<1>(v));
_print_sep();
_print(get<2>(v));
_print_p_end();
}
template <typename T, typename U, typename R, typename S>
void _print(const tuple<T, U, R, S> &v) {
_print_p_start();
_print(get<0>(v));
_print_sep();
_print(get<1>(v));
_print_sep();
_print(get<2>(v));
_print_sep();
_print(get<3>(v));
_print_p_end();
}
// =====================================
// vector set multiset map
// =====================================
template <typename T> void _print(const vector<T> &v) {
bool isnested = _is_nested(v);
_print_a_start();
if (isnested) _print_LF();
for (int i = 0; i < static_cast<int>(v.size()); ++i) {
if (i == DEBUG_LIMIT_LOOP) {
cerr << "...and more " << v.size() - DEBUG_LIMIT_LOOP;
break;
}
if (isnested) cerr << " ";
if (i) _print_sep();
_print(v[i]);
if (isnested) _print_LF();
}
_print_a_end();
}
template <typename T> void _print(const set<T> &v) {
bool isnested = _is_nested(v, 4);
_print_b_start();
if (isnested) _print_LF();
int i = 0;
for (auto &&x : v) {
if (i == DEBUG_LIMIT_LOOP) {
cerr << "...and more " << v.size() - DEBUG_LIMIT_LOOP;
break;
}
if (isnested) cerr << " ";
if (i++) _print_sep();
_print(x);
if (isnested) _print_LF();
}
_print_b_end();
}
template <typename T> void _print(const multiset<T> &v) {
bool isnested = _is_nested(v, 4);
_print_b_start();
if (isnested) _print_LF();
int i = 0;
for (auto &&x : v) {
if (i == DEBUG_LIMIT_LOOP) {
cerr << "...and more " << v.size() - DEBUG_LIMIT_LOOP;
break;
}
if (isnested) cerr << " ";
if (i++) _print_sep();
_print(x);
if (isnested) _print_LF();
}
_print_b_end();
}
template <typename T, typename U> void _print(const map<T, U> &v) {
_print_b_start();
_print_LF();
int i = 0;
for (auto &&[k, x] : v) {
if (i == DEBUG_LIMIT_LOOP) {
cerr << "...and more " << v.size() - DEBUG_LIMIT_LOOP;
break;
}
cerr << " ";
if (i++) _print_sep();
_print_p_start();
_print(k);
_print_sep();
_print(x);
_print_p_end();
_print_LF();
}
_print_b_end();
}
// =====================================
// stack queue priority_queue deque
// =====================================
template <typename T> void _print(const stack<T> &v) {
auto x = v;
_print_b_start();
int i = 0;
while (!x.empty()) {
if (i == DEBUG_LIMIT_LOOP) {
cerr << "...and more " << v.size() - DEBUG_LIMIT_LOOP;
break;
}
if (i++) _print_sep();
_print(x.top());
x.pop();
}
_print_b_end();
}
template <typename T> void _print(const queue<T> &v) {
auto x = v;
_print_b_start();
int i = 0;
while (!x.empty()) {
if (i == DEBUG_LIMIT_LOOP) {
cerr << "...and more " << v.size() - DEBUG_LIMIT_LOOP;
break;
}
if (i++) _print_sep();
_print(x.front());
x.pop();
}
_print_b_end();
}
template <typename T> void _print(const priority_queue<T> &v) {
auto x = v;
_print_b_start();
int i = 0;
while (!x.empty()) {
if (i == DEBUG_LIMIT_LOOP) {
cerr << "...and more " << v.size() - DEBUG_LIMIT_LOOP;
break;
}
if (i++) _print_sep();
_print(x.top());
x.pop();
}
_print_b_end();
}
template <typename T> void _print(const deque<T> &v) {
auto x = v;
_print_a_start();
int i = 0;
while (!x.empty()) {
if (i == DEBUG_LIMIT_LOOP) {
cerr << "...and more " << v.size() - DEBUG_LIMIT_LOOP;
break;
}
if (i++) _print_sep();
_print(x.front());
x.pop_front();
}
_print_a_end();
}
// =====================================
// base
// =====================================
template <typename T> void print_debug(const T &v, const string &name) {
cerr << "\033[90m[debug]\033[36m " << name << "\033[m => ";
_print(v);
_print_LF();
}
#define debug(...) print_debug(__VA_ARGS__, #__VA_ARGS__)
// cpp_dump
// https://zenn.dev/sassan/articles/19db660e4da0a4
// #include "cpp-dump.hpp"
// #define debug(...) cpp_dump(__VA_ARGS__)
#line 6 "tests/template.debug.test.cpp"
/**
* @brief debugのテスト
*/
int main() {
cout << "Hello World" << endl;
int a = 1ll;
char c = 'c';
string S = "sss";
pair<int, string> p = {a, S};
tuple<int, char, string> t = {a, c, S};
vector<int> A = {a};
vector<vector<string>> G = {{S, S}, {S, S}};
debug(a);
debug(c);
debug(S);
debug(p);
debug(t);
debug(A);
debug(G);
}