From ee81566ac891162ce4fb56da7648de31f0bbe7a7 Mon Sep 17 00:00:00 2001 From: Vitor Sousa Date: Mon, 3 Nov 2014 11:38:17 -0200 Subject: [PATCH] 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 --- src/bindings/eina_cxx/eina_accessor.hh | 629 +++++++++++++++---- src/bindings/eina_cxx/eina_eo_base_fwd.hh | 23 + src/bindings/eina_cxx/eina_list.hh | 21 + src/tests/eina_cxx/eina_cxx_test_accessor.cc | 86 +++ 4 files changed, 632 insertions(+), 127 deletions(-) diff --git a/src/bindings/eina_cxx/eina_accessor.hh b/src/bindings/eina_cxx/eina_accessor.hh index 98be3afd1b..e64d0ef698 100644 --- a/src/bindings/eina_cxx/eina_accessor.hh +++ b/src/bindings/eina_cxx/eina_accessor.hh @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -37,7 +38,7 @@ namespace efl { namespace eina { * Wraps an native Eina_Accessor and provide random access to data structures. */ template -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 const& other) + accessor_common_base(accessor_common_base 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& operator=(accessor const& other) + accessor_common_base& operator=(accessor_common_base 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 eina::system_error 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 - * eina::system_error 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(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& other) + void swap(accessor_common_base& other) { std::swap(_impl, other._impl); } @@ -158,9 +137,8 @@ struct accessor */ explicit operator bool() const { - return native_handle() ? &accessor::native_handle : 0 ; + return native_handle() ? &accessor_common_base::native_handle : 0 ; } -private: /** * @internal @@ -169,6 +147,234 @@ private: Eina_Accessor* _impl; }; +template +struct accessor; + +template +struct accessor::value, T>::type> + : accessor_common_base +{ + typedef accessor_common_base _base_type; + typedef accessor _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 eina::system_error 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 eina::system_error 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 + * eina::system_error 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(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 +struct accessor::value, T>::type> + : accessor_common_base +{ + typedef accessor_common_base _base_type; + typedef accessor _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 eina::system_error 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 eina::system_error 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 + * eina::system_error 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(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& lhs, accessor& rhs) * @{ */ +template +struct accessor_iterator; + /** * Random access iterator for eina::accessor. */ template -struct accessor_iterator +struct accessor_iterator::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 _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 - friend bool operator==(accessor_iterator const& lhs, accessor_iterator const& rhs) - { - return lhs._index == rhs._index; - } - - /** - * @brief Get the distance between two accessor_iterators. - * @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 - friend typename accessor_iterator::difference_type - operator-(accessor_iterator const& lhs, accessor_iterator 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 - friend - accessor_iterator operator+(accessor_iterator lhs - , typename accessor_iterator::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 - friend - accessor_iterator operator+(typename accessor_iterator::difference_type lhs - , accessor_iterator 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 - friend bool operator<(accessor_iterator const& lhs, accessor_iterator 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 - friend bool operator<=(accessor_iterator const& lhs, accessor_iterator 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 -bool operator>=(accessor_iterator const& lhs, accessor_iterator const& rhs) +template +struct accessor_iterator::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 eina::accessor. + * @param a eina::accessor object. + * @param pos Initial position of the iterator (Default = @c 0). + * + * This constructor creates an @c accessor_iterator for the given + * eina::accessor 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 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& 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& 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& 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& 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& operator++(int) + { + accessor_iterator 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& operator--(int) + { + accessor_iterator 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& other) + { + std::swap(_index, other._index); + std::swap(_accessor, other._accessor); + std::swap(_tmp_value, other._tmp_value); + } + + accessor _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 -bool operator>(accessor_iterator const& lhs, accessor_iterator const& rhs) +bool operator==(accessor_iterator const& lhs, accessor_iterator const& rhs) { - return !(lhs <= rhs); + return lhs._index == rhs._index; } /** @@ -462,6 +745,98 @@ bool operator!=(accessor_iterator const& lhs, accessor_iterator const& rhs return !(lhs == rhs); } +/** + * @brief Get the distance between two accessor_iterators. + * @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 accessor_iterator::difference_type +operator-(accessor_iterator const& lhs, accessor_iterator 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 +accessor_iterator operator+(accessor_iterator lhs + , typename accessor_iterator::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 +accessor_iterator operator+(typename accessor_iterator::difference_type lhs + , accessor_iterator 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 +bool operator<(accessor_iterator const& lhs, accessor_iterator 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 +bool operator>(accessor_iterator const& lhs, accessor_iterator 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 +bool operator<=(accessor_iterator const& lhs, accessor_iterator 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 +bool operator>=(accessor_iterator const& lhs, accessor_iterator const& rhs) +{ + return !(lhs < rhs); +} + /** * @brief Swap content between two accessor_iterators. * @param lhs First @c accessor_iterator. diff --git a/src/bindings/eina_cxx/eina_eo_base_fwd.hh b/src/bindings/eina_cxx/eina_eo_base_fwd.hh index 989869499e..b160a6d049 100644 --- a/src/bindings/eina_cxx/eina_eo_base_fwd.hh +++ b/src/bindings/eina_cxx/eina_eo_base_fwd.hh @@ -1,10 +1,33 @@ #ifndef EINA_EO_BASE_FWD_HH #define EINA_EO_BASE_FWD_HH +#include +#include + 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 diff --git a/src/bindings/eina_cxx/eina_list.hh b/src/bindings/eina_cxx/eina_list.hh index b2b6745dc8..b81097139f 100644 --- a/src/bindings/eina_cxx/eina_list.hh +++ b/src/bindings/eina_cxx/eina_list.hh @@ -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 eina::accessor to the list. + * + * Version of @ref accessor() to const-qualified inline lists. Returns + * a const-qualified eina::accessor instead. + */ + eina::accessor accessor() const + { + return eina::accessor(eina_list_accessor_new(this->_impl._list)); + } + + /** + * @brief Get a @ref eina::accessor for the list. + * @return eina::accessor to the list. + */ + eina::accessor accessor() + { + return eina::accessor(eina_list_accessor_new(this->_impl._list)); + } + friend bool operator==(list const& rhs, list const& lhs) { return rhs.size() == lhs.size() && std::equal(rhs.begin(), rhs.end(), lhs.begin()); diff --git a/src/tests/eina_cxx/eina_cxx_test_accessor.cc b/src/tests/eina_cxx/eina_cxx_test_accessor.cc index 8d04ecc226..bf7502ff9a 100644 --- a/src/tests/eina_cxx/eina_cxx_test_accessor.cc +++ b/src/tests/eina_cxx/eina_cxx_test_accessor.cc @@ -4,13 +4,26 @@ #endif #include "Eina.hh" +#include "Eo.hh" #include #include + +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 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 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 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 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 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 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 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 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); }