Rev 96 | Rev 169 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 96 | Rev 154 | ||
|---|---|---|---|
| Line 30... | Line 30... | ||
| 30 | 30 | ||
| 31 | namespace { |
31 | namespace { |
| 32 | 32 | ||
| 33 | /// Version number. If Version is left empty, then compile date in the format |
33 | /// Version number. If Version is left empty, then compile date in the format |
| 34 | /// DD-MM-YY and show in engine_info. |
34 | /// DD-MM-YY and show in engine_info. |
| 35 | const string Version = ""; |
35 | const string Version = "8"; |
| 36 | 36 | ||
| 37 | /// Our fancy logging facility. The trick here is to replace cin.rdbuf() and |
37 | /// Our fancy logging facility. The trick here is to replace cin.rdbuf() and |
| 38 | /// cout.rdbuf() with two Tie objects that tie cin and cout to a file stream. We |
38 | /// cout.rdbuf() with two Tie objects that tie cin and cout to a file stream. We |
| 39 | /// can toggle the logging of std::cout and std:cin at runtime whilst preserving |
39 | /// can toggle the logging of std::cout and std:cin at runtime whilst preserving |
| 40 | /// usual I/O functionality, all without changing a single line of code! |
40 | /// usual I/O functionality, all without changing a single line of code! |
| Line 63... | Line 63... | ||
| 63 | }; |
63 | }; |
| 64 | 64 | ||
| 65 | class Logger { |
65 | class Logger { |
| 66 | 66 | ||
| 67 | Logger() : in(cin.rdbuf(), file.rdbuf()), out(cout.rdbuf(), file.rdbuf()) {} |
67 | Logger() : in(cin.rdbuf(), file.rdbuf()), out(cout.rdbuf(), file.rdbuf()) {} |
| 68 | ~Logger() { start( |
68 | ~Logger() { start(""); } |
| 69 | 69 | ||
| 70 | ofstream file; |
70 | ofstream file; |
| 71 | Tie in, out; |
71 | Tie in, out; |
| 72 | 72 | ||
| 73 | public: |
73 | public: |
| 74 | static void start( |
74 | static void start(const std::string& fname) { |
| 75 | 75 | ||
| 76 | static Logger l; |
76 | static Logger l; |
| 77 | 77 | ||
| 78 | if ( |
78 | if (!fname.empty() && !l.file.is_open()) |
| 79 | { |
79 | { |
| 80 | l.file.open( |
80 | l.file.open(fname, ifstream::out); |
| 81 | cin.rdbuf(&l.in); |
81 | cin.rdbuf(&l.in); |
| 82 | cout.rdbuf(&l.out); |
82 | cout.rdbuf(&l.out); |
| 83 | } |
83 | } |
| 84 | else if ( |
84 | else if (fname.empty() && l.file.is_open()) |
| 85 | { |
85 | { |
| 86 | cout.rdbuf(l.out.buf); |
86 | cout.rdbuf(l.out.buf); |
| 87 | cin.rdbuf(l.in.buf); |
87 | cin.rdbuf(l.in.buf); |
| 88 | l.file.close(); |
88 | l.file.close(); |
| 89 | } |
89 | } |
| Line 155... | Line 155... | ||
| 155 | return os; |
155 | return os; |
| 156 | } |
156 | } |
| 157 | 157 | ||
| 158 | 158 | ||
| 159 | /// Trampoline helper to avoid moving Logger to misc.h |
159 | /// Trampoline helper to avoid moving Logger to misc.h |
| 160 | void start_logger( |
160 | void start_logger(const std::string& fname) { Logger::start(fname); } |
| 161 | 161 | ||
| 162 | 162 | ||
| 163 | /// prefetch() preloads the given address in L1/L2 cache. This is a non-blocking |
163 | /// prefetch() preloads the given address in L1/L2 cache. This is a non-blocking |
| 164 | /// function that doesn't stall the CPU waiting for data to be loaded from memory, |
164 | /// function that doesn't stall the CPU waiting for data to be loaded from memory, |
| 165 | /// which can be quite slow. |
165 | /// which can be quite slow. |