[glibmm] Added bool specialization for Glib::ArrayHandle.



commit 202871d761e3b14dda986eb1d303bd514fd28cf3
Author: Krzesimir Nowak <qdlacz gmail com>
Date:   Wed Feb 2 21:57:49 2011 +0100

    Added bool specialization for Glib::ArrayHandle.
    
    * glib/glibmm/arrayhandle.h: Added specialization for bool ArrayHandle.
    This is needed because std::vector<bool> is a specialization for which
    iterators does not return a reference to actual value it holds.
    * glib/glibmm/arrayhandle.cc: New file implementing destructor of
    bool ArrayHandle - the only method that is not inlined.
    * tests/glibmm_bool_arrayhandle/main.cc: New file implementing test
    checking if bool ArrayHandle actually works.
    * tests/Makefile.am: Added new test to build.

 ChangeLog                 |   14 +++
 glib/glibmm/arrayhandle.h |  214 +++++++++++++++++++++++++++++++++++++++++++++
 glib/glibmm/filelist.am   |    1 +
 tests/Makefile.am         |   52 ++++++-----
 4 files changed, 256 insertions(+), 25 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index c1efa35..8aa9690 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2011-02-02  Krzesimir Nowak  <qdlacz gmail com>
+
+	Added bool specialization for Glib::ArrayHandle.
+
+	* glib/glibmm/arrayhandle.h: Added specialization for bool ArrayHandle.
+	This is needed because std::vector<bool> is a specialization for which
+	iterators does not return a reference to actual value it holds.
+	* glib/glibmm/arrayhandle.cc: New file implementing destructor of
+	bool ArrayHandle - the only method that is not inlined.
+	* glib/glibmm/filelist.am: Added new source file to build.
+	* tests/glibmm_bool_arrayhandle/main.cc: New file implementing test
+	checking if bool ArrayHandle actually works.
+	* tests/Makefile.am: Added new test to build.
+
 2011-02-17  Kjell Ahlstedt  <kjell ahlstedt bredband net>
 
 	OptionGroup: Fix build error, remove memory leak.
diff --git a/glib/glibmm/arrayhandle.h b/glib/glibmm/arrayhandle.h
index c66c871..1d16a20 100644
--- a/glib/glibmm/arrayhandle.h
+++ b/glib/glibmm/arrayhandle.h
@@ -65,6 +65,21 @@ typename Tr::CType* create_array(For pbegin, size_t size, Tr)
   return array;
 }
 
+template <class For>
+gboolean* create_bool_array(For 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;
+}
 
 /* Convert from any container that supports forward
  * iterators and has a size() method.
@@ -83,6 +98,20 @@ struct ArraySourceTraits
   static const Glib::OwnershipType initial_ownership = Glib::OWNERSHIP_SHALLOW;
 };
 
+// source traits for bools.
+template <class Cont>
+struct BoolArraySourceTraits
+{
+  typedef gboolean CType;
+
+  static size_t get_size(const Cont& cont)
+    { return cont.size(); }
+
+  static const CType* get_data(const Cont& cont, size_t size)
+    { return Glib::Container_Helpers::create_bool_array(cont.begin(), size); }
+
+  static const Glib::OwnershipType initial_ownership = Glib::OWNERSHIP_SHALLOW;
+};
 /* Convert from a 0-terminated array.  The Cont argument must be a pointer
  * to the first element.  Note that only arrays of the C type are supported.
  */
@@ -239,6 +268,61 @@ private:
   ArrayHandle<T, Tr>& operator=(const ArrayHandle<T,Tr>&);
 };
 
+template<>
+class ArrayHandle<bool, Container_Helpers::TypeTraits<bool> >
+{
+public:
+  typedef ArrayHandle<bool, Container_Helpers::TypeTraits<bool> > Me;
+  typedef Container_Helpers::TypeTraits<bool>      Tr;
+
+  typedef typename Tr::CppType  CppType;
+  typedef typename Tr::CType    CType;
+
+  typedef CppType               value_type;
+  typedef size_t                size_type;
+  typedef ptrdiff_t             difference_type;
+
+  typedef Glib::Container_Helpers::ArrayHandleIterator<Tr>   const_iterator;
+  typedef Glib::Container_Helpers::ArrayHandleIterator<Tr>   iterator;
+
+  template <class Cont> inline
+    ArrayHandle(const Cont& container);
+
+  // Take over ownership of an array created by GTK+ functions.
+  inline ArrayHandle(const CType* array, size_t array_size, Glib::OwnershipType ownership);
+  inline ArrayHandle(const CType* array, Glib::OwnershipType ownership);
+
+  // Copying clears the ownership flag of the source handle.
+  inline ArrayHandle(const Me& other);
+
+  ~ArrayHandle();
+
+  inline const_iterator begin() const;
+  inline const_iterator end()   const;
+
+  template <class U> inline operator std::vector<U>() const;
+  template <class U> inline operator std::deque<U>()  const;
+  template <class U> inline operator std::list<U>()   const;
+
+  template <class Cont> inline
+    void assign_to(Cont& container) const;
+
+  template <class Out> inline
+    void copy(Out pdest) const;
+
+  inline const CType* data()  const;
+  inline size_t       size()  const;
+  inline bool         empty() const;
+
+private:
+  size_t                      size_;
+  const CType*                parray_;
+  mutable Glib::OwnershipType ownership_;
+
+  // No copy assignment.
+  Me& operator=(const Me&);
+};
+
 //TODO: Remove this when we can break glibmm API.
 /** 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<Glib::ustring> or std::vector<Glib::ustring>.
@@ -522,6 +606,136 @@ bool ArrayHandle<T,Tr>::empty() const
   return (size_ == 0);
 }
 
+
+/**** Glib::ArrayHandle<bool> **********************************************/
+
+template <class Cont>
+inline
+ArrayHandle<bool,Container_Helpers::TypeTraits<bool> >::ArrayHandle(const Cont& container)
+:
+  size_      (Glib::Container_Helpers::BoolArraySourceTraits<Cont>::get_size(container)),
+  parray_    (Glib::Container_Helpers::BoolArraySourceTraits<Cont>::get_data(container, size_)),
+  ownership_ (Glib::Container_Helpers::BoolArraySourceTraits<Cont>::initial_ownership)
+{}
+
+inline
+ArrayHandle<bool,Container_Helpers::TypeTraits<bool> >::ArrayHandle(const gboolean* array, size_t array_size,
+                                                                    Glib::OwnershipType ownership)
+:
+  size_      (array_size),
+  parray_    (array),
+  ownership_ (ownership)
+{}
+
+inline
+ArrayHandle<bool,Container_Helpers::TypeTraits<bool> >::ArrayHandle(const gboolean* array,
+                                                                    Glib::OwnershipType ownership)
+:
+  size_      ((array) ? Glib::Container_Helpers::compute_array_size(array) : 0),
+  parray_    (array),
+  ownership_ (ownership)
+{}
+
+inline
+ArrayHandle<bool,Container_Helpers::TypeTraits<bool> >::ArrayHandle(const ArrayHandle<bool,Container_Helpers::TypeTraits<bool> >& other)
+:
+  size_      (other.size_),
+  parray_    (other.parray_),
+  ownership_ (other.ownership_)
+{
+  other.ownership_ = Glib::OWNERSHIP_NONE;
+}
+
+inline
+ArrayHandle<bool,Container_Helpers::TypeTraits<bool> >::const_iterator ArrayHandle<bool,Container_Helpers::TypeTraits<bool> >::begin() const
+{
+  return Glib::Container_Helpers::ArrayHandleIterator<Tr>(parray_);
+}
+
+inline
+ArrayHandle<bool,Container_Helpers::TypeTraits<bool> >::const_iterator ArrayHandle<bool,Container_Helpers::TypeTraits<bool> >::end() const
+{
+  return Glib::Container_Helpers::ArrayHandleIterator<Tr>(parray_ + size_);
+}
+
+template <class U>
+inline
+ArrayHandle<bool,Container_Helpers::TypeTraits<bool> >::operator std::vector<U>() const
+{
+#ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
+  return std::vector<U>(this->begin(), this->end());
+#else
+  std::vector<U> temp;
+  temp.reserve(this->size());
+  Glib::Container_Helpers::fill_container(temp, this->begin(), this->end());
+  return temp;
+#endif
+}
+
+template <class U>
+inline
+ArrayHandle<bool,Container_Helpers::TypeTraits<bool> >::operator std::deque<U>() const
+{
+#ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
+  return std::deque<U>(this->begin(), this->end());
+#else
+  std::deque<U> temp;
+  Glib::Container_Helpers::fill_container(temp, this->begin(), this->end());
+  return temp;
+#endif
+}
+
+template <class U>
+inline
+ArrayHandle<bool,Container_Helpers::TypeTraits<bool> >::operator std::list<U>() const
+{
+#ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
+  return std::list<U>(this->begin(), this->end());
+#else
+  std::list<U> temp;
+  Glib::Container_Helpers::fill_container(temp, this->begin(), this->end());
+  return temp;
+#endif
+}
+
+template <class Cont>
+inline
+void ArrayHandle<bool,Container_Helpers::TypeTraits<bool> >::assign_to(Cont& container) const
+{
+#ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
+  container.assign(this->begin(), this->end());
+#else
+  Cont temp;
+  Glib::Container_Helpers::fill_container(temp, this->begin(), this->end());
+  container.swap(temp);
+#endif
+}
+
+template <class Out>
+inline
+void ArrayHandle<bool,Container_Helpers::TypeTraits<bool> >::copy(Out pdest) const
+{
+  std::copy(this->begin(), this->end(), pdest);
+}
+
+inline
+const gboolean* ArrayHandle<bool,Container_Helpers::TypeTraits<bool> >::data() const
+{
+  return parray_;
+}
+
+inline
+size_t ArrayHandle<bool,Container_Helpers::TypeTraits<bool> >::size() const
+{
+  return size_;
+}
+
+inline
+bool ArrayHandle<bool,Container_Helpers::TypeTraits<bool> >::empty() const
+{
+  return (size_ == 0);
+}
+
 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
 
 } // namespace Glib
diff --git a/glib/glibmm/filelist.am b/glib/glibmm/filelist.am
index 8e58b7b..80b242e 100644
--- a/glib/glibmm/filelist.am
+++ b/glib/glibmm/filelist.am
@@ -5,6 +5,7 @@ glibmm_files_built_h  = $(glibmm_files_hg:.hg=.h) $(glibmm_files_h_m4:.m4=)
 glibmm_files_built_ph = $(patsubst %.hg,private/%_p.h,$(glibmm_files_hg))
 
 glibmm_files_extra_cc =			\
+	arrayhandle.cc			\
 	class.cc			\
 	containers.cc			\
 	debug.cc			\
diff --git a/tests/Makefile.am b/tests/Makefile.am
index c31d9cb..d20d4a1 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -17,20 +17,21 @@
 
 AUTOMAKE_OPTIONS = subdir-objects
 
-check_PROGRAMS =			\
-	giomm_ioerror/test		\
-	giomm_simple/test		\
-	giomm_asyncresult_sourceobject/test \
-	glibmm_btree/test		\
-	glibmm_date/test		\
-	glibmm_nodetree/test		\
-	glibmm_ustring_compose/test	\
-	glibmm_ustring_format/test	\
-	glibmm_value/test		\
-	glibmm_valuearray/test		\
-	glibmm_variant/test		\
-	glibmm_vector/test		\
-	glibmm_bool_vector/test
+check_PROGRAMS =				\
+	giomm_ioerror/test			\
+	giomm_simple/test			\
+	giomm_asyncresult_sourceobject/test	\
+	glibmm_btree/test			\
+	glibmm_date/test			\
+	glibmm_nodetree/test			\
+	glibmm_ustring_compose/test		\
+	glibmm_ustring_format/test		\
+	glibmm_value/test			\
+	glibmm_valuearray/test			\
+	glibmm_variant/test			\
+	glibmm_vector/test			\
+	glibmm_bool_vector/test			\
+	glibmm_bool_arrayhandle/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)
@@ -54,14 +55,15 @@ giomm_simple_test_LDADD    = $(giomm_ldadd)
 giomm_asyncresult_sourceobject_test_SOURCES  = giomm_asyncresult_sourceobject/main.cc
 giomm_asyncresult_sourceobject_test_LDADD    = $(giomm_ldadd)
 
-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_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
+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_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
+glibmm_bool_arrayhandle_test_SOURCES = glibmm_bool_arrayhandle/main.cc



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