[gjs] arg: Add an utility header to access to GIArgument union members by type
- From: Philip Chimento <pchimento src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs] arg: Add an utility header to access to GIArgument union members by type
- Date: Sun, 5 Jul 2020 01:19:26 +0000 (UTC)
commit c2e40a219a020a8b35d220cc50a85deed3ec0e25
Author: Marco Trevisan (TreviƱo) <mail 3v1n0 net>
Date: Mon May 18 15:49:16 2020 +0200
arg: Add an utility header to access to GIArgument union members by type
Instead of manually picking the GIArgument union value, make possible to
select the right one using a template type, so that we can avoid
repeating the same code multiple times in the various template
functions.
As per this, utilize to avoid repetition in arg template functions
gi/arg-inl.h | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
gi/arg.cpp | 22 ++++++------
2 files changed, 123 insertions(+), 11 deletions(-)
---
diff --git a/gi/arg-inl.h b/gi/arg-inl.h
new file mode 100644
index 00000000..4c97b2b6
--- /dev/null
+++ b/gi/arg-inl.h
@@ -0,0 +1,112 @@
+/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
+/*
+ * SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
+ *
+ * Copyright (c) 2020 Marco Trevisan <marco trevisan canonical com>
+ */
+
+#pragma once
+
+#include <stdint.h>
+
+#include <type_traits>
+
+#include <girepository.h>
+#include <glib-object.h> // for GType
+#include <glib.h> // for gboolean
+
+#include "gjs/macros.h"
+
+template <typename T>
+GJS_USE inline decltype(auto) gjs_g_argument_value(GIArgument* arg,
+ T GIArgument::*member) {
+ return (arg->*member);
+}
+
+/* The tag is needed to disambiguate types such as gboolean and GType
+ * 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) {
+ static_assert(!std::is_arithmetic<T>(), "Missing declaration for type");
+
+ return reinterpret_cast<T>(
+ gjs_g_argument_value(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);
+}
+
+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);
+}
+
+template <>
+GJS_USE inline decltype(auto) gjs_g_argument_value<int8_t>(GIArgument* arg) {
+ return gjs_g_argument_value(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);
+}
+
+template <>
+GJS_USE inline decltype(auto) gjs_g_argument_value<int16_t>(GIArgument* arg) {
+ return gjs_g_argument_value(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);
+}
+
+template <>
+GJS_USE inline decltype(auto) gjs_g_argument_value<int32_t>(GIArgument* arg) {
+ return gjs_g_argument_value(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);
+}
+
+template <>
+GJS_USE inline decltype(auto) gjs_g_argument_value<int64_t>(GIArgument* arg) {
+ return gjs_g_argument_value(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);
+}
+
+template <>
+GJS_USE inline decltype(auto) gjs_g_argument_value<GType, GI_TYPE_TAG_GTYPE>(
+ GIArgument* arg) {
+ return gjs_g_argument_value(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);
+}
+
+template <>
+GJS_USE inline decltype(auto) gjs_g_argument_value<double>(GIArgument* arg) {
+ return gjs_g_argument_value(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_pointer);
+}
+
+template <>
+GJS_USE inline decltype(auto) gjs_g_argument_value<void*>(GIArgument* arg) {
+ return gjs_g_argument_value(arg, &GIArgument::v_pointer);
+}
diff --git a/gi/arg.cpp b/gi/arg.cpp
index ba706021..45d0ad24 100644
--- a/gi/arg.cpp
+++ b/gi/arg.cpp
@@ -46,6 +46,7 @@
#include <jsfriendapi.h> // for JS_IsUint8Array, JS_GetObjectFunc...
#include <mozilla/Vector.h>
+#include "gi/arg-inl.h"
#include "gi/arg.h"
#include "gi/boxed.h"
#include "gi/foreign.h"
@@ -2444,12 +2445,12 @@ gjs_array_from_g_list (JSContext *context,
return true;
}
-template <typename T, T GIArgument::*member>
+template <typename T>
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++) {
- arg->*member = *(static_cast<T*>(array) + i);
+ gjs_g_argument_value<T>(arg) = *(static_cast<T*>(array) + i);
if (!gjs_value_from_g_argument(cx, elems[i], param_info, arg, true))
return false;
@@ -2504,9 +2505,9 @@ gjs_array_from_carray_internal (JSContext *context,
return false;
}
-#define ITERATE(type) \
- if (!fill_vector_from_carray<g##type, &GIArgument::v_##type>( \
- context, elems, param_info, &arg, array, length)) \
+#define ITERATE(type) \
+ if (!fill_vector_from_carray<g##type>(context, elems, param_info, &arg, \
+ array, length)) \
return false;
switch (element_type) {
@@ -2688,14 +2689,14 @@ gjs_array_from_boxed_array (JSContext *context,
param_info, length, data);
}
-template <typename T, T GIArgument::*member>
+template <typename T>
GJS_JSAPI_RETURN_CONVENTION static bool fill_vector_from_zero_terminated_carray(
JSContext* cx, JS::RootedValueVector& elems, // NOLINT(runtime/references)
GITypeInfo* param_info, GIArgument* arg, void* c_array) {
T* array = static_cast<T*>(c_array);
for (size_t i = 0; array[i]; i++) {
- arg->*member = array[i];
+ gjs_g_argument_value<T>(arg) = array[i];
if (!elems.growBy(1)) {
JS_ReportOutOfMemory(cx);
@@ -2737,10 +2738,9 @@ gjs_array_from_zero_terminated_c_array (JSContext *context,
JS::RootedValueVector elems(context);
-#define ITERATE(type) \
- if (!fill_vector_from_zero_terminated_carray<g##type, \
- &GIArgument::v_##type>( \
- context, elems, param_info, &arg, c_array)) \
+#define ITERATE(type) \
+ if (!fill_vector_from_zero_terminated_carray<g##type>( \
+ context, elems, param_info, &arg, c_array)) \
return false;
switch (element_type) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]