diff options
Diffstat (limited to 'src/core/error.h')
-rw-r--r-- | src/core/error.h | 248 |
1 files changed, 0 insertions, 248 deletions
diff --git a/src/core/error.h b/src/core/error.h deleted file mode 100644 index e816734..0000000 --- a/src/core/error.h +++ /dev/null @@ -1,248 +0,0 @@ -#pragma once - -#include <algorithm> -#include <limits> -#include <string> -#include <string_view> -#include <variant> -#include <vector> - -#include <cassert> - -#include "common.h" - -namespace saw { -/** - * Utility class for generating errors. Has a base distinction between - * critical and recoverable errors. Additional code ids can be provided to the - * constructor if additional distinctions are necessary. - */ -class error { -public: - using code = uint32_t; -private: - code error_code_; - bool is_critical_; - std::variant<std::string_view, std::string> error_message_; - -public: - 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); - - error &operator=(error &&) = default; - - const std::string_view get_message() const; - - const std::string_view get_category() const; - - bool failed() const; - - bool is_critical() const; - bool is_recoverable() const; - - /** - * Replaces the copy constructor. We need this since we want to explicitly copy and not implicitly - */ - error copy_error() const; - - code get_id() const; - - template<typename T> - bool is_type() 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_registry(); - - SAW_FORBID_COPY(error_registry); - SAW_FORBID_MOVE(error_registry); - - error_or<const std::string_view> search_category(const error::code& id) const; - - error_or<error::code> search_id(const std::string_view& desc) const; - - 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 = std::numeric_limits<error::code>::max(); - - if(id == std::numeric_limits<error::code>::max()){ - auto& reg = get_error_registry(); - - 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){ - error::code id = impl::get_template_id<T>(); - - return error{id, T::is_critical, generic}; -} - -template<typename T> error make_error(){ - error::code id = impl::get_template_id<T>(); - - return error{id, T::is_critical}; -} - -error make_error(error::code code, const std::string_view &generic); - - -namespace err { -struct no_error { - static constexpr std::string_view description = "No error has occured"; - static constexpr bool is_critical = false; -}; - -struct recoverable { - static constexpr std::string_view description = "Generic recoverable error"; - static constexpr bool is_critical = false; -}; - -struct critical { - static constexpr std::string_view description = "Generic critical error"; - static constexpr bool is_critical = true; -}; - -struct buffer_exhausted { - static constexpr std::string_view description = "Buffer Exhausted"; - static constexpr bool is_critical = false; -}; - -struct not_found { - static constexpr std::string_view description = "Not found"; - static constexpr bool is_critical = false; -}; - -struct out_of_memory { - static constexpr std::string_view description = "Out of memory"; - static constexpr bool is_critical = true; -}; - -struct invalid_state { - static constexpr std::string_view description = "Invalid state"; - static constexpr bool is_critical = true; -}; - -struct not_supported { - static constexpr std::string_view description = "Not supported"; - static constexpr bool is_critical = false; -}; - -struct not_implemented { - static constexpr std::string_view description = "Not implemented"; - static constexpr bool is_critical = true; -}; - -struct already_exists { - static constexpr std::string_view description = "Already exists"; - static constexpr bool is_critical = false; -}; -} - -/** - * Shorthand for no error happened - */ -error no_error(); - -/** - * Exception alternative. Since I code without exceptions this class is - * essentially a kind of exception replacement. - */ -template <typename T> class error_or; - -class error_or_value { -public: - virtual ~error_or_value() = default; - - template <typename T> error_or<unfix_void<T>> &as() { - return static_cast<error_or<unfix_void<T>> &>(*this); - } - - template <typename T> const error_or<unfix_void<T>> &as() const { - return static_cast<const error_or<unfix_void<T>> &>(*this); - } -}; - -template <typename T> class error_or final : public error_or_value { -private: - std::variant<error, fix_void<T>> value_or_error_; - - static_assert(!std::is_same_v<T, void_t>, - "Don't use internal private types"); - -public: - error_or():value_or_error_{fix_void<T>{}}{} - error_or(const fix_void<T> &value) : value_or_error_{value} {} - - error_or(fix_void<T> &&value) : value_or_error_{std::move(value)} {} - - error_or(const error &error) : value_or_error_{error} {} - error_or(error &&error) : value_or_error_{std::move(error)} {} - - bool is_value() const { - return std::holds_alternative<fix_void<T>>(value_or_error_); - } - - bool is_error() const { - return std::holds_alternative<class error>(value_or_error_); - } - - class error &get_error() { - return std::get<class error>(value_or_error_); - } - - const class error &get_error() const { - return std::get<class error>(value_or_error_); - } - - fix_void<T> &get_value() { return std::get<fix_void<T>>(value_or_error_); } - - const fix_void<T> &get_value() const { - return std::get<fix_void<T>>(value_or_error_); - } -}; - -template <typename T> class error_or<error_or<T>> { -private: - error_or() = delete; -}; - -template<typename T> -bool error::is_type() const { - - return error_code_ == impl::get_template_id<T>(); -} - -} // namespace saw |