赞
踩
- //!
- //! C++工具:C++日志模板--提供调试日志和文件日志
- //!
- //! == 日志模板简介 ==
- //! 日志打印是C++程序调试的关键一环,可惜C++并没有提供标准库日志,
- //! 本文将提供一个简单轻便的调试日志,使用方式更接近C++风格
- //! 日志模板包含控制台调试日志,写入文件日志两种常见日志,
- //! 通常调试日志不会跟随程序发行,发行时采用文件日志
- //! 该日志在Linux环境下适用,但基本采用C++标准,
- //! 如需要在Windows下使用需微调代码
- //! == 日志模板简介 ==
- //!
- //!
- //! == 调试日志 ==
- //! 调试日志:提供日志开关宏,控制整体日志的打印输出
- //! 提供日志级别,可屏蔽低级日志
- //! 提供日志级别模板,可自定义日志级别
- //! 提供颜色打印开关,控制不同级别高亮打印
- //! 提供标准容器打印模板,快速打印容器内容
- //!
- //! 文件日志:提供日志级别,可屏蔽低级日志
- //! 提供日志级别模板,可自定义日志级别
- //! 提供文件限制最大长度,文件数量循环复写模式
- //! 提供无限文件数量追加写入模式
- //! == 调试日志 ==
- //!
- //! 结束语:
- //! 从性能测试结果来看,调试日志的颜色打印与常规打印性能无差距,
- //! 调试日志的时间消耗是cout/paintf打印时间的一倍,
- //! 时间消耗主要由重载符<<产生,为便捷性牺牲速度
- //! 文件日志写入文件的性能比cout/paintf打印到屏幕更快,
- //! 文件日志不错的性能与便捷性,可以在简单项目中快速使用
- //!
- #define VLOG_COLOR //需要在Tvlog.h文件之前使用
- //#define VLOG_CLOSE //需要在Tvlog.h文件之前使用
- #include "../include/Tvlog.h"
- #include <vector>
- #include <list>
-
- #include <chrono>
- #include <iostream>
- using std::string;
- using std::vector;
- using std::list;
- using std::to_string;
- using namespace std::chrono;
-
- //!
- //! 说明:主要用于计算函数运行的时间,测试函数性能
- //! steady_clock时间:精确到纳秒的均速时间
- //!
- //! 例子:
- //! {
- //! ctimel tm;
- //! func();
- //! }//到这里析构退出并打印时间
- //!
- //! 原理:构建对象时开始计时,析构时打印时间
- //!
- class ctimel
- {
- public:
- ctimel() { _begin = steady_clock::now(); }
- ~ctimel() { show(); }
-
- inline string to_str()
- {
- //顺序 [纳秒|微秒|毫秒|秒]
- auto loss = steady_clock::now() - _begin;
- string str =
- "[nan: " + std::to_string(loss.count()) +
- "|mic: " + std::to_string(duration_cast<microseconds>(loss).count()) +
- "|mil: " + std::to_string(duration_cast<milliseconds>(loss).count()) +
- "|sec: " + std::to_string(duration_cast<seconds>(loss).count()) +
- "]\n";
- return str;
- }
-
- inline void show_str(const string str) { std::cout<<str<<std::endl; }
- inline void show() { show_str(to_str()); }
- inline void update() { _begin = steady_clock::now(); }
-
- protected:
- time_point<steady_clock,nanoseconds> _begin;
- };
-
-
- void test_1()
- {
- Tvlogs::get()->set_level(vlevel4::e_info); //设置最低显示日志级别
-
- //普通打印
- vloge("== 普通打印 ==");
- vlogi("e_info level");
- vlogd("this template log");
- vlogd("10+20 ret: " << 10+20);
- vlogw("PI: "<<3.14);
- vloge("2^4 calculate: "<<2*2<<" * "<<2*2<<" = "<<4*4);
- vloge("2^4 calculate:" $(2*2) $(2*2) "=" $(4*4));
-
- //快速打印结果
- vloge("== 快速打印 ==");
- int count = 0;
- for(int i=0;i<=100;i++) count += i;
- string str = "hello world";
- int ret = 10*60;
- vlogd($(str) $(ret) $(count));
-
- //容器快速打印
- vector<string> vec;
- list<string> ls;
- for(int i=0;i<10;i++)
- {
- vec.push_back("vec:"+to_string(i));
- ls.push_back("ls:"+to_string(i));
- }
-
- vloge("== 容器打印--模板 ==");
- {
- vector<int> vec;
- for(int i=0;i<25;i++)
- {
- vec.push_back(i);
- }
- vlogc(vec);
- vlogc(vec,5);
- vlogc(vec,5,"][");
- vlogc(vec.begin(),vec.end(),5);
- vlogc(vec.begin(),vec.end(),5,".");
- }
-
- int ifor = 3;
-
- #if 1
- {
- ctimel c;
- for(int i=0;i<ifor;i++)
- {
- vlogd($(i) "hellow world");
- }
- string s1 = c.to_str();
- int value=100;
- string s = "hellow world";
- for(int i=0;i<ifor;i++)
- {
- vlogd($(i) $(value) $(s));
- }
- string s2 = c.to_str();
- }
- #endif
-
- #if 1
- {
- ctimel c;
- for(int i=0;i<ifor;i++)
- {
- std::cout<<i<<": hellow world"<<std::endl;
- }
- string s1 = c.to_str();
- int value=100;
- string s = "hellow world";
- for(int i=0;i<ifor;i++)
- {
- std::cout<<i<<": value:"<<value<<" | s:"<<s<<std::endl;
- }
- string s2 = c.to_str();
- }
- #endif
-
- #if 1
- {
- ctimel c;
- for(int i=0;i<ifor;i++)
- {
- printf("%d: hellow world\n",i);
- }
- string s1 = c.to_str();
- int value=100;
- const char *s = "hellow world";
- for(int i=0;i<ifor;i++)
- {
- printf("%d: value: %d| s: %s\n",i,value,s);
- }
- string s2 = c.to_str();
- }
- #endif
-
- }
-
- void test_2()
- {
- Tflogs::get()->init("Tflog.log",false); //设置日志文件和追加模式
- Tflogs::get()->set_level(vlevel4::e_debug); //设置最低显示日志级别
- Tflogs::get()->set_limit(5); //设置日志数量(启动循环覆盖)--不设置则默认无限制
- Tflogs::get()->set_length(1024*1024*10); //设置最大日志长度(10M)--不设置默认64M
-
- //普通打印
- floge("== 普通打印 ==");
- flogi("e_info level");
- flogd("this template log");
- flogd("10+20 ret: " << 10+20);
- flogw("PI: "<<3.14);
- floge("2^4 calculate: "<<2*2<<" * "<<2*2<<" = "<<4*4);
- floge("2^4 calculate:" $(2*2) $(2*2) "=" $(4*4));
-
- //快速打印结果
- floge("== 快速打印 ==");
- int count = 0;
- for(int i=0;i<=100;i++) count += i;
- string str = "hello world";
- int ret = 10*60;
- flogd($(str) $(ret) $(count));
-
- int ifor = 3;
-
- #if 1
- {
- ctimel c;
- for(int i=0;i<ifor;i++)
- {
- flogw($(i) "hellow world");
- }
- string s1 = c.to_str();
- int value=100;
- string s = "hellow world";
- for(int i=0;i<ifor;i++)
- {
- flogw($(i) $(value) $(s));
- }
- string s2 = c.to_str();
- }
- #endif
- }
-
- int main()
- {
- printf("== begin ==\n");
-
- test_1();
- test_2();
-
- printf("== end ==\n");
- return 0;
- }
-
- /*
- * 测试结果:各个版本的运行时间
- *
- //flog:
- [nan: 3999236206|mic: 3999236|mil: 3999|sec: 3]
- [nan: 3981404537|mic: 3981404|mil: 3981|sec: 3]
- [nan: 3943364553|mic: 3943364|mil: 3943|sec: 3]
- //vlog-color:
- [nan: 9553316241|mic: 9553316|mil: 9553|sec: 9]
- [nan: 9509730052|mic: 9509730|mil: 9509|sec: 9]
- [nan: 9444099080|mic: 9444099|mil: 9444|sec: 9]
- //vlog:
- [nan: 9377207274|mic: 9377207|mil: 9377|sec: 9]
- [nan: 9237833979|mic: 9237833|mil: 9237|sec: 9]
- [nan: 9389804775|mic: 9389804|mil: 9389|sec: 9]
- //cout:
- [nan: 5033779586|mic: 5033779|mil: 5033|sec: 5]
- [nan: 5081468378|mic: 5081468|mil: 5081|sec: 5]
- [nan: 5098394323|mic: 5098394|mil: 5098|sec: 5]
- //print:
- [nan: 4815928537|mic: 4815928|mil: 4815|sec: 4]
- [nan: 4650109190|mic: 4650109|mil: 4650|sec: 4]
- [nan: 4881491074|mic: 4881491|mil: 4881|sec: 4]
- *
- * 测试结果:各个版本的打印格式
- *
- //flog:
- [2023-06-07 22:30:44] [War] <<<< [i: 0] hellow world [../cpp_tools/main_Tvlog.cpp:<227>]
- [2023-06-07 22:30:44] [War] <<<< [i: 1] hellow world [../cpp_tools/main_Tvlog.cpp:<227>]
- [2023-06-07 22:30:44] [War] <<<< [i: 2] hellow world [../cpp_tools/main_Tvlog.cpp:<227>]
- [2023-06-07 22:30:44] [War] <<<< [i: 0] [value: 100] [s: hellow world] [../cpp_tools/main_Tvlog.cpp:<234>]
- [2023-06-07 22:30:44] [War] <<<< [i: 1] [value: 100] [s: hellow world] [../cpp_tools/main_Tvlog.cpp:<234>]
- [2023-06-07 22:30:44] [War] <<<< [i: 2] [value: 100] [s: hellow world] [../cpp_tools/main_Tvlog.cpp:<234>]
- //vlog:
- [Deb][../cpp_tools/main_Tvlog.cpp:<146>] <<<< [i: 0] hellow world
- [Deb][../cpp_tools/main_Tvlog.cpp:<146>] <<<< [i: 1] hellow world
- [Deb][../cpp_tools/main_Tvlog.cpp:<146>] <<<< [i: 2] hellow world
- [Deb][../cpp_tools/main_Tvlog.cpp:<153>] <<<< [i: 0] [value: 100] [s: hellow world]
- [Deb][../cpp_tools/main_Tvlog.cpp:<153>] <<<< [i: 1] [value: 100] [s: hellow world]
- [Deb][../cpp_tools/main_Tvlog.cpp:<153>] <<<< [i: 2] [value: 100] [s: hellow world]
- //cout:
- 0: hellow world
- 1: hellow world
- 2: hellow world
- 0: value:100 | s:hellow world
- 1: value:100 | s:hellow world
- 2: value:100 | s:hellow world
- //print:
- 0: hellow world
- 1: hellow world
- 2: hellow world
- 0: value: 100| s: hellow world
- 1: value: 100| s: hellow world
- 2: value: 100| s: hellow world
- *
- * 测试结果:test_1函数的打印结果
- *
- == begin ==
- [Err][../cpp_tools/main_Tvlog.cpp:<95>] <<<< == 普通打印 ==
- [Inf][../cpp_tools/main_Tvlog.cpp:<96>] <<<< e_info level
- [Deb][../cpp_tools/main_Tvlog.cpp:<97>] <<<< this template log
- [Deb][../cpp_tools/main_Tvlog.cpp:<98>] <<<< 10+20 ret: 30
- [War][../cpp_tools/main_Tvlog.cpp:<99>] <<<< PI: 3.14
- [Err][../cpp_tools/main_Tvlog.cpp:<100>] <<<< 2^4 calculate: 4 * 4 = 16
- [Err][../cpp_tools/main_Tvlog.cpp:<101>] <<<< 2^4 calculate:[2*2: 4] [2*2: 4] =[4*4: 16]
- [Err][../cpp_tools/main_Tvlog.cpp:<104>] <<<< == 快速打印 ==
- [Deb][../cpp_tools/main_Tvlog.cpp:<109>] <<<< [str: hello world] [ret: 600] [count: 5050]
- [Err][../cpp_tools/main_Tvlog.cpp:<125>] <<<< == 容器打印--模板 ==
- | [../cpp_tools/main_Tvlog.cpp:<132>]
- | size: 25
- | 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
- | [../cpp_tools/main_Tvlog.cpp:<133>]
- | size: 25
- | 0 1 2 3 4
- | 5 6 7 8 9
- | 10 11 12 13 14
- | 15 16 17 18 19
- | 20 21 22 23 24
- | [../cpp_tools/main_Tvlog.cpp:<134>]
- | size: 25
- | 0][1][2][3][4][
- | 5][6][7][8][9][
- | 10][11][12][13][14][
- | 15][16][17][18][19][
- | 20][21][22][23][24][
- | [../cpp_tools/main_Tvlog.cpp:<135>]
- | size: 25
- | 0 1 2 3 4
- | 5 6 7 8 9
- | 10 11 12 13 14
- | 15 16 17 18 19
- | 20 21 22 23 24
- | [../cpp_tools/main_Tvlog.cpp:<136>]
- | size: 25
- | 0.1.2.3.4.
- | 5.6.7.8.9.
- | 10.11.12.13.14.
- | 15.16.17.18.19.
- | 20.21.22.23.24.
- == end ==
- *
- * 测试结果:test_2函数的打印结果
- *
- [2023-06-07 22:34:36] [Err] <<<< == 普通打印 == [../cpp_tools/main_Tvlog.cpp:<204>]
- [2023-06-07 22:34:36] [Deb] <<<< this template log [../cpp_tools/main_Tvlog.cpp:<206>]
- [2023-06-07 22:34:36] [Deb] <<<< 10+20 ret: 30 [../cpp_tools/main_Tvlog.cpp:<207>]
- [2023-06-07 22:34:36] [War] <<<< PI: 3.14 [../cpp_tools/main_Tvlog.cpp:<208>]
- [2023-06-07 22:34:36] [Err] <<<< 2^4 calculate: 4 * 4 = 16 [../cpp_tools/main_Tvlog.cpp:<209>]
- [2023-06-07 22:34:36] [Err] <<<< 2^4 calculate:[2*2: 4] [2*2: 4] =[4*4: 16] [../cpp_tools/main_Tvlog.cpp:<210>]
- [2023-06-07 22:34:36] [Err] <<<< == 快速打印 == [../cpp_tools/main_Tvlog.cpp:<213>]
- [2023-06-07 22:34:36] [Deb] <<<< [str: hello world] [ret: 600] [count: 5050] [../cpp_tools/main_Tvlog.cpp:<218>]
- */
- //!
- //! Tvlog.h
- //!
- #ifndef TVLOG_H
- #define TVLOG_H
-
- #include <iostream>
- #include <fstream>
- #include <mutex>
-
- //== 单例模板 ==
- template<class T>
- class Tsingle_d
- {
- public:
- static T* get()
- {
- if(_obj == nullptr)
- {
- _mut.lock();
- if(_obj == nullptr) { _obj = new T; }
- _mut.unlock();
- }
- return _obj;
- }
-
- void clean()
- {
- _mut.lock();
- delete _obj; _obj = nullptr;
- _mut.unlock();
- }
-
- private:
- static T *_obj;
- static std::mutex _mut;
- friend T;
- Tsingle_d() = default;
- ~Tsingle_d() = default;
- Tsingle_d(const Tsingle_d &) = delete ;
- };
-
- template<class T> T *Tsingle_d<T>::_obj = nullptr;
- template<class T> std::mutex Tsingle_d<T>::_mut;
- //== 单例模板 ==
-
-
- //== 等级 ==
- namespace level4
- { enum level{ e_error,e_warning,e_debug,e_info }; }
-
- namespace level8
- { enum level{ e_off,e_fatal,e_error,e_warning,e_debug,e_trace,e_all }; }
- //== 等级 ==
-
-
- //== 调试日志模板 ==
- //提供等级自定义模板参数
- template<class Tlevel>
- class Tvlog
- {
- public:
- inline void set_level(Tlevel el){ _level = el; } //设置等级
-
- inline Tvlog& operator<<(Tlevel el)
- { if(el <= _level) _ok = true; else _ok = false; return *this; };
-
- inline Tvlog& operator<<(std::ostream& (*end)(std::ostream&))
- { if(_ok) std::cout<<end; return *this; };
-
- template<class T>
- inline Tvlog& operator<<(const T &log)
- { if(_ok) std::cout<<log; return *this; };
-
- private:
- bool _ok = false; //判断等级是否符合
- Tlevel _level; //最低显示的等级
- };
- //== 调试日志模板 ==
-
-
- //== 文件日志模板 ==
- //提供等级自定义模板参数
- template<class Tlevel>
- class Tflog
- {
- public:
- inline bool init(const std::string &file = "Tflog.log",bool app = true) //初始化日志
- {
- _file = file;
- if(app) _mode = std::ios::app; else _mode = std::ios::out;
- if(_fs.is_open() == false) _fs.open(_file,_mode);
- return _fs.is_open();
- }
-
- static std::string date_time() //获取秒精度的日期时间
- {
- time_t t; time(&t); char buf[64] = {0};
- strftime(buf,sizeof(buf),"%Y-%m-%d %H:%M:%S",localtime(&t));
- return std::string(buf);
- }
-
- inline void set_limit(int max) { _limit_max = max; } //设置数量限制
- inline void set_level(Tlevel el) { _level = el; } //设置等级
- inline void set_length(size_t len) { _len_max = len;} //设置文件长度
- inline void close_log() { _fs.close(); } //关闭日志
-
- inline Tflog& operator<<(Tlevel el)
- { if(el <= _level) _ok = true; else _ok = false; return *this; };
-
- inline Tflog& operator<<(std::ostream& (*end)(std::ostream&))
- { if(_ok &&_fs.is_open()){ _fs<<end; update_file(); } return *this; };
-
- template<class T>
- inline Tflog& operator<<(const T &log)
- { if(_ok &&_fs.is_open()) _fs<<log; return *this; };
-
- private:
- bool _ok = false; //判断等级是否符合
- int _limit_max = 0; //日志文件限制数量
- int _limit_now = 1; //当前写入日志
- Tlevel _level; //最低显示的等级
- std::fstream _fs; //文件对象
- std::string _file; //文件名
- size_t _len_max = (1 << 26); //最大长度--64M
- std::ios_base::openmode _mode; //文件打开模式
-
- void update_file() //超出最大文件限制后更新文件名
- {
- if(_len_max < (size_t)_fs.tellg())
- {
- if(_limit_max == 0) write_unlimited();
- else write_limit();
- }
- }
-
- void write_unlimited() //无限制日志
- {
- _fs.close();
- for(int i=1;;i++)
- {
- std::string new_file = std::to_string(i)+"_"+_file;
- if(exist_file(new_file) == false)
- { rename(_file.c_str(),new_file.c_str()); break; }
- }
- _fs.open(_file,_mode);
- }
-
- void write_limit() //限制日志数量
- {
- _fs.close();
- {
- std::string new_file = std::to_string(_limit_now)+"_"+_file;
- rename(_file.c_str(),new_file.c_str());
- _limit_now++;
- if(_limit_now > _limit_max) _limit_now = 1;
- }
- _fs.open(_file,_mode);
- }
-
- static bool exist_file(const std::string &filename) //判断文件是否存在
- { std::ifstream f(filename); return f.is_open(); }
- };
- //== 文件日志模板 ==
-
- typedef level4::level vlevel4;
- typedef Tsingle_d<Tflog<vlevel4>> Tflogs;
- typedef Tsingle_d<Tvlog<vlevel4>> Tvlogs;
-
- //颜色打印--注释掉则无颜色
- //#define VLOG_COLOR
-
- //调试打印--开启则关闭调试打印
- //#define VLOG_CLOSE
-
-
- //== 功能宏 ==
- //快速打印变量值
- //参数:打印的值
- #define $(value) "["#value": "<<value<<"] "
- //== 功能宏 ==
-
-
- //== 打印工厂宏 ==
- #define VMAKE_LOG(txt,type,...) \
- *Tsvlog::get()<<type \
- <<txt "["<<__FILE__<<":<"<<__LINE__<<">] <<<< " \
- <<__VA_ARGS__<<std::endl \
- #define VMAKE_LOG_COL(txt,type,...) \
- *Tvlogs::get()<<type \
- <<txt "["<<__FILE__<<":<"<<__LINE__<<">] <<<< " \
- <<__VA_ARGS__<<"\033[0m"<<std::endl \
- #define FMAKE_LOG(txt,type,...) \
- *Tflogs::get()<<type \
- <<"["<<Tflogs::get()->date_time()<<"] " \
- <<txt " <<<< "<<__VA_ARGS__ \
- <<" ["<<__FILE__<<":<"<<__LINE__<<">]"<<std::endl \
- //== 打印工厂宏 ==
- //== 调试日志宏 ==
- #ifndef VLOG_CLOSE
- #ifndef VLOG_COLOR
- #define vlogi(...) VMAKE_LOG("[Inf]",vlevel4::e_info,__VA_ARGS__)
- #define vlogd(...) VMAKE_LOG("[Deb]",vlevel4::e_debug,__VA_ARGS__)
- #define vlogw(...) VMAKE_LOG("[War]",vlevel4::e_warning,__VA_ARGS__)
- #define vloge(...) VMAKE_LOG("[Err]",vlevel4::e_error,__VA_ARGS__)
- #else //== 颜色打印分界 ==
- #define vlogi(...) VMAKE_LOG_COL("[Inf]",vlevel4::e_info,__VA_ARGS__)
- #define vlogd(...) VMAKE_LOG_COL("\033[32m[Deb]",vlevel4::e_debug,__VA_ARGS__)
- #define vlogw(...) VMAKE_LOG_COL("\033[33m[War]",vlevel4::e_warning,__VA_ARGS__)
- #define vloge(...) VMAKE_LOG_COL("\033[31m[Err]",vlevel4::e_error,__VA_ARGS__)
- #endif
- #else
- #define vlogi(...)
- #define vlogd(...)
- #define vlogw(...)
- #define vloge(...)
- #endif
- //== 调试日志宏 ==
- //== 文件日志宏 ==
- #define flogi(...) FMAKE_LOG("[Inf]",vlevel4::e_info,__VA_ARGS__)
- #define flogd(...) FMAKE_LOG("[Deb]",vlevel4::e_debug,__VA_ARGS__)
- #define flogw(...) FMAKE_LOG("[War]",vlevel4::e_warning,__VA_ARGS__)
- #define floge(...) FMAKE_LOG("[Err]",vlevel4::e_error,__VA_ARGS__)
- //== 文件日志宏 ==
- //===== 容器打印 =====
- //参数:容器
- template<class T>
- void print_con(const T& con)
- {
- std::cout<<"| size: "<<con.size()<<std::endl<<"| ";
- for(const auto &a:con)
- {
- std::cout<<a<<" ";
- }
- std::cout<<std::endl;
- }
- //参数:容器,换行长度
- template<class T>
- void print_con(const T& con,int len)
- {
- int count = 0;
- std::cout<<"| size: "<<con.size()<<std::endl<<"| ";
- for(const auto &a:con)
- {
- if(count >= len) { count = 0; std::cout<<std::endl<<"| "; }
- count++;
- std::cout<<a<<" ";
- }
- std::cout<<std::endl;
- }
- //参数:容器,换行长度,分割符
- template<class T>
- void print_con(const T& con,int len,const std::string &flg)
- {
- int count = 0;
- std::cout<<"| size: "<<con.size()<<std::endl<<"| ";
- for(const auto &a:con)
- {
- if(count >= len) { count = 0; std::cout<<std::endl<<"| "; }
- count++;
- std::cout<<a<<flg;
- }
- std::cout<<std::endl;
- }
- //参数:开始迭代器,结束迭代器,长度
- template<class Tit>
- void print_con(Tit begin,Tit end,int len)
- {
- int count = 0;
- std::cout<<"| size: "<<end - begin<<std::endl<<"| ";
- for(auto it=begin;it!=end;it++)
- {
- if(count >= len) { count = 0; std::cout<<std::endl<<"| "; }
- count++;
- std::cout<<*it<<" ";
- }
- std::cout<<std::endl;
- }
- //参数:开始迭代器,结束迭代器,长度,分割符号
- template<class Tit>
- void print_con(Tit begin,Tit end,int len,const std::string &flg)
- {
- int count = 0;
- std::cout<<"| size: "<<end - begin<<std::endl<<"| ";
- for(auto it=begin;it!=end;it++)
- {
- if(count >= len) { count = 0; std::cout<<std::endl<<"| "; }
- count++;
- std::cout<<*it<<flg;
- }
- std::cout<<std::endl;
- }
- #ifndef VLOG_CLOSE
- //参数:$v的容器打印,$v的参数
- #define vlogc(...) \
- std::cout<<"| ["<<__FILE__<<":<"<<__LINE__<<">]"<<std::endl; \
- print_con(__VA_ARGS__);
- #else
- #define vlogc(...)
- #endif
- //== 容器打印格式 ==
- #endif // TVLOG_H
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。