diff options
author | Krzesimir Nowak <qdlacz@gmail.com> | 2011-02-02 21:57:49 +0100 |
---|---|---|
committer | Murray Cumming <murrayc@murrayc.com> | 2011-02-21 09:33:28 +0100 |
commit | 202871d761e3b14dda986eb1d303bd514fd28cf3 (patch) | |
tree | 8cf7b2a30cfbd3d11bcf01ecff8fd23dbaceab06 /glib | |
parent | 2622421a587bcb332e41ab5aa51e531a1f8ab6ad (diff) | |
download | glibmm-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.h | 214 | ||||
-rw-r--r-- | glib/glibmm/filelist.am | 1 |
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 \ |