blob: faf5e29405331e179fa7e47da15c915a5f0afe8b (
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
87
88
89
90
|
#include <vector>
#include <iostream>
#include <stdexcept>
using namespace std;
#define CAT_IMPL(s1, s2) s1##s2
#define CAT(s1, s2) CAT_IMPL(s1, s2)
#define ANONYMOUS(x) CAT(x, __COUNTER__)
struct ITranslator {
virtual bool translate(string&) = 0;
};
template<typename T>
struct Translator : ITranslator {
Translator(string(*func)(T)) : m_func(func) {}
bool translate(string& res) {
try {
throw;
} catch(T ex) {
res = m_func(ex);
return true;
} catch(...) {
return false;
}
}
string(*m_func)(T);
};
void regTranslatorImpl(ITranslator* t); // fwd decl
template<typename T>
int regTranslator(string(*func)(T)) {
static Translator<T> t(func);
regTranslatorImpl(&t);
return 0;
}
#define REG_TRANSLATOR_2(name, type) \
static string name(type); \
static int ANONYMOUS(TRANS_) = regTranslator(&name); \
static string name(type)
#define REG_TRANSLATOR(type) REG_TRANSLATOR_2(ANONYMOUS(TRANS_), type)
// impl
vector<ITranslator*> translators;
void regTranslatorImpl(ITranslator* t) {
translators.push_back(t);
}
string translate() {
// try translators
string res;
for(size_t i = 0; i < translators.size(); ++i)
if(translators[i]->translate(res))
return res;
// proceed with default translation
try {
throw;
} catch(exception& ex) {
return ex.what();
} catch(string& msg) {
return msg;
} catch(const char* msg) {
return msg;
} catch(...) {
return "Unknown exception!";
}
}
// usage
REG_TRANSLATOR(double& e) {
return string("double: ") + to_string(e);
}
int main() {
try {
//throw 42;
throw 5.0;
//throw runtime_error("whops!");
} catch(...) {
cout << translate() << endl;
}
}
|