From f61f7ebacc987200428c1f9f685ee33e98f4a970 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Wed, 15 Feb 2023 02:43:16 +0700 Subject: [PATCH] welcome error codes --- develop/singles/headers/meta.hpp/meta_all.hpp | 109 +++++++++++++++--- headers/meta.hpp/meta_base.hpp | 5 +- headers/meta.hpp/meta_base/base.hpp | 1 + headers/meta.hpp/meta_base/exceptions.hpp | 93 +++++++++++++-- .../meta_detail/value_utilities/uarg.hpp | 4 +- .../meta_detail/value_utilities/uinst.hpp | 2 +- headers/meta.hpp/meta_uvalue/uvalue.hpp | 6 +- 7 files changed, 187 insertions(+), 33 deletions(-) diff --git a/develop/singles/headers/meta.hpp/meta_all.hpp b/develop/singles/headers/meta.hpp/meta_all.hpp index c2459cf..799a946 100644 --- a/develop/singles/headers/meta.hpp/meta_all.hpp +++ b/develop/singles/headers/meta.hpp/meta_all.hpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -307,23 +308,100 @@ namespace meta_hpp::detail # define META_HPP_TRY try # define META_HPP_CATCH(...) catch ( __VA_ARGS__ ) # define META_HPP_RETHROW() throw -# define META_HPP_THROW(...) throw ::meta_hpp::detail::exception(__VA_ARGS__) #else # define META_HPP_TRY if ( true ) # define META_HPP_CATCH(...) if ( false ) # define META_HPP_RETHROW() std::abort() -# define META_HPP_THROW(...) std::abort() #endif namespace meta_hpp::detail { -#if !defined(META_HPP_NO_EXCEPTIONS) - class exception final : public std::runtime_error { - public: - explicit exception(const char* what) - : std::runtime_error(what) {} + enum class generic_error { + no_error, + bad_uvalue_cast, + bad_argument_cast, + bad_instance_cast, }; + + class generic_error_category final : public std::error_category { + public: + ~generic_error_category() override = default; + + generic_error_category(generic_error_category&&) = delete; + generic_error_category(const generic_error_category&) = delete; + + generic_error_category& operator=(generic_error_category&&) = delete; + generic_error_category& operator=(const generic_error_category&) = delete; + + [[nodiscard]] const char* name() const noexcept override { + return "generic"; + } + + [[nodiscard]] std::string message(int ev) const override { + switch ( static_cast(ev) ) { + case generic_error::no_error: + return "no error"; + case generic_error::bad_uvalue_cast: + return "bad uvalue cast"; + case generic_error::bad_argument_cast: + return "bad argument cast"; + case generic_error::bad_instance_cast: + return "bad instance cast"; + } + return "unexpected error code"; + } + + static const std::error_category& instance() noexcept { + static const generic_error_category instance; + return instance; + } + + private: + generic_error_category() = default; + }; +} + +namespace std +{ + template <> + struct is_error_code_enum : true_type {}; +} + +namespace meta_hpp::detail +{ + inline std::error_code make_error_code(generic_error err) noexcept { + static_assert(std::is_same_v>); + return std::error_code{static_cast(err), generic_error_category::instance()}; + } +} + +namespace meta_hpp::detail +{ + class generic_exception final : public std::logic_error { + public: + explicit generic_exception(generic_error err) + : generic_exception{make_error_code(err)} {} + + explicit generic_exception(std::error_code ec) + : std::logic_error(ec.message()) + , error_code_{ec} {} + + [[nodiscard]] const std::error_code& code() const noexcept { + return error_code_; + } + + private: + std::error_code error_code_{}; + }; + + [[noreturn]] inline void throw_generic_exception(generic_error err) { +#if !defined(META_HPP_NO_EXCEPTIONS) + throw generic_exception{err}; +#else + (void)err; + std::abort(); #endif + } } namespace meta_hpp::detail @@ -1333,9 +1411,8 @@ namespace meta_hpp::detail namespace meta_hpp { -#if !defined(META_HPP_NO_EXCEPTIONS) - using detail::exception; -#endif + using detail::generic_error; + using detail::generic_exception; using detail::hashed_string; using detail::memory_buffer; @@ -5558,7 +5635,7 @@ namespace meta_hpp::detail } } - META_HPP_THROW("bad argument cast"); + throw_generic_exception(generic_error::bad_argument_cast); } template < typename To > @@ -5614,7 +5691,7 @@ namespace meta_hpp::detail } } - META_HPP_THROW("bad argument cast"); + throw_generic_exception(generic_error::bad_argument_cast); } } @@ -6068,7 +6145,7 @@ namespace meta_hpp::detail } } - META_HPP_THROW("bad instance cast"); + throw_generic_exception(generic_error::bad_instance_cast); } } @@ -8675,7 +8752,7 @@ namespace meta_hpp } } - META_HPP_THROW("bad value cast"); + throw_generic_exception(generic_error::bad_uvalue_cast); } template < typename T > @@ -8692,7 +8769,7 @@ namespace meta_hpp } } - META_HPP_THROW("bad value cast"); + throw_generic_exception(generic_error::bad_uvalue_cast); } template < typename T > @@ -8709,7 +8786,7 @@ namespace meta_hpp } } - META_HPP_THROW("bad value cast"); + throw_generic_exception(generic_error::bad_uvalue_cast); } template < typename T > diff --git a/headers/meta.hpp/meta_base.hpp b/headers/meta.hpp/meta_base.hpp index 447cc1c..92b3022 100644 --- a/headers/meta.hpp/meta_base.hpp +++ b/headers/meta.hpp/meta_base.hpp @@ -30,9 +30,8 @@ namespace meta_hpp { -#if !defined(META_HPP_NO_EXCEPTIONS) - using detail::exception; -#endif + using detail::generic_error; + using detail::generic_exception; using detail::hashed_string; using detail::memory_buffer; diff --git a/headers/meta.hpp/meta_base/base.hpp b/headers/meta.hpp/meta_base/base.hpp index 220469d..62bd1cc 100644 --- a/headers/meta.hpp/meta_base/base.hpp +++ b/headers/meta.hpp/meta_base/base.hpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include diff --git a/headers/meta.hpp/meta_base/exceptions.hpp b/headers/meta.hpp/meta_base/exceptions.hpp index 056303a..ebeebf2 100644 --- a/headers/meta.hpp/meta_base/exceptions.hpp +++ b/headers/meta.hpp/meta_base/exceptions.hpp @@ -12,21 +12,98 @@ # define META_HPP_TRY try # define META_HPP_CATCH(...) catch ( __VA_ARGS__ ) # define META_HPP_RETHROW() throw -# define META_HPP_THROW(...) throw ::meta_hpp::detail::exception(__VA_ARGS__) #else # define META_HPP_TRY if ( true ) # define META_HPP_CATCH(...) if ( false ) # define META_HPP_RETHROW() std::abort() -# define META_HPP_THROW(...) std::abort() #endif namespace meta_hpp::detail { -#if !defined(META_HPP_NO_EXCEPTIONS) - class exception final : public std::runtime_error { - public: - explicit exception(const char* what) - : std::runtime_error(what) {} + enum class generic_error { + no_error, + bad_uvalue_cast, + bad_argument_cast, + bad_instance_cast, + }; + + class generic_error_category final : public std::error_category { + public: + ~generic_error_category() override = default; + + generic_error_category(generic_error_category&&) = delete; + generic_error_category(const generic_error_category&) = delete; + + generic_error_category& operator=(generic_error_category&&) = delete; + generic_error_category& operator=(const generic_error_category&) = delete; + + [[nodiscard]] const char* name() const noexcept override { + return "generic"; + } + + [[nodiscard]] std::string message(int ev) const override { + switch ( static_cast(ev) ) { + case generic_error::no_error: + return "no error"; + case generic_error::bad_uvalue_cast: + return "bad uvalue cast"; + case generic_error::bad_argument_cast: + return "bad argument cast"; + case generic_error::bad_instance_cast: + return "bad instance cast"; + } + return "unexpected error code"; + } + + static const std::error_category& instance() noexcept { + static const generic_error_category instance; + return instance; + } + + private: + generic_error_category() = default; }; -#endif +} + +namespace std +{ + template <> + struct is_error_code_enum : true_type {}; +} + +namespace meta_hpp::detail +{ + inline std::error_code make_error_code(generic_error err) noexcept { + static_assert(std::is_same_v>); + return std::error_code{static_cast(err), generic_error_category::instance()}; + } +} + +namespace meta_hpp::detail +{ + class generic_exception final : public std::logic_error { + public: + explicit generic_exception(generic_error err) + : generic_exception{make_error_code(err)} {} + + explicit generic_exception(std::error_code ec) + : std::logic_error(ec.message()) + , error_code_{ec} {} + + [[nodiscard]] const std::error_code& code() const noexcept { + return error_code_; + } + + private: + std::error_code error_code_{}; + }; + + [[noreturn]] inline void throw_generic_exception(generic_error err) { +#if !defined(META_HPP_NO_EXCEPTIONS) + throw generic_exception{err}; +#else + (void)err; + std::abort(); +#endif + } } diff --git a/headers/meta.hpp/meta_detail/value_utilities/uarg.hpp b/headers/meta.hpp/meta_detail/value_utilities/uarg.hpp index e710c02..76e7233 100644 --- a/headers/meta.hpp/meta_detail/value_utilities/uarg.hpp +++ b/headers/meta.hpp/meta_detail/value_utilities/uarg.hpp @@ -313,7 +313,7 @@ namespace meta_hpp::detail } } - META_HPP_THROW("bad argument cast"); + throw_generic_exception(generic_error::bad_argument_cast); } template < typename To > @@ -369,7 +369,7 @@ namespace meta_hpp::detail } } - META_HPP_THROW("bad argument cast"); + throw_generic_exception(generic_error::bad_argument_cast); } } diff --git a/headers/meta.hpp/meta_detail/value_utilities/uinst.hpp b/headers/meta.hpp/meta_detail/value_utilities/uinst.hpp index 638fd77..4f40b9b 100644 --- a/headers/meta.hpp/meta_detail/value_utilities/uinst.hpp +++ b/headers/meta.hpp/meta_detail/value_utilities/uinst.hpp @@ -231,6 +231,6 @@ namespace meta_hpp::detail } } - META_HPP_THROW("bad instance cast"); + throw_generic_exception(generic_error::bad_instance_cast); } } diff --git a/headers/meta.hpp/meta_uvalue/uvalue.hpp b/headers/meta.hpp/meta_uvalue/uvalue.hpp index db50f39..084f609 100644 --- a/headers/meta.hpp/meta_uvalue/uvalue.hpp +++ b/headers/meta.hpp/meta_uvalue/uvalue.hpp @@ -453,7 +453,7 @@ namespace meta_hpp } } - META_HPP_THROW("bad value cast"); + throw_generic_exception(generic_error::bad_uvalue_cast); } template < typename T > @@ -470,7 +470,7 @@ namespace meta_hpp } } - META_HPP_THROW("bad value cast"); + throw_generic_exception(generic_error::bad_uvalue_cast); } template < typename T > @@ -487,7 +487,7 @@ namespace meta_hpp } } - META_HPP_THROW("bad value cast"); + throw_generic_exception(generic_error::bad_uvalue_cast); } template < typename T >