[glibmm] Added bool specialization for Glib::ArrayHandle.
- From: Murray Cumming <murrayc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glibmm] Added bool specialization for Glib::ArrayHandle.
- Date: Mon, 21 Feb 2011 08:37:18 +0000 (UTC)
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]