forked from enlightenment/efl
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.
This commit is contained in:
parent
a85348b70b
commit
fd0cf8b764
|
@ -415,6 +415,32 @@ public:
|
||||||
{
|
{
|
||||||
return rend();
|
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::swap;
|
||||||
using _base_type::max_size;
|
using _base_type::max_size;
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
#include <Eina.h>
|
#include <Eina.h>
|
||||||
|
|
||||||
|
#include <eina_eo_concrete_fwd.hh>
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
|
||||||
|
@ -128,8 +130,9 @@ protected:
|
||||||
* automatically take care of allocating a deallocating resources using
|
* automatically take care of allocating a deallocating resources using
|
||||||
* the RAII programming idiom.
|
* the RAII programming idiom.
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T, typename Enable = void>
|
||||||
struct iterator : _common_iterator_base<T const>
|
struct iterator
|
||||||
|
: _common_iterator_base<typename std::enable_if<!std::is_convertible<T*, ::efl::eo::concrete const* const>::value, T const>::type>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
typedef _common_iterator_base<T const> base_type; /**< Type for the base class. */
|
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);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -415,6 +415,30 @@ public:
|
||||||
{
|
{
|
||||||
return rend();
|
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::swap;
|
||||||
using _base_type::max_size;
|
using _base_type::max_size;
|
||||||
using _base_type::native_handle;
|
using _base_type::native_handle;
|
||||||
|
|
|
@ -3,8 +3,12 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <Eina.hh>
|
#include <Eina.hh>
|
||||||
|
#include <Eo.hh>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include "eina_cxx_suite.h"
|
#include "eina_cxx_suite.h"
|
||||||
|
#include "simple.eo.hh"
|
||||||
|
|
||||||
START_TEST(eina_cxx_iterator_equal)
|
START_TEST(eina_cxx_iterator_equal)
|
||||||
{
|
{
|
||||||
|
@ -28,8 +32,35 @@ START_TEST(eina_cxx_iterator_equal)
|
||||||
}
|
}
|
||||||
END_TEST
|
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
|
void
|
||||||
eina_test_iterator(TCase *tc)
|
eina_test_iterator(TCase *tc)
|
||||||
{
|
{
|
||||||
tcase_add_test(tc, eina_cxx_iterator_equal);
|
tcase_add_test(tc, eina_cxx_iterator_equal);
|
||||||
|
tcase_add_test(tc, eina_cxx_eo_iterator_equal);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue