diff options
author | Vitor Sousa <vitorsousasilva@gmail.com> | 2015-12-01 17:25:11 -0200 |
---|---|---|
committer | Vitor Sousa <vitorsousasilva@gmail.com> | 2016-03-18 17:47:09 -0300 |
commit | fd0cf8b76459da70e2ef0116b19a322913cc92bb (patch) | |
tree | 81fb62dfec860e64fe17c8f50e8b5d02d549a8f1 /src | |
parent | a85348b70bdae9672ed2017d9a0c16fa315edcfa (diff) | |
download | efl-fd0cf8b76459da70e2ef0116b19a322913cc92bb.tar.gz |
eina_cxx: Add specialized eina::iterator for Eo* wrappers
Add specialization of eina::iterator for Eo* C++ wrappers.
Specialize ibegin/iend methods in eina::list and eina::array of
Eo* wrappers to use the new eina::iterator.
Add unit test.
Diffstat (limited to 'src')
-rw-r--r-- | src/bindings/eina_cxx/eina_array.hh | 26 | ||||
-rw-r--r-- | src/bindings/eina_cxx/eina_iterator.hh | 86 | ||||
-rw-r--r-- | src/bindings/eina_cxx/eina_list.hh | 24 | ||||
-rw-r--r-- | src/tests/eina_cxx/eina_cxx_test_iterator.cc | 31 |
4 files changed, 165 insertions, 2 deletions
diff --git a/src/bindings/eina_cxx/eina_array.hh b/src/bindings/eina_cxx/eina_array.hh index d352de5ab7..7c8e7985d0 100644 --- a/src/bindings/eina_cxx/eina_array.hh +++ b/src/bindings/eina_cxx/eina_array.hh @@ -415,6 +415,32 @@ public: { return rend(); } + eina::iterator<value_type> ibegin() + { + return _eo_array_access_traits::ibegin<value_type>(this->_impl._array); + } + eina::iterator<value_type> iend() + { + return _eo_array_access_traits::iend<value_type>(this->_impl._array); + } + + eina::iterator<value_type const> ibegin() const + { + return _eo_array_access_traits::ibegin<value_type>(this->_impl._array); + } + + eina::iterator<value_type const> iend() const + { + return _eo_array_access_traits::iend<value_type>(this->_impl._array); + } + eina::iterator<value_type const> cibegin() const + { + return _eo_array_access_traits::cibegin<value_type>(this->_impl._array); + } + eina::iterator<value_type const> ciend() const + { + return _eo_array_access_traits::ciend<value_type>(this->_impl._array); + } using _base_type::swap; using _base_type::max_size; diff --git a/src/bindings/eina_cxx/eina_iterator.hh b/src/bindings/eina_cxx/eina_iterator.hh index 9518cf43dd..81eb2ee508 100644 --- a/src/bindings/eina_cxx/eina_iterator.hh +++ b/src/bindings/eina_cxx/eina_iterator.hh @@ -3,6 +3,8 @@ #include <Eina.h> +#include <eina_eo_concrete_fwd.hh> + #include <cstdlib> #include <iterator> @@ -128,8 +130,9 @@ protected: * automatically take care of allocating a deallocating resources using * the RAII programming idiom. */ -template <typename T> -struct iterator : _common_iterator_base<T const> +template <typename T, typename Enable = void> +struct iterator + : _common_iterator_base<typename std::enable_if<!std::is_convertible<T*, ::efl::eo::concrete const* const>::value, T const>::type> { private: typedef _common_iterator_base<T const> base_type; /**< Type for the base class. */ @@ -204,6 +207,85 @@ public: } }; +template <typename T> +struct iterator<T, typename std::enable_if<std::is_convertible<T*, ::efl::eo::concrete const* const>::value, void>::type> + : _common_iterator_base<Eo const> +{ +private: + typedef _common_iterator_base<Eo const> base_type; /**< Type for the base class. */ + typename base_type::pointer _value; /**< @internal */ + typedef iterator<T> self_type; /**< Type for the specialized iterator itself. */ +public: + typedef typename base_type::value_type value_type; /**< Type for elements returned by the iterator. */ + typedef typename base_type::pointer pointer; /**< Type for a pointer to an element. */ + typedef typename base_type::reference reference; /**< Type for a reference to an element. */ + typedef typename base_type::difference_type difference_type; /**< Type to represent the distance between two iterators. */ + typedef typename base_type::iterator_category iterator_category; /**< Defines the iterator category as the same of the base class. */ + + /** + * @brief Creates a iterator wrapping the given native @c Eina_Iterator handle. + * + * This constructor creates an iterator that wraps the given native + * @c Eina_Iterator handle, providing an OOP interface to it. + */ + explicit iterator(Eina_Iterator* iterator_ = 0) + : base_type(iterator_) + { + if(this->_iterator) + ++*this; + } + + + /** + * @brief Move the iterator to the next position. + * @return The iterator itself. + * + * This operator increments the iterator, making it point to the + * position right after the current one. + * At the end, it returns a reference to itself. + */ + self_type& operator++() + { + void* data; + Eina_Bool r = ::eina_iterator_next(this->_iterator, &data); + if(!r) + this->_iterator = 0; + _value = static_cast<pointer>(data); + return *this; + } + + /** + * @brief Move the iterator to the next position. + * @return The iterator itself. + * + * Works exactly like @ref operator++(). + */ + self_type& operator++(int) + { + return ++**this; + } + + /** + * @brief Get a reference to the element currently pointed by the iterator. + * @return Reference to the current element. + */ + T const& operator*() const + { + // relies on layout compatibility between eo::concrete and Eo* + return *reinterpret_cast<T const*>(&_value); + } + + /** + * @brief Return a pointer to the current element, which member will be accessed. + * @return Pointer to the element currently pointed by the iterator. + */ + T const* operator->() const + { + // relies on layout compatibility between eo::concrete and Eo* + return reinterpret_cast<T const*>(&_value); + } +}; + /** * @} */ diff --git a/src/bindings/eina_cxx/eina_list.hh b/src/bindings/eina_cxx/eina_list.hh index c1a02b50dc..ae140b2069 100644 --- a/src/bindings/eina_cxx/eina_list.hh +++ b/src/bindings/eina_cxx/eina_list.hh @@ -415,6 +415,30 @@ public: { return rend(); } + eina::iterator<value_type> ibegin() + { + return _eo_list_access_traits::ibegin<value_type>(this->_impl._list); + } + eina::iterator<value_type> iend() + { + return _eo_list_access_traits::iend<value_type>(this->_impl._list); + } + eina::iterator<value_type const> ibegin() const + { + return _eo_list_access_traits::ibegin<value_type>(this->_impl._list); + } + eina::iterator<value_type const> iend() const + { + return _eo_list_access_traits::iend<value_type>(this->_impl._list); + } + eina::iterator<value_type const> cibegin() const + { + return _eo_list_access_traits::cibegin<value_type>(this->_impl._list); + } + eina::iterator<value_type const> ciend() const + { + return _eo_list_access_traits::ciend<value_type>(this->_impl._list); + } using _base_type::swap; using _base_type::max_size; using _base_type::native_handle; diff --git a/src/tests/eina_cxx/eina_cxx_test_iterator.cc b/src/tests/eina_cxx/eina_cxx_test_iterator.cc index 8f7136a9fc..3fe4c9d2d1 100644 --- a/src/tests/eina_cxx/eina_cxx_test_iterator.cc +++ b/src/tests/eina_cxx/eina_cxx_test_iterator.cc @@ -3,8 +3,12 @@ #endif #include <Eina.hh> +#include <Eo.hh> + +#include <algorithm> #include "eina_cxx_suite.h" +#include "simple.eo.hh" START_TEST(eina_cxx_iterator_equal) { @@ -28,8 +32,35 @@ START_TEST(eina_cxx_iterator_equal) } END_TEST +START_TEST(eina_cxx_eo_iterator_equal) +{ + efl::eina::eina_init eina_init; + efl::eo::eo_init eo_init; + + efl::eina::list<simple> list; + + simple const w1; + simple const w2; + simple const w3; + simple const w4; + + list.push_back(w1); + list.push_back(w2); + list.push_back(w3); + list.push_back(w4); + + efl::eina::iterator<simple> iterator = list.ibegin() + , last_iterator = list.iend(); + + simple const result[] = {w1, w2, w3, w4}; + + ck_assert(std::equal(iterator, last_iterator, result)); +} +END_TEST + void eina_test_iterator(TCase *tc) { tcase_add_test(tc, eina_cxx_iterator_equal); + tcase_add_test(tc, eina_cxx_eo_iterator_equal); } |