1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
|
#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
|