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. |