forked from emscripten-core/emscripten
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_exceptions_rethrow.cpp
More file actions
94 lines (86 loc) · 2.45 KB
/
Copy pathtest_exceptions_rethrow.cpp
File metadata and controls
94 lines (86 loc) · 2.45 KB
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
91
92
93
#include <ios>
#include <iostream>
#include <sstream>
#include <stdexcept>
namespace
{
struct TestEnum
{
enum type
{
Zero,
One
};
};
// An input operator a-la-boost date_time. This input operator will catch
// anything and rethrow if the exception mask for the input stream is set to
// throw on failure.
std::istream& operator>>(std::istream& in, TestEnum::type& value)
{
try {
std::string raw;
if (not (in >> raw)) { return in; }
if (raw == "Zero") { value = TestEnum::Zero; return in; }
if (raw == "One") { value = TestEnum::One; return in; }
// The boost input operator uses it's own facet for input which can
// throw, so we simulate something failing by just throwing an exception
// directly.
std::ios_base::failure failz("<input failure>");
std::cout
<< "Throwing std::ios_base::failure: |" << failz.what() << "|..."
<< std::endl;
throw failz;
}
catch (...) {
const std::ios_base::iostate exception_mask = in.exceptions();
if (std::ios_base::failbit & exception_mask) {
try { in.setstate(std::ios_base::failbit); }
catch(std::ios_base::failure&) {}
throw; // rethrow original exception
}
else {
in.setstate(std::ios_base::failbit);
}
}
return in;
}
}
int main()
{
try {
// Show that setting the input stream to throw on failure does not
// preserve the exception type.
std::istringstream iss("Three");
TestEnum::type value = TestEnum::Zero;
// Tell the stream to throw on failure.
iss.exceptions(std::ios_base::failbit);
// We expect this to fail.
iss >> value;
if (iss.fail()) {
std::cout
<< "No exception thrown; Failed to convert 'Three' to "
"TestEnum::type... fail" << std::endl;
}
else {
std::cout
<< "Successfully converted 'Three' to TestEnum::type: " << value
<< "... fail" << std::endl;
}
}
catch(const std::ios_base::failure& ex) {
// This is what we expect to catch.
std::cout
<< "Caught std::ios_base::failure: |" << ex.what() << "|... ok"
<< std::endl;
}
catch(const std::exception& ex) {
std::cout << "Caught exception: " << ex.what() << "... fail" << std::endl;
}
catch (...) {
// This is what is actually caught.
std::cout
<< "Unknown exception caught converting 'Three' to TestEnum... fail"
<< std::endl;
}
return 0;
}