Methods
T(block)
: 在代码块前后插入提示文字(包含代码块行号), 以确定代码块是否被执行以及是否执行成功.V(variable)
: 打印变量名及其值.log()
: 返回一个错误流, 该错误流自动添加空格和换行符, 并且支持注册自定义类型和格式, 例如显示打印string中的转义字符, 打印vector等.
Example Usage
T(
int root = 0;
dfs(root);
)
int age = 97;
V(age)
vector<vector<int> > tree(2);
tree[0] = {0, 1};
log() << "hello vector:" << tree << 1;
log() << "hello
string:" << string("
_n/") << 2;
TRY line 4
DONE line 4
age = 97
hello vector: vector(vector(0, 1), vector()) 1
hello
string: "
_n/" 2
Implementation
#define T(f) cerr << "
TRY line " << __line__ << endl;
f;
cerr << "
DONE line " << __line__ << endl;
#define V(x) cerr << #x << " = " << x << endl;
class log {
public:
log(): m_space(true) {}
~log() { cerr << endl; }
bool autoInsertSpace() const { return m_space; }
log& space(bool sp = true) { m_space = sp; return *this; }
// string
log& operator<< (const string &s) {
cerr << """;
string str = s;
replace(str, "\", "\\");
replace(str, "
", "\n");
replace(str, "
", "\r");
replace(str, " ", "\t");
replace(str, "v", "\v");
replace(str, """, "\"");
cerr << str << """ << (m_space ? " " : "");
return *this;
}
// vector
template <typename T>
log& operator<< (const vector<T> &v) {
bool initSpace = autoInsertSpace();
cerr << "vector(";
for (size_t i = 0; i < v.size(); ++i) {
if (i) cerr << ", ";
(*this).space(false) << v[i];
}
(*this).space(initSpace) << ")";
return (*this);
}
// default
template <typename T>
log& operator<< (const T &x) {
cerr << x << (m_space ? " " : "");
return *this;
}
private:
void replace(string &str, const string &from, const string &to) {
for (size_t p = str.find(from); p != string::npos; p = str.find(from, p + to.size())) {
str.replace(p, from.size(), to);
}
}
bool m_space;
};
以上展示了向log()注册新类型的一种方法, 即添加类函数. 也可以通过在类外重载<<操作符的方式注册. 注意, 无论哪种方法都要确保恢复space状态.
例如:
struct Time {
int hour, minute, second;
};
log& operator<< (log &lg, const Time &time) {
bool initSpace = lg.autoInsertSpace();
lg.space(false) << time.hour << ":" << time.minute << time.second;
lg.space(initSpace) << "";
return lg;
}