lsnes rr2-β24
[lsnes.git] / src / library / exrethrow.cpp
blobf44265a352b4336045efde86459e157ca3fe0f36
1 #include "exrethrow.hpp"
2 #include <functional>
3 #include <list>
4 #include <iostream>
5 #include <future>
7 namespace exrethrow
9 ex_spec<std::exception, 0> std_exception;
10 ex_spec<std::logic_error, 1> std_logic_error;
11 ex_spec<std::domain_error, 2> std_domain_error;
12 ex_spec<std::invalid_argument, 2> std_invalid_argument;
13 ex_spec<std::length_error, 2> std_length_error;
14 ex_spec<std::out_of_range, 2> std_out_of_range;
15 ex_spec<std::future_error, 2> std_future_error;
16 ex_spec<std::runtime_error, 1> std_runtime_error;
17 ex_spec<std::range_error, 2> std_range_error;
18 ex_spec<std::overflow_error, 2> std_overflow_error;
19 ex_spec<std::underflow_error, 2> std_underflow_error;
20 ex_spec<std::system_error, 2> std_system_error;
21 ex_spec<std::bad_cast, 1> std_bad_cast;
22 ex_spec<std::bad_exception, 1> std_bad_exception;
23 ex_spec<std::bad_function_call, 1> std_bad_function_call;
24 ex_spec<std::bad_typeid, 1> std_bad_typeid;
25 ex_spec<std::bad_weak_ptr, 1> std_bad_weak_ptr;
26 ex_spec<std::ios_base::failure, 1> std_ios_base_failure;
28 struct exspec_item {
29 unsigned prio;
30 std::function<bool(std::exception& e)> identify;
31 std::function<void()> (*throwfn)(std::exception& e);
33 std::list<exspec_item>* exspecs;
35 void add_ex_spec(unsigned prio, std::function<bool(std::exception& e)> identify,
36 std::function<void()> (*throwfn)(std::exception& e))
38 exspec_item i;
39 i.prio = prio;
40 i.identify = identify;
41 i.throwfn = throwfn;
42 if(!exspecs)
43 exspecs = new std::list<exspec_item>;
44 for(auto j = exspecs->begin(); j != exspecs->end(); j++) {
45 if(j->prio <= prio) {
46 exspecs->insert(j, i);
47 return;
50 exspecs->push_back(i);
53 std::function<void()> get_throw_fn(std::exception& e)
55 for(auto& i : *exspecs) {
56 if(i.identify(e))
57 return i.throwfn(e);
59 return []() -> void { throw std::runtime_error("Unknown exception"); };
62 storage::storage()
64 null = true;
67 storage::storage(std::exception& e)
69 null = false;
70 oom = false;
71 if(dynamic_cast<std::bad_alloc*>(&e)) {
72 oom = true;
73 return;
75 try {
76 do_rethrow = get_throw_fn(e);
77 } catch(...) {
78 oom = true;
82 void storage::rethrow()
84 if(null) return;
85 if(oom)
86 throw std::bad_alloc();
87 do_rethrow();
90 storage::operator bool()
92 return !null;