summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVitor Sousa <vitorsousasilva@gmail.com>2015-12-01 17:25:11 -0200
committerVitor Sousa <vitorsousasilva@gmail.com>2016-03-18 17:47:09 -0300
commitfd0cf8b76459da70e2ef0116b19a322913cc92bb (patch)
tree81fb62dfec860e64fe17c8f50e8b5d02d549a8f1 /src
parenta85348b70bdae9672ed2017d9a0c16fa315edcfa (diff)
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.hh26
-rw-r--r--src/bindings/eina_cxx/eina_iterator.hh86
-rw-r--r--src/bindings/eina_cxx/eina_list.hh24
-rw-r--r--src/tests/eina_cxx/eina_cxx_test_iterator.cc31
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:
415 { 415 {
416 return rend(); 416 return rend();
417 } 417 }
418 eina::iterator<value_type> ibegin()
419 {
420 return _eo_array_access_traits::ibegin<value_type>(this->_impl._array);
421 }
422 eina::iterator<value_type> iend()
423 {
424 return _eo_array_access_traits::iend<value_type>(this->_impl._array);
425 }
426
427 eina::iterator<value_type const> ibegin() const
428 {
429 return _eo_array_access_traits::ibegin<value_type>(this->_impl._array);
430 }
431
432 eina::iterator<value_type const> iend() const
433 {
434 return _eo_array_access_traits::iend<value_type>(this->_impl._array);
435 }
436 eina::iterator<value_type const> cibegin() const
437 {
438 return _eo_array_access_traits::cibegin<value_type>(this->_impl._array);
439 }
440 eina::iterator<value_type const> ciend() const
441 {
442 return _eo_array_access_traits::ciend<value_type>(this->_impl._array);
443 }
418 444
419 using _base_type::swap; 445 using _base_type::swap;
420 using _base_type::max_size; 446 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 @@
3 3
4#include <Eina.h> 4#include <Eina.h>
5 5
6#include <eina_eo_concrete_fwd.hh>
7
6#include <cstdlib> 8#include <cstdlib>
7#include <iterator> 9#include <iterator>
8 10
@@ -128,8 +130,9 @@ protected:
128 * automatically take care of allocating a deallocating resources using 130 * automatically take care of allocating a deallocating resources using
129 * the RAII programming idiom. 131 * the RAII programming idiom.
130 */ 132 */
131template <typename T> 133template <typename T, typename Enable = void>
132struct iterator : _common_iterator_base<T const> 134struct iterator
135 : _common_iterator_base<typename std::enable_if<!std::is_convertible<T*, ::efl::eo::concrete const* const>::value, T const>::type>
133{ 136{
134private: 137private:
135 typedef _common_iterator_base<T const> base_type; /**< Type for the base class. */ 138 typedef _common_iterator_base<T const> base_type; /**< Type for the base class. */
@@ -204,6 +207,85 @@ public:
204 } 207 }
205}; 208};
206 209
210template <typename T>
211struct iterator<T, typename std::enable_if<std::is_convertible<T*, ::efl::eo::concrete const* const>::value, void>::type>
212 : _common_iterator_base<Eo const>
213{
214private:
215 typedef _common_iterator_base<Eo const> base_type; /**< Type for the base class. */
216 typename base_type::pointer _value; /**< @internal */
217 typedef iterator<T> self_type; /**< Type for the specialized iterator itself. */
218public:
219 typedef typename base_type::value_type value_type; /**< Type for elements returned by the iterator. */
220 typedef typename base_type::pointer pointer; /**< Type for a pointer to an element. */
221 typedef typename base_type::reference reference; /**< Type for a reference to an element. */
222 typedef typename base_type::difference_type difference_type; /**< Type to represent the distance between two iterators. */
223 typedef typename base_type::iterator_category iterator_category; /**< Defines the iterator category as the same of the base class. */
224
225 /**
226 * @brief Creates a iterator wrapping the given native @c Eina_Iterator handle.
227 *
228 * This constructor creates an iterator that wraps the given native
229 * @c Eina_Iterator handle, providing an OOP interface to it.
230 */
231 explicit iterator(Eina_Iterator* iterator_ = 0)
232 : base_type(iterator_)
233 {
234 if(this->_iterator)
235 ++*this;
236 }
237
238
239 /**
240 * @brief Move the iterator to the next position.
241 * @return The iterator itself.
242 *
243 * This operator increments the iterator, making it point to the
244 * position right after the current one.
245 * At the end, it returns a reference to itself.
246 */
247 self_type& operator++()
248 {
249 void* data;
250 Eina_Bool r = ::eina_iterator_next(this->_iterator, &data);
251 if(!r)
252 this->_iterator = 0;
253 _value = static_cast<pointer>(data);
254 return *this;
255 }
256
257 /**
258 * @brief Move the iterator to the next position.
259 * @return The iterator itself.
260 *
261 * Works exactly like @ref operator++().
262 */
263 self_type& operator++(int)
264 {
265 return ++**this;
266 }
267
268 /**
269 * @brief Get a reference to the element currently pointed by the iterator.
270 * @return Reference to the current element.
271 */
272 T const& operator*() const
273 {
274 // relies on layout compatibility between eo::concrete and Eo*
275 return *reinterpret_cast<T const*>(&_value);
276 }
277
278 /**
279 * @brief Return a pointer to the current element, which member will be accessed.
280 * @return Pointer to the element currently pointed by the iterator.
281 */
282 T const* operator->() const
283 {
284 // relies on layout compatibility between eo::concrete and Eo*
285 return reinterpret_cast<T const*>(&_value);
286 }
287};
288
207/** 289/**
208 * @} 290 * @}
209 */ 291 */
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:
415 { 415 {
416 return rend(); 416 return rend();
417 } 417 }
418 eina::iterator<value_type> ibegin()
419 {
420 return _eo_list_access_traits::ibegin<value_type>(this->_impl._list);
421 }
422 eina::iterator<value_type> iend()
423 {
424 return _eo_list_access_traits::iend<value_type>(this->_impl._list);
425 }
426 eina::iterator<value_type const> ibegin() const
427 {
428 return _eo_list_access_traits::ibegin<value_type>(this->_impl._list);
429 }
430 eina::iterator<value_type const> iend() const
431 {
432 return _eo_list_access_traits::iend<value_type>(this->_impl._list);
433 }
434 eina::iterator<value_type const> cibegin() const
435 {
436 return _eo_list_access_traits::cibegin<value_type>(this->_impl._list);
437 }
438 eina::iterator<value_type const> ciend() const
439 {
440 return _eo_list_access_traits::ciend<value_type>(this->_impl._list);
441 }
418 using _base_type::swap; 442 using _base_type::swap;
419 using _base_type::max_size; 443 using _base_type::max_size;
420 using _base_type::native_handle; 444 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 @@
3#endif 3#endif
4 4
5#include <Eina.hh> 5#include <Eina.hh>
6#include <Eo.hh>
7
8#include <algorithm>
6 9
7#include "eina_cxx_suite.h" 10#include "eina_cxx_suite.h"
11#include "simple.eo.hh"
8 12
9START_TEST(eina_cxx_iterator_equal) 13START_TEST(eina_cxx_iterator_equal)
10{ 14{
@@ -28,8 +32,35 @@ START_TEST(eina_cxx_iterator_equal)
28} 32}
29END_TEST 33END_TEST
30 34
35START_TEST(eina_cxx_eo_iterator_equal)
36{
37 efl::eina::eina_init eina_init;
38 efl::eo::eo_init eo_init;
39
40 efl::eina::list<simple> list;
41
42 simple const w1;
43 simple const w2;
44 simple const w3;
45 simple const w4;
46
47 list.push_back(w1);
48 list.push_back(w2);
49 list.push_back(w3);
50 list.push_back(w4);
51
52 efl::eina::iterator<simple> iterator = list.ibegin()
53 , last_iterator = list.iend();
54
55 simple const result[] = {w1, w2, w3, w4};
56
57 ck_assert(std::equal(iterator, last_iterator, result));
58}
59END_TEST
60
31void 61void
32eina_test_iterator(TCase *tc) 62eina_test_iterator(TCase *tc)
33{ 63{
34 tcase_add_test(tc, eina_cxx_iterator_equal); 64 tcase_add_test(tc, eina_cxx_iterator_equal);
65 tcase_add_test(tc, eina_cxx_eo_iterator_equal);
35} 66}