-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtee_stream.cpp
72 lines (58 loc) · 1.59 KB
/
tee_stream.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#ifndef TEE_STREAM_CPP
#define TEE_STREAM_CPP
#include <iostream>
#include <fstream>
#include <streambuf>
class TeeStream : public std::streambuf {
public:
TeeStream(std::streambuf* sb1, std::streambuf* sb2) : sb1(sb1), sb2(sb2) {}
protected:
// This function is called when outputting each character via the stream.
virtual int overflow(int c) {
if (c == EOF) {
return !EOF;
} else {
int const r1 = sb1->sputc(c);
int const r2 = sb2->sputc(c);
return (r1 == EOF || r2 == EOF) ? EOF : c;
}
}
// Sync both stream buffers.
virtual int sync() {
int const r1 = sb1->pubsync();
int const r2 = sb2->pubsync();
return (r1 == 0 && r2 == 0) ? 0 : -1;
}
private:
std::streambuf* sb1;
std::streambuf* sb2;
};
class TeeLogger {
public:
TeeLogger(const std::string& filepath) : file_stream(filepath),
tee_buf(std::cout.rdbuf(), file_stream.rdbuf()),
tee_stream(&tee_buf) {}
std::ostream& get_stream() {
return tee_stream;
}
std::ofstream& get_file_stream() {
return file_stream;
}
private:
std::ofstream file_stream;
TeeStream tee_buf;
std::ostream tee_stream;
};
// Initial code generated using gpt4:
// https://chat.openai.com/c/d51cfec5-e702-4a5b-a471-2487619c4df1
/*
Example usage:
int main() {
TeeLogger tee_logger("log.txt");
std::ostream& log_stream = tee_logger.get_stream();
// This message will go to both std::cout and log.txt
log_stream << "Hello, world!" << std::endl;
return 0;
}
*/
#endif