[glibmm/glibmm-2-60] Glib: Add some Glib::Value<> specializations



commit 5a1540e6504775e01c8c7e69cb26b9172836180c
Author: Kjell Ahlstedt <kjellahlstedt gmail com>
Date:   Mon Mar 18 15:24:06 2019 +0100

    Glib: Add some Glib::Value<> specializations
    
    * glib/glibmm/error.[cc|h]: Add operator bool(). Add Glib::Value<Glib::Error>
    so Glib::Error can be used in _WRAP_PROPERTY().
    * glib/glibmm/value.[cc|h]: Add Glib::ValueBase_Variant, base class of
    Glib::Value<VariantBase>.
    * glib/src/variant.[ccg|hg]: Add Glib::Value<VariantBase> which is
    needed in _WRAP_PROPERTY() in Gio:Action.
    * glib/src/varianttype.[ccg|hg]: Add Glib::Value<VariantType> which is
    needed in _WRAP_PROPERTY() in Gio:Action.
    
    All data types that occur in _WRAP_PROPERTY() must have correct Glib::Value<>
    specializations. In most cases missing Value<> specializations are noticed
    only during execution of code that calls an affected property_*() method.

 glib/glibmm/error.cc     | 21 +++++++++++++++++++++
 glib/glibmm/error.h      | 25 ++++++++++++++++++++++++-
 glib/glibmm/value.cc     | 29 +++++++++++++++++++++++++++++
 glib/glibmm/value.h      | 21 ++++++++++++++++++++-
 glib/src/variant.ccg     | 12 ++++++++++++
 glib/src/variant.hg      | 14 ++++++++++++++
 glib/src/varianttype.ccg | 18 ++++++++++++++++++
 glib/src/varianttype.hg  | 16 ++++++++++++++++
 8 files changed, 154 insertions(+), 2 deletions(-)
---
diff --git a/glib/glibmm/error.cc b/glib/glibmm/error.cc
index e3afe5bc..68c20e18 100644
--- a/glib/glibmm/error.cc
+++ b/glib/glibmm/error.cc
@@ -78,6 +78,11 @@ Error::~Error() noexcept
     g_error_free(gobject_);
 }
 
+Error::operator bool() const
+{
+  return gobject_ != nullptr;
+}
+
 GQuark
 Error::domain() const
 {
@@ -184,4 +189,20 @@ Error::throw_exception(GError* gobject)
   throw Glib::Error(gobject);
 }
 
+// Glib::Value<Glib::Error>
+GType Value<Error>::value_type()
+{
+  return g_error_get_type();
+}
+
+void Value<Error>::set(const CppType& data)
+{
+  set_boxed(data.gobj());
+}
+
+Value<Error>::CppType Value<Error>::get() const
+{
+  return Glib::Error(static_cast<CType>(get_boxed()), true);
+}
+
 } // namespace Glib
diff --git a/glib/glibmm/error.h b/glib/glibmm/error.h
index c015e757..f9d83eb9 100644
--- a/glib/glibmm/error.h
+++ b/glib/glibmm/error.h
@@ -1,4 +1,3 @@
-// -*- c++ -*-
 #ifndef _GLIBMM_ERROR_H
 #define _GLIBMM_ERROR_H
 
@@ -20,6 +19,7 @@
 
 #include <glibmmconfig.h>
 #include <glibmm/exception.h>
+#include <glibmm/value.h>
 #include <glib.h>
 
 namespace Glib
@@ -37,6 +37,12 @@ public:
 
   ~Error() noexcept override;
 
+  /** Test whether the %Error has an underlying instance.
+   *
+   * @newin{2,60}
+   */
+  explicit operator bool() const;
+
   GQuark domain() const;
   int code() const;
   Glib::ustring what() const override;
@@ -64,6 +70,23 @@ protected:
   GError* gobject_;
 };
 
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+// This is needed so Glib::Error can be used with
+// Glib::Value and _WRAP_PROPERTY.
+template <>
+class Value<Glib::Error> : public ValueBase_Boxed
+{
+public:
+  using CppType = Glib::Error;
+  using CType = GError*;
+
+  static GType value_type();
+
+  void set(const CppType& data);
+  CppType get() const;
+};
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+
 } // namespace Glib
 
 #endif /* _GLIBMM_ERROR_H */
diff --git a/glib/glibmm/value.cc b/glib/glibmm/value.cc
index 3eece8f9..1c01338b 100644
--- a/glib/glibmm/value.cc
+++ b/glib/glibmm/value.cc
@@ -279,6 +279,35 @@ ValueBase_String::create_param_spec(const Glib::ustring& name,
       get_cstring(), static_cast<GParamFlags>(flags));
 }
 
+/**** Glib::ValueBase_Variant ************************************************/
+
+// static
+GType ValueBase_Variant::value_type()
+{
+  return G_TYPE_VARIANT;
+}
+
+void ValueBase_Variant::set_variant(GVariant* data)
+{
+  g_value_set_variant(&gobject_, data);
+}
+
+GVariant* ValueBase_Variant::get_variant() const
+{
+  return g_value_get_variant(&gobject_);
+}
+
+GParamSpec* ValueBase_Variant::create_param_spec(const Glib::ustring& name,
+  const Glib::ustring& nick, const Glib::ustring& blurb, Glib::ParamFlags flags) const
+{
+  GVariant* gvariant = g_value_get_variant(&gobject_);
+  const GVariantType* gvariant_type = gvariant ? g_variant_get_type(gvariant) : G_VARIANT_TYPE_ANY;
+
+  return g_param_spec_variant(
+    name.c_str(), c_str_or_nullptr(nick), c_str_or_nullptr(blurb),
+    gvariant_type, gvariant, static_cast<GParamFlags>(flags));
+}
+
 /**** Glib::Value<std::string> *********************************************/
 
 void
diff --git a/glib/glibmm/value.h b/glib/glibmm/value.h
index fc8205c3..0ab4407a 100644
--- a/glib/glibmm/value.h
+++ b/glib/glibmm/value.h
@@ -196,9 +196,28 @@ protected:
   const char* get_cstring() const; // never returns nullptr
 };
 
+/**
+ * @ingroup glibmmValue
+ */
+class ValueBase_Variant : public ValueBase
+{
+public:
+  static GType value_type() G_GNUC_CONST;
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+  GParamSpec* create_param_spec(const Glib::ustring& name, const Glib::ustring& nick,
+                                const Glib::ustring& blurb, Glib::ParamFlags flags) const;
+#endif
+
+protected:
+  void set_variant(GVariant* data);
+  GVariant* get_variant() const; // doesn't copy, may return nullptr
+};
+
+
 } // namespace Glib
 
-/* Include generic Glib::Value<> template, before any specializations:
+/* Include primary Glib::Value<> template, before any specializations:
  */
 #define _GLIBMM_VALUE_H_INCLUDE_VALUE_CUSTOM_H
 #include <glibmm/value_custom.h>
diff --git a/glib/src/variant.ccg b/glib/src/variant.ccg
index 998955c7..9ef2d2c9 100644
--- a/glib/src/variant.ccg
+++ b/glib/src/variant.ccg
@@ -731,4 +731,16 @@ Variant<type_vec_string>::get_iter() const
   return VariantContainerBase::get_iter(variant_type());
 }
 
+/*---------------------Value<Glib::VariantBase>---------------------*/
+
+void Value<VariantBase>::set(CppType data)
+{
+  set_variant(data.gobj());
+}
+
+Value<VariantBase>::CppType Value<VariantBase>::get() const
+{
+  return CppType(get_variant(), true);
+}
+
 } // namespace Glib
diff --git a/glib/src/variant.hg b/glib/src/variant.hg
index 62f1bda6..40732fe1 100644
--- a/glib/src/variant.hg
+++ b/glib/src/variant.hg
@@ -1668,4 +1668,18 @@ VariantIter Variant<std::tuple<Types...>>::get_iter() const
   return VariantContainerBase::get_iter(type);
 }
 
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+// This is needed so Glib::VariantBase can be used with
+// Glib::Value and _WRAP_PROPERTY in Gio::Action and elsewhere.
+template <>
+class Value<Glib::VariantBase> : public ValueBase_Variant
+{
+public:
+  using CppType = Glib::VariantBase;
+
+  void set(CppType data);
+  CppType get() const;
+};
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+
 } // namespace Glib
diff --git a/glib/src/varianttype.ccg b/glib/src/varianttype.ccg
index ff1784fa..cd45bd5f 100644
--- a/glib/src/varianttype.ccg
+++ b/glib/src/varianttype.ccg
@@ -136,4 +136,22 @@ std::vector<VariantType> VariantType::get_item_types() const
   return result;
 }
 
+// Glib::Value<Glib::VariantType>
+GType Value<VariantType>::value_type()
+{
+  // The type function is *not* called g_variant_type_get_type().
+  // Use the macro in order to avoid using the non-standard function name here.
+  return G_TYPE_VARIANT_TYPE;
+}
+
+void Value<VariantType>::set(const CppType& data)
+{
+  set_boxed(data.gobj());
+}
+
+Value<VariantType>::CppType Value<VariantType>::get() const
+{
+  return Glib::wrap(static_cast<CType>(get_boxed()), true);
+}
+
 } // namespace GLib
diff --git a/glib/src/varianttype.hg b/glib/src/varianttype.hg
index 4a8a3550..a326e111 100644
--- a/glib/src/varianttype.hg
+++ b/glib/src/varianttype.hg
@@ -18,6 +18,7 @@ _DEFS(glibmm,glib)
 
 #include <glibmmconfig.h>
 #include <glib-object.h> //For gsize
+#include <glibmm/value.h>
 #include <string>
 #include <vector>
 
@@ -244,6 +245,21 @@ extern const VariantType VARIANT_TYPE_BYTESTRING;
 
 extern const VariantType VARIANT_TYPE_BYTESTRING_ARRAY;
 
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+// This is needed so Glib::VariantType can be used with
+// Glib::Value and _WRAP_PROPERTY in Gio::Action and elsewhere.
+template <>
+class Value<Glib::VariantType> : public ValueBase_Boxed
+{
+public:
+  using CppType = Glib::VariantType;
+  using CType = GVariantType*;
 
+  static GType value_type();
+
+  void set(const CppType& data);
+  CppType get() const;
+};
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
 
 } // namespace Glib


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