blob: 6fd661362640040945c684ee0c4ac8ba4109a649 (
plain)
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
|
#ifndef CHANGE_SRC_LOGGER_H_
#define CHANGE_SRC_LOGGER_H_
#include <mutex>
#include <ext/stdio_filebuf.h>
#include <boost/process.hpp>
namespace utility {
class Logger {
#define FOR_EACH_ARGUMENT(...)\
auto&& tmp = { (__VA_ARGS__, 0)... }; (void) tmp;
public:
Logger(const int target_fd):
buffer_(target_fd, std::ios::out),
stream_(&this->buffer_) { }
template <typename... Args>
void append(const Args&... args) {
std::lock_guard<std::mutex> guard(this->write_mutex_);
FOR_EACH_ARGUMENT(this->stream_ << args);
this->stream_ << std::endl;
}
// Forward the contents of a given standard output stream to the log target
//
// While `this->stream_ << stream.rdbuf()` would be more effective it sadly
// does not work with `boost::process::pistream` due to a broken pipe error
// in conjunction with the required `boost::process::capture_stream` context
// flag.
//
void forward(boost::process::pistream& stream) {
std::lock_guard<std::mutex> guard(this->write_mutex_);
this->stream_ << std::string(
(std::istreambuf_iterator<char>(stream)),
(std::istreambuf_iterator<char>())
);
}
private:
__gnu_cxx::stdio_filebuf<char> buffer_;
std::ostream stream_;
std::mutex write_mutex_;
#undef FOR_EACH_ARGUMENT
};
}
#endif // CHANGE_SRC_LOGGER_H_
|