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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
#include "error.h"
namespace saw {
error::error(error::code code_, bool is_critical__)
: error_code_{static_cast<error::code>(code_)}, is_critical_{is_critical__} {}
error::error(error::code code_, bool is_critical__, const std::string_view &msg)
:
error_code_{static_cast<error::code>(code_)}
, is_critical_{is_critical__}, error_message_{msg}{}
error::error(error &&error)
:
error_code_{std::move(error.error_code_)}
, is_critical_{std::move(error.is_critical_)}
, error_message_{std::move(error.error_message_)}{}
const std::string_view error::message() const {
return std::visit(
[this](auto &&arg) -> const std::string_view {
using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same_v<T, std::string>) {
return std::string_view{arg};
} else if constexpr (std::is_same_v<T, std::string_view>) {
return arg;
} else {
return "Error in class Error. Good luck :)";
}
},
error_message_);
}
bool error::failed() const {
return this->is_error<err::no_error>();
}
bool error::is_critical() const {
return is_critical_;
}
bool error::is_recoverable() const {
return !is_critical_;
}
error error::copy_error() const {
auto copy_error_code = error_code_;
error error{copy_error_code, is_critical_};
try {
error.error_message_ = error_message_;
} catch (const std::bad_alloc &) {
error.error_message_ =
std::string_view{"Error while copying Error string. Out of memory"};
}
return error;
}
error::code error::get_id() const { return error_code_; }
namespace impl {
error_registry& get_error_registry() {
static own<error_registry> reg = nullptr;
if(!reg){
reg = heap<error_registry>();
}
assert(reg);
return *reg;
}
}
error no_error(){
return make_error<err::no_error>();
}
namespace impl {
error_or<error::code> error_registry::search_id(const std::string_view& desc)const{
/**
* Search the index in the vector
*/
size_t i{};
size_t info_max_size = std::min<std::size_t>(infos.size(), std::numeric_limits<error::code>::max());
for(i = 0; i < info_max_size; ++i){
if(infos.at(i).description == desc){
break;
}
}
if(i == info_max_size){
return make_error<err::not_found>();
}
return static_cast<error::code>(i);
}
error_or<error::code> error_registry::search_or_register_id(const std::string_view& desc, bool is_critical){
auto err_or_id = search_id(desc);
if(err_or_id.is_value()){
return err_or_id.get_value();
}
auto& err = err_or_id.get_error();
if(err.is_error<err::not_found>()){
size_t new_index = infos.size();
if(new_index == std::numeric_limits<error::code>::max()){
return make_error<err::out_of_memory>("Error registry ids are exhausted");
}
infos.emplace_back(error_info{desc, is_critical});
return static_cast<error::code>(new_index);
}
return std::move(err);
}
}
} // namespace saw
|