summaryrefslogtreecommitdiff
path: root/glib
diff options
context:
space:
mode:
authorKrzesimir Nowak <qdlacz@gmail.com>2011-02-02 21:57:49 +0100
committerMurray Cumming <murrayc@murrayc.com>2011-02-21 09:33:28 +0100
commit202871d761e3b14dda986eb1d303bd514fd28cf3 (patch)
tree8cf7b2a30cfbd3d11bcf01ecff8fd23dbaceab06 /glib
parent2622421a587bcb332e41ab5aa51e531a1f8ab6ad (diff)
downloadglibmm-202871d761e3b14dda986eb1d303bd514fd28cf3.tar.gz
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.
Diffstat (limited to 'glib')
-rw-r--r--glib/glibmm/arrayhandle.h214
-rw-r--r--glib/glibmm/filelist.am1
2 files changed, 215 insertions, 0 deletions
diff --git a/glib/glibmm/arrayhandle.h b/glib/glibmm/arrayhandle.h
index c66c8716..1d16a205 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 8e58b7b7..80b242e8 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 \