blob: 5896da294e74a258d37edd811079352ad54168e7 (
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
#include <vector>
#include <utility>
#include <iostream>
#include <string>
#include <list>
#include <new>
#define CAT_IMPL(s1, s2) s1##s2
#define CAT(s1, s2) CAT_IMPL(s1, s2)
#define ANONYMOUS(x) CAT(x, __COUNTER__)
#define NUM_CAPTURES_ON_STACK 5
struct ICapture { virtual std::string toString() const = 0; };
void addToCaptures(const ICapture* ptr);
void popFromCaptures();
void printCaptures();
struct InfoBuilder {
template<typename T>
struct Capture : ICapture {
const T* capture;
Capture(const T* in) : capture(in) {}
std::string toString() const override { return std::to_string(*capture); }
};
struct Chunk { char buf[sizeof(Capture<char>)]; };
Chunk stackChunks[NUM_CAPTURES_ON_STACK];
int numCaptures = 0;
std::list<Chunk> heapChunks;
template<typename T>
InfoBuilder& operator<<(const T& in) {
if(numCaptures < NUM_CAPTURES_ON_STACK) {
addToCaptures(new (stackChunks[numCaptures].buf) Capture<T>(&in));
} else {
heapChunks.push_back(Chunk());
addToCaptures(new (heapChunks.back().buf) Capture<T>(&in));
}
++numCaptures;
return *this;
}
~InfoBuilder() {
for(int i = 0; i < numCaptures; ++i)
popFromCaptures();
}
template<typename T>
InfoBuilder& operator<<(const T&&) = delete; // prevent rvalues from being captured
};
#define INFO_IMPL(name, x) InfoBuilder name; name << x
#define INFO(x) INFO_IMPL(ANONYMOUS(_CAPTURE_), x)
// impl
std::vector<const ICapture*> captures;
void addToCaptures(const ICapture* ptr) { captures.push_back(ptr); }
void popFromCaptures() { captures.pop_back(); }
void printCaptures() {
for(size_t i = 0; i < captures.size(); ++i)
std::cout << captures[i]->toString() << std::endl;
}
// usage
int main() {
int var1 = 42;
int var2 = 43;
int var3 = 45;
int var4 = 46;
int var5 = 47;
float var6 = 48.f;
bool var7 = true;
INFO(var1 << var2 << var3 << var4 << var5 << var6 << var7);
printCaptures();
}
|