| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- #ifndef GI_EXCEPTION_HPP
- #define GI_EXCEPTION_HPP
- #include "base.hpp"
- #include "wrap.hpp"
- #include <exception>
- #include <glib.h>
- 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<Error, GError>
- {
- typedef gi::detail::GBoxedWrapperBase<Error, GError> 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<Error, ::GError, detail::Error, Error_Ref>
- {
- 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<typename Cpp, typename Enable = typename std::enable_if<
- std::is_base_of<Error, Cpp>::value>::type>
- static Cpp wrap(const typename Cpp::BaseObjectType *obj)
- {
- static_assert(sizeof(Cpp) == sizeof(Error), "type wrap not supported");
- Error w(const_cast<GError *>(obj));
- return std::move(*static_cast<Cpp *>(&w));
- }
- };
- class Error_Ref
- : public gi::detail::GBoxedRefWrapper<GLib::Error, ::GError, detail::Error>
- {
- typedef gi::detail::GBoxedRefWrapper<GLib::Error, ::GError, detail::Error>
- 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<GError>
- {
- 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
|