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 ibegin() + { + return _eo_array_access_traits::ibegin(this->_impl._array); + } + eina::iterator iend() + { + return _eo_array_access_traits::iend(this->_impl._array); + } + + eina::iterator ibegin() const + { + return _eo_array_access_traits::ibegin(this->_impl._array); + } + + eina::iterator iend() const + { + return _eo_array_access_traits::iend(this->_impl._array); + } + eina::iterator cibegin() const + { + return _eo_array_access_traits::cibegin(this->_impl._array); + } + eina::iterator ciend() const + { + return _eo_array_access_traits::ciend(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 +#include + #include #include @@ -128,8 +130,9 @@ protected: * automatically take care of allocating a deallocating resources using * the RAII programming idiom. */ -template -struct iterator : _common_iterator_base +template +struct iterator + : _common_iterator_base::value, T const>::type> { private: typedef _common_iterator_base base_type; /**< Type for the base class. */ @@ -204,6 +207,85 @@ public: } }; +template +struct iterator::value, void>::type> + : _common_iterator_base +{ +private: + typedef _common_iterator_base base_type; /**< Type for the base class. */ + typename base_type::pointer _value; /**< @internal */ + typedef iterator 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(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(&_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(&_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 ibegin() + { + return _eo_list_access_traits::ibegin(this->_impl._list); + } + eina::iterator iend() + { + return _eo_list_access_traits::iend(this->_impl._list); + } + eina::iterator ibegin() const + { + return _eo_list_access_traits::ibegin(this->_impl._list); + } + eina::iterator iend() const + { + return _eo_list_access_traits::iend(this->_impl._list); + } + eina::iterator cibegin() const + { + return _eo_list_access_traits::cibegin(this->_impl._list); + } + eina::iterator ciend() const + { + return _eo_list_access_traits::ciend(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 +#include + +#include #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 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 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); }