[glibmm] Added vectorutils.h.



commit 3762d17a42a27fa91877674d4d5142b7a51aef69
Author: Krzesimir Nowak <qdlacz gmail com>
Date:   Mon Jan 24 18:51:28 2011 +0100

    Added vectorutils.h.
    
    * glib/glibmm/vectorutils.[h|cc]: New files implementing an array, list,
    slist <-> std::vector convertions. It implements also a specialization
    for bool types.
    * glib/glibmm.h: Include vectorutils.h.
    * glib/glibmm/filelist.am: Added vectorutils to build.
    * tests/glibmm_vector/main.cc: New test for general vectorutils check.
    * tests/glibmm_bool_vector/main.cc: New test checking bool specializations.
    * tests/Makefile.am: Added above tests to build system.

 ChangeLog                        |   13 +
 glib/glibmm.h                    |    1 +
 glib/glibmm/filelist.am          |    2 +
 glib/glibmm/vectorutils.cc       |   73 ++++
 glib/glibmm/vectorutils.h        |  796 ++++++++++++++++++++++++++++++++++++++
 tests/Makefile.am                |    9 +-
 tests/glibmm_bool_vector/main.cc |   82 ++++
 tests/glibmm_vector/main.cc      |  580 +++++++++++++++++++++++++++
 8 files changed, 1554 insertions(+), 2 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 6400213..d57b707 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2011-01-24  Krzesimir Nowak  <qdlacz gmail com>
+
+	Added vectorutils.h.
+
+	* glib/glibmm/vectorutils.[h|cc]: New files implementing an array, list,
+	slist <-> std::vector convertions. It implements also a specialization
+	for bool types.
+	* glib/glibmm.h: Include vectorutils.h.
+	* glib/glibmm/filelist.am: Added vectorutils to build.
+	* tests/glibmm_vector/main.cc: New test for general vectorutils check.
+	* tests/glibmm_bool_vector/main.cc: New test checking bool specializations.
+	* tests/Makefile.am: Added above tests to build system.
+
 2011-01-20  Murray Cumming  <murrayc murrayc com>
 
 	Resolver: lookup_service(), lookup_by_address(): Fix the reference counting.
diff --git a/glib/glibmm.h b/glib/glibmm.h
index ae4ee0c..e404488 100644
--- a/glib/glibmm.h
+++ b/glib/glibmm.h
@@ -132,6 +132,7 @@
 #include <glibmm/variant.h>
 #include <glibmm/variantiter.h>
 #include <glibmm/varianttype.h>
+#include <glibmm/vectorutils.h>
 #include <glibmm/wrap.h>
 
 #endif /* _GLIBMM_H */
diff --git a/glib/glibmm/filelist.am b/glib/glibmm/filelist.am
index ccc7202..8e58b7b 100644
--- a/glib/glibmm/filelist.am
+++ b/glib/glibmm/filelist.am
@@ -36,6 +36,7 @@ glibmm_files_extra_cc =			\
 	utility.cc			\
 	value.cc			\
 	value_custom.cc			\
+	vectorutils.cc			\
 	wrap.cc
 
 glibmm_files_extra_h =			\
@@ -78,6 +79,7 @@ glibmm_files_extra_h =			\
 	utility.h			\
 	value.h				\
 	value_custom.h			\
+	vectorutils.h			\
 	wrap.h				\
 	wrap_init.h
 
diff --git a/glib/glibmm/vectorutils.cc b/glib/glibmm/vectorutils.cc
new file mode 100644
index 0000000..c264c79
--- /dev/null
+++ b/glib/glibmm/vectorutils.cc
@@ -0,0 +1,73 @@
+/* Copyright (C) 2011 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <glibmm/vectorutils.h>
+
+namespace Glib
+{
+
+namespace Container_Helpers
+{
+
+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;
+}
+
+} // namespace Container_Helpers
+
+/**** Glib::ArrayHandler<bool> ************************/
+
+ArrayHandler<bool, Glib::Container_Helpers::TypeTraits<bool> >::VectorType
+ArrayHandler<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
+}
+
+ArrayHandler<bool, Glib::Container_Helpers::TypeTraits<bool> >::VectorType
+ArrayHandler<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);
+}
+
+ArrayHandler<bool, Glib::Container_Helpers::TypeTraits<bool> >::ArrayKeeperType
+ArrayHandler<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);
+}
+
+} // namespace Glib
diff --git a/glib/glibmm/vectorutils.h b/glib/glibmm/vectorutils.h
new file mode 100644
index 0000000..a2d3227
--- /dev/null
+++ b/glib/glibmm/vectorutils.h
@@ -0,0 +1,796 @@
+// -*- c++ -*-
+#ifndef _GLIBMM_VECTORUTILS_H
+#define _GLIBMM_VECTORUTILS_H
+
+/* Copyright (C) 2011 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <vector>
+#include <glibmmconfig.h>
+#include <glibmm/containerhandle_shared.h>
+
+/* There are three types of functions:
+ * 1. Returning a container.
+ * 2. Taking a container as a parameter.
+ * 3. Returning a container as a parameter.
+ *
+ * Ad 1. When a function returns a container it can own:
+ * a) a container and data, callers ownership - none (caller owns neither
+ *    container nor data),
+ * b) only data, callers ownership - shallow (caller owns only a container),
+ * c) nothing, callers ownership - deep (caller owns both container and data).
+ *
+ * Above cases are simple - here we just create a vector with copies of returned
+ * container's data and then, depending on ownership transfer, we destroy
+ * nothing or container only or both container and data.
+ *
+ * Ad 2. When a function takes a container as a parameter it can take
+ * an ownership of:
+ * a) a container and data, callers ownership - none (caller loses ownership
+ *    of both container and data),
+ * b) only data, callers ownership - shallow (caller loses ownership of data),
+ * c) nothing, callers ownership - deep (caller does not lose ownership
+ *    to both container and data).
+ *
+ * Above cases are also simple - from given vector we create a C copy
+ * of container and data, pass them to function and then, depending on ownership
+ * transfer, we destroy nothing or container only or both container and data.
+ * But note that a) and b) cases are probably wrong by design, so we don't cover
+ * them here.
+ *
+ * Ad 3. Such functions are best wrapped by hand if we want to use a vector
+ * here.
+ */
+
+namespace Glib
+{
+
+namespace Container_Helpers
+{
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+// TODO: docs!
+
+/* Count the number of elements in a 0-terminated sequence.
+ */
+template <class T> inline
+size_t compute_array_size2 (const T* array)
+{
+  const T* pend (array);
+
+  while (*pend)
+  {
+    ++pend;
+  }
+
+  return (pend - array);
+}
+
+/* Allocate and fill a 0-terminated array.  The size argument
+ * specifies the number of elements in the input sequence.
+ */
+template <class Tr>
+typename Tr::CType* create_array (typename std::vector<typename Tr::CppType>::const_iterator pbegin, size_t size)
+{
+  typedef typename Tr::CType CType;
+
+  CType *const array (static_cast<CType*> (g_malloc((size + 1) * sizeof (CType))));
+  CType *const array_end (array + size);
+
+  for (CType* pdest (array); pdest != array_end; ++pdest)
+  {
+    // Use & to force a warning if the iterator returns a temporary object.
+    *pdest = Tr::to_c_type (*&*pbegin);
+    ++pbegin;
+  }
+  *array_end = CType ();
+
+  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);
+
+/* Create and fill a GList as efficient as possible.
+ * This requires bidirectional iterators.
+ */
+template <class Tr>
+GList* create_glist (const typename std::vector<typename Tr::CppType>::const_iterator pbegin,
+                     typename std::vector<typename Tr::CppType>::const_iterator pend)
+{
+  GList* head (0);
+
+  while (pend != pbegin)
+  {
+    // Use & to force a warning if the iterator returns a temporary object.
+    const void *const item (Tr::to_c_type(*&*--pend));
+    head = g_list_prepend(head, const_cast<void*> (item));
+  }
+
+  return head;
+}
+
+/* Create and fill a GSList as efficient as possible.
+ * This requires bidirectional iterators.
+ */
+template <class Tr>
+GSList* create_gslist (const typename std::vector<typename Tr::CppType>::const_iterator pbegin,
+                       typename std::vector<typename Tr::CppType>::const_iterator pend)
+{
+  GSList* head (0);
+
+  while (pend != pbegin)
+  {
+    // Use & to force a warning if the iterator returns a temporary object.
+    const void *const item (Tr::to_c_type(*&*--pend));
+    head = g_slist_prepend (head, const_cast<void*> (item));
+  }
+
+  return head;
+}
+
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+
+
+/**
+ * @ingroup ContHelpers
+ */
+template <class Tr>
+class ArrayIterator
+{
+public:
+  typedef typename Tr::CppType              CppType;
+  typedef typename Tr::CType                CType;
+
+  typedef std::random_access_iterator_tag   iterator_category;
+  typedef CppType                           value_type;
+  typedef ptrdiff_t                         difference_type;
+  typedef value_type                        reference;
+  typedef void                              pointer;
+
+  explicit inline ArrayIterator (const CType* pos);
+
+  inline value_type operator* () const;
+  inline value_type operator[] (difference_type offset) const;
+
+  inline ArrayIterator<Tr> &     operator++ ();
+  inline const ArrayIterator<Tr> operator++ (int);
+
+  // All this random access stuff is only there because STL algorithms
+  // usually have optimized specializations for random access iterators,
+  // and we don't want to give away efficiency for nothing.
+  inline ArrayIterator<Tr>&      operator+= (difference_type rhs);
+  inline ArrayIterator<Tr>&      operator-= (difference_type rhs);
+  inline const ArrayIterator<Tr> operator+ (difference_type rhs) const;
+  inline const ArrayIterator<Tr> operator- (difference_type rhs) const;
+  inline difference_type operator- (const ArrayIterator<Tr>& rhs) const;
+
+  inline bool operator== (const ArrayIterator<Tr>& rhs) const;
+  inline bool operator!= (const ArrayIterator<Tr>& rhs) const;
+  inline bool operator< (const ArrayIterator<Tr>& rhs) const;
+  inline bool operator> (const ArrayIterator<Tr>& rhs) const;
+  inline bool operator<= (const ArrayIterator<Tr>& rhs) const;
+  inline bool operator>= (const ArrayIterator<Tr>& rhs) const;
+
+private:
+  const CType* pos_;
+};
+
+/**
+ * @ingroup ContHelpers
+ * If a method takes this as an argument, or has this as a return type, then you can use a standard
+ * container such as std::list or std::vector.
+ */
+template <class Tr>
+class ListIterator
+{
+public:
+  typedef typename Tr::CppType        CppType;
+  typedef typename Tr::CType          CType;
+
+  typedef std::forward_iterator_tag   iterator_category;
+  typedef CppType                     value_type;
+  typedef ptrdiff_t                   difference_type;
+  typedef value_type                  reference;
+  typedef void                        pointer;
+
+  explicit inline ListIterator (const GList* node);
+
+  inline value_type                   operator* () const;
+  inline ListIterator<Tr>&            operator++ ();
+  inline const ListIterator<Tr>       operator++ (int);
+
+  inline bool operator== (const ListIterator<Tr>& rhs) const;
+  inline bool operator!= (const ListIterator<Tr>& rhs) const;
+
+private:
+  const GList* node_;
+};
+
+/**
+ * @ingroup ContHelpers
+ * If a method takes this as an argument, or has this as a return type, then you can use a standard
+ * container such as std::list or std::vector.
+ */
+template <class Tr>
+class SListIterator
+{
+public:
+  typedef typename Tr::CppType        CppType;
+  typedef typename Tr::CType          CType;
+
+  typedef std::forward_iterator_tag   iterator_category;
+  typedef CppType                     value_type;
+  typedef ptrdiff_t                   difference_type;
+  typedef value_type                  reference;
+  typedef void                        pointer;
+
+  explicit inline SListIterator (const GSList* node);
+
+  inline value_type                   operator* () const;
+  inline SListIterator<Tr>&           operator++ ();
+  inline const SListIterator<Tr>      operator++ (int);
+
+  inline bool operator== (const SListIterator<Tr>& rhs) const;
+  inline bool operator!= (const SListIterator<Tr>& rhs) const;
+
+private:
+  const GSList* node_;
+};
+
+template <typename Tr>
+class ArrayKeeper
+{
+public:
+  typedef typename Tr::CppType        CppType;
+  typedef typename Tr::CType          CType;
+
+  explicit inline ArrayKeeper (const CType* array, size_t array_size, Glib::OwnershipType ownership);
+  inline ArrayKeeper (const ArrayKeeper& keeper);
+  ~ArrayKeeper ();
+
+  inline CType* data () const;
+
+private:
+  CType* array_;
+  size_t array_size_;
+  mutable Glib::OwnershipType ownership_;
+};
+
+template <typename Tr>
+class GListKeeper
+{
+public:
+  typedef typename Tr::CppType        CppType;
+  typedef typename Tr::CType          CType;
+
+  explicit inline GListKeeper (const GList* glist, Glib::OwnershipType ownership);
+  inline GListKeeper (const GListKeeper& keeper);
+  ~GListKeeper ();
+
+  inline GList* data () const;
+
+private:
+  GList* glist_;
+  mutable Glib::OwnershipType ownership_;
+};
+
+template <typename Tr>
+class GSListKeeper
+{
+public:
+  typedef typename Tr::CppType        CppType;
+  typedef typename Tr::CType          CType;
+
+  explicit inline GSListKeeper (const GSList* gslist, Glib::OwnershipType ownership);
+  inline GSListKeeper (const GSListKeeper& keeper);
+  ~GSListKeeper ();
+
+  inline GSList* data () const;
+
+private:
+  GSList* gslist_;
+  mutable Glib::OwnershipType ownership_;
+};
+
+} // namespace Container_Helpers
+
+// a struct instead of templated functions because standard template arguments
+// for function templates is a C++0x feature...
+template <typename T, typename Tr = Glib::Container_Helpers::TypeTraits<T> >
+class ArrayHandler
+{
+public:
+  typedef typename Tr::CType CType;
+  typedef T CppType;
+  typedef std::vector<CppType> VectorType;
+  typedef typename Glib::Container_Helpers::ArrayKeeper<Tr> ArrayKeeperType;
+  typedef typename Glib::Container_Helpers::ArrayIterator<Tr> ArrayIteratorType;
+
+// 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 ArrayKeeperType vector_to_array (const VectorType& vector);
+};
+
+template <>
+class ArrayHandler<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::ArrayIterator<Glib::Container_Helpers::TypeTraits<bool> > ArrayIteratorType;
+
+// 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 ArrayKeeperType vector_to_array (const VectorType& vector);
+};
+
+template <typename T, typename Tr = Glib::Container_Helpers::TypeTraits<T> >
+class ListHandler
+{
+public:
+  typedef typename Tr::CType CType;
+  typedef T CppType;
+  typedef std::vector<CppType> VectorType;
+  typedef typename Glib::Container_Helpers::GListKeeper<Tr> GListKeeperType;
+  typedef typename Glib::Container_Helpers::ListIterator<Tr> ListIteratorType;
+
+// maybe think about using C++0x move constructors?
+  static VectorType list_to_vector (GList* glist, Glib::OwnershipType ownership);
+  static GListKeeperType vector_to_list (const VectorType& vector);
+};
+
+template <typename T, typename Tr = Glib::Container_Helpers::TypeTraits<T> >
+class SListHandler
+{
+public:
+  typedef typename Tr::CType CType;
+  typedef T CppType;
+  typedef std::vector<CppType> VectorType;
+  typedef typename Glib::Container_Helpers::GSListKeeper<Tr> GSListKeeperType;
+  typedef typename Glib::Container_Helpers::SListIterator<Tr> SListIteratorType;
+
+// maybe think about using C++0x move constructors?
+  static VectorType slist_to_vector (GSList* gslist, Glib::OwnershipType ownership);
+  static GSListKeeperType vector_to_slist (const VectorType& vector);
+};
+
+/***************************************************************************/
+/*  Inline implementation                                                  */
+/***************************************************************************/
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+namespace Container_Helpers
+{
+
+/**** Glib::Container_Helpers::ArrayIterator<> ***********************/
+
+template <class Tr> inline
+ArrayIterator<Tr>::ArrayIterator (const CType* pos)
+:
+  pos_ (pos)
+{}
+
+template <class Tr> inline
+typename ArrayIterator<Tr>::value_type ArrayIterator<Tr>::operator* () const
+{
+  return Tr::to_cpp_type (*pos_);
+}
+
+template <class Tr> inline
+typename ArrayIterator<Tr>::value_type
+ArrayIterator<Tr>::operator[] (difference_type offset) const
+{
+  return Tr::to_cpp_type (pos_[offset]);
+}
+
+template <class Tr> inline
+ArrayIterator<Tr>& ArrayIterator<Tr>::operator++ ()
+{
+  ++pos_;
+  return *this;
+}
+
+template <class Tr> inline
+const ArrayIterator<Tr> ArrayIterator<Tr>::operator++ (int)
+{
+  return ArrayIterator<Tr> (pos_++);
+}
+
+template <class Tr> inline
+ArrayIterator<Tr>&
+ArrayIterator<Tr>::operator+= (typename ArrayIterator<Tr>::difference_type rhs)
+{
+  pos_ += rhs;
+  return *this;
+}
+
+template <class Tr> inline
+ArrayIterator<Tr>&
+ArrayIterator<Tr>::operator-= (typename ArrayIterator<Tr>::difference_type rhs)
+{
+  pos_ -= rhs;
+  return *this;
+}
+
+template <class Tr> inline
+const ArrayIterator<Tr>
+ArrayIterator<Tr>::operator+ (typename ArrayIterator<Tr>::difference_type rhs) const
+{
+  return ArrayIterator<Tr> (pos_ + rhs);
+}
+
+template <class Tr> inline
+const ArrayIterator<Tr>
+ArrayIterator<Tr>::operator- (typename ArrayIterator<Tr>::difference_type rhs) const
+{
+  return ArrayIterator<Tr> (pos_ - rhs);
+}
+
+template <class Tr> inline
+typename ArrayIterator<Tr>::difference_type
+ArrayIterator<Tr>::operator- (const ArrayIterator<Tr>& rhs) const
+{
+  return (pos_ - rhs.pos_);
+}
+
+template <class Tr> inline
+bool ArrayIterator<Tr>::operator== (const ArrayIterator<Tr>& rhs) const
+{
+  return (pos_ == rhs.pos_);
+}
+
+template <class Tr> inline
+bool ArrayIterator<Tr>::operator!= (const ArrayIterator<Tr>& rhs) const
+{
+  return (pos_ != rhs.pos_);
+}
+
+template <class Tr> inline
+bool ArrayIterator<Tr>::operator< (const ArrayIterator<Tr>& rhs) const
+{
+  return (pos_ < rhs.pos_);
+}
+
+template <class Tr> inline
+bool ArrayIterator<Tr>::operator> (const ArrayIterator<Tr>& rhs) const
+{
+  return (pos_ > rhs.pos_);
+}
+
+template <class Tr> inline
+bool ArrayIterator<Tr>::operator<= (const ArrayIterator<Tr>& rhs) const
+{
+  return (pos_ <= rhs.pos_);
+}
+
+template <class Tr> inline
+bool ArrayIterator<Tr>::operator>= (const ArrayIterator<Tr>& rhs) const
+{
+  return (pos_ >= rhs.pos_);
+}
+
+/**** Glib::Container_Helpers::ListIterator<> ************************/
+
+template <class Tr> inline
+ListIterator<Tr>::ListIterator (const GList* node)
+:
+  node_ (node)
+{}
+
+template <class Tr> inline
+typename ListIterator<Tr>::value_type ListIterator<Tr>::operator* () const
+{
+  return Tr::to_cpp_type (static_cast<typename Tr::CTypeNonConst> (node_->data));
+}
+
+template <class Tr> inline
+ListIterator<Tr>& ListIterator<Tr>::operator++ ()
+{
+  node_ = node_->next;
+  return *this;
+}
+
+template <class Tr> inline
+const ListIterator<Tr> ListIterator<Tr>::operator++ (int)
+{
+  const ListIterator<Tr> tmp (*this);
+  node_ = node_->next;
+  return tmp;
+}
+
+template <class Tr> inline
+bool ListIterator<Tr>::operator== (const ListIterator<Tr>& rhs) const
+{
+  return (node_ == rhs.node_);
+}
+
+template <class Tr> inline
+bool ListIterator<Tr>::operator!= (const ListIterator<Tr>& rhs) const
+{
+  return (node_ != rhs.node_);
+}
+
+/**** Glib::Container_Helpers::SListIterator<> ************************/
+
+template <class Tr> inline
+SListIterator<Tr>::SListIterator (const GSList* node)
+:
+  node_ (node)
+{}
+
+template <class Tr> inline
+typename SListIterator<Tr>::value_type SListIterator<Tr>::operator* () const
+{
+  return Tr::to_cpp_type (static_cast<typename Tr::CTypeNonConst> (node_->data));
+}
+
+template <class Tr> inline
+SListIterator<Tr>& SListIterator<Tr>::operator++ ()
+{
+  node_ = node_->next;
+  return *this;
+}
+
+template <class Tr> inline
+const SListIterator<Tr> SListIterator<Tr>::operator++ (int)
+{
+  const ListIterator<Tr> tmp (*this);
+  node_ = node_->next;
+  return tmp;
+}
+
+template <class Tr> inline
+bool SListIterator<Tr>::operator== (const SListIterator<Tr>& rhs) const
+{
+  return (node_ == rhs.node_);
+}
+
+template <class Tr> inline
+bool SListIterator<Tr>::operator!= (const SListIterator<Tr>& rhs) const
+{
+  return (node_ != rhs.node_);
+}
+
+/**** Glib::Container_Helpers::ArrayKeeper<> ************************/
+
+template <typename Tr>
+inline ArrayKeeper<Tr>::ArrayKeeper (const CType* array, size_t array_size, Glib::OwnershipType ownership)
+:
+  array_ (const_cast<CType*> (array)),
+  array_size_ (array_size),
+  ownership_ (ownership)
+{}
+
+template <typename Tr>
+inline ArrayKeeper<Tr>::ArrayKeeper (const ArrayKeeper& keeper)
+:
+  array_ (keeper.array_),
+  array_size_ (keeper.array_size_),
+  ownership_ (keeper.ownership_)
+{
+  keeper.ownership_ = Glib::OWNERSHIP_NONE;
+}
+
+template <typename Tr>
+ArrayKeeper<Tr>::~ArrayKeeper ()
+{
+  if (array_ && ownership_ != Glib::OWNERSHIP_NONE)
+  {
+    if (ownership_ != Glib::OWNERSHIP_SHALLOW)
+    {
+      // Deep ownership: release each container element.
+      const CType *const array_end (array_ + array_size_);
+
+      for (const CType* p (array_); p != array_end; ++p)
+      {
+        Tr::release_c_type (*p);
+      }
+    }
+    g_free (const_cast<CType*> (array_));
+  }
+}
+
+template <typename Tr>
+inline typename Tr::CType* ArrayKeeper<Tr>::data () const
+{
+  return array_;
+}
+
+/**** Glib::Container_Helpers::GListKeeper<> ************************/
+
+template <typename Tr>
+inline GListKeeper<Tr>::GListKeeper (const GList* glist, Glib::OwnershipType ownership)
+:
+  glist_ (const_cast<GList*> (glist)),
+  ownership_ (ownership)
+{}
+
+template <typename Tr>
+inline GListKeeper<Tr>::GListKeeper (const GListKeeper& keeper)
+:
+  glist_ (keeper.glist_),
+  ownership_ (keeper.ownership_)
+{
+  keeper.ownership_ = Glib::OWNERSHIP_NONE;
+}
+
+template <typename Tr>
+GListKeeper<Tr>::~GListKeeper ()
+{
+  typedef typename Tr::CTypeNonConst CTypeNonConst;
+
+  if (glist_ && ownership_ != Glib::OWNERSHIP_NONE)
+  {
+    if (ownership_ != Glib::OWNERSHIP_SHALLOW)
+    {
+      // Deep ownership: release each container element.
+      for (GList* node = glist_; node; node = node->next)
+      {
+        Tr::release_c_type (static_cast<CTypeNonConst> (node->data));
+      }
+    }
+    g_list_free (glist_);
+  }
+}
+
+template <typename Tr>
+inline GList* GListKeeper<Tr>::data () const
+{
+  return glist_;
+}
+
+/**** Glib::Container_Helpers::GSListKeeper<> ************************/
+
+template <typename Tr>
+inline GSListKeeper<Tr>::GSListKeeper (const GSList* gslist, Glib::OwnershipType ownership)
+:
+  gslist_ (const_cast<GSList*> (gslist)),
+  ownership_ (ownership)
+{}
+
+template <typename Tr>
+inline GSListKeeper<Tr>::GSListKeeper (const GSListKeeper& keeper)
+:
+  gslist_ (keeper.gslist_),
+  ownership_ (keeper.ownership_)
+{
+  keeper.ownership_ = Glib::OWNERSHIP_NONE;
+}
+
+template <typename Tr>
+GSListKeeper<Tr>::~GSListKeeper ()
+{
+  typedef typename Tr::CTypeNonConst CTypeNonConst;
+  if (gslist_ && ownership_ != Glib::OWNERSHIP_NONE)
+  {
+    if (ownership_ != Glib::OWNERSHIP_SHALLOW)
+    {
+      // Deep ownership: release each container element.
+      for (GSList* node = gslist_; node; node = node->next)
+      {
+        Tr::release_c_type (static_cast<CTypeNonConst> (node->data));
+      }
+    }
+    g_slist_free (gslist_);
+  }
+}
+
+template <typename Tr>
+inline GSList* GSListKeeper<Tr>::data () const
+{
+  return gslist_;
+}
+
+} // namespace Container_Helpers
+
+/**** Glib::ArrayHandler<> ************************/
+
+template <typename T, class Tr>
+typename ArrayHandler<T, Tr>::VectorType
+ArrayHandler<T, Tr>::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
+}
+
+template <typename T, class Tr>
+typename ArrayHandler<T, Tr>::VectorType
+ArrayHandler<T, Tr>::array_to_vector(const CType* array, Glib::OwnershipType ownership)
+{
+  return array_to_vector (array, Glib::Container_Helpers::compute_array_size2 (array), ownership);
+}
+
+template <typename T, class Tr>
+typename ArrayHandler<T, Tr>::ArrayKeeperType
+ArrayHandler<T, Tr>::vector_to_array (const VectorType& vector)
+{
+  return ArrayKeeperType (Glib::Container_Helpers::create_array<Tr> (vector.begin (), vector.size ()), vector.size (), Glib::OWNERSHIP_SHALLOW);
+}
+
+/**** Glib::ListHandler<> ************************/
+
+template <typename T, class Tr>
+typename ListHandler<T, Tr>::VectorType
+ListHandler<T, Tr>::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
+}
+
+template <typename T, class Tr>
+typename ListHandler<T, Tr>::GListKeeperType
+ListHandler<T, Tr>::vector_to_list (const VectorType& vector)
+{
+  return GListKeeperType (Glib::Container_Helpers::create_glist<Tr> (vector.begin(), vector.end()), Glib::OWNERSHIP_SHALLOW);
+}
+
+/**** Glib::SListHandler<> ************************/
+
+template <typename T, class Tr>
+typename SListHandler<T, Tr>::VectorType
+SListHandler<T, Tr>::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
+}
+
+template <typename T, class Tr>
+typename SListHandler<T, Tr>::GSListKeeperType
+SListHandler<T, Tr>::vector_to_slist (const VectorType& vector)
+{
+  return GSListKeeperType (Glib::Container_Helpers::create_gslist<Tr> (vector.begin (), vector.end ()), Glib::OWNERSHIP_SHALLOW);
+}
+
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+
+} // namespace Glib
+
+
+#endif /* _GLIBMM_VECTORUTILS_H */
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 13aeaf1..c31d9cb 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -28,7 +28,9 @@ check_PROGRAMS =			\
 	glibmm_ustring_format/test	\
 	glibmm_value/test		\
 	glibmm_valuearray/test		\
-	glibmm_variant/test
+	glibmm_variant/test		\
+	glibmm_vector/test		\
+	glibmm_bool_vector/test
 
 glibmm_includes = -I$(top_builddir)/glib $(if $(srcdir:.=),-I$(top_srcdir)/glib)
 giomm_includes  = -I$(top_builddir)/gio $(if $(srcdir:.=),-I$(top_srcdir)/gio)
@@ -56,7 +58,10 @@ glibmm_btree_test_SOURCES           = glibmm_btree/main.cc
 glibmm_date_test_SOURCES            = glibmm_date/main.cc
 glibmm_nodetree_test_SOURCES        = glibmm_nodetree/main.cc
 glibmm_ustring_compose_test_SOURCES = glibmm_ustring_compose/main.cc
-glibmm_ustring_format_test_SOURCES = glibmm_ustring_format/main.cc
+glibmm_ustring_format_test_SOURCES  = glibmm_ustring_format/main.cc
 glibmm_value_test_SOURCES           = glibmm_value/glibmm_value.cc glibmm_value/main.cc
 glibmm_valuearray_test_SOURCES      = glibmm_valuearray/main.cc
 glibmm_variant_test_SOURCES         = glibmm_variant/main.cc
+glibmm_vector_test_SOURCES          = glibmm_vector/main.cc
+glibmm_vector_test_LDADD            = $(giomm_ldadd)
+glibmm_bool_vector_test_SOURCES     = glibmm_bool_vector/main.cc
diff --git a/tests/glibmm_bool_vector/main.cc b/tests/glibmm_bool_vector/main.cc
new file mode 100644
index 0000000..47b6796
--- /dev/null
+++ b/tests/glibmm_bool_vector/main.cc
@@ -0,0 +1,82 @@
+/* Copyright (C) 2011 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <cstdlib>
+#include <ctime>
+
+#include <iostream>
+
+#include <glibmm.h>
+
+const unsigned int magic_limit (5);
+
+void
+setup_rand ()
+{
+  static bool setup (false);
+
+  if (!setup)
+  {
+    setup = true;
+    std::srand (std::time (0));
+  }
+}
+
+gboolean*
+c_get_bool_array ()
+{
+  gboolean* array (static_cast<gboolean*> (g_malloc ((magic_limit + 1) * sizeof (gboolean))));
+
+  setup_rand ();
+  for (unsigned int iter (0); iter < magic_limit; ++iter)
+  {
+    array[iter] = std::rand() % 2 ? TRUE : FALSE;
+  }
+  array[magic_limit] = FALSE;
+  return array;
+}
+
+void
+c_print_bool_array (gboolean* array)
+{
+  for (unsigned int iter (0); iter < magic_limit; ++iter)
+  {
+    std::cout << iter << ": " << (array[iter] ? "TRUE" : "FALSE") << "\n";
+  }
+}
+
+std::vector<bool>
+cxx_get_bool_array ()
+{
+  return Glib::ArrayHandler<bool>::array_to_vector (c_get_bool_array (), magic_limit, Glib::OWNERSHIP_SHALLOW);
+}
+
+void
+cxx_print_bool_array (const std::vector<bool>& v)
+{
+  c_print_bool_array (const_cast<gboolean*> (Glib::ArrayHandler<bool>::vector_to_array (v).data ()));
+}
+
+int main(int, char**)
+{
+  Glib::init();
+
+  std::vector<bool> va (cxx_get_bool_array ());
+
+  cxx_print_bool_array (va);
+
+  return 0;
+}
diff --git a/tests/glibmm_vector/main.cc b/tests/glibmm_vector/main.cc
new file mode 100644
index 0000000..4b64276
--- /dev/null
+++ b/tests/glibmm_vector/main.cc
@@ -0,0 +1,580 @@
+/* Copyright (C) 2010 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+// ugly code ahead.
+
+#include <iostream>
+
+#include <gio/gio.h>
+
+#include <glibmm/vectorutils.h>
+
+#include <giomm/credentials.h>
+#include <giomm/init.h>
+
+// utilities
+
+const unsigned int magic_limit (5);
+
+GList*
+create_list ()
+{
+  GList* head = 0;
+
+  for (unsigned int iter (0); iter < magic_limit; ++iter)
+  {
+    head = g_list_prepend (head, g_credentials_new ());
+  }
+  return g_list_reverse (head);
+}
+
+void
+print_list (GList* list)
+{
+  unsigned int counter (1);
+
+  for (GList* node (list); node; node = node->next, ++counter)
+  {
+    std::cout << counter << ": ";
+    if (G_IS_CREDENTIALS (node->data))
+    {
+      std::cout << node->data << ", ref: " << G_OBJECT (node->data)->ref_count <<"\n";
+    }
+    else
+    {
+      std::cout << "no C instance?\n";
+    }
+  }
+}
+
+GSList*
+create_slist ()
+{
+  GSList* head = 0;
+
+  for (unsigned int iter (0); iter < magic_limit; ++iter)
+  {
+    head = g_slist_prepend (head, g_credentials_new ());
+  }
+  return g_slist_reverse (head);
+}
+
+void
+print_slist (GSList* slist)
+{
+  unsigned int counter (1);
+
+  for (GSList* node (slist); node; node = node->next, ++counter)
+  {
+    std::cout << counter << ": ";
+    if (G_IS_CREDENTIALS (node->data))
+    {
+      std::cout << node->data << ", ref: " << G_OBJECT (node->data)->ref_count <<"\n";
+    }
+    else
+    {
+      std::cout << "no C instance?\n";
+    }
+  }
+}
+
+GCredentials**
+create_array ()
+{
+  GCredentials** array = g_new0 (GCredentials*, magic_limit + 1);
+
+  for (unsigned int iter (0); iter < magic_limit; ++iter)
+  {
+    array[iter] = g_credentials_new ();
+  }
+  return array;
+}
+
+void
+print_array (GCredentials** array)
+{
+  for (unsigned int iter (0); iter < magic_limit; ++iter)
+  {
+    GCredentials* credentials (array[iter]);
+
+    std::cout << iter + 1 << ": ";
+    if (G_IS_CREDENTIALS (credentials))
+    {
+      std::cout << reinterpret_cast<gpointer> (credentials) << ", ref: " << G_OBJECT (credentials)->ref_count << "\n";
+    }
+    else
+    {
+      std::cout << "no C instance?\n";
+    }
+  }
+}
+
+// shallow copy
+GCredentials**
+copy_array (GCredentials** array)
+{
+  GCredentials** dup = g_new0 (GCredentials*, magic_limit + 1);
+
+  for (unsigned int iter (0); iter < magic_limit; ++iter)
+  {
+    dup[iter] = array[iter];
+  }
+  dup[magic_limit] = 0;
+  return dup;
+}
+
+void
+free_array (GCredentials** array, bool container_too = true)
+{
+  for (unsigned int iter (0); iter < magic_limit; ++iter)
+  {
+    g_object_unref (array[iter]);
+  }
+  if (container_too)
+  {
+    g_free (array);
+  }
+}
+
+void
+print_vector (const std::vector<Glib::RefPtr<Gio::Credentials> >& v)
+{
+  const unsigned int size (v.size ());
+
+  for (unsigned int iter (0); iter < size; ++iter)
+  {
+    const Glib::RefPtr<Gio::Credentials>& obj_ptr (v[iter]);
+
+    std::cout << iter + 1 << ": ";
+    if (obj_ptr)
+    {
+      GCredentials* gobj (obj_ptr->gobj ());
+
+      if (G_IS_CREDENTIALS (gobj))
+      {
+        std::cout << static_cast<gpointer> (gobj) << ", ref: " << G_OBJECT (gobj)->ref_count << "\n";
+      }
+      else
+      {
+        std::cout << "No C instance?\n";
+      }
+    }
+    else
+    {
+      std::cout << "No C++ instance?\n";
+    }
+  }
+}
+
+struct Cache
+{
+public:
+  Cache()
+  : glist_ (create_list ()),
+    gslist_ (create_slist ()),
+    garray_ (create_array ())
+  {}
+
+  ~Cache()
+  {
+    if (glist_)
+    {
+      g_list_foreach (glist_, reinterpret_cast<GFunc> (g_object_unref), 0);
+      g_list_free (glist_);
+    }
+    if (gslist_)
+    {
+      g_slist_foreach (gslist_, reinterpret_cast<GFunc> (g_object_unref), 0);
+      g_slist_free (gslist_);
+    }
+    if (garray_)
+    {
+      free_array (garray_);
+    }
+  }
+
+  GList*
+  get_list () const
+  {
+    return glist_;
+  }
+
+  GSList*
+  get_slist () const
+  {
+    return gslist_;
+  }
+
+  GCredentials**
+  get_array () const
+  {
+    return garray_;
+  }
+
+private:
+  // just in case
+  Cache (const Cache&);
+  Cache operator= (const Cache&);
+
+  GList* glist_;
+  GSList* gslist_;
+  GCredentials** garray_;
+};
+
+Cache&
+get_cache ()
+{
+  static Cache global_cache;
+
+  return global_cache;
+}
+
+// C functions
+
+GList*
+c_get_deep_owned_list ()
+{
+  return get_cache ().get_list ();
+}
+
+GList*
+c_get_shallow_owned_list ()
+{
+  return g_list_copy (c_get_deep_owned_list ());
+}
+
+GList*
+c_get_unowned_list ()
+{
+  return create_list ();
+}
+
+GSList*
+c_get_deep_owned_slist ()
+{
+  return get_cache ().get_slist ();
+}
+
+GSList*
+c_get_shallow_owned_slist ()
+{
+  return g_slist_copy (c_get_deep_owned_slist ());
+}
+
+GSList*
+c_get_unowned_slist ()
+{
+  return create_slist ();
+}
+
+GCredentials**
+c_get_deep_owned_array ()
+{
+  return get_cache ().get_array ();
+}
+
+GCredentials**
+c_get_shallow_owned_array ()
+{
+  return copy_array (c_get_deep_owned_array ());
+}
+
+GCredentials**
+c_get_unowned_array ()
+{
+  return create_array ();
+}
+
+/* these are probably buggy by design...
+void
+c_take_list_all (GList* list)
+{
+  if (list)
+  {
+    print_list (list);
+    g_list_foreach (list, reinterpret_cast<GFunc> (g_object_unref), 0);
+    g_list_free (list);
+  }
+}
+
+void
+c_take_list_members (GList* list)
+{
+  if (list)
+  {
+    print_list (list);
+    g_list_foreach (list, reinterpret_cast<GFunc> (g_object_unref), 0);
+  }
+}
+*/
+
+void
+c_take_list_nothing (GList* list)
+{
+  if (list)
+  {
+    print_list (list);
+  }
+}
+
+/* they are probably buggy by design...
+void
+c_take_slist_all (GSList* slist)
+{
+  if (slist)
+  {
+    print_slist (slist);
+    g_slist_foreach (slist, reinterpret_cast<GFunc> (g_object_unref), 0);
+    g_slist_free (slist);
+  }
+}
+
+void
+c_take_list_members (GSList* slist)
+{
+  if (slist)
+  {
+    print_slist (slist);
+    g_slist_foreach (slist, reinterpret_cast<GFunc> (g_object_unref), 0);
+  }
+}
+*/
+
+void
+c_take_slist_nothing (GSList* slist)
+{
+  if (slist)
+  {
+    print_slist (slist);
+  }
+}
+
+/* they are probably buggy by design...
+void
+c_take_array_all (GCredentials** array)
+{
+  if (array)
+  {
+    print_array (array);
+    free_array (array);
+  }
+}
+
+void
+c_take_array_members (GCredentials** array)
+{
+  if (array)
+  {
+    print_array (array);
+    free_array (array, false);
+  }
+}
+*/
+
+void
+c_take_array_nothing (GCredentials** array)
+{
+  if (array)
+  {
+    print_array (array);
+  }
+}
+
+// C++ wrappers.
+
+std::vector<Glib::RefPtr<Gio::Credentials> >
+cxx_get_deep_owned_list ()
+{
+  return Glib::ListHandler<Glib::RefPtr<Gio::Credentials> >::list_to_vector (c_get_deep_owned_list (), Glib::OWNERSHIP_NONE);
+}
+
+std::vector<Glib::RefPtr<Gio::Credentials> >
+cxx_get_shallow_owned_list ()
+{
+  return Glib::ListHandler<Glib::RefPtr<Gio::Credentials> >::list_to_vector (c_get_shallow_owned_list (), Glib::OWNERSHIP_SHALLOW);
+}
+
+std::vector<Glib::RefPtr<Gio::Credentials> >
+cxx_get_unowned_list ()
+{
+  return Glib::ListHandler<Glib::RefPtr<Gio::Credentials> >::list_to_vector (c_get_unowned_list (), Glib::OWNERSHIP_DEEP);
+}
+
+std::vector<Glib::RefPtr<Gio::Credentials> >
+cxx_get_deep_owned_slist ()
+{
+  return Glib::SListHandler<Glib::RefPtr<Gio::Credentials> >::slist_to_vector (c_get_deep_owned_slist (), Glib::OWNERSHIP_NONE);
+}
+
+std::vector<Glib::RefPtr<Gio::Credentials> >
+cxx_get_shallow_owned_slist ()
+{
+  return Glib::SListHandler<Glib::RefPtr<Gio::Credentials> >::slist_to_vector (c_get_shallow_owned_slist (), Glib::OWNERSHIP_SHALLOW);
+}
+
+std::vector<Glib::RefPtr<Gio::Credentials> >
+cxx_get_unowned_slist ()
+{
+  return Glib::SListHandler<Glib::RefPtr<Gio::Credentials> >::slist_to_vector (c_get_unowned_slist (), Glib::OWNERSHIP_DEEP);
+}
+
+std::vector<Glib::RefPtr<Gio::Credentials> >
+cxx_get_deep_owned_array ()
+{
+  return Glib::ArrayHandler<Glib::RefPtr<Gio::Credentials> >::array_to_vector (c_get_deep_owned_array (), Glib::OWNERSHIP_NONE);
+}
+
+std::vector<Glib::RefPtr<Gio::Credentials> >
+cxx_get_shallow_owned_array ()
+{
+  return Glib::ArrayHandler<Glib::RefPtr<Gio::Credentials> >::array_to_vector (c_get_shallow_owned_array (), Glib::OWNERSHIP_SHALLOW);
+}
+
+std::vector<Glib::RefPtr<Gio::Credentials> >
+cxx_get_unowned_array ()
+{
+  return Glib::ArrayHandler<Glib::RefPtr<Gio::Credentials> >::array_to_vector (c_get_unowned_array (), Glib::OWNERSHIP_DEEP);
+}
+
+/* they are probably buggy by design...
+void
+cxx_list_take_all (const std::vector<Glib::RefPtr<Gio::Credentials> >& v)
+{
+  c_take_list_all (Glib::ListHandler<Glib::RefPtr<Gio::Credentials> >::vector_to_list (v).data ());
+}
+
+void
+cxx_list_take_members (const std::vector<Glib::RefPtr<Gio::Credentials> >& v)
+{
+  c_take_list_members (Glib::ListHandler<Glib::RefPtr<Gio::Credentials> >::vector_to_list (v).data ());
+}
+*/
+
+void
+cxx_list_take_nothing (const std::vector<Glib::RefPtr<Gio::Credentials> >& v)
+{
+  c_take_list_nothing (Glib::ListHandler<Glib::RefPtr<Gio::Credentials> >::vector_to_list (v).data ());
+}
+
+/* they are probably buggy by design...
+void
+cxx_slist_take_all (const std::vector<Glib::RefPtr<Gio::Credentials> >& v)
+{
+  c_take_slist_all (Glib::SListHandler<Glib::RefPtr<Gio::Credentials> >::vector_to_slist (v).data ());
+}
+
+void
+cxx_slist_take_members (const std::vector<Glib::RefPtr<Gio::Credentials> >& v)
+{
+  c_take_slist_members (Glib::SListHandler<Glib::RefPtr<Gio::Credentials> >::vector_to_slist (v).data ());
+}
+*/
+
+void
+cxx_slist_take_nothing (const std::vector<Glib::RefPtr<Gio::Credentials> >& v)
+{
+  c_take_slist_nothing (Glib::SListHandler<Glib::RefPtr<Gio::Credentials> >::vector_to_slist (v).data ());
+}
+
+/* they are probably buggy by design...
+void
+cxx_array_take_all (const std::vector<Glib::RefPtr<Gio::Credentials> >& v)
+{
+  c_take_array_all (Glib::ArrayHandler<Glib::RefPtr<Gio::Credentials> >::vector_to_array (v).data ());
+}
+
+void
+cxx_array_take_members (const std::vector<Glib::RefPtr<Gio::Credentials> >& v)
+{
+  c_take_array_members (Glib::ArrayHandler<Glib::RefPtr<Gio::Credentials> >::vector_to_array (v).data ());
+}
+*/
+
+void
+cxx_array_take_nothing (const std::vector<Glib::RefPtr<Gio::Credentials> >& v)
+{
+  c_take_array_nothing (Glib::ArrayHandler<Glib::RefPtr<Gio::Credentials> >::vector_to_array (v).data ());
+}
+
+
+int
+main()
+{
+  Gio::init ();
+
+  Cache& cache (get_cache ());
+
+  std::cout << "Cache list before:\n";
+  print_list (cache.get_list ());
+  std::cout << "Cache slist before:\n";
+  print_slist (cache.get_slist ());
+  std::cout << "Cache array before:\n";
+  print_array (cache.get_array ());
+  std::cout << "Deep owned list:\n";
+  print_vector (cxx_get_deep_owned_list ());
+  std::cout << "Shallow owned list:\n";
+  print_vector (cxx_get_shallow_owned_list ());
+  std::cout << "Unowned list:\n";
+  print_vector (cxx_get_unowned_list ());
+  std::cout << "Deep owned slist:\n";
+  print_vector (cxx_get_deep_owned_slist ());
+  std::cout << "Shallow owned slist:\n";
+  print_vector (cxx_get_shallow_owned_slist ());
+  std::cout << "Unowned slist:\n";
+  print_vector (cxx_get_unowned_slist ());
+  std::cout << "Deep owned array:\n";
+  print_vector (cxx_get_deep_owned_array ());
+  std::cout << "Shallow owned array:\n";
+  print_vector (cxx_get_shallow_owned_array ());
+  std::cout << "Unowned array:\n";
+  print_vector (cxx_get_unowned_array ());
+  std::cout << "Cache list after:\n";
+  print_list (cache.get_list ());
+  std::cout << "Cache slist after:\n";
+  print_slist (cache.get_slist ());
+  std::cout << "Cache array after:\n";
+  print_array (cache.get_array ());
+
+  std::vector<Glib::RefPtr<Gio::Credentials> > v (cxx_get_unowned_list ());
+
+  std::cout << "Gotten vector before:\n";
+  print_vector (v);
+  // I am wondering if C functions wrapped by the ones below are not buggy by
+  // design. Anyway - it segfaults. Maybe the test case is just wrong.
+  //std::cout << "Take list all:\n";
+  //cxx_list_take_all (v);
+  //std::cout << "Take list members:\n";
+  //cxx_list_take_members (v);
+  std::cout << "Take list nothing:\n";
+  cxx_list_take_nothing (v);
+  // Ditto.
+  //std::cout << "Take slist all:\n";
+  //cxx_slist_take_all (v);
+  //std::cout << "Take slist members:\n";
+  //cxx_slist_take_members (v);
+  std::cout << "Take slist nothing:\n";
+  cxx_slist_take_nothing (v);
+  // Ditto.
+  //std::cout << "Take array all:\n";
+  //cxx_array_take_all (v);
+  //std::cout << "Take array members:\n";
+  //cxx_array_take_members (v);
+  std::cout << "Take array nothing:\n";
+  cxx_array_take_nothing (v);
+  std::cout << "Gotten vector after:\n";
+  print_vector (v);
+}



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