forked from enlightenment/efl
eina_cxx: Fix eina::accessor for C++ Eo wrappers
Created a specialization of the eina::accessor for C++ Eo wrappers. Created an override of the "accessor" methods in the eina::list specialization for Eo wrappers (in eina_list.hh). It is necessary to create accessors with the correct type. Created specializations of std::is_base_of to avoid compilation errors related with _Eo_Opaque type. Added new test cases in "eina_cxx_test_accessor.cc" to test the accessor specialization. Added efl::eina::eina_init to the existing test cases to correctly do the on demand initialization required by the tests. @fix
This commit is contained in:
parent
7f82494459
commit
ee81566ac8
|
@ -4,6 +4,7 @@
|
|||
#include <Eina.h>
|
||||
#include <eina_error.hh>
|
||||
#include <eina_throw.hh>
|
||||
#include <eina_eo_base_fwd.hh>
|
||||
|
||||
#include <memory>
|
||||
#include <iterator>
|
||||
|
@ -37,7 +38,7 @@ namespace efl { namespace eina {
|
|||
* Wraps an native Eina_Accessor and provide random access to data structures.
|
||||
*/
|
||||
template <typename T>
|
||||
struct accessor
|
||||
struct accessor_common_base
|
||||
{
|
||||
typedef unsigned int key_type; /**< Type for accessor key. */
|
||||
typedef T mapped_type; /**< Type for accessor mapped elements. */
|
||||
|
@ -47,7 +48,7 @@ struct accessor
|
|||
/**
|
||||
* @brief Default constructor. Creates an empty accessor.
|
||||
*/
|
||||
accessor() : _impl(0) {}
|
||||
accessor_common_base() : _impl(0) {}
|
||||
|
||||
/**
|
||||
* @brief Create an accessor object that wraps the given Eina accessor.
|
||||
|
@ -60,7 +61,7 @@ struct accessor
|
|||
* gains ownership of the given handle, deallocating it at destruction
|
||||
* time.
|
||||
*/
|
||||
explicit accessor(Eina_Accessor* impl)
|
||||
explicit accessor_common_base(Eina_Accessor* impl)
|
||||
: _impl(impl)
|
||||
{
|
||||
assert(_impl != 0);
|
||||
|
@ -74,7 +75,7 @@ struct accessor
|
|||
* accessor object, so that the newly created object can be used
|
||||
* freely.
|
||||
*/
|
||||
accessor(accessor<T> const& other)
|
||||
accessor_common_base(accessor_common_base<T> const& other)
|
||||
: _impl(eina_accessor_clone(other._impl))
|
||||
{}
|
||||
|
||||
|
@ -86,7 +87,7 @@ struct accessor
|
|||
* This operator replaces the current native Eina accessor by a copy
|
||||
* of the native accessor inside the given object.
|
||||
*/
|
||||
accessor<T>& operator=(accessor<T> const& other)
|
||||
accessor_common_base<T>& operator=(accessor_common_base<T> const& other)
|
||||
{
|
||||
eina_accessor_free(_impl);
|
||||
_impl = eina_accessor_clone(other._impl);
|
||||
|
@ -98,33 +99,11 @@ struct accessor
|
|||
/**
|
||||
* @brief Destructor. Free the internal @c Eina_Acessor.
|
||||
*/
|
||||
~accessor()
|
||||
~accessor_common_base()
|
||||
{
|
||||
eina_accessor_free(_impl);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieve the data of the accessor at a given position.
|
||||
* @param i The position of the element.
|
||||
* @return Constant reference to the retrieved data.
|
||||
* @throw <tt>eina::system_error</tt> if the given element could not be retrieved.
|
||||
*
|
||||
* This operator retrieves a constant reference to the element at the
|
||||
* given position. If the element could not be retrieved an
|
||||
* <tt>eina::system_error</tt> is thrown.
|
||||
*/
|
||||
mapped_type& operator[](size_type i) const
|
||||
{
|
||||
assert(_impl != 0);
|
||||
void* p;
|
||||
if(!eina_accessor_data_get(_impl, i, &p))
|
||||
{
|
||||
eina::error_code ec = efl::eina::get_error_code();
|
||||
EFL_CXX_THROW(eina::system_error(ec, "EFL Eina Error"));
|
||||
}
|
||||
return *static_cast<mapped_type*>(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the handle for the wrapped @c Eina_Accessor.
|
||||
* @return Internal handle for the native Eina accessor.
|
||||
|
@ -144,7 +123,7 @@ struct accessor
|
|||
* This member function swaps the internal @c Eina_Acessor with the
|
||||
* given accessor object.
|
||||
*/
|
||||
void swap(accessor<T>& other)
|
||||
void swap(accessor_common_base<T>& other)
|
||||
{
|
||||
std::swap(_impl, other._impl);
|
||||
}
|
||||
|
@ -158,9 +137,8 @@ struct accessor
|
|||
*/
|
||||
explicit operator bool() const
|
||||
{
|
||||
return native_handle() ? &accessor<T>::native_handle : 0 ;
|
||||
return native_handle() ? &accessor_common_base<T>::native_handle : 0 ;
|
||||
}
|
||||
private:
|
||||
|
||||
/**
|
||||
* @internal
|
||||
|
@ -169,6 +147,234 @@ private:
|
|||
Eina_Accessor* _impl;
|
||||
};
|
||||
|
||||
template <typename T, typename Enable = T>
|
||||
struct accessor;
|
||||
|
||||
template <typename T>
|
||||
struct accessor<T, typename std::enable_if< ! std::is_base_of<efl::eo::base, T>::value, T>::type>
|
||||
: accessor_common_base<T>
|
||||
{
|
||||
typedef accessor_common_base<T> _base_type;
|
||||
typedef accessor<T> _self_type;
|
||||
|
||||
typedef typename _base_type::key_type key_type;
|
||||
typedef typename _base_type::mapped_type mapped_type;
|
||||
typedef typename _base_type::value_type value_type;
|
||||
typedef typename _base_type::size_type size_type;
|
||||
|
||||
/**
|
||||
* @brief Default constructor. Creates an empty accessor.
|
||||
*/
|
||||
accessor() : _base_type() {}
|
||||
|
||||
/**
|
||||
* @brief Create an accessor object that wraps the given Eina accessor.
|
||||
* @param impl Native @c Eina_Accessor to be wrapped.
|
||||
*
|
||||
* This constructor creates an accessor object that wraps the given
|
||||
* Eina_Accessor and provides access to the data pointed by it.
|
||||
*
|
||||
* @warning It is important to note that the created accessor object
|
||||
* gains ownership of the given handle, deallocating it at destruction
|
||||
* time.
|
||||
*/
|
||||
explicit accessor(Eina_Accessor* impl) : _base_type(impl) {}
|
||||
|
||||
/**
|
||||
* @brief Copy constructor. Creates a copy of the given accessor object.
|
||||
* @param other Other accessor object.
|
||||
*
|
||||
* This constructor clones the internal @c Eina_Accessor of the given
|
||||
* accessor object, so that the newly created object can be used
|
||||
* freely.
|
||||
*/
|
||||
accessor(_self_type const& other) : _base_type(other) {}
|
||||
|
||||
/**
|
||||
* @brief Assignment Operator. Replace the current content.
|
||||
* @param other Other accessor object.
|
||||
* @throw <tt>eina::system_error</tt> if the Eina accessor could not be cloned.
|
||||
*
|
||||
* This operator replaces the current native Eina accessor by a copy
|
||||
* of the native accessor inside the given object.
|
||||
*/
|
||||
_self_type& operator=(_self_type const& other)
|
||||
{
|
||||
_base_type::operator=(other);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Destructor. Free the internal @c Eina_Acessor.
|
||||
*/
|
||||
~accessor()
|
||||
{
|
||||
// Cleanup is already done in the base class.
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieve the data of the accessor at a given position.
|
||||
* @param i The position of the element.
|
||||
* @return Constant reference to the retrieved data.
|
||||
* @throw <tt>eina::system_error</tt> if the given element could not be retrieved.
|
||||
*
|
||||
* This operator retrieves a constant reference to the element at the
|
||||
* given position. If the element could not be retrieved an
|
||||
* <tt>eina::system_error</tt> is thrown.
|
||||
*/
|
||||
mapped_type& operator[](size_type i) const
|
||||
{
|
||||
assert(this->_impl != 0);
|
||||
void* p;
|
||||
if(!eina_accessor_data_get(this->_impl, i, &p))
|
||||
{
|
||||
eina::error_code ec = efl::eina::get_error_code();
|
||||
EFL_CXX_THROW(eina::system_error(ec, "EFL Eina Error"));
|
||||
}
|
||||
return *static_cast<mapped_type*>(p);
|
||||
}
|
||||
|
||||
using _base_type::native_handle;
|
||||
|
||||
/**
|
||||
* @brief Swap content between both objects.
|
||||
* @param other Other accessor object.
|
||||
*
|
||||
* This member function swaps the internal @c Eina_Acessor with the
|
||||
* given accessor object.
|
||||
*/
|
||||
void swap(_self_type& other)
|
||||
{
|
||||
_base_type::swap(other);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Cast to @c boolean based on the wrapped @c Eina_Accessor.
|
||||
* @return @c true if the wrapped handle is not @c NULL, @c false otherwise.
|
||||
*
|
||||
* Boolean typecast overload for easy validation of the accessor
|
||||
* object. Returns @c false if it does not have an internal
|
||||
* @c Eina_Accessor, i.e. if the current handle is not @c NULL.
|
||||
*/
|
||||
explicit operator bool() const
|
||||
{
|
||||
return native_handle() ? &_self_type::native_handle : 0 ;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct accessor<T, typename std::enable_if<std::is_base_of<efl::eo::base, T>::value, T>::type>
|
||||
: accessor_common_base<T>
|
||||
{
|
||||
typedef accessor_common_base<T> _base_type;
|
||||
typedef accessor<T> _self_type;
|
||||
|
||||
typedef typename _base_type::key_type key_type;
|
||||
typedef typename _base_type::mapped_type mapped_type;
|
||||
typedef typename _base_type::value_type value_type;
|
||||
typedef typename _base_type::size_type size_type;
|
||||
|
||||
/**
|
||||
* @brief Default constructor. Creates an empty accessor.
|
||||
*/
|
||||
accessor() : _base_type() {}
|
||||
|
||||
/**
|
||||
* @brief Create an accessor object that wraps the given Eina accessor.
|
||||
* @param impl Native @c Eina_Accessor to be wrapped.
|
||||
*
|
||||
* This constructor creates an accessor object that wraps the given
|
||||
* Eina_Accessor and provides access to the data pointed by it.
|
||||
*
|
||||
* @warning It is important to note that the created accessor object
|
||||
* gains ownership of the given handle, deallocating it at destruction
|
||||
* time.
|
||||
*/
|
||||
explicit accessor(Eina_Accessor* impl) : _base_type(impl) {}
|
||||
|
||||
/**
|
||||
* @brief Copy constructor. Creates a copy of the given accessor object.
|
||||
* @param other Other accessor object.
|
||||
*
|
||||
* This constructor clones the internal @c Eina_Accessor of the given
|
||||
* accessor object, so that the newly created object can be used
|
||||
* freely.
|
||||
*/
|
||||
accessor(_self_type const& other) : _base_type(other) {}
|
||||
|
||||
/**
|
||||
* @brief Assignment Operator. Replace the current content.
|
||||
* @param other Other accessor object.
|
||||
* @throw <tt>eina::system_error</tt> if the Eina accessor could not be cloned.
|
||||
*
|
||||
* This operator replaces the current native Eina accessor by a copy
|
||||
* of the native accessor inside the given object.
|
||||
*/
|
||||
_self_type& operator=(_self_type const& other)
|
||||
{
|
||||
_base_type::operator=(other);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Destructor. Free the internal @c Eina_Acessor.
|
||||
*/
|
||||
~accessor()
|
||||
{
|
||||
// Cleanup is already done in the base class.
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieve the data of the accessor at a given position.
|
||||
* @param i The position of the element.
|
||||
* @return Constant reference to the retrieved data.
|
||||
* @throw <tt>eina::system_error</tt> if the given element could not be retrieved.
|
||||
*
|
||||
* This operator retrieves a constant reference to the element at the
|
||||
* given position. If the element could not be retrieved an
|
||||
* <tt>eina::system_error</tt> is thrown.
|
||||
*/
|
||||
mapped_type operator[](size_type i) const
|
||||
{
|
||||
assert(this->_impl != 0);
|
||||
void* p;
|
||||
if(!eina_accessor_data_get(this->_impl, i, &p))
|
||||
{
|
||||
eina::error_code ec = efl::eina::get_error_code();
|
||||
EFL_CXX_THROW(eina::system_error(ec, "EFL Eina Error"));
|
||||
}
|
||||
|
||||
// TODO Do we need to ref this Eo* instance ?
|
||||
|
||||
return mapped_type(::eo_ref(static_cast<Eo*>(p)));
|
||||
}
|
||||
|
||||
using _base_type::native_handle;
|
||||
|
||||
/**
|
||||
* @brief Swap content between both objects.
|
||||
* @param other Other accessor object.
|
||||
*
|
||||
* This member function swaps the internal @c Eina_Acessor with the
|
||||
* given accessor object.
|
||||
*/
|
||||
void swap(_self_type& other)
|
||||
{
|
||||
_base_type::swap(other);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Cast to @c boolean based on the wrapped @c Eina_Accessor.
|
||||
* @return @c true if the wrapped handle is not @c NULL, @c false otherwise.
|
||||
*
|
||||
* Boolean typecast overload for easy validation of the accessor
|
||||
* object. Returns @c false if it does not have an internal
|
||||
* @c Eina_Accessor, i.e. if the current handle is not @c NULL.
|
||||
*/
|
||||
explicit operator bool() const
|
||||
{
|
||||
return native_handle() ? &_self_type::native_handle : 0 ;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Swap the contents of the two accessor objects.
|
||||
* @param lhs First accessor object.
|
||||
|
@ -191,11 +397,14 @@ void swap(accessor<U>& lhs, accessor<U>& rhs)
|
|||
* @{
|
||||
*/
|
||||
|
||||
template <typename T, class Enable = T>
|
||||
struct accessor_iterator;
|
||||
|
||||
/**
|
||||
* Random access iterator for <tt>eina::accessor</tt>.
|
||||
*/
|
||||
template <typename T>
|
||||
struct accessor_iterator
|
||||
struct accessor_iterator<T, typename std::enable_if< ! std::is_base_of<efl::eo::base, T>::value, T>::type>
|
||||
{
|
||||
typedef T value_type; /**< Type of the elements. */
|
||||
typedef value_type* pointer; /**< Pointer to element type. */
|
||||
|
@ -339,115 +548,189 @@ struct accessor_iterator
|
|||
std::swap(_accessor, other._accessor);
|
||||
}
|
||||
|
||||
private:
|
||||
accessor<T> _accessor; /**< @internal */
|
||||
unsigned int _index; /**< @internal */
|
||||
|
||||
/**
|
||||
* @brief Check if @p lhs and @p rhs point to the same position.
|
||||
* @param lhs @c accessor_iterator at the left side of the expression.
|
||||
* @param rhs @c accessor_iterator at the right side of the expression.
|
||||
* @return @c true if both @p lhs and @p rhs point to the same position.
|
||||
*/
|
||||
template <typename U>
|
||||
friend bool operator==(accessor_iterator<U> const& lhs, accessor_iterator<U> const& rhs)
|
||||
{
|
||||
return lhs._index == rhs._index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the distance between two <tt>accessor_iterator</tt>s.
|
||||
* @param lhs @c accessor_iterator at the left side of the expression.
|
||||
* @param rhs @c accessor_iterator at the right side of the expression.
|
||||
* @return The number of elements between @p lhs and @p rhs.
|
||||
*/
|
||||
template <typename U>
|
||||
friend typename accessor_iterator<U>::difference_type
|
||||
operator-(accessor_iterator<U> const& lhs, accessor_iterator<U> const& rhs)
|
||||
{
|
||||
return lhs._index - rhs._index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get an @c accessor_iterator moved @p rhs positions forward.
|
||||
* @param lhs @c accessor_iterator object.
|
||||
* @param rhs Number of positions relative to the current element.
|
||||
* @return Copy of @p lhs moved @p rhs positions forward.
|
||||
*/
|
||||
template <typename U>
|
||||
friend
|
||||
accessor_iterator<U> operator+(accessor_iterator<U> lhs
|
||||
, typename accessor_iterator<U>::difference_type rhs)
|
||||
{
|
||||
lhs._index += rhs;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get an @c accessor_iterator moved @p lhs positions forward.
|
||||
* @param lhs Number of positions relative to the current element.
|
||||
* @param rhs @c accessor_iterator object.
|
||||
* @return Copy of @p rhs moved @p lhs positions forward.
|
||||
*/
|
||||
template <typename U>
|
||||
friend
|
||||
accessor_iterator<U> operator+(typename accessor_iterator<U>::difference_type lhs
|
||||
, accessor_iterator<U> rhs)
|
||||
{
|
||||
return rhs + lhs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if @p lhs points to a position before the position pointed by @p rhs.
|
||||
* @param lhs @c accessor_iterator at the left side of the expression.
|
||||
* @param rhs @c accessor_iterator at the right side of the expression.
|
||||
* @return @c true if @p lhs points to a position before the position
|
||||
* pointed by @p rhs, @c false otherwise.
|
||||
*/
|
||||
template <typename U>
|
||||
friend bool operator<(accessor_iterator<U> const& lhs, accessor_iterator<U> const& rhs)
|
||||
{
|
||||
return lhs._index < rhs._index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if the position pointed by @p lhs is the same or is before the one pointed by @p rhs.
|
||||
* @param lhs @c accessor_iterator at the left side of the expression.
|
||||
* @param rhs @c accessor_iterator at the right side of the expression.
|
||||
* @return @c true if the position pointed by @p lhs is the same or is
|
||||
* before the position pointed by @p rhs, @c false otherwise.
|
||||
*/
|
||||
template <typename U>
|
||||
friend bool operator<=(accessor_iterator<U> const& lhs, accessor_iterator<U> const& rhs)
|
||||
{
|
||||
return lhs._index <= rhs._index;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Check if the position pointed by @p lhs is the same or is after the one pointed by @p rhs.
|
||||
* @param lhs @c accessor_iterator at the left side of the expression.
|
||||
* @param rhs @c accessor_iterator at the right side of the expression.
|
||||
* @return @c true if the position pointed by @p lhs is the same or is
|
||||
* after the position pointed by @p rhs, @c false otherwise.
|
||||
* Specialization for all data types that are not derivated from efl::eo::base.
|
||||
*/
|
||||
template <typename U>
|
||||
bool operator>=(accessor_iterator<U> const& lhs, accessor_iterator<U> const& rhs)
|
||||
template <typename T>
|
||||
struct accessor_iterator<T, typename std::enable_if<std::is_base_of<efl::eo::base, T>::value, T>::type>
|
||||
{
|
||||
return !(lhs < rhs);
|
||||
}
|
||||
typedef T value_type; /**< Type of the elements. */
|
||||
typedef value_type* pointer; /**< Pointer to element type. */
|
||||
typedef value_type& reference; /**< Reference to element type. */
|
||||
typedef std::ptrdiff_t difference_type; /**< Type to represent the distance between two @ref accessor_iterators */
|
||||
typedef std::input_iterator_tag iterator_category; /**< Defines the iterator as being a random access iterator. */
|
||||
|
||||
|
||||
/**
|
||||
* @brief Creates an @c accessor_iterator to the given <tt>eina::accessor</tt>.
|
||||
* @param a <tt>eina::accessor</tt> object.
|
||||
* @param pos Initial position of the iterator (Default = @c 0).
|
||||
*
|
||||
* This constructor creates an @c accessor_iterator for the given
|
||||
* <tt>eina::accessor</tt> object. The position initially pointed by
|
||||
* the iterator can be supplied via the @p pos argument, by default
|
||||
* it is the first position (index @c 0).
|
||||
*/
|
||||
accessor_iterator(accessor<T> const& a, unsigned int pos = 0u)
|
||||
: _accessor(a), _index(pos), _tmp_value(0)
|
||||
{}
|
||||
|
||||
~accessor_iterator()
|
||||
{
|
||||
if(_tmp_value) {
|
||||
delete _tmp_value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Move the iterator forward by @p i positions.
|
||||
* @param i Number of positions to move.
|
||||
* @return The @c accessor_iterator itself.
|
||||
*/
|
||||
accessor_iterator<T>& operator+=(difference_type i)
|
||||
{
|
||||
_index += i;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Move the iterator back by @p i positions.
|
||||
* @param i Number of positions to move.
|
||||
* @return The @c accessor_iterator itself.
|
||||
*/
|
||||
accessor_iterator<T>& operator-=(difference_type i)
|
||||
{
|
||||
_index -= i;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the element @p i positions away from the current element.
|
||||
* @param i Position relative to the current element.
|
||||
* @return Copy of the element @p i positions away from the
|
||||
* element currently pointed by the @c accessor_iterator.
|
||||
*/
|
||||
value_type operator[](difference_type i)
|
||||
{
|
||||
return _accessor[_index + i];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Move the iterator to the next position.
|
||||
* @return The @c accessor_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.
|
||||
*/
|
||||
accessor_iterator<T>& operator++()
|
||||
{
|
||||
++_index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Move the iterator to the previous position.
|
||||
* @return The @c accessor_iterator itself.
|
||||
*
|
||||
* This operator decrements the iterator, making it point to the
|
||||
* position right before the current one.
|
||||
* At the end, it returns a reference to itself.
|
||||
*/
|
||||
accessor_iterator<T>& operator--()
|
||||
{
|
||||
--_index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Move the iterator to the next position.
|
||||
* @return A copy of the @c accessor_iterator before the change.
|
||||
*
|
||||
* This operator increments the iterator, making it point to the
|
||||
* position right after the current one.
|
||||
* At the end, it returns a copy of the @c accessor_iterator before
|
||||
* the change.
|
||||
*/
|
||||
accessor_iterator<T>& operator++(int)
|
||||
{
|
||||
accessor_iterator<T> tmp(*this);
|
||||
++*this;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Move the iterator to the previous position.
|
||||
* @return A copy of the @c accessor_iterator before the change.
|
||||
*
|
||||
* This operator decrements the iterator, making it point to the
|
||||
* position right before the current one.
|
||||
* At the end, it returns a copy of the @c accessor_iterator before
|
||||
* the change.
|
||||
*/
|
||||
accessor_iterator<T>& operator--(int)
|
||||
{
|
||||
accessor_iterator<T> tmp(*this);
|
||||
--*this;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get a reference to the element currently pointed by the @c accessor_iterator.
|
||||
* @return Copy of the current element.
|
||||
*/
|
||||
value_type operator*() const
|
||||
{
|
||||
return _accessor[_index];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return a pointer to a copy of the current element, which member will be accessed.
|
||||
* @return Pointer a copy of the element currently pointed by the @c accessor_iterator.
|
||||
*/
|
||||
pointer operator->() const
|
||||
{
|
||||
if(!_tmp_value)
|
||||
{
|
||||
_tmp_value = new value_type(_accessor[_index]);
|
||||
}
|
||||
else
|
||||
{
|
||||
*_tmp_value = _accessor[_index];
|
||||
}
|
||||
return _tmp_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Swap content with the given @c accessor_iterator.
|
||||
* @param other Another @c accessor_iterator of the same type.
|
||||
*/
|
||||
void swap(accessor_iterator<T>& other)
|
||||
{
|
||||
std::swap(_index, other._index);
|
||||
std::swap(_accessor, other._accessor);
|
||||
std::swap(_tmp_value, other._tmp_value);
|
||||
}
|
||||
|
||||
accessor<T> _accessor; /**< @internal */
|
||||
unsigned int _index; /**< @internal */
|
||||
pointer _tmp_value; /**< @internal */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Check if @p lhs points to a position after the position pointed by @p rhs.
|
||||
* @brief Check if @p lhs and @p rhs point to the same position.
|
||||
* @param lhs @c accessor_iterator at the left side of the expression.
|
||||
* @param rhs @c accessor_iterator at the right side of the expression.
|
||||
* @return @c true if @p lhs points to a position after the position
|
||||
* pointed by @p rhs, @c false otherwise.
|
||||
* @return @c true if both @p lhs and @p rhs point to the same position.
|
||||
*/
|
||||
template <typename U>
|
||||
bool operator>(accessor_iterator<U> const& lhs, accessor_iterator<U> const& rhs)
|
||||
bool operator==(accessor_iterator<U> const& lhs, accessor_iterator<U> const& rhs)
|
||||
{
|
||||
return !(lhs <= rhs);
|
||||
return lhs._index == rhs._index;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -462,6 +745,98 @@ bool operator!=(accessor_iterator<U> const& lhs, accessor_iterator<U> const& rhs
|
|||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the distance between two <tt>accessor_iterator</tt>s.
|
||||
* @param lhs @c accessor_iterator at the left side of the expression.
|
||||
* @param rhs @c accessor_iterator at the right side of the expression.
|
||||
* @return The number of elements between @p lhs and @p rhs.
|
||||
*/
|
||||
template <typename U>
|
||||
typename accessor_iterator<U>::difference_type
|
||||
operator-(accessor_iterator<U> const& lhs, accessor_iterator<U> const& rhs)
|
||||
{
|
||||
return lhs._index - rhs._index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get an @c accessor_iterator moved @p rhs positions forward.
|
||||
* @param lhs @c accessor_iterator object.
|
||||
* @param rhs Number of positions relative to the current element.
|
||||
* @return Copy of @p lhs moved @p rhs positions forward.
|
||||
*/
|
||||
template <typename U>
|
||||
accessor_iterator<U> operator+(accessor_iterator<U> lhs
|
||||
, typename accessor_iterator<U>::difference_type rhs)
|
||||
{
|
||||
lhs += rhs;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get an @c accessor_iterator moved @p lhs positions forward.
|
||||
* @param lhs Number of positions relative to the current element.
|
||||
* @param rhs @c accessor_iterator object.
|
||||
* @return Copy of @p rhs moved @p lhs positions forward.
|
||||
*/
|
||||
template <typename U>
|
||||
accessor_iterator<U> operator+(typename accessor_iterator<U>::difference_type lhs
|
||||
, accessor_iterator<U> const& rhs)
|
||||
{
|
||||
return rhs + lhs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if @p lhs points to a position before the position pointed by @p rhs.
|
||||
* @param lhs @c accessor_iterator at the left side of the expression.
|
||||
* @param rhs @c accessor_iterator at the right side of the expression.
|
||||
* @return @c true if @p lhs points to a position before the position
|
||||
* pointed by @p rhs, @c false otherwise.
|
||||
*/
|
||||
template <typename U>
|
||||
bool operator<(accessor_iterator<U> const& lhs, accessor_iterator<U> const& rhs)
|
||||
{
|
||||
return lhs._index < rhs._index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if @p lhs points to a position after the position pointed by @p rhs.
|
||||
* @param lhs @c accessor_iterator at the left side of the expression.
|
||||
* @param rhs @c accessor_iterator at the right side of the expression.
|
||||
* @return @c true if @p lhs points to a position after the position
|
||||
* pointed by @p rhs, @c false otherwise.
|
||||
*/
|
||||
template <typename U>
|
||||
bool operator>(accessor_iterator<U> const& lhs, accessor_iterator<U> const& rhs)
|
||||
{
|
||||
return rhs < lhs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if the position pointed by @p lhs is the same or is before the one pointed by @p rhs.
|
||||
* @param lhs @c accessor_iterator at the left side of the expression.
|
||||
* @param rhs @c accessor_iterator at the right side of the expression.
|
||||
* @return @c true if the position pointed by @p lhs is the same or is
|
||||
* before the position pointed by @p rhs, @c false otherwise.
|
||||
*/
|
||||
template <typename U>
|
||||
bool operator<=(accessor_iterator<U> const& lhs, accessor_iterator<U> const& rhs)
|
||||
{
|
||||
return !(rhs < lhs);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if the position pointed by @p lhs is the same or is after the one pointed by @p rhs.
|
||||
* @param lhs @c accessor_iterator at the left side of the expression.
|
||||
* @param rhs @c accessor_iterator at the right side of the expression.
|
||||
* @return @c true if the position pointed by @p lhs is the same or is
|
||||
* after the position pointed by @p rhs, @c false otherwise.
|
||||
*/
|
||||
template <typename U>
|
||||
bool operator>=(accessor_iterator<U> const& lhs, accessor_iterator<U> const& rhs)
|
||||
{
|
||||
return !(lhs < rhs);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Swap content between two <tt>accessor_iterator</tt>s.
|
||||
* @param lhs First @c accessor_iterator.
|
||||
|
|
|
@ -1,10 +1,33 @@
|
|||
#ifndef EINA_EO_BASE_FWD_HH
|
||||
#define EINA_EO_BASE_FWD_HH
|
||||
|
||||
#include <Eo.h>
|
||||
#include <type_traits>
|
||||
|
||||
namespace efl { namespace eo {
|
||||
|
||||
struct base;
|
||||
|
||||
} }
|
||||
|
||||
namespace std {
|
||||
template <>
|
||||
struct is_base_of< ::efl::eo::base, ::Eo > : std::false_type {};
|
||||
template <>
|
||||
struct is_base_of< ::efl::eo::base, const ::Eo > : std::false_type {};
|
||||
template <>
|
||||
struct is_base_of< ::efl::eo::base, volatile ::Eo > : std::false_type {};
|
||||
template <>
|
||||
struct is_base_of< ::efl::eo::base, const volatile ::Eo > : std::false_type {};
|
||||
|
||||
template <>
|
||||
struct is_base_of< const ::efl::eo::base, ::Eo > : std::false_type {};
|
||||
template <>
|
||||
struct is_base_of< const ::efl::eo::base, const ::Eo > : std::false_type {};
|
||||
template <>
|
||||
struct is_base_of< const ::efl::eo::base, volatile ::Eo > : std::false_type {};
|
||||
template <>
|
||||
struct is_base_of< const ::efl::eo::base, const volatile ::Eo > : std::false_type {};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -413,6 +413,27 @@ public:
|
|||
using _base_type::max_size;
|
||||
using _base_type::native_handle;
|
||||
|
||||
/**
|
||||
* @brief Get a constant @ref eina::accessor for the list.
|
||||
* @return Constant <tt>eina::accessor</tt> to the list.
|
||||
*
|
||||
* Version of @ref accessor() to const-qualified inline lists. Returns
|
||||
* a const-qualified <tt>eina::accessor</tt> instead.
|
||||
*/
|
||||
eina::accessor<T const> accessor() const
|
||||
{
|
||||
return eina::accessor<T const>(eina_list_accessor_new(this->_impl._list));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get a @ref eina::accessor for the list.
|
||||
* @return <tt>eina::accessor</tt> to the list.
|
||||
*/
|
||||
eina::accessor<T> accessor()
|
||||
{
|
||||
return eina::accessor<T>(eina_list_accessor_new(this->_impl._list));
|
||||
}
|
||||
|
||||
friend bool operator==(list<T, CloneAllocator> const& rhs, list<T, CloneAllocator> const& lhs)
|
||||
{
|
||||
return rhs.size() == lhs.size() && std::equal(rhs.begin(), rhs.end(), lhs.begin());
|
||||
|
|
|
@ -4,13 +4,26 @@
|
|||
#endif
|
||||
|
||||
#include "Eina.hh"
|
||||
#include "Eo.hh"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <check.h>
|
||||
|
||||
|
||||
const Eo_Class *simple_class_get(void);
|
||||
#define MY_CLASS simple_class_get()
|
||||
|
||||
struct wrapper : efl::eo::base
|
||||
{
|
||||
explicit wrapper(Eo* o)
|
||||
: base(o) {}
|
||||
};
|
||||
|
||||
START_TEST(eina_cxx_accessor_indexing)
|
||||
{
|
||||
efl::eina::eina_init eina_init;
|
||||
|
||||
efl::eina::ptr_list<int> list;
|
||||
list.push_back(new int(5));
|
||||
list.push_back(new int(10));
|
||||
|
@ -26,8 +39,36 @@ START_TEST(eina_cxx_accessor_indexing)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(eina_cxx_eo_accessor_indexing)
|
||||
{
|
||||
efl::eina::eina_init eina_init;
|
||||
efl::eo::eo_init eo_init;
|
||||
|
||||
efl::eina::list<wrapper> list;
|
||||
|
||||
wrapper const w1(eo_add(MY_CLASS, NULL));
|
||||
wrapper const w2(eo_add(MY_CLASS, NULL));
|
||||
wrapper const w3(eo_add(MY_CLASS, NULL));
|
||||
wrapper const w4(eo_add(MY_CLASS, NULL));
|
||||
|
||||
list.push_back(w1);
|
||||
list.push_back(w2);
|
||||
list.push_back(w3);
|
||||
list.push_back(w4);
|
||||
|
||||
efl::eina::accessor<wrapper> accessor(list.accessor());
|
||||
|
||||
ck_assert(accessor[0] == w1);
|
||||
ck_assert(accessor[1] == w2);
|
||||
ck_assert(accessor[2] == w3);
|
||||
ck_assert(accessor[3] == w4);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(eina_cxx_accessor_iterator)
|
||||
{
|
||||
efl::eina::eina_init eina_init;
|
||||
|
||||
efl::eina::ptr_list<int> list;
|
||||
list.push_back(new int(5));
|
||||
list.push_back(new int(10));
|
||||
|
@ -38,6 +79,12 @@ START_TEST(eina_cxx_accessor_iterator)
|
|||
for(efl::eina::accessor_iterator<int> first (list.accessor())
|
||||
, last (list.accessor(), list.size()); first != last; ++first, ++pos)
|
||||
{
|
||||
if(pos >= 4u)
|
||||
{
|
||||
ck_assert_msg(0, "accessor_iterator out of bounds");
|
||||
break;
|
||||
}
|
||||
|
||||
ck_assert(pos != 0u || *first == 5);
|
||||
ck_assert(pos != 1u || *first == 10);
|
||||
ck_assert(pos != 2u || *first == 15);
|
||||
|
@ -46,8 +93,45 @@ START_TEST(eina_cxx_accessor_iterator)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(eina_cxx_eo_accessor_iterator)
|
||||
{
|
||||
efl::eina::eina_init eina_init;
|
||||
efl::eo::eo_init eo_init;
|
||||
|
||||
efl::eina::list<wrapper> list;
|
||||
|
||||
wrapper const w1(eo_add(MY_CLASS, NULL));
|
||||
wrapper const w2(eo_add(MY_CLASS, NULL));
|
||||
wrapper const w3(eo_add(MY_CLASS, NULL));
|
||||
wrapper const w4(eo_add(MY_CLASS, NULL));
|
||||
|
||||
list.push_back(w1);
|
||||
list.push_back(w2);
|
||||
list.push_back(w3);
|
||||
list.push_back(w4);
|
||||
|
||||
std::size_t pos = 0u;
|
||||
for(efl::eina::accessor_iterator<wrapper> first (list.accessor())
|
||||
, last (list.accessor(), list.size()); first != last; ++first, ++pos)
|
||||
{
|
||||
if(pos >= 4u)
|
||||
{
|
||||
ck_assert_msg(0, "accessor_iterator out of bounds");
|
||||
break;
|
||||
}
|
||||
|
||||
ck_assert(pos != 0u || *first == w1);
|
||||
ck_assert(pos != 1u || *first == w2);
|
||||
ck_assert(pos != 2u || *first == w3);
|
||||
ck_assert(pos != 3u || *first == w4);
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(eina_cxx_accessor_relops)
|
||||
{
|
||||
efl::eina::eina_init eina_init;
|
||||
|
||||
efl::eina::ptr_list<int> list;
|
||||
list.push_back(new int(5));
|
||||
list.push_back(new int(10));
|
||||
|
@ -101,6 +185,8 @@ void
|
|||
eina_test_accessor(TCase* tc)
|
||||
{
|
||||
tcase_add_test(tc, eina_cxx_accessor_indexing);
|
||||
tcase_add_test(tc, eina_cxx_eo_accessor_indexing);
|
||||
tcase_add_test(tc, eina_cxx_accessor_iterator);
|
||||
tcase_add_test(tc, eina_cxx_eo_accessor_iterator);
|
||||
tcase_add_test(tc, eina_cxx_accessor_relops);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue