diff options
Diffstat (limited to 'src/core/error.cpp')
-rw-r--r-- | src/core/error.cpp | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/src/core/error.cpp b/src/core/error.cpp new file mode 100644 index 0000000..727ca95 --- /dev/null +++ b/src/core/error.cpp @@ -0,0 +1,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 |