[glibmm] Variant: Really declare the cast_dyamic() specialization for ustring.



commit c724c60cb0a566230565d270e1584cd50f0e1478
Author: Murray Cumming <murrayc murrayc com>
Date:   Tue Mar 29 10:09:09 2011 +0200

    Variant: Really declare the cast_dyamic() specialization for ustring.
    
    * glib/src/variant.[hg|ccg]: Mention the specialization in the .h file instead
    of just in the .ccg file.
    Also write a custom Variant<std::string>::get() implementation because this
    can be used for types other than just bytestring.
    * tests/glibmm_variant/main.cc: Add tests for the new casts.

 ChangeLog                    |   32 +++++++++-----
 glib/src/variant.ccg         |   21 ++++++++-
 glib/src/variant.hg          |   17 +++++--
 tests/glibmm_variant/main.cc |  100 +++++++++++++++++++++++++++++++++++++++++-
 4 files changed, 151 insertions(+), 19 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 6f05913..282200b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2011-03-29  Murray Cumming  <murrayc murrayc com>
+
+	Variant: Really declare the cast_dyamic() specialization for ustring.
+
+	* glib/src/variant.[hg|ccg]: Mention the specialization in the .h file instead
+	of just in the .ccg file.
+	Also write a custom Variant<std::string>::get() implementation because this
+	can be used for types other than just bytestring.
+	* tests/glibmm_variant/main.cc: Add tests for the new casts.
+
 2011-03-28  Krzesimir Nowak  <qdlacz gmail com>
 
 	ArrayHandle: Make it compilable with MSVC 2005, 2008, 2010.
@@ -11,23 +21,23 @@
 	Variant: Use the VARIANT_TYPE_* constants.
 
 	* glib/src/variant.ccg: Use the constants instead of creating static members.
-	
+
 2011-03-28  Murray Cumming  <murrayc murrayc com>
 
 	VariantType: Capitalize the standard types.
 
-	* glib/src/varianttype.[hg|ccg]: Use, for instance VARIANT_TYPE_STRING instead 
-	of VariantTypeString. This seems more appropriate for a constant and is the 
+	* glib/src/varianttype.[hg|ccg]: Use, for instance VARIANT_TYPE_STRING instead
+	of VariantTypeString. This seems more appropriate for a constant and is the
 	style used by gtkmm's STOCK_* items, which this is based on.
 	* glib/src/variant.ccg: Adapt.
-	
+
 2011-03-28  Murray Cumming  <murrayc murrayc com>
 
 	Variant: Add cast_dynamic<> specializations for strings.
 
-	* glib/src/variant.[hg|ccg]: Add cast_dynamic() specializations for 
-	Vector<std::string> and Vector<Glib::ustring>, because this type seems 
-	appropriate for multiple types. For instance, see 
+	* glib/src/variant.[hg|ccg]: Add cast_dynamic() specializations for
+	Vector<std::string> and Vector<Glib::ustring>, because this type seems
+	appropriate for multiple types. For instance, see
 	http://library.gnome.org/devel/glib/unstable/glib-GVariant.html#g-variant-get-string
 	Thanks to Povietkin Konstantin.
 
@@ -37,12 +47,12 @@
 
 	Gio::DBus*: More use of VariantContainerBase.
 
-	* gio/src/dbusconnection.hg: 
+	* gio/src/dbusconnection.hg:
 	* gio/src/dbusinterfacevtable.hg: Correct the documentation.
-	* gio/src/dbusproxy.[hg|cgg]: call(): Take a VariantContainerBase instead of 
+	* gio/src/dbusproxy.[hg|cgg]: call(): Take a VariantContainerBase instead of
 	a VariantBase.
-	signal: Provide a VariantContainerBase instead of a VariantBase, though this 
-	is not documented as necessarily being a tuple, though it is multiple 
+	signal: Provide a VariantContainerBase instead of a VariantBase, though this
+	is not documented as necessarily being a tuple, though it is multiple
 	values.
 
 2011-03-27  Murray Cumming  <murrayc murrayc com>
diff --git a/glib/src/variant.ccg b/glib/src/variant.ccg
index a627531..adad1d6 100644
--- a/glib/src/variant.ccg
+++ b/glib/src/variant.ccg
@@ -18,6 +18,7 @@
 #include <glibmm/variant.h>
 #include <glibmm/utility.h>
 #include <glib.h>
+//#include <iostream>
 
 namespace Glib
 {
@@ -105,6 +106,7 @@ throw(std::bad_cast)
   }
   else
   {
+    //std::cerr << "vtype=" << v.get_type_string() << std::endl;
     throw std::bad_cast();
   }
 }
@@ -180,7 +182,7 @@ Glib::ustring Variant<Glib::ustring>::get() const
   return Glib::ustring(g_variant_get_string(gobject_, 0));
 }
 
-// Variant<std::string> makes sense for multiple types.
+// Variant<Glib::ustring> makes sense for multiple types.
 // See http://library.gnome.org/devel/glib/unstable/glib-GVariant.html#g-variant-get-string
 template<>
 Variant<Glib::ustring> VariantBase::cast_dynamic< Variant<Glib::ustring> >(const VariantBase& v)
@@ -200,6 +202,7 @@ throw(std::bad_cast)
   }
   else
   {
+    //std::cerr << "vtype=" << v.get_type_string() << std::endl;
     throw std::bad_cast();
   }
 }
@@ -235,7 +238,7 @@ throw(std::bad_cast)
 
   const VariantType vtype = v.get_type();
   if( vtype.equal(VARIANT_TYPE_STRING) ||
-      vtype.equal(VARIANT_TYPE_BYTESTRING) ||  
+      vtype.equal(VARIANT_TYPE_BYTESTRING) ||
       vtype.equal(VARIANT_TYPE_OBJECT_PATH) ||
       vtype.equal(VARIANT_TYPE_SIGNATURE) )
   {
@@ -243,10 +246,24 @@ throw(std::bad_cast)
   }
   else
   {
+    //std::cerr << "vtype=" << v.get_type_string() << std::endl;
     throw std::bad_cast();
   }
 }
 
+std::string Variant<std::string>::get() const
+{
+  const VariantType vtype = get_type();
+
+  const char* pch = 0;
+  if(vtype.equal(VARIANT_TYPE_BYTESTRING))
+    pch = g_variant_get_string(gobject_, 0);
+  else //g_variant_get_string() cna handle strings, object paths, and signatures.
+    pch = g_variant_get_string(gobject_, 0);
+
+  return std::string(pch);
+}
+
 typedef std::vector<Glib::ustring> type_vec_ustring;
 
 // static
diff --git a/glib/src/variant.hg b/glib/src/variant.hg
index ddaaf63..dc715d7 100644
--- a/glib/src/variant.hg
+++ b/glib/src/variant.hg
@@ -400,7 +400,8 @@ public:
   _WRAP_METHOD(VariantBase get() const, g_variant_get_variant)
 };
 
-/** Specialization of Variant containing a Glib::ustring.
+/** Specialization of Variant containing a Glib::ustring, for variants of type
+ * string, bytestring, object path, or signature.
  * @newin{2,28}
  * @ingroup Variant
  */
@@ -452,8 +453,13 @@ public:
   _IGNORE(g_variant_get_string, g_variant_dup_string)
 };
 
-/** Specialization of Variant containing a std::string (a non-capable
- * UTF-8 string).
+template<>
+Variant<Glib::ustring> VariantBase::cast_dynamic< Variant<Glib::ustring> >(const VariantBase& v)
+throw(std::bad_cast);
+
+/** Specialization of Variant containing a std::string, for variants of type
+ * bytestring, object path, or signature.
+ * See also Variant<Glib::ustring> for UTF-8 strings.
  * @newin{2,28}
  * @ingroup Variant
  */
@@ -496,8 +502,9 @@ public:
    */
   static Variant<std::string> create(const std::string& data);
 
-  _WRAP_METHOD(std::string get() const, g_variant_get_bytestring)
-   _IGNORE(g_variant_dup_bytestring)
+  //TODO: Documentation.
+  std::string get() const;
+  _IGNORE(g_variant_get_bytestring, g_variant_dup_bytestring)
 };
 
 template<>
diff --git a/tests/glibmm_variant/main.cc b/tests/glibmm_variant/main.cc
index 9cd2815..efc151f 100644
--- a/tests/glibmm_variant/main.cc
+++ b/tests/glibmm_variant/main.cc
@@ -114,6 +114,101 @@ int main(int, char**)
   return EXIT_SUCCESS;
 }
 
+//Test casting of multiple types to a ustring:
+static void test_dynamic_cast_ustring_types()
+{
+  Glib::VariantBase vbase_string = Glib::wrap(
+    g_variant_new("s", "somestring"));
+
+  try
+  {
+    Glib::Variant<Glib::ustring> derived =
+      Glib::VariantBase::cast_dynamic< Glib::Variant<Glib::ustring> >(vbase_string);
+    ostr << "Casted string Glib::Variant<Glib::ustring>: " << derived.get() << std::endl;
+  }
+  catch(const std::bad_cast& e)
+  {
+    g_assert_not_reached();
+  }
+
+
+  Glib::VariantBase vbase_objectpath = Glib::wrap(
+    g_variant_new_object_path("/remote/object/path"));
+
+  try
+  {
+    Glib::Variant<Glib::ustring> derived =
+      Glib::VariantBase::cast_dynamic< Glib::Variant<Glib::ustring> >(vbase_objectpath);
+    ostr << "Casted object path Glib::Variant<Glib::ustring>: " << derived.get() << std::endl;
+  }
+  catch(const std::bad_cast& e)
+  {
+    g_assert_not_reached();
+  }
+
+  Glib::VariantBase vbase_signature = Glib::wrap(
+    g_variant_new_signature("aas"));
+
+  try
+  {
+    Glib::Variant<Glib::ustring> derived =
+      Glib::VariantBase::cast_dynamic< Glib::Variant<Glib::ustring> >(vbase_signature);
+    ostr << "Casted signature Glib::Variant<Glib::ustring>: " << derived.get() << std::endl;
+  }
+  catch(const std::bad_cast& e)
+  {
+    g_assert_not_reached();
+  }
+}
+
+
+//Test casting of multiple types to a std::string:
+static void test_dynamic_cast_string_types()
+{
+  Glib::VariantBase vbase_string = Glib::wrap(
+    g_variant_new("s", "somestring"));
+
+  try
+  {
+    Glib::Variant<std::string> derived =
+      Glib::VariantBase::cast_dynamic< Glib::Variant<std::string> >(vbase_string);
+    ostr << "Casted string Glib::Variant<std::string>: " << derived.get() << std::endl;
+  }
+  catch(const std::bad_cast& e)
+  {
+    g_assert_not_reached();
+  }
+
+
+  Glib::VariantBase vbase_objectpath = Glib::wrap(
+    g_variant_new_object_path("/remote/object/path"));
+
+  try
+  {
+    Glib::Variant<std::string> derived =
+      Glib::VariantBase::cast_dynamic< Glib::Variant<std::string> >(vbase_objectpath);
+    ostr << "Casted object path Glib::Variant<std::string>: " << derived.get() << std::endl;
+  }
+  catch(const std::bad_cast& e)
+  {
+    g_assert_not_reached();
+  }
+
+  Glib::VariantBase vbase_signature = Glib::wrap(
+    g_variant_new_signature("aas"));
+
+  try
+  {
+    Glib::Variant<std::string> derived =
+      Glib::VariantBase::cast_dynamic< Glib::Variant<std::string> >(vbase_signature);
+    ostr << "Casted signature Glib::Variant<std::string>: " << derived.get() << std::endl;
+  }
+  catch(const std::bad_cast& e)
+  {
+    g_assert_not_reached();
+  }
+}
+
 static void test_dynamic_cast()
 {
   Glib::Variant<int> v1 = Glib::Variant<int>::create(10);
@@ -139,7 +234,7 @@ static void test_dynamic_cast()
   {
   }
 
-  // A t-uple
+  // A tuple
   std::vector<Glib::VariantBase> vec_var(2);
   vec_var[0] = Glib::Variant<int>::create(1);
   vec_var[1] = Glib::Variant<Glib::ustring>::create("coucou");
@@ -194,4 +289,7 @@ static void test_dynamic_cast()
   Glib::Variant<Glib::ustring> var_s2 =
     Glib::VariantBase::cast_dynamic<Glib::Variant<Glib::ustring> >(var_v.get());
   g_assert(var_s2.get() == "test variant");
+
+  test_dynamic_cast_ustring_types();
+  test_dynamic_cast_string_types();
 }



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