[glibmm] Added a new Glib::Variant<> specialization to deal with arrays.
- From: José Alburquerque <jaalburqu src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glibmm] Added a new Glib::Variant<> specialization to deal with arrays.
- Date: Fri, 17 Dec 2010 04:19:14 +0000 (UTC)
commit abff30a5fadb81335f969e8839b946fbacc024a5
Author: José Alburquerque <jaalburqu svn gnome org>
Date: Thu Dec 16 19:37:41 2010 -0500
Added a new Glib::Variant<> specialization to deal with arrays.
* glib/src/variant.{ccg,hg} (VariantBase::get_maybe): Move the method
that gets a maybe of a container to Variant<VariantBase> because it a
container specific method.
(Variant<VariantBase>::get): Correct this method so that it uses an
output parameter instead of returning a VariantBase.
(Variant< std::vector<T> >): Added a new specialization designed to
deal with variant arrays. Similar types dealing with array of strings
should also be added.
(typedefs): Added some typedefs that might possibly be useful later.
(docs): Added docs to methods without them.
* glib/src/variant_basictypes.{cc,h}.m4:
(variant_type): Made all the static variant_type() methods return a
Glib::VariantType so the C++ wrapper is used.
* glib/src/variantiter.{ccg,hg}: Corrected the includes so
variantiter.h can be included in variant.h.
ChangeLog | 20 +++
glib/src/variant.ccg | 51 ++++----
glib/src/variant.hg | 245 +++++++++++++++++++++++++++++++++++--
glib/src/variant_basictypes.cc.m4 | 5 +-
glib/src/variant_basictypes.h.m4 | 6 +-
glib/src/variantiter.ccg | 2 +
glib/src/variantiter.hg | 5 +-
7 files changed, 293 insertions(+), 41 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 0614956..fd368e1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2010-12-16 José Alburquerque <jaalburqu svn gnome org>
+
+ Added a new Glib::Variant<> specialization to deal with arrays.
+
+ * glib/src/variant.{ccg,hg} (VariantBase::get_maybe): Move the method
+ that gets a maybe of a container to Variant<VariantBase> because it a
+ container specific method.
+ (Variant<VariantBase>::get): Correct this method so that it uses an
+ output parameter instead of returning a VariantBase.
+ (Variant< std::vector<T> >): Added a new specialization designed to
+ deal with variant arrays. Similar types dealing with array of strings
+ should also be added.
+ (typedefs): Added some typedefs that might possibly be useful later.
+ (docs): Added docs to methods without them.
+ * glib/src/variant_basictypes.{cc,h}.m4:
+ (variant_type): Made all the static variant_type() methods return a
+ Glib::VariantType so the C++ wrapper is used.
+ * glib/src/variantiter.{ccg,hg}: Corrected the includes so
+ variantiter.h can be included in variant.h.
+
2010-12-15 José Alburquerque <jaalburqu svn gnome org>
glibmm: Add a Variant<std::string> specialization.
diff --git a/glib/src/variant.ccg b/glib/src/variant.ccg
index 22f9690..22b0d1e 100644
--- a/glib/src/variant.ccg
+++ b/glib/src/variant.ccg
@@ -17,7 +17,7 @@
#include <glibmm/variant.h>
#include <glibmm/utility.h>
-#include <glib/gvariant.h>
+#include <glib.h>
namespace Glib
{
@@ -38,21 +38,6 @@ void VariantBase::byteswap(VariantBase& result) const
result.init(g_value); // g_value is already referenced.
}
-bool VariantBase::get_maybe(Glib::VariantBase& maybe) const
-{
- GVariant* const g_value =
- g_variant_get_maybe(const_cast<GVariant*>(gobj()));
-
- if(g_value)
- {
- maybe.init(g_value); // g_value is already referenced.
- return true;
- }
- else
- return false;
-}
-
-
/****************** Specializations ***********************************/
@@ -67,9 +52,10 @@ void VariantBase::init(const GVariant* cobject, bool take_a_reference)
}
// static
-const GVariantType* Variant<VariantBase>::variant_type()
+const VariantType& Variant<VariantBase>::variant_type()
{
- return G_VARIANT_TYPE_VARIANT;
+ static VariantType type(G_VARIANT_TYPE_VARIANT);
+ return type;
}
Variant<VariantBase> Variant<VariantBase>::create(const VariantBase& data)
@@ -82,15 +68,31 @@ Variant<VariantBase> Variant<VariantBase>::create(const VariantBase& data)
return result;
}
-VariantBase Variant<VariantBase>::get() const
+void Variant<VariantBase>::get(VariantBase& child) const
{
- return VariantBase(g_variant_get_variant(gobject_));
+ GVariant* const gvariant = g_variant_get_variant(gobject_);
+ child.init(gvariant);
+}
+
+bool Variant<VariantBase>::get_maybe(Glib::VariantBase& maybe) const
+{
+ GVariant* const g_value =
+ g_variant_get_maybe(const_cast<GVariant*>(gobj()));
+
+ if(g_value)
+ {
+ maybe.init(g_value); // g_value is already referenced.
+ return true;
+ }
+ else
+ return false;
}
// static
-const GVariantType* Variant<Glib::ustring>::variant_type()
+const VariantType& Variant<Glib::ustring>::variant_type()
{
- return G_VARIANT_TYPE_STRING;
+ static VariantType type(G_VARIANT_TYPE_STRING);
+ return type;
}
Variant<Glib::ustring>
@@ -111,9 +113,10 @@ Glib::ustring Variant<Glib::ustring>::get() const
}
// static
-const GVariantType* Variant<std::string>::variant_type()
+const VariantType& Variant<std::string>::variant_type()
{
- return G_VARIANT_TYPE_BYTESTRING;
+ static VariantType type(G_VARIANT_TYPE_BYTESTRING);
+ return type;
}
Variant<std::string>
diff --git a/glib/src/variant.hg b/glib/src/variant.hg
index 1dc4c08..35037b7 100644
--- a/glib/src/variant.hg
+++ b/glib/src/variant.hg
@@ -19,7 +19,9 @@ _DEFS(glibmm,glib)
#include <glibmmconfig.h>
#include <glibmm/varianttype.h>
+#include <glibmm/variantiter.h>
#include <glibmm/ustring.h>
+#include <vector>
namespace Glib
{
@@ -60,9 +62,6 @@ public:
_WRAP_METHOD(bool is_container() const, g_variant_is_container)
_WRAP_METHOD(GVariantClass classify() const, g_variant_classify)
- bool get_maybe(Glib::VariantBase& maybe) const;
- _IGNORE(g_variant_get_maybe)
-
_WRAP_METHOD(gsize get_size() const, g_variant_get_size)
_WRAP_METHOD(gconstpointer get_data(), g_variant_get_data)
_WRAP_METHOD(void store(gpointer data) const, g_variant_store)
@@ -148,26 +147,56 @@ class Variant<VariantBase> : public VariantBase
_CLASS_GENERIC(Variant<VariantBase>, GVariant)
public:
- typedef GVariant* CType;
+ typedef GVariant* CType;
+ typedef VariantBase CppType;
+ typedef Variant<VariantBase> CppContainerType;
+ /// Default constructor.
Variant<VariantBase>()
: VariantBase()
{}
+ /** GVariant constructor.
+ * @param castitem The GVariant to wrap.
+ */
explicit Variant<VariantBase>(GVariant* castitem)
: VariantBase(castitem)
{}
- static const GVariantType* variant_type() G_GNUC_CONST;
-
- //This must have a create() method because otherwise it would be a copy constructor.
+ /** Gets the Glib::VariantType.
+ * @return The Glib::VariantType.
+ * @newin{2,28}
+ */
+ static const Glib::VariantType& variant_type() G_GNUC_CONST;
+
+ //This must have a create() method because otherwise it would be a copy
+ //constructor.
+ /** Creates a new Glib::Variant<VariantBase>.
+ * @param data The value of the new Glib::Variant<VariantBase>.
+ * @return The new Glib::Variant<VariantBase>.
+ * @newin{2,28}
+ */
static Variant<VariantBase> create(const Glib::VariantBase& data);
_IGNORE(g_variant_new_variant)
- VariantBase get() const;
+ /** Gets the child of the Glib::Variant<VariantBase>.
+ * @param child The location in which to store the child.
+ * @newin{2,28}
+ */
+ void get(Glib::VariantBase& child) const;
_IGNORE(g_variant_get_variant)
_WRAP_METHOD(gsize get_n_children() const, g_variant_n_children)
+
+ /** If this is a maybe-typed instance, extract its value. If the value is
+ * Nothing, then this function returns <tt>0</tt>.
+ *
+ * @param maybe A place in which to return the value (the value may be
+ * <tt>0</tt>).
+ * @newin{2,28}
+ */
+ bool get_maybe(Glib::VariantBase& maybe) const;
+ _IGNORE(g_variant_get_maybe)
};
/** Specialization of Glib::Variant containing a Glib::ustring.
@@ -180,17 +209,35 @@ class Variant<Glib::ustring> : public VariantBase
public:
typedef char* CType;
+ /// Default constructor.
Variant<Glib::ustring>()
: VariantBase()
{}
+ /** GVariant constructor.
+ * @param castitem The GVariant to wrap.
+ */
explicit Variant<Glib::ustring>(GVariant* castitem)
: VariantBase(castitem)
{}
- static const GVariantType* variant_type() G_GNUC_CONST;
+ /** Gets the Glib::VariantType.
+ * @return The Glib::VariantType.
+ * @newin{2,28}
+ */
+ static const Glib::VariantType& variant_type() G_GNUC_CONST;
+
+ /** Creates a new Glib::Variant<Glib::ustring>.
+ * @param data The value of the new Glib::Variant<Glib::ustring>.
+ * @return The new Glib::Variant<Glib::ustring>.
+ * @newin{2,28}
+ */
static Variant<Glib::ustring> create(const Glib::ustring& data);
+ /** Gets the contents of the Glib::Variant<Glib::ustring>.
+ * @return The contents of the Glib::Variant<Glib::ustring>.
+ * @newin{2,28}
+ */
Glib::ustring get() const;
_IGNORE(g_variant_get_string, g_variant_dup_string)
};
@@ -205,21 +252,100 @@ class Variant<std::string> : public VariantBase
public:
typedef char* CType;
+ /// Default constructor.
Variant<std::string>()
: VariantBase()
{}
+ /** GVariant constructor.
+ * @param castitem The GVariant to wrap.
+ */
explicit Variant<std::string>(GVariant* castitem)
: VariantBase(castitem)
{}
- static const GVariantType* variant_type() G_GNUC_CONST;
+ /** Gets the Glib::VariantType.
+ * @return The Glib::VariantType.
+ * @newin{2,28}
+ */
+ static const Glib::VariantType& variant_type() G_GNUC_CONST;
+
+ /** Creates a new Glib::Variant<std::string>.
+ * @param data The value of the new Glib::Variant<std::string>.
+ * @return The new Glib::Variant<std::string>.
+ * @newin{2,28}
+ */
static Variant<std::string> create(const std::string& data);
+ /** Gets the contents of the Glib::Variant<std::string>.
+ * @return The contents of the Glib::Variant<std::string>.
+ * @newin{2,28}
+ */
std::string get() const;
_IGNORE(g_variant_get_bytestring, g_variant_dup_bytestring)
};
+/** Specialization of Glib::Variant containing an array of items.
+ */
+template <class T>
+class Variant< std::vector<T> > : public Variant<VariantBase>
+{
+public:
+ typedef T CppType;
+ typedef std::vector<T> CppContainerType;
+
+ /// Default constructor.
+ Variant< std::vector<T> >()
+ : Variant<VariantBase>()
+ {}
+
+ /** GVariant constructor.
+ * @param castitem The GVariant to wrap.
+ */
+ explicit Variant< std::vector<T> >(GVariant* castitem)
+ : Variant<VariantBase>(castitem)
+ {}
+
+ /** Gets the Glib::VariantType.
+ * @return The Glib::VariantType.
+ * @newin{2,28}
+ */
+ static const Glib::VariantType& variant_type() G_GNUC_CONST;
+
+ /** Creates a new Glib::Variant< std::vector<T> > (a variant array).
+ * @param data The array of the new Glib::Variant< std::vector<T> >.
+ * @return The new Glib::Variant< std::vector<T> >.
+ * @newin{2,28}
+ */
+ static Variant< std::vector<T> > create(const std::vector<T>& data);
+ _IGNORE(g_variant_new_array)
+
+ /** Gets a specific element of the array. It is an error if index_ is
+ * greater than the number of child items in the container. See
+ * Glib::Variant<VariantBase>::n_children().
+ *
+ * This function is O(1).
+ *
+ * @param index The index of the element.
+ * @return The element at index @index.
+ * @newin{2,28}
+ */
+ T get(gsize index) const;
+
+ /** Gets the vector of the Glib::Variant< std::vector<T> >.
+ * @return The vector.
+ * @newin{2,28}
+ */
+ std::vector<T> get() const;
+ _IGNORE(get_variant_get_fixed_array)
+
+ /** Gets a VariantIter of the contained array.
+ * @return the VaraintIter.
+ * @newin{2,28}
+ */
+ VariantIter get_iter();
+};
+
} // namespace Glib
@@ -242,3 +368,102 @@ _IGNORE(
#define _GLIBMM_VARIANT_H_INCLUDE_VARIANT_BASICTYPES_H
#include <glibmm/variant_basictypes.h>
#undef _GLIBMM_VARIANT_H_INCLUDE_VARIANT_BASICTYPES_H
+
+namespace Glib
+{
+
+/*-----------------------Glib::Variant< std::vector<T> --------------------*/
+
+// static
+template<class T>
+const VariantType& Variant< std::vector<T> >::variant_type()
+{
+ static VariantType type(G_VARIANT_TYPE_ARRAY);
+ return type;
+}
+
+template<class T>
+Variant< std::vector<T> >
+Variant< std::vector<T> >::create(const std::vector<T>& data)
+{
+ // Get the variant type of the elements as a string.
+ std::string element_variant_type =
+ static_cast<char*>(Variant<T>::variant_type().gobj());
+
+ // Get the variant type of the array as a string.
+ std::string array_variant_type = "a" + element_variant_type;
+
+ // Create a GVariantBuilder to build the array.
+ GVariantBuilder* builder =
+ g_variant_builder_new(G_VARIANT_TYPE(array_variant_type.c_str()));
+
+ // Add the elements of the vector into the builder.
+ for(typename std::vector<T>::iterator iter = data.begin(); iter < data.end();
+ iter++)
+ {
+ g_variant_builder_add(builder, element_variant_type, *iter);
+ }
+
+ // Create the variant using the builder.
+ Variant< std::vector<T> > result =
+ Variant< std::vector<T> >(g_variant_new(array_variant_type.c_str(),
+ builder));
+
+ // Remove the floating reference (since it is newly created).
+ g_variant_ref_sink(result.gobj());
+
+ return result;
+}
+
+template<class T>
+T Variant< std::vector<T> >::get(gsize index) const
+{
+ GVariant* gvariant = g_variant_get_child_value(gobj(), index);
+ Glib::Variant<T> variant(gvariant, true /* take extra ref to preserve */);
+ return variant.get();
+}
+
+template<class T>
+std::vector<T> Variant< std::vector<T> >::get() const
+{
+ // Get the variant type of the elements as a string.
+ std::string element_variant_type =
+ static_cast<char*>(Variant<T>::variant_type().gobj());
+
+ // Get the variant type of the array as a string.
+ std::string array_variant_type = "a" + element_variant_type;
+
+ // Get the GVariantIter.
+ GVariantIter* g_iter = 0;
+ g_variant_get(gobj(), array_variant_type.c_str(), &g_iter);
+
+ // Wrap the GVariantIter.
+ VariantIter iter(g_iter);
+
+ std::vector<T> result;
+ Glib::Variant<T> element;
+
+ while(iter.next_value(element))
+ result.push_back(element.get());
+
+ return result;
+}
+
+template<class T>
+VariantIter Variant< std::vector<T> >::get_iter()
+{
+ // Get the variant type of the elements as a string.
+ std::string element_variant_type =
+ static_cast<char*>(Variant<T>::variant_type().gobj());
+
+ // Get the variant type of the array as a string.
+ std::string array_variant_type = "a" + element_variant_type;
+
+ // Get the GVariantIter.
+ GVariantIter* g_iter = 0;
+ g_variant_get(gobj(), array_variant_type.c_str(), &g_iter);
+
+ return VariantIter(g_iter);
+}
+
+} // namespace Glib
diff --git a/glib/src/variant_basictypes.cc.m4 b/glib/src/variant_basictypes.cc.m4
index 9dea5f2..1b54ac1 100644
--- a/glib/src/variant_basictypes.cc.m4
+++ b/glib/src/variant_basictypes.cc.m4
@@ -36,9 +36,10 @@ dnl Please ignore the format stuff. I was just tired and played a little.
/**** Glib::Variant<$1> translit(format([%]eval(57-len([$1]))[s],[****/]),[ ],[*])
// static
-const GVariantType* Variant<$1>::variant_type()
+const VariantType& Variant<$1>::variant_type()
{
- return G_VARIANT_TYPE_[]UPPER($3);
+ static VariantType type(G_VARIANT_TYPE_[]UPPER($3));
+ return type;
}
Variant<$1> Variant<$1>::create($1 data)
diff --git a/glib/src/variant_basictypes.h.m4 b/glib/src/variant_basictypes.h.m4
index ee0662d..4a095da 100644
--- a/glib/src/variant_basictypes.h.m4
+++ b/glib/src/variant_basictypes.h.m4
@@ -54,10 +54,10 @@ public:
: VariantBase(castitem)
{}
- /** Gets the GVariantType.
- * @return The GVariantType.
+ /** Gets the Glib::VariantType.
+ * @return The Glib::VariantType.
*/
- static const GVariantType* variant_type() G_GNUC_CONST;
+ static const VariantType& variant_type() G_GNUC_CONST;
/** Creates a new Glib::Variant<$1>.
* @param data The value of the new Glib::Variant<$1>.
diff --git a/glib/src/variantiter.ccg b/glib/src/variantiter.ccg
index bf3502c..6c20ac9 100644
--- a/glib/src/variantiter.ccg
+++ b/glib/src/variantiter.ccg
@@ -15,6 +15,8 @@
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include <glibmm/variant.h>
+#include <glib.h>
namespace Glib
{
diff --git a/glib/src/variantiter.hg b/glib/src/variantiter.hg
index 8ea6dac..7f38a77 100644
--- a/glib/src/variantiter.hg
+++ b/glib/src/variantiter.hg
@@ -15,13 +15,14 @@
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <glibmm/variant.h>
-
+#include <glib.h>
_DEFS(glibmm,glib)
namespace Glib
{
+class VariantBase;
+
//This can't be like a real iterator (like Gtk::TextIter),
//because g_iter_value_get_next_value() both gets a value and changes the iterator.
//GtkTextIter allows us to go forward and then separately get the current value.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]