[glibmm/vector] Partially added bool specializations of vector utils.



commit 10a59e1ad064c1039e867e2d497ca5840d4094f5
Author: Krzesimir Nowak <qdlacz gmail com>
Date:   Thu Jan 20 21:32:10 2011 +0100

    Partially added bool specializations of vector utils.
    
    Also changed keepers' casting operator into data() method, because
    it didn't work nicely with const_casts. Of course the code does not
    compile now...

 glib/glibmm/vectorutils.h   |  177 +++++++++++++++++++++++++++++++++++++++----
 tests/glibmm_vector/main.cc |    6 +-
 2 files changed, 166 insertions(+), 17 deletions(-)
---
diff --git a/glib/glibmm/vectorutils.h b/glib/glibmm/vectorutils.h
index 75a46d8..3b9ba63 100644
--- a/glib/glibmm/vectorutils.h
+++ b/glib/glibmm/vectorutils.h
@@ -81,8 +81,8 @@ size_t compute_array_size2(const T* array)
 /* Allocate and fill a 0-terminated array.  The size argument
  * specifies the number of elements in the input sequence.
  */
-template <class Tr, class For>
-typename Tr::CType* create_array2(For pbegin, size_t size)
+template <class Tr>
+typename Tr::CType* create_array2(typename std::vector<typename Tr::CppType>::const_iterator pbegin, size_t size)
 {
   typedef typename Tr::CType CType;
 
@@ -100,11 +100,31 @@ typename Tr::CType* create_array2(For pbegin, size_t size)
   return array;
 }
 
+/* first class function for bools, because std::vector<bool> is a specialization
+ * which does not conform to being an STL container.
+ */
+gboolean* create_bool_array (std::vector<bool>::const_iterator pbegin,
+                             size_t size)
+{
+  gboolean *const array (static_cast<gboolean*>(g_malloc((size + 1) * sizeof (gboolean))));
+  gboolean *const array_end (array + size);
+
+  for (gboolean* pdest (array); pdest != array_end; ++pdest)
+  {
+    *pdest = *pbegin;
+    ++pbegin;
+  }
+
+  *array_end = false;
+  return array;
+}
+
 /* Create and fill a GList as efficient as possible.
  * This requires bidirectional iterators.
  */
-template <class Tr, class Bi>
-GList* create_glist2(Bi pbegin, Bi pend)
+template <class Tr>
+GList* create_glist2(const typename std::vector<typename Tr::CppType>::const_iterator pbegin,
+                     typename std::vector<typename Tr::CppType>::const_iterator pend)
 {
   GList* head = 0;
 
@@ -118,11 +138,29 @@ GList* create_glist2(Bi pbegin, Bi pend)
   return head;
 }
 
+/* first class function for bools, because std::vector<bool> is a specialization
+ * which does not conform to being an STL container.
+ */
+GList* create_bool_glist (const std::vector<bool>::const_iterator pbegin,
+                          std::vector<bool>::const_iterator pend)
+{
+  GList* head = 0;
+
+  while (pend != pbegin)
+  {
+    gboolean item (*--pend);
+    head = g_list_prepend (head, GINT_TO_POINTER(item));
+  }
+
+  return head;
+}
+
 /* Create and fill a GSList as efficient as possible.
  * This requires bidirectional iterators.
  */
-template <class Tr, class Bi>
-GSList* create_gslist2(Bi pbegin, Bi pend)
+template <class Tr>
+GSList* create_gslist2(const typename std::vector<typename Tr::CppType>::const_iterator pbegin,
+                       typename std::vector<typename Tr::CppType>::const_iterator pend)
 {
   GSList* head = 0;
 
@@ -136,6 +174,23 @@ GSList* create_gslist2(Bi pbegin, Bi pend)
   return head;
 }
 
+/* first class function for bools, because std::vector<bool> is a specialization
+ * which does not conform to being an STL container.
+ */
+GSList* create_bool_gslist (const std::vector<bool>::const_iterator pbegin,
+                            std::vector<bool>::const_iterator pend)
+{
+  GSList* head = 0;
+
+  while (pend != pbegin)
+  {
+    gboolean item (*--pend);
+    head = g_slist_prepend (head, GINT_TO_POINTER(item));
+  }
+
+  return head;
+}
+
 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
 
 
@@ -257,7 +312,7 @@ public:
   inline ArrayKeeper (const ArrayKeeper& keeper);
   ~ArrayKeeper ();
 
-  inline operator CType* () const;
+  inline CType* data() const;
 
 private:
   CType* array_;
@@ -276,7 +331,7 @@ public:
   inline GListKeeper (const GListKeeper& keeper);
   ~GListKeeper ();
 
-  inline operator GList* () const;
+  inline GList* data() const;
 
 private:
   GList* glist_;
@@ -294,7 +349,7 @@ public:
   inline GSListKeeper (const GSListKeeper& keeper);
   ~GSListKeeper ();
 
-  inline operator GSList* () const;
+  inline GSList* data() const;
 
 private:
   GSList* gslist_;
@@ -329,6 +384,30 @@ public:
   static GSListKeeperType vector_to_slist (const VectorType& vector);
 };
 
+template <>
+class VectorHandler<bool>
+{
+public:
+  typedef gboolean CType;
+  typedef bool CppType;
+  typedef std::vector<bool> VectorType;
+  typedef Glib::Container_Helpers::ArrayKeeper<Glib::Container_Helpers::TypeTraits<bool> > ArrayKeeperType;
+  typedef Glib::Container_Helpers::GListKeeper<Glib::Container_Helpers::TypeTraits<bool> > GListKeeperType;
+  typedef Glib::Container_Helpers::GSListKeeper<Glib::Container_Helpers::TypeTraits<bool> > GSListKeeperType;
+  typedef Glib::Container_Helpers::ArrayIterator<Glib::Container_Helpers::TypeTraits<bool> > ArrayIteratorType;
+  typedef Glib::Container_Helpers::ListIterator<Glib::Container_Helpers::TypeTraits<bool> > ListIteratorType;
+  typedef Glib::Container_Helpers::SListIterator<Glib::Container_Helpers::TypeTraits<bool> > SListIteratorType;
+
+// maybe think about using C++0x move constructors?
+  static VectorType array_to_vector (const CType* array, size_t array_size, Glib::OwnershipType ownership);
+  static VectorType array_to_vector (const CType* array, Glib::OwnershipType ownership);
+  static VectorType list_to_vector (GList* glist, Glib::OwnershipType ownership);
+  static VectorType slist_to_vector (GSList* gslist, Glib::OwnershipType ownership);
+  static ArrayKeeperType vector_to_array (const VectorType& vector);
+  static GListKeeperType vector_to_list (const VectorType& vector);
+  static GSListKeeperType vector_to_slist (const VectorType& vector);
+};
+
 /***************************************************************************/
 /*  Inline implementation                                                  */
 /***************************************************************************/
@@ -567,7 +646,7 @@ ArrayKeeper<Tr>::~ArrayKeeper ()
 }
 
 template <typename Tr>
-inline ArrayKeeper<Tr>::operator CType* () const
+inline typename Tr::CType* ArrayKeeper<Tr>::data () const
 {
   return array_;
 }
@@ -609,7 +688,7 @@ GListKeeper<Tr>::~GListKeeper ()
 }
 
 template <typename Tr>
-inline GListKeeper<Tr>::operator GList* () const
+inline GList* GListKeeper<Tr>::data () const
 {
   return glist_;
 }
@@ -651,7 +730,7 @@ GSListKeeper<Tr>::~GSListKeeper ()
 }
 
 template <typename Tr>
-inline GSListKeeper<Tr>::operator GSList* () const
+inline GSList* GSListKeeper<Tr>::data () const
 {
   return gslist_;
 }
@@ -719,7 +798,7 @@ template <typename T, class Tr>
 typename VectorHandler<T, Tr>::ArrayKeeperType
 VectorHandler<T, Tr>::vector_to_array (const VectorType& vector)
 {
-  return ArrayKeeperType (Glib::Container_Helpers::create_array2<Tr> (vector.begin (), vector.size ()), vector.size(), Glib::OWNERSHIP_SHALLOW);
+  return ArrayKeeperType (Glib::Container_Helpers::create_array2<Tr> (vector.begin (), vector.size ()), vector.size (), Glib::OWNERSHIP_SHALLOW);
 }
 
 template <typename T, class Tr>
@@ -736,10 +815,80 @@ VectorHandler<T, Tr>::vector_to_slist (const VectorType& vector)
   return GSListKeeperType (Glib::Container_Helpers::create_gslist2<Tr> (vector.begin (), vector.end ()), Glib::OWNERSHIP_SHALLOW);
 }
 
+/**** Glib::VectorHandler<bool> ************************/
+
+VectorHandler<bool, Glib::Container_Helpers::TypeTraits<bool> >::VectorType
+VectorHandler<bool, Glib::Container_Helpers::TypeTraits<bool> >::array_to_vector (const CType* array, size_t array_size, Glib::OwnershipType ownership)
+{
+  // it will handle destroying data depending on passed ownership.
+  ArrayKeeperType keeper (array, array_size, ownership);
+#ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
+  return VectorType (ArrayIteratorType (array), ArrayIteratorType (array + array_size));
+#else
+  VectorType temp;
+  temp.reserve (array_size);
+  Glib::Container_Helpers::fill_container (temp, ArrayIteratorType (array), ArrayIteratorType (array + array_size));
+  return temp;
+#endif
+}
+
+VectorHandler<bool, Glib::Container_Helpers::TypeTraits<bool> >::VectorType
+VectorHandler<bool, Glib::Container_Helpers::TypeTraits<bool> >::array_to_vector(const CType* array, Glib::OwnershipType ownership)
+{
+  return array_to_vector (array, Glib::Container_Helpers::compute_array_size2 (array), ownership);
+}
+
+VectorHandler<bool, Glib::Container_Helpers::TypeTraits<bool> >::VectorType
+VectorHandler<bool, Glib::Container_Helpers::TypeTraits<bool> >::list_to_vector (GList* glist, Glib::OwnershipType ownership)
+{
+  // it will handle destroying data depending on passed ownership.
+  GListKeeperType keeper (glist, ownership);
+#ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
+  return VectorType (ListIteratorType (glist), ListIteratorType (0));
+#else
+  VectorType temp;
+  temp.reserve (g_list_length (glist));
+  Glib::Container_Helpers::fill_container (temp, ListIteratorType (glist), ListIteratorType (0));
+  return temp;
+#endif
+}
+
+VectorHandler<bool, Glib::Container_Helpers::TypeTraits<bool> >::VectorType
+VectorHandler<bool, Glib::Container_Helpers::TypeTraits<bool> >::slist_to_vector (GSList* gslist, Glib::OwnershipType ownership)
+{
+  // it will handle destroying data depending on passed ownership.
+  GSListKeeperType keeper (gslist, ownership);
+#ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
+  return VectorType (SListIteratorType (gslist), SListIteratorType (0));
+#else
+  VectorType temp;
+  temp.reserve (g_slist_length (gslist));
+  Glib::Container_Helpers::fill_container (temp, SListIteratorType (gslist), SListIteratorType (0));
+  return temp;
+#endif
+}
+
+typename VectorHandler<bool, Glib::Container_Helpers::TypeTraits<bool> >::ArrayKeeperType
+VectorHandler<bool, Glib::Container_Helpers::TypeTraits<bool> >::vector_to_array (const VectorType& vector)
+{
+  return ArrayKeeperType (Glib::Container_Helpers::create_bool_array (vector.begin (), vector.size ()), vector.size (), Glib::OWNERSHIP_SHALLOW);
+}
+
+VectorHandler<bool, Glib::Container_Helpers::TypeTraits<bool> >::GListKeeperType
+VectorHandler<bool, Glib::Container_Helpers::TypeTraits<bool> >::vector_to_list (const VectorType& vector)
+{
+  return GListKeeperType (Glib::Container_Helpers::create_bool_glist (vector.begin (), vector.end ()), Glib::OWNERSHIP_SHALLOW);
+}
+
+VectorHandler<bool, Glib::Container_Helpers::TypeTraits<bool> >::GSListKeeperType
+VectorHandler<bool, Glib::Container_Helpers::TypeTraits<bool> >::vector_to_slist (const VectorType& vector)
+{
+  return GSListKeeperType (Glib::Container_Helpers::create_bool_gslist (vector.begin (), vector.end ()), Glib::OWNERSHIP_SHALLOW);
+}
+
 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
 
 } // namespace Glib
 
 
 #endif /* _GLIBMM_VECTORUTILS_H */
-
diff --git a/tests/glibmm_vector/main.cc b/tests/glibmm_vector/main.cc
index 8f41afc..8151879 100644
--- a/tests/glibmm_vector/main.cc
+++ b/tests/glibmm_vector/main.cc
@@ -490,7 +490,7 @@ cxx_list_take_members (const std::vector<Glib::RefPtr<Gio::Credentials> >& v)
 void
 cxx_list_take_nothing (const std::vector<Glib::RefPtr<Gio::Credentials> >& v)
 {
-  take_list_nothing (Glib::VectorHandler<Glib::RefPtr<Gio::Credentials> >::vector_to_list (v));
+  take_list_nothing (Glib::VectorHandler<Glib::RefPtr<Gio::Credentials> >::vector_to_list (v).data());
 }
 
 /* they are probably buggy by design...
@@ -510,7 +510,7 @@ cxx_slist_take_members (const std::vector<Glib::RefPtr<Gio::Credentials> >& v)
 void
 cxx_slist_take_nothing (const std::vector<Glib::RefPtr<Gio::Credentials> >& v)
 {
-  take_slist_nothing (Glib::VectorHandler<Glib::RefPtr<Gio::Credentials> >::vector_to_slist (v));
+  take_slist_nothing (Glib::VectorHandler<Glib::RefPtr<Gio::Credentials> >::vector_to_slist (v).data());
 }
 
 /* they are probably buggy by design...
@@ -530,7 +530,7 @@ cxx_array_take_members (const std::vector<Glib::RefPtr<Gio::Credentials> >& v)
 void
 cxx_array_take_nothing (const std::vector<Glib::RefPtr<Gio::Credentials> >& v)
 {
-  take_array_nothing (Glib::VectorHandler<Glib::RefPtr<Gio::Credentials> >::vector_to_array (v));
+  take_array_nothing (Glib::VectorHandler<Glib::RefPtr<Gio::Credentials> >::vector_to_array (v).data());
 }
 
 



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