diff options
author | Murray Cumming <murrayc@murrayc.com> | 2014-04-03 10:56:31 +0200 |
---|---|---|
committer | Murray Cumming <murrayc@murrayc.com> | 2014-04-03 10:56:31 +0200 |
commit | ca67c931dd24a27bb5bb9de56abb6cf6fcb28018 (patch) | |
tree | 1ee83cc254ffa85a98fb51403d4b4a6689d37ccf | |
parent | b1952db2640f12817eb11266eedb640e29c0c399 (diff) | |
download | glibmm-ca67c931dd24a27bb5bb9de56abb6cf6fcb28018.tar.gz |
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.
-rw-r--r-- | glib/glibmm.h | 1 | ||||
-rw-r--r-- | glib/src/filelist.am | 1 | ||||
-rw-r--r-- | glib/src/glib_extra_objects.defs | 6 | ||||
-rw-r--r-- | glib/src/variant.hg | 2 | ||||
-rw-r--r-- | glib/src/variantdict.ccg | 39 | ||||
-rw-r--r-- | glib/src/variantdict.hg | 140 | ||||
-rw-r--r-- | tools/m4/convert_gio.m4 | 10 | ||||
-rw-r--r-- | tools/m4/convert_glib.m4 | 15 |
8 files changed, 202 insertions, 12 deletions
diff --git a/glib/glibmm.h b/glib/glibmm.h index 9438ee95..296db7b7 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 0c5ef5dd..8db85003 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 1774ec40..d190f3c9 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 1ab266e7..9c9e6860 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 00000000..ddc061dd --- /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 00000000..7afbd4ea --- /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 a6f04a3e..c0e404aa 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 3dd4e8d1..a3803905 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)') |