[glibmm] Add Glib::VariantDict, needed for GApplication.



commit ca67c931dd24a27bb5bb9de56abb6cf6fcb28018
Author: Murray Cumming <murrayc murrayc com>
Date:   Thu Apr 3 10:56:31 2014 +0200

    Add Glib::VariantDict, needed for GApplication.
    
    * glib/src/filelist.am:
    * glib/src/variantdict.[hg|ccg]: Add it as a generic refcounted
      type, with templated lookup_value() and insert_value() methods,
      though these are completely untested so far.
    * glib/src/variant.hg: Ignore a g_variant_dict_* function that
      gmmproc thinks is part of Variant.
    * tools/m4/convert_gio.m4:
    * tools/m4/convert_glib.m4: Move all Variant* conversion to the
      glib conversions and add a necessary one.
    * glib/glibmm.h: Include variantdict.h.

 glib/glibmm.h                    |    1 +
 glib/src/filelist.am             |    1 +
 glib/src/glib_extra_objects.defs |    6 ++
 glib/src/variant.hg              |    2 +
 glib/src/variantdict.ccg         |   39 +++++++++++
 glib/src/variantdict.hg          |  140 ++++++++++++++++++++++++++++++++++++++
 tools/m4/convert_gio.m4          |   10 ---
 tools/m4/convert_glib.m4         |   15 ++++-
 8 files changed, 202 insertions(+), 12 deletions(-)
---
diff --git a/glib/glibmm.h b/glib/glibmm.h
index 9438ee9..296db7b 100644
--- a/glib/glibmm.h
+++ b/glib/glibmm.h
@@ -142,6 +142,7 @@
 #include <glibmm/value.h>
 #include <glibmm/valuearray.h>
 #include <glibmm/variant.h>
+#include <glibmm/variantdict.h>
 #include <glibmm/variantiter.h>
 #include <glibmm/varianttype.h>
 #include <glibmm/vectorutils.h>
diff --git a/glib/src/filelist.am b/glib/src/filelist.am
index 0c5ef5d..8db8500 100644
--- a/glib/src/filelist.am
+++ b/glib/src/filelist.am
@@ -42,6 +42,7 @@ glibmm_files_hg =             \
        uriutils.hg             \
        valuearray.hg           \
        variant.hg              \
+       variantdict.hg          \
        variantiter.hg          \
        varianttype.hg
 
diff --git a/glib/src/glib_extra_objects.defs b/glib/src/glib_extra_objects.defs
index 1774ec4..d190f3c 100644
--- a/glib/src/glib_extra_objects.defs
+++ b/glib/src/glib_extra_objects.defs
@@ -73,6 +73,12 @@
   (gtype-id "G_TYPE_VARIANT")
 )
 
+(define-object VariantDict
+  (in-module "GLib")
+  (c-name "GVariantDict")
+  (gtype-id "G_TYPE_VARIANT_DICT")
+)
+
 (define-object VariantType
   (in-module "GLib")
   (c-name "GVariantType")
diff --git a/glib/src/variant.hg b/glib/src/variant.hg
index 1ab266e..9c9e686 100644
--- a/glib/src/variant.hg
+++ b/glib/src/variant.hg
@@ -210,6 +210,8 @@ public:
    template<class V_CastTo>
    static V_CastTo cast_dynamic(const VariantBase& v) throw(std::bad_cast);
 
+   _IGNORE(g_variant_dict_new)
+
 private:
   /** Relational operators are deleted to prevent invalid conversion
    * to const void*.
diff --git a/glib/src/variantdict.ccg b/glib/src/variantdict.ccg
new file mode 100644
index 0000000..ddc061d
--- /dev/null
+++ b/glib/src/variantdict.ccg
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2014 The gtkmm Development Team
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <glib.h>
+
+namespace Glib
+{
+
+bool VariantDict::lookup_value_variant(const Glib::ustring& key, const VariantType& expected_type, 
VariantBase& value) const
+{
+  GVariant* const g_value =
+    g_variant_dict_lookup_value(const_cast<GVariantDict*>(gobj()),
+      key.c_str(),
+      expected_type.gobj());
+  if(!g_value)
+    return false;  
+
+  value.init(g_value); // g_value is already referenced.
+  return true;
+}
+
+} //namespace Glib
+
+
diff --git a/glib/src/variantdict.hg b/glib/src/variantdict.hg
new file mode 100644
index 0000000..7afbd4e
--- /dev/null
+++ b/glib/src/variantdict.hg
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2014 The glibmm Development Team
+ *
+ * This library is free software, ) you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, ) either
+ * version 2.1 of the License, or(at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY, ) without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library, ) if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <glibmm/variant.h>
+
+_DEFS(glibmm,glib)
+
+namespace Glib
+{
+
+/** VariantDict is a mutable interface to Variant dictionaries.
+ *
+ * It can be used for doing a sequence of dictionary lookups in an
+ * efficient way on an existing Variant dictionary or it can be used
+ * to construct new dictionaries with a hashtable-like interface.  It
+ * can also be used for taking existing dictionaries and modifying them
+ * in order to create new ones.
+ *
+ * newin{2,40}
+ */
+class VariantDict
+{
+  //GVariantDict is registered as a boxed type, but it has ref/unref functions instead of copy/free,
+  //so we use it via RefPtr.
+  _CLASS_OPAQUE_REFCOUNTED(VariantDict, GVariantDict, NONE, g_variant_dict_ref, g_variant_dict_unref)
+  _IGNORE(g_variant_dict_ref, g_variant_dict_unref, g_variant_dict_init)
+
+public:
+  _WRAP_METHOD(static Glib::RefPtr<VariantDict> create(const VariantBase& from_asv{?}), g_variant_dict_new)
+
+
+//TODO: Add a method overload that does not take expected_type (which can be null),
+//just returning a VariantBase that should be cast_dynamic()ed?
+
+  /** Looks up a value in the VariantDict. See also lookup_value().
+   *
+   * If the @a key is not found the false is returned.
+   *
+   * The @a expected_type string specifies what type of value is expected.
+   * If the value associated with @a key has a different type then false is
+   * returned.
+   *
+   * If the key is found and the value has the correct type, it is
+   * returned in the @a value output variable.
+   */
+  bool lookup_value_variant(const Glib::ustring& key, const VariantType& expected_type, VariantBase& value) 
const;
+  _IGNORE(g_variant_dict_lookup_value)
+
+  /** Looks up a value in the VariantDict.
+   *
+   * If the @a key is not found the false is returned.
+   *
+   * If the value associated with @a key has a different type than expected then false is
+   * returned.
+   *
+   * If the key is found and the value has the correct type, it is
+   * returned in the @a value output variable.
+   */
+  template <typename T_Value>
+  bool lookup_value(const Glib::ustring& key, T_Value& value) const;
+  _IGNORE(g_variant_dict_lookup)
+
+
+  _WRAP_METHOD(bool contains(const Glib::ustring& key) const, g_variant_dict_contains)
+
+  _IGNORE(g_variant_dict_insert)
+
+
+  _WRAP_METHOD(void insert_value_variant(const Glib::ustring& key, const VariantBase& value), 
g_variant_dict_insert_value)
+
+  /** Inserts (or replaces) a key in a VariantDict.
+   * 
+   * @param key The key to insert a value for.
+   * @param value The value to insert.
+   */
+  template <typename T_Value>
+  void insert_value(const Glib::ustring& key, const T_Value& value);
+
+
+  _WRAP_METHOD(bool remove(const Glib::ustring& key), g_variant_dict_remove)
+
+  _WRAP_METHOD(void clear(), g_variant_dict_clear)
+
+  _IGNORE(g_variant_dict_end)
+};
+
+template <typename T_Value>
+void VariantDict::insert_value(const Glib::ustring& key, const T_Value& value)
+{
+  typedef Glib::Variant<T_Value> type_glib_variant;
+
+  //TODO: Can we do any check like this here, before glib does?
+  //g_return_val_if_fail(
+  //  g_variant_type_equal(g_action_get_parameter_type(const_cast<GAction*>(gobj())), 
type_glib_variant::variant_type().gobj()),
+  //  Glib::ustring());
+  return insert_value_variant(key, type_glib_variant::create(value));
+}
+
+template <typename T_Value>
+bool VariantDict::lookup_value(const Glib::ustring& key, T_Value& value) const
+{
+  value = T_Value(); //Make sure that it is initialized.
+
+  typedef Glib::Variant<T_Value> type_glib_variant;
+
+  //TODO: Can we do any check like this here, before glib does?
+  //g_variant_type_equal(g_action_group_get_action_state_type(const_cast<GActionGroup*>(gobj()), 
action_name.c_str()), type_glib_variant::variant_type().gobj()));
+
+  Glib::VariantBase variantBase;
+  const bool result = lookup_value_variant(key, type_glib_variant::variant_type(), variantBase);
+
+  try
+  {
+    const type_glib_variant variantDerived = variantBase.cast_dynamic<type_glib_variant>(variantBase);
+    value = variantDerived.get();
+  }
+  catch(const std::bad_cast& ex)
+  {
+    return false;
+  }
+}
+
+} //namespace Glib
+
+
diff --git a/tools/m4/convert_gio.m4 b/tools/m4/convert_gio.m4
index a6f04a3..c0e404a 100644
--- a/tools/m4/convert_gio.m4
+++ b/tools/m4/convert_gio.m4
@@ -302,16 +302,6 @@ _CONVERSION(`const Glib::RefPtr<TlsPassword>&',`GTlsPassword*',`Glib::unwrap($3)
 _CONVERSION(`GUnixFDList*',`Glib::RefPtr<UnixFDList>',`Glib::wrap($3)')
 _CONVERSION(`const Glib::RefPtr<UnixFDList>&',`GUnixFDList*',`Glib::unwrap($3)')
 
-#Variant
-_CONVERSION(`GVariant*',`Glib::VariantBase',`Glib::wrap($3, false)')
-_CONVERSION(`GVariant*',`Glib::VariantContainerBase',`Glib::VariantContainerBase($3, false)')
-_CONVERSION(`const Glib::VariantBase&',`GVariant*',`const_cast<GVariant*>(($3).gobj())')
-_CONVERSION(`const Glib::VariantContainerBase&',`GVariant*',`const_cast<GVariant*>(($3).gobj())')
-
-#VariantType
-_CONVERSION(`const GVariantType*',`Glib::VariantType',`Glib::wrap(const_cast<GVariantType*>($3), true)')
-_CONVERSION(`const Glib::VariantType&',`const GVariantType*',`$3.gobj()')
-
 #Volume
 _CONVERSION(`GVolume*',`Glib::RefPtr<Volume>',`Glib::wrap($3)')
 
diff --git a/tools/m4/convert_glib.m4 b/tools/m4/convert_glib.m4
index 3dd4e8d..a380390 100644
--- a/tools/m4/convert_glib.m4
+++ b/tools/m4/convert_glib.m4
@@ -154,10 +154,21 @@ _CONVERSION(`const Glib::ValueBase&',`GValue*',`const_cast<GValue*>(($3).gobj())
 _CONVERSION(`GValue*', `Glib::ValueBase&', `*reinterpret_cast<Glib::ValueBase*>($3)')
 _CONVERSION(`const GValue*', `const Glib::ValueBase&', `*reinterpret_cast<const Glib::ValueBase*>($3)')
 
-dnl VariantContainerBase
+#Variant
+_CONVERSION(`GVariant*',`Glib::VariantBase',`Glib::wrap($3, false)')
+_CONVERSION(`GVariant*',`Glib::VariantContainerBase',`Glib::VariantContainerBase($3, false)')
+_CONVERSION(`const VariantBase&',`GVariant*',`const_cast<GVariant*>(($3).gobj())')
+_CONVERSION(`const Glib::VariantBase&',`GVariant*',`const_cast<GVariant*>(($3).gobj())')
+_CONVERSION(`const Glib::VariantContainerBase&',`GVariant*',`const_cast<GVariant*>(($3).gobj())')
+
+# VariantContainerBase
 _CONVERSION(`const VariantContainerBase&',`GVariant*',`const_cast<GVariant*>(($3).gobj())')
 
-dnl VariantType
+#VariantDict
+_CONVERSION(`GVariantDict*',`Glib::RefPtr<VariantDict>',`Glib::wrap($3)')
+
+#VariantType
+_CONVERSION(`const GVariantType*',`Glib::VariantType',`Glib::wrap(const_cast<GVariantType*>($3), true)')
 _CONVERSION(`const VariantType&',`const GVariantType*',`($3).gobj()')
 _CONVERSION(`const Glib::VariantType&',`const GVariantType*',`($3).gobj()')
 _CONVERSION(`GVariantType*',`VariantType',`Glib::wrap($3)')


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