[gjs/arg-inlines: 4/11] arg: Make possible to set any pointer type without casting



commit 1d95aeac012d279b83d160f16a7f9c96537c8b61
Author: Marco Trevisan (TreviƱo) <mail 3v1n0 net>
Date:   Sun May 10 23:39:40 2020 +0200

    arg: Make possible to set any pointer type without casting
    
    By default we consider a GIArgument to be a pointer value, unless a
    scalar is used, but in such case we must have defined a proper accessor
    or we'd fail anyway as per the static assertions.
    
    We can also use const_cast to always cast down to the un-const type so
    that we can avoid doing specializations for both const T* and T* as it
    happens with char* and const char*
    
    (Philip: Changed to use pattern-matching with T* instead of
    std::is_pointer)

 gi/arg-inl.h | 21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)
---
diff --git a/gi/arg-inl.h b/gi/arg-inl.h
index e1fbd6a4..5e5d411c 100644
--- a/gi/arg-inl.h
+++ b/gi/arg-inl.h
@@ -9,6 +9,7 @@
 
 #include <stdint.h>
 
+#include <cstddef>  // for nullptr_t
 #include <type_traits>
 
 #include <girepository.h>
@@ -30,7 +31,9 @@ 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>(
+    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));
 }
 
@@ -111,11 +114,22 @@ GJS_USE inline decltype(auto) gjs_g_argument_value<void*>(GIArgument* arg) {
     return gjs_g_argument_value(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);
+}
+
 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;
 }
 
+template <typename T, GITypeTag TAG = GI_TYPE_TAG_VOID>
+inline void gjs_g_argument_value_set(GIArgument* arg, T* v) {
+    using NonconstT = std::remove_const_t<T>;
+    gjs_g_argument_value<NonconstT*, TAG>(arg) = const_cast<NonconstT*>(v);
+}
 template <>
 inline void gjs_g_argument_value_set<bool>(GIArgument* arg, bool v) {
     gjs_g_argument_value<bool>(arg) = !!v;
@@ -127,11 +141,6 @@ inline void gjs_g_argument_value_set<gboolean, GI_TYPE_TAG_BOOLEAN>(
     gjs_g_argument_value<bool>(arg) = !!v;
 }
 
-template <>
-inline void gjs_g_argument_value_set(GIArgument* arg, const char* v) {
-    gjs_g_argument_value<char*>(arg) = const_cast<char*>(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);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]