[glibmm] Glib: Add some Glib::Value<> specializations



commit 73e7da4f21b13b252fc2f54e905543390ce914e2
Author: Kjell Ahlstedt <kjellahlstedt gmail com>
Date:   Fri Jan 18 10:41:31 2019 +0100

    Glib: Add some Glib::Value<> specializations
    
    * glib/glibmm/error.[cc|h]: Add operator bool(). Add Glib::Value<Glib::Error>
    which is needed in _WRAP_PROPERTY() in Gtk::MediaStream.
    * glib/glibmm/objectbase.[cc|h]: Add get_base_type(), which is necessary for
    one of the existing Value<> specializations to apply. ObjectBase is used
    in _WRAP_PROPERTY() in Glib::Binding.
    * 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/objectbase.cc |  5 +++++
 glib/glibmm/objectbase.h  |  8 ++++++++
 glib/src/variant.ccg      | 29 +++++++++++++++++++++++++++++
 glib/src/variant.hg       | 22 ++++++++++++++++++++++
 glib/src/varianttype.ccg  | 18 ++++++++++++++++++
 glib/src/varianttype.hg   | 16 ++++++++++++++++
 8 files changed, 143 insertions(+), 1 deletion(-)
---
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..5f49ee26 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 in Gtk::MediaStream.
+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/objectbase.cc b/glib/glibmm/objectbase.cc
index 9be57e77..f23c4977 100644
--- a/glib/glibmm/objectbase.cc
+++ b/glib/glibmm/objectbase.cc
@@ -389,6 +389,11 @@ ObjectBase::thaw_notify()
   g_object_thaw_notify(gobj());
 }
 
+GType ObjectBase::get_base_type()
+{
+  return G_TYPE_OBJECT;
+}
+
 void ObjectBase::add_custom_interface_class(const Interface_Class* iface_class)
 {
   if (!priv_pimpl_)
diff --git a/glib/glibmm/objectbase.h b/glib/glibmm/objectbase.h
index 6beaa59d..cf391dcf 100644
--- a/glib/glibmm/objectbase.h
+++ b/glib/glibmm/objectbase.h
@@ -59,6 +59,14 @@ public:
   ObjectBase(const ObjectBase&) = delete;
   ObjectBase& operator=(const ObjectBase&) = delete;
 
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+  // get_base_type() is needed so Glib::ObjectBase can be used with
+  // Glib::Value and _WRAP_PROPERTY in Glib::Binding without a
+  // Value<RefPtr<ObjectBase>> specialization.
+  // The Value<RefPtr<T>> specialization requires T::get_base_type().
+  static GType get_base_type() G_GNUC_CONST;
+#endif
+
 protected:
   /** This default constructor is called implicitly from the constructor of user-derived
    * classes, even if, for instance, Gtk::Button calls a different ObjectBase constructor.
diff --git a/glib/src/variant.ccg b/glib/src/variant.ccg
index 086c7970..ec3fc94a 100644
--- a/glib/src/variant.ccg
+++ b/glib/src/variant.ccg
@@ -692,4 +692,33 @@ Variant<type_vec_string>::get_iter() const
   return VariantContainerBase::get_iter(variant_type());
 }
 
+/*---------------------Value<Glib::VariantBase>---------------------*/
+
+// static
+GType Value<VariantBase>::value_type()
+{
+  return G_TYPE_VARIANT;
+}
+
+void Value<VariantBase>::set(CppType data)
+{
+  g_value_set_variant(&gobject_, data.gobj());
+}
+
+Value<VariantBase>::CppType Value<VariantBase>::get() const
+{
+  return CppType(g_value_get_variant(&gobject_), true);
+}
+
+GParamSpec* Value<VariantBase>::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));
+}
+
 } // namespace Glib
diff --git a/glib/src/variant.hg b/glib/src/variant.hg
index 41e96745..be42eb83 100644
--- a/glib/src/variant.hg
+++ b/glib/src/variant.hg
@@ -1588,4 +1588,26 @@ VariantIter Variant<std::tuple<Types...>>::get_iter() const
   return VariantContainerBase::get_iter(type);
 }
 
+/*---------------------Value<Glib::VariantBase>---------------------*/
+
+// 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
+{
+public:
+  using CppType = Glib::VariantBase;
+  using CType = GVariant*;
+
+  static GType value_type() G_GNUC_CONST;
+
+  void set(CppType data);
+  CppType get() 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
+};
+
 } // 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 ba16db75..50ddac16 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>
 
@@ -242,6 +243,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]