Commit e779673d authored by Philip Chimento's avatar Philip Chimento 🚮

arg: Rename GIArgument accessor templates to be shorter

These are used a *lot*, so let's give them the shortest name that still
denotes what they are for.
parent 52c269b0
......@@ -18,9 +18,25 @@
#include "gjs/macros.h"
// GIArgument accessor templates
//
// These are intended to make access to the GIArgument union more type-safe and
// reduce bugs that occur from assigning to one member and reading from another.
// (These bugs often work fine on one processor architecture but crash on
// another.)
//
// gjs_arg_member<T>(GIArgument*) - returns a reference to the appropriate union
// member that would hold the type T. Rarely used, unless as a pointer to a
// return location.
// gjs_arg_get<T>(GIArgument*) - returns the value of type T from the
// appropriate union member.
// gjs_arg_set(GIArgument*, T) - sets the appropriate union member for type T.
// gjs_arg_unset<T>(GIArgument*) - sets the appropriate zero value in the
// appropriate union member for type T.
template <typename T>
GJS_USE inline decltype(auto) gjs_g_argument_value(GIArgument* arg,
T GIArgument::*member) {
GJS_USE inline decltype(auto) gjs_arg_member(GIArgument* arg,
T GIArgument::*member) {
return (arg->*member);
}
......@@ -28,157 +44,156 @@ GJS_USE inline decltype(auto) gjs_g_argument_value(GIArgument* arg,
* which are in fact typedef's of other generic types.
* Setting a tag for a type allows to perform proper specialization. */
template <typename T, GITypeTag TAG = GI_TYPE_TAG_VOID>
GJS_USE inline decltype(auto) gjs_g_argument_value(GIArgument* arg) {
GJS_USE inline decltype(auto) gjs_arg_member(GIArgument* arg) {
static_assert(!std::is_arithmetic<T>(), "Missing declaration for type");
using NonconstPtrT =
std::add_pointer_t<std::remove_const_t<std::remove_pointer_t<T>>>;
return reinterpret_cast<NonconstPtrT&>(
gjs_g_argument_value(arg, &GIArgument::v_pointer));
gjs_arg_member(arg, &GIArgument::v_pointer));
}
template <>
GJS_USE inline decltype(auto) gjs_g_argument_value<bool>(GIArgument* arg) {
return gjs_g_argument_value(arg, &GIArgument::v_boolean);
GJS_USE inline decltype(auto) gjs_arg_member<bool>(GIArgument* arg) {
return gjs_arg_member(arg, &GIArgument::v_boolean);
}
template <>
GJS_USE inline decltype(auto)
gjs_g_argument_value<gboolean, GI_TYPE_TAG_BOOLEAN>(GIArgument* arg) {
return gjs_g_argument_value(arg, &GIArgument::v_boolean);
GJS_USE inline decltype(auto) gjs_arg_member<gboolean, GI_TYPE_TAG_BOOLEAN>(
GIArgument* arg) {
return gjs_arg_member(arg, &GIArgument::v_boolean);
}
template <>
GJS_USE inline decltype(auto) gjs_g_argument_value<int8_t>(GIArgument* arg) {
return gjs_g_argument_value(arg, &GIArgument::v_int8);
GJS_USE inline decltype(auto) gjs_arg_member<int8_t>(GIArgument* arg) {
return gjs_arg_member(arg, &GIArgument::v_int8);
}
template <>
GJS_USE inline decltype(auto) gjs_g_argument_value<uint8_t>(GIArgument* arg) {
return gjs_g_argument_value(arg, &GIArgument::v_uint8);
GJS_USE inline decltype(auto) gjs_arg_member<uint8_t>(GIArgument* arg) {
return gjs_arg_member(arg, &GIArgument::v_uint8);
}
template <>
GJS_USE inline decltype(auto) gjs_g_argument_value<int16_t>(GIArgument* arg) {
return gjs_g_argument_value(arg, &GIArgument::v_int16);
GJS_USE inline decltype(auto) gjs_arg_member<int16_t>(GIArgument* arg) {
return gjs_arg_member(arg, &GIArgument::v_int16);
}
template <>
GJS_USE inline decltype(auto) gjs_g_argument_value<uint16_t>(GIArgument* arg) {
return gjs_g_argument_value(arg, &GIArgument::v_uint16);
GJS_USE inline decltype(auto) gjs_arg_member<uint16_t>(GIArgument* arg) {
return gjs_arg_member(arg, &GIArgument::v_uint16);
}
template <>
GJS_USE inline decltype(auto) gjs_g_argument_value<int32_t>(GIArgument* arg) {
return gjs_g_argument_value(arg, &GIArgument::v_int32);
GJS_USE inline decltype(auto) gjs_arg_member<int32_t>(GIArgument* arg) {
return gjs_arg_member(arg, &GIArgument::v_int32);
}
template <>
GJS_USE inline decltype(auto) gjs_g_argument_value<uint32_t>(GIArgument* arg) {
return gjs_g_argument_value(arg, &GIArgument::v_uint32);
GJS_USE inline decltype(auto) gjs_arg_member<uint32_t>(GIArgument* arg) {
return gjs_arg_member(arg, &GIArgument::v_uint32);
}
template <>
GJS_USE inline decltype(auto) gjs_g_argument_value<int64_t>(GIArgument* arg) {
return gjs_g_argument_value(arg, &GIArgument::v_int64);
GJS_USE inline decltype(auto) gjs_arg_member<int64_t>(GIArgument* arg) {
return gjs_arg_member(arg, &GIArgument::v_int64);
}
template <>
GJS_USE inline decltype(auto) gjs_g_argument_value<uint64_t>(GIArgument* arg) {
return gjs_g_argument_value(arg, &GIArgument::v_uint64);
GJS_USE inline decltype(auto) gjs_arg_member<uint64_t>(GIArgument* arg) {
return gjs_arg_member(arg, &GIArgument::v_uint64);
}
// gunichar is stored in v_uint32
template <>
GJS_USE inline decltype(auto) gjs_g_argument_value<char32_t>(GIArgument* arg) {
return gjs_g_argument_value(arg, &GIArgument::v_uint32);
GJS_USE inline decltype(auto) gjs_arg_member<char32_t>(GIArgument* arg) {
return gjs_arg_member(arg, &GIArgument::v_uint32);
}
template <>
GJS_USE inline decltype(auto) gjs_g_argument_value<GType, GI_TYPE_TAG_GTYPE>(
GJS_USE inline decltype(auto) gjs_arg_member<GType, GI_TYPE_TAG_GTYPE>(
GIArgument* arg) {
return gjs_g_argument_value(arg, &GIArgument::v_ssize);
return gjs_arg_member(arg, &GIArgument::v_ssize);
}
template <>
GJS_USE inline decltype(auto) gjs_g_argument_value<float>(GIArgument* arg) {
return gjs_g_argument_value(arg, &GIArgument::v_float);
GJS_USE inline decltype(auto) gjs_arg_member<float>(GIArgument* arg) {
return gjs_arg_member(arg, &GIArgument::v_float);
}
template <>
GJS_USE inline decltype(auto) gjs_g_argument_value<double>(GIArgument* arg) {
return gjs_g_argument_value(arg, &GIArgument::v_double);
GJS_USE inline decltype(auto) gjs_arg_member<double>(GIArgument* arg) {
return gjs_arg_member(arg, &GIArgument::v_double);
}
template <>
GJS_USE inline decltype(auto) gjs_g_argument_value<char*>(GIArgument* arg) {
return gjs_g_argument_value(arg, &GIArgument::v_string);
GJS_USE inline decltype(auto) gjs_arg_member<char*>(GIArgument* arg) {
return gjs_arg_member(arg, &GIArgument::v_string);
}
template <>
GJS_USE inline decltype(auto) gjs_g_argument_value<void*>(GIArgument* arg) {
return gjs_g_argument_value(arg, &GIArgument::v_pointer);
GJS_USE inline decltype(auto) gjs_arg_member<void*>(GIArgument* arg) {
return gjs_arg_member(arg, &GIArgument::v_pointer);
}
template <>
GJS_USE inline decltype(auto) gjs_g_argument_value<std::nullptr_t>(
GIArgument* arg) {
return gjs_g_argument_value(arg, &GIArgument::v_pointer);
GJS_USE inline decltype(auto) gjs_arg_member<std::nullptr_t>(GIArgument* arg) {
return gjs_arg_member(arg, &GIArgument::v_pointer);
}
template <typename T, GITypeTag TAG = GI_TYPE_TAG_VOID>
inline void gjs_g_argument_value_set(GIArgument* arg, T v) {
gjs_g_argument_value<T, TAG>(arg) = v;
inline void gjs_arg_set(GIArgument* arg, T v) {
gjs_arg_member<T, TAG>(arg) = v;
}
template <typename T, GITypeTag TAG = GI_TYPE_TAG_VOID>
inline void gjs_g_argument_value_set(GIArgument* arg, T* v) {
inline void gjs_arg_set(GIArgument* arg, T* v) {
using NonconstT = std::remove_const_t<T>;
gjs_g_argument_value<NonconstT*, TAG>(arg) = const_cast<NonconstT*>(v);
gjs_arg_member<NonconstT*, TAG>(arg) = const_cast<NonconstT*>(v);
}
// Store function pointers as void*. It is a requirement of GLib that your
// compiler can do this
template <typename ReturnT, typename... Args>
inline void gjs_g_argument_value_set(GIArgument* arg, ReturnT (*v)(Args...)) {
gjs_g_argument_value<void*>(arg) = reinterpret_cast<void*>(v);
inline void gjs_arg_set(GIArgument* arg, ReturnT (*v)(Args...)) {
gjs_arg_member<void*>(arg) = reinterpret_cast<void*>(v);
}
template <>
inline void gjs_g_argument_value_set<bool>(GIArgument* arg, bool v) {
gjs_g_argument_value<bool>(arg) = !!v;
inline void gjs_arg_set<bool>(GIArgument* arg, bool v) {
gjs_arg_member<bool>(arg) = !!v;
}
template <>
inline void gjs_g_argument_value_set<gboolean, GI_TYPE_TAG_BOOLEAN>(
GIArgument* arg, gboolean v) {
gjs_g_argument_value<bool>(arg) = !!v;
inline void gjs_arg_set<gboolean, GI_TYPE_TAG_BOOLEAN>(GIArgument* arg,
gboolean v) {
gjs_arg_member<bool>(arg) = !!v;
}
template <typename T, GITypeTag TAG = GI_TYPE_TAG_VOID>
GJS_USE inline T gjs_g_argument_value_get(GIArgument* arg) {
return gjs_g_argument_value<T, TAG>(arg);
GJS_USE inline T gjs_arg_get(GIArgument* arg) {
return gjs_arg_member<T, TAG>(arg);
}
template <>
GJS_USE inline bool gjs_g_argument_value_get<bool>(GIArgument* arg) {
return !!gjs_g_argument_value<bool>(arg);
GJS_USE inline bool gjs_arg_get<bool>(GIArgument* arg) {
return !!gjs_arg_member<bool>(arg);
}
template <>
GJS_USE inline gboolean gjs_g_argument_value_get<gboolean, GI_TYPE_TAG_BOOLEAN>(
GJS_USE inline gboolean gjs_arg_get<gboolean, GI_TYPE_TAG_BOOLEAN>(
GIArgument* arg) {
return !!gjs_g_argument_value<bool>(arg);
return !!gjs_arg_member<bool>(arg);
}
template <typename T, GITypeTag TAG = GI_TYPE_TAG_VOID>
inline std::enable_if_t<!std::is_pointer<T>::value> gjs_g_argument_value_unset(
inline std::enable_if_t<!std::is_pointer<T>::value> gjs_arg_unset(
GIArgument* arg) {
gjs_g_argument_value_set<T, TAG>(arg, static_cast<T>(0));
gjs_arg_set<T, TAG>(arg, static_cast<T>(0));
}
template <typename T, GITypeTag TAG = GI_TYPE_TAG_VOID>
inline std::enable_if_t<std::is_pointer<T>::value> gjs_g_argument_value_unset(
inline std::enable_if_t<std::is_pointer<T>::value> gjs_arg_unset(
GIArgument* arg) {
gjs_g_argument_value_set<T, TAG>(arg, nullptr);
gjs_arg_set<T, TAG>(arg, nullptr);
}
......@@ -674,7 +674,7 @@ value_to_ghashtable_key(JSContext *cx,
template <typename T>
GJS_USE static T* heap_value_new_from_arg(GIArgument* val_arg) {
T* heap_val = g_new(T, 1);
*heap_val = gjs_g_argument_value_get<T>(val_arg);
*heap_val = gjs_arg_get<T>(val_arg);
return heap_val;
}
......@@ -2460,7 +2460,7 @@ GJS_JSAPI_RETURN_CONVENTION static bool fill_vector_from_carray(
JSContext* cx, JS::RootedValueVector& elems, // NOLINT(runtime/references)
GITypeInfo* param_info, GIArgument* arg, void* array, size_t length) {
for (size_t i = 0; i < length; i++) {
gjs_g_argument_value_set(arg, *(static_cast<T*>(array) + i));
gjs_arg_set(arg, *(static_cast<T*>(array) + i));
if (!gjs_value_from_g_argument(cx, elems[i], param_info, arg, true))
return false;
......@@ -2706,7 +2706,7 @@ GJS_JSAPI_RETURN_CONVENTION static bool fill_vector_from_zero_terminated_carray(
T* array = static_cast<T*>(c_array);
for (size_t i = 0; array[i]; i++) {
gjs_g_argument_value_set(arg, array[i]);
gjs_arg_set(arg, array[i]);
if (!elems.growBy(1)) {
JS_ReportOutOfMemory(cx);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment