#ifndef GI_EXCEPTION_HPP #define GI_EXCEPTION_HPP #include "base.hpp" #include "wrap.hpp" #include #include namespace gi { namespace detail { inline std::logic_error transform_error(GType tp, const char *name = nullptr) { auto n = g_type_name(tp); auto msg = std::string("could not transform value to type ") + detail::make_string(n); if (name) msg += std::string(" of property \'") + name + "\'"; return std::invalid_argument(msg); } inline std::logic_error unknown_property_error(GType tp, const gchar *property) { auto n = g_type_name(tp); auto msg = std::string("object of type ") + detail::make_string(n) + " does not have property \'" + detail::make_string(property) + "\'"; return std::invalid_argument(msg); } inline std::logic_error unknown_signal_error(GType tp, const std::string &name) { auto n = g_type_name(tp); auto msg = std::string("object of type ") + detail::make_string(n) + " does not have signal \'" + name + "\'"; return std::invalid_argument(msg); } inline std::logic_error invalid_signal_callback_error( GType tp, const std::string &name, const std::string &_msg) { auto n = g_type_name(tp); auto msg = std::string("invalid callback for signal ") + n + "::" + name + "; " + _msg; return std::invalid_argument(msg); } // partially generated GError wrapper class Error : public gi::detail::GBoxedWrapperBase { typedef gi::detail::GBoxedWrapperBase super_type; public: Error(GError *obj = nullptr) : super_type(obj) {} static GType get_type_() G_GNUC_CONST { return g_error_get_type(); } // use with care; dangling reference caution applies here gint &code_() { return gobj_()->code; } const gint &code_() const { return gobj_()->code; } // use with care; dangling reference caution applies here gi::cstring_v message_() const { return gobj_()->message; } // gboolean g_error_matches (const GError* error, GQuark domain, gint code); inline bool matches(GQuark domain, gint code) const { return g_error_matches(gobj_(), domain, code); } }; // class } // namespace detail namespace repository { namespace GLib { class Error_Ref; class Error : public std::runtime_error, public detail::GBoxedWrapper { typedef std::runtime_error super; static inline std::string make_message(GError *error) { return error ? detail::make_string(g_quark_to_string(error->domain)) + ": " + detail::make_string(error->message) + "(" + std::to_string(error->code) + ")" : ""; } public: explicit Error(GError *obj = nullptr) : super(make_message(obj)) { data_ = obj; } // GError* g_error_new_literal (GQuark domain, gint code, const gchar* // message); static inline Error new_literal( GQuark domain, gint code, const std::string &message) { return Error(g_error_new_literal( domain, code, gi::unwrap(message, gi::transfer_none))); } // GError* g_error_copy (const GError* error); inline Error copy() const { return Error(g_error_copy(gobj_())); } // override wrap since we are no longer in a simple single-base case template::value>::type> static Cpp wrap(const typename Cpp::BaseObjectType *obj) { static_assert(sizeof(Cpp) == sizeof(Error), "type wrap not supported"); Error w(const_cast(obj)); return std::move(*static_cast(&w)); } }; class Error_Ref : public gi::detail::GBoxedRefWrapper { typedef gi::detail::GBoxedRefWrapper super_type; using super_type::super_type; // GError* g_error_copy (const GError* error); inline Error copy() const { return Error(g_error_copy(gobj_())); } }; } // namespace GLib template<> struct declare_cpptype_of { typedef GLib::Error type; }; } // namespace repository inline void check_error(GError *error) { if (error) detail::try_throw(repository::GLib::Error(error)); } namespace detail { inline repository::GLib::Error missing_symbol_error(const std::string &symbol) { ::GQuark domain = g_quark_from_static_string("gi-error-quark"); auto error = g_error_new(domain, 0, "could not find symbol %s", symbol.c_str()); return repository::GLib::Error(error); } } // namespace detail // exception specification is generated according to settings and situation // some derived code (e.g. overrides) may need to follow suit accordingly #if GI_EXPECTED // no exception if reported through expected #define GI_NOEXCEPT_DECL(nonthrowing) noexcept #elif GI_DL // otherwise, everything can start failing if resolved at runtime #define GI_NOEXCEPT_DECL(nonthrowing) #else // otherwise, depends on whether (wrapped) function is (GError) throwing #define GI_NOEXCEPT_DECL(nonthrowing) noexcept(nonthrowing) #endif } // namespace gi #endif // GI_EXCEPTION_HPP