diff options
Diffstat (limited to 'forstio/core/error.h')
-rw-r--r-- | forstio/core/error.h | 112 |
1 files changed, 66 insertions, 46 deletions
diff --git a/forstio/core/error.h b/forstio/core/error.h index a8d299b..304b375 100644 --- a/forstio/core/error.h +++ b/forstio/core/error.h @@ -1,5 +1,7 @@ #pragma once +#include <algorithm> +#include <limits> #include <string> #include <string_view> #include <variant> @@ -19,13 +21,13 @@ class error { public: using code = uint32_t; private: - std::variant<std::string_view, std::string> error_message_; code error_code_; + bool is_critical_; + std::variant<std::string_view, std::string> error_message_; public: - error(); - error(error::code id); - error(error::code id, const std::string_view &msg); + error(error::code id, bool is_critical); + error(error::code id, bool is_critical, const std::string_view &msg); error(error &&error); SAW_FORBID_COPY(error); @@ -44,82 +46,94 @@ public: error copy_error() const; code get_id() const; + + template<typename T> + bool is_error() const; }; +template<typename T> +class error_or; + namespace impl { class error_registry { private: struct error_info { + error_info() = delete; + error_info(const std::string_view& d_, bool critical_):description{d_}, is_critical{critical_}{} + std::string_view description; + bool is_critical; }; std::vector<error_info> infos; public: - error::code search_or_register_id(const std::string_view& desc){ - auto find = std::find_if(infos.begin(), infos.end(), - - ); + error_or<error::code> search_id(const std::string_view& desc) const; - if( find != find.end() ){ - - } - } + error_or<error::code> search_or_register_id(const std::string_view& desc, bool is_critical); }; error_registry& get_error_registry(); template<typename T> error::code get_template_id(){ - static error::code id = 0; + static error::code id = std::numeric_limits<error::code>::max(); - if(id == 0){ + if(id == std::numeric_limits<error::code>::max()){ auto& reg = get_error_registry(); - id = reg.search_or_register_id(typename T::description); + + auto err_or_id = reg.search_or_register_id(T::description, T::is_critical); + if(err_or_id.is_error()){ + return std::numeric_limits<error::code>::max(); + } + + id = err_or_id.get_value(); } return id; } +} template<typename T> error make_error(const std::string_view& generic){ - auto id = get_template_id<T>(); + error::code id = impl::get_template_id<T>(); - return error{id}; + return error{id, T::is_critical, generic}; } -error make_error(const std::string_view &generic, error::code c); +template<typename T> error make_error(){ + error::code id = impl::get_template_id<T>(); -template <typename Formatter> -error make_error(const Formatter &formatter, error::code code, - const std::string_view &generic) { - try { - std::string error_msg = formatter(); - return error{std::move(error_msg), code}; - } catch (std::bad_alloc &) { - return error{generic, code}; - } + return error{id, T::is_critical}; } -error critical_error(const std::string_view &generic, - error::code c = error::code::GenericCritical); +error make_error(error::code code, const std::string_view &generic); -template <typename Formatter> -error critical_error(const Formatter &formatter, - const std::string_view &generic, - error::code c = error::code::GenericCritical) { - return make_error(formatter, c, generic); -} -error recoverable_error(const std::string_view &generic, - error::code c = error::code::GenericRecoverable); +namespace err { +struct no_error { + static constexpr std::string_view description = "No error has occured"; + static constexpr bool is_critical = false; +}; + +struct buffer_exhausted { + static constexpr std::string_view description = "Buffer is too small"; + static constexpr bool is_critical = false; +}; + +struct not_found { + static constexpr std::string_view description = "Not found"; + static constexpr bool is_critical = false; +}; -template <typename Formatter> -error recoverable_error(const Formatter &formatter, - const std::string_view &generic, - error::code c = error::code::GenericRecoverable) { - return make_error(formatter, c, generic); +struct out_of_memory { + static constexpr std::string_view description = "Out of memory"; + static constexpr bool is_critical = true; +}; } +/** + * Shorthand for no error happened + */ error no_error(); /** @@ -165,17 +179,17 @@ public: return std::holds_alternative<class error>(value_or_error_); } - class error &error() { + class error &get_error() { return std::get<class error>(value_or_error_); } - const class error &error() const { + const class error &get_error() const { return std::get<class error>(value_or_error_); } - fix_void<T> &value() { return std::get<fix_void<T>>(value_or_error_); } + fix_void<T> &get_value() { return std::get<fix_void<T>>(value_or_error_); } - const fix_void<T> &value() const { + const fix_void<T> &get_value() const { return std::get<fix_void<T>>(value_or_error_); } }; @@ -185,4 +199,10 @@ private: error_or() = delete; }; +template<typename T> +bool error::is_error() const { + + return error_code_ == impl::get_template_id<T>(); +} + } // namespace saw |