From 5942207b25d746585c2b9eb93393e1af9dcb0ad7 Mon Sep 17 00:00:00 2001 From: Felipe Magno de Almeida Date: Mon, 10 Mar 2014 12:24:29 +0900 Subject: [PATCH] eina-cxx: Added range types for containers Summary: Added inarray, inlist, ptr_array and ptr_list's range types named: range_inarray, range_inlist, range_ptr_array and range_ptr_list. Each has two "flavours": mutable and not mutable. The const versions are parameterized by a const parameter. For example: range_ptr_list and the mutable doesn't have the const, so: range_ptr_list. The difference between the two is that the const versions can't modify the elements from the sequence, while the mutable allows so. Also, the const receives a Eina_Array const* while the mutable must have a Eina_Array*. Reviewers: cedric CC: savio, cedric Differential Revision: https://phab.enlightenment.org/D613 --- src/bindings/eina_cxx/eina_inarray.hh | 264 ++++++++++++-- src/bindings/eina_cxx/eina_inlist.hh | 203 +++++++++-- src/bindings/eina_cxx/eina_ptrarray.hh | 262 +++++++++++--- src/bindings/eina_cxx/eina_ptrlist.hh | 356 +++++++++++++++++-- src/bindings/eina_cxx/eina_range_types.hh | 180 ++++++++++ src/tests/eina_cxx/eina_cxx_test_inarray.cc | 32 ++ src/tests/eina_cxx/eina_cxx_test_inlist.cc | 31 ++ src/tests/eina_cxx/eina_cxx_test_ptrarray.cc | 31 ++ src/tests/eina_cxx/eina_cxx_test_ptrlist.cc | 31 ++ 9 files changed, 1252 insertions(+), 138 deletions(-) create mode 100644 src/bindings/eina_cxx/eina_range_types.hh diff --git a/src/bindings/eina_cxx/eina_inarray.hh b/src/bindings/eina_cxx/eina_inarray.hh index 4b59be6e0d..7f6f9d2006 100644 --- a/src/bindings/eina_cxx/eina_inarray.hh +++ b/src/bindings/eina_cxx/eina_inarray.hh @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -10,10 +11,170 @@ namespace efl { namespace eina { +struct _inarray_access_traits { + + template + struct const_iterator + { + typedef T const* type; + }; + template + struct iterator + { + typedef T* type; + }; + template + struct const_native_handle + { + typedef Eina_Inarray const* type; + }; + template + struct native_handle + { + typedef Eina_Inarray* type; + }; + + template + static Eina_Inarray* native_handle_from_const(Eina_Inarray const* array) + { + return const_cast(array); + } +template +static T& back(Eina_Inarray* raw) +{ + assert(!_inarray_access_traits::empty(raw)); + return *static_cast( ::eina_inarray_nth(raw, _inarray_access_traits::size(raw)-1u)); +} +template +static T const& back(Eina_Inarray const* raw) +{ + return _inarray_access_traits::back(const_cast(raw)); +} +template +static T& front(Eina_Inarray* raw) +{ + assert(!empty(raw)); + return *static_cast( ::eina_inarray_nth(raw, 0u)); +} +template +static T const& front(Eina_Inarray const* raw) +{ + return _inarray_access_traits::front(const_cast(raw)); +} +template +static T* begin(Eina_Inarray* raw) +{ + return !raw->members ? 0 : static_cast( ::eina_inarray_nth(raw, 0u)); +} +template +static T* end(Eina_Inarray* raw) +{ + return !raw->members ? 0 + : static_cast( ::eina_inarray_nth(raw, _inarray_access_traits::size(raw) -1)) + 1; +} +template +static T const* begin(Eina_Inarray const* raw) +{ + return _inarray_access_traits::begin(const_cast(raw)); +} +template +static T const* end(Eina_Inarray const* raw) +{ + return _inarray_access_traits::end(const_cast(raw)); +} +template +static std::reverse_iterator rbegin(Eina_Inarray const* raw) +{ + return std::reverse_iterator(_inarray_access_traits::begin(raw)); +} +template +static std::reverse_iterator rend(Eina_Inarray const* raw) +{ + return std::reverse_iterator(_inarray_access_traits::end(raw)); +} +template +static std::reverse_iterator rbegin(Eina_Inarray* raw) +{ + return std::reverse_iterator(_inarray_access_traits::begin(raw)); +} +template +static std::reverse_iterator rend(Eina_Inarray* raw) +{ + return std::reverse_iterator(_inarray_access_traits::end(raw)); +} +template +static T const* cbegin(Eina_Inarray const* raw) +{ + return _inarray_access_traits::begin(raw); +} +template +static T const* cend(Eina_Inarray const* raw) +{ + return _inarray_access_traits::end(raw); +} +template +static std::reverse_iterator crbegin(Eina_Inarray const* raw) +{ + return _inarray_access_traits::rbegin(raw); +} +template +static std::reverse_iterator crend(Eina_Inarray const* raw) +{ + return _inarray_access_traits::rend(raw); +} +template +static inline bool empty(Eina_Inarray const* raw) +{ + return _inarray_access_traits::size(raw) == 0; +} +template +static inline std::size_t size(Eina_Inarray const* raw) +{ + return ::eina_inarray_count(raw); +} +template +static T const& index(Eina_Inarray const* raw, std::size_t i) +{ + return *(_inarray_access_traits::begin(raw) + i); +} +template +static T& index(Eina_Inarray* raw, std::size_t i) +{ + return *(_inarray_access_traits::begin(raw) + i); +} + +}; + +template +struct inarray; + +template +struct range_inarray : _range_template +{ + typedef _range_template _base_type; + typedef typename std::remove_const::type value_type; + + range_inarray(Eina_Inarray* array) + : _base_type(array) + {} + range_inarray(inarray& array) + : _base_type(array.native_handle()) + {} + + value_type& operator[](std::size_t index) const + { + return _inarray_access_traits::index(this->native_handle(), index); + } +}; + struct _inarray_common_base { typedef std::size_t size_type; + typedef Eina_Inarray* native_handle_type; + typedef Eina_Inarray const* const_native_handle_type; + explicit _inarray_common_base(Eina_Inarray* array) + : _array(array) {} explicit _inarray_common_base(size_type member_size) : _array( ::eina_inarray_new(member_size, 0) ) { @@ -25,12 +186,14 @@ struct _inarray_common_base size_type size() const { - return ::eina_inarray_count(_array); + return _inarray_access_traits::size(_array); } bool empty() const { - return size() == 0u; + return _inarray_access_traits::empty(_array); } + native_handle_type native_handle() { return _array; } + const_native_handle_type native_handle() const { return _array; } Eina_Inarray* _array; private: @@ -52,13 +215,18 @@ public: typedef const_pointer const_iterator; typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; + typedef _base_type::native_handle_type native_handle_type; + typedef _base_type::const_native_handle_type const_native_handle_type; typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; using _base_type::size; using _base_type::empty; + using _base_type::native_handle; + _pod_inarray(Eina_Inarray* array) + : _base_type(array) {} _pod_inarray() : _base_type(sizeof(T)) { } @@ -98,7 +266,10 @@ public: } void push_back(T const& value) { + size_type s = size(); eina_inarray_push(_array, &value); + assert(size() != s); + assert(size() == s + 1u); } void pop_back() { @@ -166,71 +337,77 @@ public: void assign(InputIterator i, InputIterator j , typename eina::enable_if::value>::type* = 0); void assign(size_type n, value_type const& t); + value_type& operator[](size_type i) + { + return *(begin() + i); + } + value_type const& operator[](size_type i) const + { + return const_cast&>(*this)[i]; + } value_type& back() { - assert(!empty()); - return *static_cast(eina_inarray_nth(_array, size()-1u)); + return _inarray_access_traits::back(_array); } value_type const& back() const { - return const_cast<_pod_inarray&>(*this).back(); + return _inarray_access_traits::back(_array); } value_type& front() { - assert(!empty()); - return *static_cast(eina_inarray_nth(_array, 0u)); + return _inarray_access_traits::front(_array); } value_type const& front() const { - return const_cast<_pod_inarray&>(*this).front(); + return _inarray_access_traits::front(_array); } iterator begin() { - return !_array->members ? 0 : static_cast(::eina_inarray_nth(_array, 0u)); + return _inarray_access_traits::begin(_array); } iterator end() { - return !_array->members ? 0 : static_cast(::eina_inarray_nth(_array, size()-1)) + 1; + return _inarray_access_traits::end(_array); } const_iterator begin() const { - return const_cast< _pod_inarray&>(*this).begin(); + return _inarray_access_traits::begin(_array); } const_iterator end() const { - return const_cast< _pod_inarray&>(*this).end(); + return _inarray_access_traits::end(_array); } const_reverse_iterator rbegin() const { - return const_reverse_iterator(begin()); + return _inarray_access_traits::rbegin(_array); } const_reverse_iterator rend() const { - return const_reverse_iterator(end()); + return _inarray_access_traits::rend(_array); } reverse_iterator rbegin() { - return reverse_iterator(begin()); + return _inarray_access_traits::rbegin(_array); } reverse_iterator rend() { - return reverse_iterator(end()); + return _inarray_access_traits::rend(_array); } const_iterator cbegin() const { - return begin(); + return _inarray_access_traits::cbegin(_array); } const_iterator cend() const { - return end(); + return _inarray_access_traits::cend(_array); } const_reverse_iterator crbegin() const { - return rbegin(); + return _inarray_access_traits::crbegin(_array); } const_reverse_iterator crend() const { - return rend(); + return _inarray_access_traits::crend(_array); } void swap(_pod_inarray& other) { @@ -269,6 +446,8 @@ public: using _base_type::size; using _base_type::empty; + _nonpod_inarray(Eina_Inarray* array) + : _base_type(array) {} _nonpod_inarray() : _base_type(sizeof(T)) { } @@ -419,71 +598,77 @@ public: void assign(InputIterator i, InputIterator j , typename eina::enable_if::value>::type* = 0); void assign(size_type n, value_type const& t); + value_type& operator[](size_type i) + { + return *(begin() + i); + } + value_type const& operator[](size_type i) const + { + return const_cast&>(*this)[i]; + } value_type& back() { - assert(!empty()); - return *static_cast(eina_inarray_nth(_array, size()-1u)); + return _inarray_access_traits::back(_array); } value_type const& back() const { - return const_cast<_nonpod_inarray&>(*this).back(); + return _inarray_access_traits::back(_array); } value_type& front() { - assert(!empty()); - return *static_cast(eina_inarray_nth(_array, 0u)); + return _inarray_access_traits::front(_array); } value_type const& front() const { - return const_cast<_nonpod_inarray&>(*this).front(); + return _inarray_access_traits::front(_array); } iterator begin() { - return static_cast(_array->members); + return _inarray_access_traits::begin(_array); } iterator end() { - return static_cast(_array->members) + _array->len; + return _inarray_access_traits::end(_array); } const_iterator begin() const { - return const_cast< _nonpod_inarray&>(*this).begin(); + return _inarray_access_traits::begin(_array); } const_iterator end() const { - return const_cast< _nonpod_inarray&>(*this).end(); + return _inarray_access_traits::end(_array); } const_reverse_iterator rbegin() const { - return const_reverse_iterator(begin()); + return _inarray_access_traits::rbegin(_array); } const_reverse_iterator rend() const { - return const_reverse_iterator(end()); + return _inarray_access_traits::rend(_array); } reverse_iterator rbegin() { - return reverse_iterator(begin()); + return _inarray_access_traits::rbegin(_array); } reverse_iterator rend() { - return reverse_iterator(end()); + return _inarray_access_traits::rend(_array); } const_iterator cbegin() const { - return begin(); + return _inarray_access_traits::cbegin(_array); } const_iterator cend() const { - return end(); + return _inarray_access_traits::cend(_array); } const_reverse_iterator crbegin() const { - return rbegin(); + return _inarray_access_traits::crbegin(_array); } const_reverse_iterator crend() const { - return rend(); + return _inarray_access_traits::crend(_array); } void swap(_nonpod_inarray& other) { @@ -508,6 +693,8 @@ class inarray : public eina::if_, _pod_inarray typedef typename eina::if_, _pod_inarray , _nonpod_inarray >::type _base_type; public: + inarray(Eina_Inarray* array) + : _base_type(array) {} inarray() : _base_type() {} inarray(typename _base_type::size_type n, typename _base_type::value_type const& t) : _base_type(n, t) {} @@ -539,7 +726,6 @@ void swap(inarray& lhs, inarray& rhs) } - } } #endif diff --git a/src/bindings/eina_cxx/eina_inlist.hh b/src/bindings/eina_cxx/eina_inlist.hh index 168b262c53..9144735857 100644 --- a/src/bindings/eina_cxx/eina_inlist.hh +++ b/src/bindings/eina_cxx/eina_inlist.hh @@ -5,8 +5,10 @@ #include #include #include +#include #include +#include namespace efl { namespace eina { @@ -47,19 +49,21 @@ Eina_Inlist const* _get_list(_inlist_node const* n) template struct _inlist_iterator { - typedef T value_type; - typedef T* pointer; - typedef T& reference; + typedef typename std::remove_const::type value_type; + typedef value_type* pointer; + typedef value_type& reference; typedef std::ptrdiff_t difference_type; typedef std::bidirectional_iterator_tag iterator_category; _inlist_iterator() {} - explicit _inlist_iterator(_inlist_node* list, _inlist_node* node) + explicit _inlist_iterator(_inlist_node* list, _inlist_node* node) : _list(list), _node(node) {} + _inlist_iterator(_inlist_iterator::type> const& other) + : _list(other._list), _node(other._node) {} _inlist_iterator& operator++() { - _node = _get_node(_node->__in_list.next); + _node = _get_node(_node->__in_list.next); return *this; } _inlist_iterator operator++(int) @@ -71,9 +75,9 @@ struct _inlist_iterator _inlist_iterator& operator--() { if(_node) - _node = _get_node(_node->__in_list.prev); + _node = _get_node(_node->__in_list.prev); else - _node = _get_node(_list->__in_list.last); + _node = _get_node(_list->__in_list.last); return *this; } _inlist_iterator operator--(int) @@ -82,26 +86,28 @@ struct _inlist_iterator --*this; return tmp; } - T const& operator*() const + T& operator*() const { return _node->object; } - T const* operator->() const + T* operator->() const { return &_node->object; } - _inlist_node* native_handle() + _inlist_node* native_handle() { return _node; } - _inlist_node const* native_handle() const + _inlist_node const* native_handle() const { return _node; } private: - _inlist_node* _list; - _inlist_node* _node; + _inlist_node* _list; + _inlist_node* _node; + template + friend struct _inlist_iterator; friend bool operator==(_inlist_iterator lhs, _inlist_iterator rhs) { return lhs._node == rhs._node; @@ -114,6 +120,154 @@ bool operator!=(_inlist_iterator lhs, _inlist_iterator rhs) return !(lhs == rhs); } +struct _inlist_access_traits { + template + struct const_iterator + { + typedef _inlist_iterator type; + }; + template + struct iterator + { + typedef _inlist_iterator type; + }; + template + struct const_native_handle + { + typedef Eina_Inlist const* type; + }; + template + struct native_handle + { + typedef Eina_Inlist* type; + }; + + template + static Eina_Inlist* native_handle_from_const(Eina_Inlist const* list) + { + return const_cast(list); + } + template + static std::size_t size(Eina_Inlist const* list) + { + return ::eina_inlist_count(list); + } + template + static bool empty(Eina_Inlist const* list) + { + return list == 0; + } + template + static T& back(Eina_Inlist* list) + { + return _get_node(list->last)->object; + } + template + static T const& back(Eina_Inlist const* list) + { + return _inlist_access_traits::back(const_cast(list)); + } + template + static T& front(Eina_Inlist* list) + { + return _get_node(list)->object; + } + template + static T const& front(Eina_Inlist const* list) + { + return _inlist_access_traits::front(const_cast(list)); + } + template + static _inlist_iterator begin(Eina_Inlist const* list) + { + return _inlist_access_traits::begin(const_cast(list)); + } + template + static _inlist_iterator end(Eina_Inlist const* list) + { + return _inlist_access_traits::end(const_cast(list)); + } + template + static _inlist_iterator begin(Eina_Inlist* list) + { + return _inlist_iterator(_get_node(list), _get_node(list)); + } + template + static _inlist_iterator end(Eina_Inlist* list) + { + return _inlist_iterator(_get_node(list), 0); + } + template + static std::reverse_iterator<_inlist_iterator > rbegin(Eina_Inlist* list) + { + return std::reverse_iterator<_inlist_iterator >(_inlist_access_traits::begin(list)); + } + template + static std::reverse_iterator<_inlist_iterator > rend(Eina_Inlist* list) + { + return std::reverse_iterator<_inlist_iterator >(_inlist_access_traits::end(list)); + } + template + static std::reverse_iterator<_inlist_iterator > rbegin(Eina_Inlist const* list) + { + return _inlist_access_traits::rbegin(const_cast(list)); + } + template + static std::reverse_iterator<_inlist_iterator > rend(Eina_Inlist const* list) + { + return _inlist_access_traits::rend(const_cast(list)); + } + template + static _inlist_iterator cbegin(Eina_Inlist const* list) + { + return _inlist_access_traits::begin(list); + } + template + static _inlist_iterator cend(Eina_Inlist const* list) + { + return _inlist_access_traits::end(list); + } + template + static std::reverse_iterator<_inlist_iterator > crbegin(Eina_Inlist const* list) + { + return _inlist_access_traits::rbegin(list); + } + template + static std::reverse_iterator<_inlist_iterator > crend(Eina_Inlist const* list) + { + return _inlist_access_traits::rend(list); + } +}; + +template +struct inlist; + +template +struct range_inlist : _range_template +{ + typedef _range_template _base_type; + typedef typename _base_type::value_type value_type; + + range_inlist(Eina_Inlist* list) + : _base_type(list) {} + template + range_inlist(inlist& list) + : _base_type(list.native_handle()) + {} +}; + +template +bool operator==(range_inlistconst& lhs, range_inlistconst& rhs) +{ + return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin()); +} + +template +bool operator!=(range_inlist const& lhs, range_inlistconst& rhs) +{ + return !(lhs == rhs); +} + template struct _inlist_common_base { @@ -221,11 +375,11 @@ public: } size_type size() const { - return ::eina_inlist_count(this->_impl._list); + return _inlist_access_traits::size(native_handle()); } bool empty() const { - return this->_impl._list == 0; + return _inlist_access_traits::empty(native_handle()); } allocator_type get_allocator() const { @@ -351,42 +505,41 @@ public: clear(); insert(end(), n, t); } - value_type& back() { - return _get_node(this->_impl._list->last)->object; + return _inlist_access_traits::back(native_handle()); } value_type const& back() const { - return const_cast&>(*this).back(); + return _inlist_access_traits::back(native_handle()); } value_type& front() { - return _get_node(this->_impl._list)->object; + return _inlist_access_traits::front(native_handle()); } value_type const& front() const { - return const_cast&>(*this).front(); + return _inlist_access_traits::front(native_handle()); } const_iterator begin() const { - return const_iterator(_get_node(this->_impl._list), _get_node(this->_impl._list)); + return _inlist_access_traits::begin(native_handle()); } const_iterator end() const { - return const_iterator(_get_node(this->_impl._list), 0); + return _inlist_access_traits::end(native_handle()); } iterator begin() { - return iterator(_get_node(this->_impl._list), _get_node(this->_impl._list)); + return _inlist_access_traits::begin(native_handle()); } iterator end() { - return iterator(_get_node(this->_impl._list), 0); + return _inlist_access_traits::end(native_handle()); } const_reverse_iterator rbegin() const { - return const_reverse_iterator(begin()); + return _inlist_access_traits::end(this->_impl._list); } const_reverse_iterator rend() const { diff --git a/src/bindings/eina_cxx/eina_ptrarray.hh b/src/bindings/eina_cxx/eina_ptrarray.hh index 85ed8b607b..b08d258811 100644 --- a/src/bindings/eina_cxx/eina_ptrarray.hh +++ b/src/bindings/eina_cxx/eina_ptrarray.hh @@ -3,8 +3,8 @@ #include #include -#include #include +#include #include #include @@ -13,18 +13,8 @@ namespace efl { namespace eina { -struct _ptr_array_iterator_base -{ - _ptr_array_iterator_base() : _ptr(0) {} - _ptr_array_iterator_base(void** ptr) - : _ptr(ptr) - {} - - void** _ptr; -}; - template -struct _ptr_array_iterator : protected _ptr_array_iterator_base +struct _ptr_array_iterator { typedef T value_type; typedef value_type* pointer; @@ -32,17 +22,16 @@ struct _ptr_array_iterator : protected _ptr_array_iterator_base typedef std::ptrdiff_t difference_type; typedef std::bidirectional_iterator_tag iterator_category; - _ptr_array_iterator() {} + _ptr_array_iterator() : _ptr(0) {} explicit _ptr_array_iterator(void** ptr) - : _ptr_array_iterator_base(ptr) + : _ptr(ptr) { } _ptr_array_iterator(_ptr_array_iterator::type> const& other) - : _ptr_array_iterator_base(static_cast<_ptr_array_iterator_base const&>(other)) + : _ptr(other._ptr) { } - _ptr_array_iterator& operator++() { ++_ptr; @@ -77,6 +66,9 @@ struct _ptr_array_iterator : protected _ptr_array_iterator_base { return _ptr; } +private: + template + friend struct _ptr_array_iterator; friend inline bool operator==(_ptr_array_iterator lhs, _ptr_array_iterator rhs) { return lhs._ptr == rhs._ptr; @@ -102,6 +94,190 @@ struct _ptr_array_iterator : protected _ptr_array_iterator_base { return lhs._ptr - rhs._ptr; } + + void** _ptr; +}; + +struct _ptr_array_access_traits { + +template + +struct iterator +{ + typedef _ptr_array_iterator type; +}; +template +struct const_iterator : iterator +{ +}; +template +struct native_handle +{ + typedef Eina_Array* type; +}; +template +struct const_native_handle +{ + typedef Eina_Array const* type; +}; +template +static Eina_Array* native_handle_from_const(Eina_Array const* array) +{ + return const_cast(array); +} +template +static T& back(Eina_Array* array) +{ + return *static_cast(array->data[size(array)-1]); +} +template +static T const& back(Eina_Array const* array) +{ + return _ptr_array_access_traits::back(const_cast(array)); +} +template +static T& front(Eina_Array* array) +{ + return *static_cast(array->data[0]); +} +template +static T const& front(Eina_Array const* array) +{ + return _ptr_array_access_traits::front(const_cast(array)); +} +template +static T& index(Eina_Array* array, std::size_t index) +{ + return *static_cast(array->data[index]); +} +template +static T const& index(Eina_Array const* array, std::size_t index) +{ + return _ptr_array_access_traits::index(const_cast(array), index); +} +template +static _ptr_array_iterator begin(Eina_Array* array) +{ + return _ptr_array_iterator(array->data); +} +template +static _ptr_array_iterator end(Eina_Array* array) +{ + return _ptr_array_iterator(array->data + size(array)); +} +template +static _ptr_array_iterator begin(Eina_Array const* array) +{ + return _ptr_array_access_traits::begin(const_cast(array)); +} +template +static _ptr_array_iterator end(Eina_Array const* array) +{ + return _ptr_array_access_traits::end(const_cast(array)); +} +template +static std::reverse_iterator<_ptr_array_iterator > rbegin(Eina_Array* array) +{ + return std::reverse_iterator<_ptr_array_iterator >(_ptr_array_access_traits::begin(array)); +} +template +static std::reverse_iterator<_ptr_array_iterator > rend(Eina_Array* array) +{ + return std::reverse_iterator<_ptr_array_iterator >(_ptr_array_access_traits::end(array)); +} +template +static std::reverse_iterator<_ptr_array_iterator > rbegin(Eina_Array const* array) +{ + return std::reverse_iterator<_ptr_array_iterator >(_ptr_array_access_traits::begin(const_cast(array))); +} +template +static std::reverse_iterator<_ptr_array_iterator > rend(Eina_Array const* array) +{ + return std::reverse_iterator<_ptr_array_iterator >(_ptr_array_access_traits::end(const_cast(array))); +} +template +static _ptr_array_iterator cbegin(Eina_Array const* array) +{ + return _ptr_array_access_traits::begin(array); +} +template +static _ptr_array_iterator cend(Eina_Array const* array) +{ + return _ptr_array_access_traits::end(array); +} +template +static std::reverse_iterator<_ptr_array_iterator > crbegin(Eina_Array const* array) +{ + return _ptr_array_access_traits::rbegin(array); +} +template +static std::reverse_iterator<_ptr_array_iterator > crend(Eina_Array const* array) +{ + return _ptr_array_access_traits::rend(array); +} +template +static eina::iterator ibegin(Eina_Array* array) +{ + return eina::iterator( ::eina_array_iterator_new(array) ); +} +template +static eina::iterator iend(Eina_Array* array) +{ + return eina::iterator(); +} +template +static eina::iterator ibegin(Eina_Array const* array) +{ + return eina::iterator( ::eina_array_iterator_new(array) ); +} +template +static eina::iterator iend(Eina_Array const* array) +{ + return eina::iterator(); +} +template +static eina::iterator cibegin(Eina_Array const* array) +{ + return _ptr_array_access_traits::ibegin(array); +} +template +static eina::iterator ciend(Eina_Array const* array) +{ + return _ptr_array_access_traits::iend(array); +} +template +static std::size_t size(Eina_Array const* array) +{ + return eina_array_count(array); +} +template +static bool empty(Eina_Array const* array) +{ + return size(array) == 0u; +} + +}; + +template +struct ptr_array; + +template +struct range_ptr_array : _range_template +{ + typedef _range_template _base_type; + typedef typename _base_type::value_type value_type; + + range_ptr_array(Eina_Array* array) + : _base_type(array) + {} + template + range_ptr_array(ptr_array& array) + : _base_type(array.native_handle()) + {} + value_type& operator[](std::size_t index) const + { + return _ptr_array_access_traits::index(this->native_handle(), index); + } }; template @@ -344,107 +520,101 @@ public: clear(); insert(end(), n, t); } - value_type& back() { - return *static_cast(this->_impl._array->data[size()-1]); + return _ptr_array_access_traits::back(this->_impl._array); } value_type const& back() const { - return const_cast&>(*this).back(); + return _ptr_array_access_traits::back(this->_impl._array); } value_type& front() { - return *static_cast(this->_impl._array->data[0]); + return _ptr_array_access_traits::front(this->_impl._array); } value_type const& front() const { - return const_cast&>(*this).front(); + return _ptr_array_access_traits::front(this->_impl._array); } - const_reference operator[](size_type index) const { - pointer data = static_cast - (this->_impl._array->data[index]); - return *data; + return _ptr_array_access_traits::index(this->_impl._array, index); } reference operator[](size_type index) { - return const_cast - (const_castconst&>(*this)[index]); + return _ptr_array_access_traits::index(this->_impl._array, index); } - const_iterator begin() const { - return const_iterator(this->_impl._array->data); + return _ptr_array_access_traits::begin(this->_impl._array); } const_iterator end() const { - return const_iterator(this->_impl._array->data + size()); + return _ptr_array_access_traits::end(this->_impl._array); } iterator begin() { - return iterator(this->_impl._array->data); + return _ptr_array_access_traits::begin(this->_impl._array); } iterator end() { - return iterator(this->_impl._array->data + size()); + return _ptr_array_access_traits::end(this->_impl._array); } const_reverse_iterator rbegin() const { - return const_reverse_iterator(begin()); + return _ptr_array_access_traits::rbegin(this->_impl._array); } const_reverse_iterator rend() const { - return const_reverse_iterator(end()); + return _ptr_array_access_traits::rend(this->_impl._array); } reverse_iterator rbegin() { - return reverse_iterator(begin()); + return _ptr_array_access_traits::rbegin(this->_impl._array); } reverse_iterator rend() { - return reverse_iterator(end()); + return _ptr_array_access_traits::rend(this->_impl._array); } const_iterator cbegin() const { - return begin(); + return _ptr_array_access_traits::cbegin(this->_impl._array); } const_iterator cend() const { - return end(); + return _ptr_array_access_traits::cend(this->_impl._array); } const_reverse_iterator crbegin() const { - return rbegin(); + return _ptr_array_access_traits::crbegin(this->_impl._array); } const_reverse_iterator crend() const { - return rend(); + return _ptr_array_access_traits::crend(this->_impl._array); } eina::iterator ibegin() { - return eina::iterator( ::eina_array_iterator_new(this->_impl._array) ); + return _ptr_array_access_traits::ibegin(this->_impl._array); } eina::iterator iend() { - return eina::iterator(); + return _ptr_array_access_traits::iend(this->_impl._array); } eina::iterator ibegin() const { - return eina::iterator( ::eina_array_iterator_new(this->_impl._array) ); + return _ptr_array_access_traits::ibegin(this->_impl._array); } eina::iterator iend() const { - return eina::iterator(); + return _ptr_array_access_traits::iend(this->_impl._array); } eina::iterator cibegin() const { - return ibegin(); + return _ptr_array_access_traits::cibegin(this->_impl._array); } eina::iterator ciend() const { - return iend(); + return _ptr_array_access_traits::ciend(this->_impl._array); } void swap(ptr_array& other) { diff --git a/src/bindings/eina_cxx/eina_ptrlist.hh b/src/bindings/eina_cxx/eina_ptrlist.hh index 0ae0319a1f..435077de91 100644 --- a/src/bindings/eina_cxx/eina_ptrlist.hh +++ b/src/bindings/eina_cxx/eina_ptrlist.hh @@ -29,7 +29,7 @@ protected: template struct _ptr_list_iterator : _ptr_list_iterator_base { - typedef T value_type; + typedef typename remove_cv::type value_type; typedef value_type* pointer; typedef value_type& reference; @@ -38,7 +38,7 @@ struct _ptr_list_iterator : _ptr_list_iterator_base : _ptr_list_iterator_base(list, node) { } - _ptr_list_iterator(_ptr_list_iterator::type> const& other) + _ptr_list_iterator(_ptr_list_iterator const& other) : _ptr_list_iterator_base(static_cast<_ptr_list_iterator_base const&>(other)) { } @@ -95,6 +95,308 @@ struct _ptr_list_iterator : _ptr_list_iterator_base } }; +struct _ptr_list_access_traits { + +template +struct iterator +{ + typedef _ptr_list_iterator type; +}; +template +struct const_iterator : iterator {}; +template +struct native_handle +{ + typedef Eina_List* type; +}; +template +struct const_native_handle +{ + typedef Eina_List const* type; +}; +template +static Eina_List* native_handle_from_const(Eina_List const* list) +{ + return const_cast(list); +} +template +static T& back(Eina_List* list) +{ + return *static_cast(eina_list_data_get(eina_list_last(list))); +} +template +static T const& back(Eina_List const* list) +{ + return _ptr_list_access_traits::back(const_cast(list)); +} +template +static T& front(Eina_List* list) +{ + return *static_cast(eina_list_data_get(list)); +} +template +static T const& front(Eina_List const* list) +{ + return _ptr_list_access_traits::front(const_cast(list)); +} +template +static _ptr_list_iterator begin(Eina_List* list) +{ + return _ptr_list_iterator(list, list); +} +template +static _ptr_list_iterator end(Eina_List* list) +{ + return _ptr_list_iterator(list, 0); +} +template +static _ptr_list_iterator begin(Eina_List const* list) +{ + return _ptr_list_access_traits::begin(const_cast(list)); +} +template +static _ptr_list_iterator end(Eina_List const* list) +{ + return _ptr_list_access_traits::end(const_cast(list)); +} +template +static std::reverse_iterator<_ptr_list_iterator > rbegin(Eina_List* list) +{ + return std::reverse_iterator<_ptr_list_iterator >(_ptr_list_access_traits::begin(list)); +} +template +static std::reverse_iterator<_ptr_list_iterator > rend(Eina_List* list) +{ + return std::reverse_iterator<_ptr_list_iterator >(_ptr_list_access_traits::end(list)); +} +template +static std::reverse_iterator<_ptr_list_iterator > rbegin(Eina_List const* list) +{ + return _ptr_list_access_traits::rbegin(const_cast(list)); +} +template +static std::reverse_iterator<_ptr_list_iterator > rend(Eina_List const* list) +{ + return _ptr_list_access_traits::rend(const_cast(list)); +} +template +static _ptr_list_iterator cbegin(Eina_List const* list) +{ + return _ptr_list_access_traits::begin(list); +} +template +static _ptr_list_iterator cend(Eina_List const* list) +{ + return _ptr_list_access_traits::end(list); +} +template +static std::reverse_iterator<_ptr_list_iterator > crbegin(Eina_List const* list) +{ + return _ptr_list_access_traits::rbegin(list); +} +template +static std::reverse_iterator<_ptr_list_iterator > crend(Eina_List const* list) +{ + return _ptr_list_access_traits::rend(list); +} +template +static eina::iterator ibegin(Eina_List* list) +{ + return eina::iterator( ::eina_list_iterator_new(list) ); +} +template +static eina::iterator iend(Eina_List*) +{ + return eina::iterator(); +} +template +static eina::iterator ibegin(Eina_List const* list) +{ + return eina::iterator( ::eina_list_iterator_new(list) ); +} +template +static eina::iterator iend(Eina_List const* list) +{ + return eina::iterator(); +} +template +static eina::iterator cibegin(Eina_List const* list) +{ + return _ptr_list_access_traits::ibegin(list); +} +template +static eina::iterator ciend(Eina_List const* list) +{ + return _ptr_list_access_traits::iend(list); +} +template +static std::size_t size(Eina_List const* list) +{ + return eina_list_count(list); +} +template +static bool empty(Eina_List const* list) +{ + return _ptr_list_access_traits::size(list) == 0u; +} + +}; + +template +struct _const_range_ptr_list +{ + typedef _ptr_list_iterator const_iterator; + typedef const_iterator iterator; + typedef T value_type; + typedef T& reference; + typedef T const& const_reference; + typedef T* pointer; + typedef T const* const_pointer; + typedef std::reverse_iterator const_reverse_iterator; + typedef const_reverse_iterator reverse_iterator; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + typedef Eina_List const* native_handle_type; + typedef _const_range_ptr_list _self_type; + + _const_range_ptr_list(native_handle_type list) + : _list(list) {} + + native_handle_type native_handle() const { return _list; } + value_type const& back() const + { + return _ptr_list_access_traits::back(_list); + } + value_type const& front() const + { + return _ptr_list_access_traits::front(_list); + } + const_iterator begin() const + { + return _ptr_list_access_traits::begin(_list); + } + const_iterator end() const + { + return _ptr_list_access_traits::end(_list); + } + const_reverse_iterator rbegin() const + { + return _ptr_list_access_traits::rbegin(_list); + } + const_reverse_iterator rend() const + { + return _ptr_list_access_traits::rend(_list); + } + const_iterator cbegin() const + { + return _ptr_list_access_traits::cbegin(_list); + } + const_iterator cend() const + { + return _ptr_list_access_traits::cend(_list); + } + const_reverse_iterator crbegin() const + { + return _ptr_list_access_traits::crbegin(_list); + } + const_reverse_iterator crend() const + { + return _ptr_list_access_traits::crend(_list); + } + void swap(_self_type& other) + { + std::swap(_list, other._list); + } + bool empty() const + { + return _ptr_list_access_traits::empty(_list); + } + size_type size() const + { + return _ptr_list_access_traits::size(_list); + } + + native_handle_type _list; +}; + +template +void swap(_const_range_ptr_list& lhs, _const_range_ptr_list& rhs) +{ + lhs.swap(rhs); +} + +template +struct _mutable_range_ptr_list : _const_range_ptr_list +{ + typedef _const_range_ptr_list _base_type; + typedef T value_type; + typedef _ptr_list_iterator iterator; + typedef T& reference; + typedef T* pointer; + typedef std::reverse_iterator reverse_iterator; + typedef typename _base_type::const_iterator const_iterator; + typedef typename _base_type::const_reference const_reference; + typedef typename _base_type::const_pointer const_pointer; + typedef typename _base_type::const_reverse_iterator const_reverse_iterator; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + typedef Eina_List* native_handle_type; + typedef _mutable_range_ptr_list _self_type; + + _mutable_range_ptr_list(native_handle_type list) + : _base_type(list) {} + + native_handle_type native_handle() const + { + return const_cast(_base_type::native_handle()); + } + value_type& back() const + { + return _ptr_list_access_traits::back(native_handle()); + } + value_type& front() const + { + return _ptr_list_access_traits::front(native_handle()); + } + iterator begin() const + { + return _ptr_list_access_traits::begin(native_handle()); + } + iterator end() const + { + return _ptr_list_access_traits::end(native_handle()); + } + reverse_iterator rbegin() const + { + return _ptr_list_access_traits::rbegin(native_handle()); + } + reverse_iterator rend() const + { + return _ptr_list_access_traits::rend(native_handle()); + } +}; + +template +struct ptr_list; + +template +struct range_ptr_list : _range_template +{ + typedef _range_template _base_type; + typedef typename _base_type::value_type value_type; + typedef typename _base_type::native_handle_type native_handle_type; + + range_ptr_list(native_handle_type list) + : _base_type(list) + {} + template + range_ptr_list(ptr_list& list) + : _base_type(list.native_handle()) + {} +}; + template struct _ptr_list_common_base { @@ -209,11 +511,11 @@ public: } std::size_t size() const { - return eina_list_count(this->_impl._list); + return _ptr_list_access_traits::size(this->_impl._list); } bool empty() const { - return size() == 0u; + return _ptr_list_access_traits::empty(this->_impl._list); } clone_allocator_type get_clone_allocator() const { @@ -357,95 +659,93 @@ public: clear(); insert(end(), n, t); } - value_type& back() { - return *static_cast(eina_list_data_get(eina_list_last(this->_impl._list))); + return _ptr_list_access_traits::back(this->_impl._list); } value_type const& back() const { - return const_cast&>(*this).back(); + return _ptr_list_access_traits::back(this->_impl._list); } value_type& front() { - return *static_cast(eina_list_data_get(this->_impl._list)); + return _ptr_list_access_traits::front(this->_impl._list); } value_type const& front() const { - return const_cast&>(*this).front(); + return _ptr_list_access_traits::front(this->_impl._list); } - const_iterator begin() const { - return const_iterator(this->_impl._list, this->_impl._list); + return _ptr_list_access_traits::cbegin(this->_impl._list); } const_iterator end() const { - return const_iterator(this->_impl._list, 0); + return _ptr_list_access_traits::cend(this->_impl._list); } iterator begin() { - return iterator(this->_impl._list, this->_impl._list); + return _ptr_list_access_traits::begin(this->_impl._list); } iterator end() { - return iterator(this->_impl._list, 0); + return _ptr_list_access_traits::end(this->_impl._list); } const_reverse_iterator rbegin() const { - return const_reverse_iterator(begin()); + return _ptr_list_access_traits::rbegin(this->_impl._list); } const_reverse_iterator rend() const { - return const_reverse_iterator(end()); + return _ptr_list_access_traits::rend(this->_impl._list); } reverse_iterator rbegin() { - return reverse_iterator(begin()); + return _ptr_list_access_traits::rbegin(this->_impl._list); } reverse_iterator rend() { - return reverse_iterator(end()); + return _ptr_list_access_traits::rend(this->_impl._list); } const_iterator cbegin() const { - return begin(); + return _ptr_list_access_traits::cbegin(this->_impl._list); } const_iterator cend() const { - return end(); + return _ptr_list_access_traits::cend(this->_impl._list); } const_reverse_iterator crbegin() const { - return rbegin(); + return _ptr_list_access_traits::crbegin(this->_impl._list); } const_reverse_iterator crend() const { - return rend(); + return _ptr_list_access_traits::crend(this->_impl._list); } eina::iterator ibegin() { - return eina::iterator( ::eina_list_iterator_new(this->_impl._list) ); + return _ptr_list_access_traits::ibegin(this->_impl._list); } eina::iterator iend() { - return eina::iterator(); + return _ptr_list_access_traits::iend(this->_impl._list); } eina::iterator ibegin() const { - return eina::iterator( ::eina_list_iterator_new(this->_impl._list) ); + return _ptr_list_access_traits::ibegin(this->_impl._list); } eina::iterator iend() const { - return eina::iterator(); + return _ptr_list_access_traits::iend(this->_impl._list); } eina::iterator cibegin() const { - return ibegin(); + return _ptr_list_access_traits::cibegin(this->_impl._list); } eina::iterator ciend() const { - return iend(); + return _ptr_list_access_traits::ciend(this->_impl._list); } void swap(ptr_list& other) { diff --git a/src/bindings/eina_cxx/eina_range_types.hh b/src/bindings/eina_cxx/eina_range_types.hh new file mode 100644 index 0000000000..217eef5148 --- /dev/null +++ b/src/bindings/eina_cxx/eina_range_types.hh @@ -0,0 +1,180 @@ +#ifndef EINA_RANGE_TYPES_HH_ +#define EINA_RANGE_TYPES_HH_ + +namespace efl { namespace eina { + +template +struct _const_range_template +{ + typedef typename Traits::template const_iterator::type const_iterator; + typedef typename Traits::template iterator::type iterator; + typedef T value_type; + typedef T& reference; + typedef T const& const_reference; + typedef T* pointer; + typedef T const* const_pointer; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + typedef typename Traits::template const_native_handle::type native_handle_type; + typedef _const_range_template _self_type; + + _const_range_template(native_handle_type handle) + : _handle(handle) {} + + native_handle_type native_handle() const { return _handle; } + value_type const& back() const + { + return Traits::template back(_handle); + } + value_type const& front() const + { + return Traits::template front(_handle); + } + const_iterator begin() const + { + return cbegin(); + } + const_iterator end() const + { + return cend(); + } + const_reverse_iterator crbegin() const + { + return const_reverse_iterator(Traits::template begin(_handle)); + } + const_reverse_iterator crend() const + { + return const_reverse_iterator(Traits::template rend(_handle)); + } + const_iterator cbegin() const + { + return Traits::template cbegin(_handle); + } + const_iterator cend() const + { + return Traits::template cend(_handle); + } + const_reverse_iterator rbegin() + { + return crbegin(); + } + const_reverse_iterator rend() + { + return crend(); + } + bool empty() const + { + return Traits::template empty(_handle); + } + size_type size() const + { + return Traits::template size(_handle); + } + void swap(_self_type& other) + { + std::swap(_handle, other._handle); + } +protected: + native_handle_type _handle; +}; + +template +void swap(_const_range_template& lhs, _const_range_template& rhs) +{ + lhs.swap(rhs); +} + +template +struct _mutable_range_template : _const_range_template +{ + typedef T value_type; + typedef typename Traits::template iterator::type iterator; + typedef std::reverse_iterator reverse_iterator; + typedef typename Traits::template native_handle::type native_handle_type; + typedef _const_range_template _base_type; + + _mutable_range_template(native_handle_type handle) + : _base_type(handle) {} + + native_handle_type native_handle() const + { + return Traits::template native_handle_from_const(_base_type::native_handle()); + } + value_type& back() const + { + return Traits::template back(native_handle()); + } + value_type& front() const + { + return Traits::template front(native_handle()); + } + iterator begin() const + { + return Traits::template begin(native_handle()); + } + iterator end() const + { + return Traits::template end(native_handle()); + } + reverse_iterator rbegin() const + { + return Traits::template rbegin(native_handle()); + } + reverse_iterator rend() const + { + return Traits::template rend(native_handle()); + } +protected: + using _base_type::_handle; +}; + +template +struct _range_template : private std::conditional + ::value + , _const_range_template::type, Traits> + , _mutable_range_template >::type +{ + typedef std::integral_constant::value> is_mutable; + typedef typename std::remove_const::type value_type; + typedef typename std::conditional + , _const_range_template >::type _base_type; + typedef typename Traits::template native_handle::type native_handle_type; + + typedef value_type& reference; + typedef value_type const& const_reference; + typedef value_type* pointer; + typedef value_type const* const_pointer; + typedef typename Traits::template const_iterator::type const_iterator; + typedef typename _base_type::const_reverse_iterator const_reverse_iterator; + typedef typename Traits::template iterator::type iterator; + typedef typename _base_type::reverse_iterator reverse_iterator; + typedef typename _base_type::size_type size_type; + typedef typename _base_type::difference_type difference_type; + + _range_template(native_handle_type handle) + : _base_type(handle) + {} + + using _base_type::native_handle; + using _base_type::back; + using _base_type::front; + using _base_type::begin; + using _base_type::end; + using _base_type::rbegin; + using _base_type::rend; + using _base_type::cbegin; + using _base_type::cend; + using _base_type::crbegin; + using _base_type::crend; + using _base_type::empty; + using _base_type::size; +protected: + using _base_type::_handle; +}; + +} } + +#endif diff --git a/src/tests/eina_cxx/eina_cxx_test_inarray.cc b/src/tests/eina_cxx/eina_cxx_test_inarray.cc index d2e526c45b..c0f464e036 100644 --- a/src/tests/eina_cxx/eina_cxx_test_inarray.cc +++ b/src/tests/eina_cxx/eina_cxx_test_inarray.cc @@ -15,7 +15,9 @@ START_TEST(eina_cxx_inarray_pod_push_back) efl::eina::inarray array; array.push_back(5); + std::cout << "array size: " << array.size() << std::endl; array.push_back(10); + std::cout << "array size: " << array.size() << std::endl; array.push_back(15); int result[] = {5, 10, 15}; @@ -372,6 +374,35 @@ START_TEST(eina_cxx_inarray_nonpod_erase) } END_TEST +START_TEST(eina_cxx_range_inarray) +{ + efl::eina::eina_init eina_init; + + efl::eina::inarray array; + array.push_back(5); + array.push_back(10); + array.push_back(15); + + int result[] = {5, 10, 15}; + + efl::eina::range_inarray range_array(array); + + ck_assert(range_array.size() == 3); + ck_assert(std::equal(range_array.begin(), range_array.end(), result)); + + ck_assert(range_array[0] == 5); + + *range_array.begin() = 0; + + int result1[] = {0, 10, 15}; + + ck_assert(range_array.size() == 3); + ck_assert(std::equal(range_array.begin(), range_array.end(), result1)); + + ck_assert(range_array[0] == 0); +} +END_TEST + void eina_test_inarray(TCase *tc) { @@ -385,4 +416,5 @@ eina_test_inarray(TCase *tc) tcase_add_test(tc, eina_cxx_inarray_nonpod_insert); tcase_add_test(tc, eina_cxx_inarray_nonpod_erase); tcase_add_test(tc, eina_cxx_inarray_nonpod_constructors); + tcase_add_test(tc, eina_cxx_range_inarray); } diff --git a/src/tests/eina_cxx/eina_cxx_test_inlist.cc b/src/tests/eina_cxx/eina_cxx_test_inlist.cc index 09934f3f04..e33a783f2f 100644 --- a/src/tests/eina_cxx/eina_cxx_test_inlist.cc +++ b/src/tests/eina_cxx/eina_cxx_test_inlist.cc @@ -199,6 +199,36 @@ START_TEST(eina_cxx_inlist_erase) } END_TEST +START_TEST(eina_cxx_inlist_range) +{ + efl::eina::eina_init eina_init; + + efl::eina::inlist list; + list.push_back(5); + list.push_back(10); + list.push_back(15); + list.push_back(20); + list.push_back(25); + list.push_back(30); + + efl::eina::range_inlist range_list(list); + + ck_assert(range_list.size() == 6u); + + int result[] = {5, 10, 15, 20, 25, 30}; + ck_assert(std::equal(range_list.begin(), range_list.end(), result)); + + efl::eina::range_inlist const_range_list(list); + + ck_assert(const_range_list.size() == 6u); + ck_assert(std::equal(range_list.begin(), range_list.end(), result)); + + *range_list.begin() = 0; + ck_assert(*const_range_list.begin() == 0); + ck_assert(*list.begin() == 0); +} +END_TEST + void eina_test_inlist(TCase *tc) { @@ -209,4 +239,5 @@ eina_test_inlist(TCase *tc) tcase_add_test(tc, eina_cxx_inlist_insert); tcase_add_test(tc, eina_cxx_inlist_erase); tcase_add_test(tc, eina_cxx_inlist_constructors); + tcase_add_test(tc, eina_cxx_inlist_range); } diff --git a/src/tests/eina_cxx/eina_cxx_test_ptrarray.cc b/src/tests/eina_cxx/eina_cxx_test_ptrarray.cc index 4e9a13b933..5b4ae40705 100644 --- a/src/tests/eina_cxx/eina_cxx_test_ptrarray.cc +++ b/src/tests/eina_cxx/eina_cxx_test_ptrarray.cc @@ -169,6 +169,36 @@ START_TEST(eina_cxx_ptrarray_erase) } END_TEST +START_TEST(eina_cxx_ptrarray_range) +{ + efl::eina::eina_init eina_init; + + efl::eina::ptr_array array; + array.push_back(new int(5)); + array.push_back(new int(10)); + array.push_back(new int(15)); + array.push_back(new int(20)); + array.push_back(new int(25)); + array.push_back(new int(30)); + + efl::eina::range_ptr_array range_array(array); + + ck_assert(range_array.size() == 6u); + + int result[] = {5, 10, 15, 20, 25, 30}; + ck_assert(std::equal(range_array.begin(), range_array.end(), result)); + + efl::eina::range_ptr_array const_range_array(array); + + ck_assert(const_range_array.size() == 6u); + ck_assert(std::equal(range_array.begin(), range_array.end(), result)); + + *range_array.begin() = 0; + ck_assert(*const_range_array.begin() == 0); + ck_assert(*array.begin() == 0); +} +END_TEST + void eina_test_ptrarray(TCase* tc) { @@ -177,4 +207,5 @@ eina_test_ptrarray(TCase* tc) tcase_add_test(tc, eina_cxx_ptrarray_insert); tcase_add_test(tc, eina_cxx_ptrarray_constructors); tcase_add_test(tc, eina_cxx_ptrarray_erase); + tcase_add_test(tc, eina_cxx_ptrarray_range); } diff --git a/src/tests/eina_cxx/eina_cxx_test_ptrlist.cc b/src/tests/eina_cxx/eina_cxx_test_ptrlist.cc index c95adc3b21..dbded3ac46 100644 --- a/src/tests/eina_cxx/eina_cxx_test_ptrlist.cc +++ b/src/tests/eina_cxx/eina_cxx_test_ptrlist.cc @@ -199,6 +199,36 @@ START_TEST(eina_cxx_ptrlist_erase) } END_TEST +START_TEST(eina_cxx_ptrlist_range) +{ + efl::eina::eina_init eina_init; + + efl::eina::ptr_list list; + list.push_back(new int(5)); + list.push_back(new int(10)); + list.push_back(new int(15)); + list.push_back(new int(20)); + list.push_back(new int(25)); + list.push_back(new int(30)); + + efl::eina::range_ptr_list range_list(list); + + ck_assert(range_list.size() == 6u); + + int result[] = {5, 10, 15, 20, 25, 30}; + ck_assert(std::equal(range_list.begin(), range_list.end(), result)); + + efl::eina::range_ptr_list const_range_list(list); + + ck_assert(const_range_list.size() == 6u); + ck_assert(std::equal(range_list.begin(), range_list.end(), result)); + + *range_list.begin() = 0; + ck_assert(*const_range_list.begin() == 0); + ck_assert(*list.begin() == 0); +} +END_TEST + void eina_test_ptrlist(TCase* tc) { @@ -209,4 +239,5 @@ eina_test_ptrlist(TCase* tc) tcase_add_test(tc, eina_cxx_ptrlist_insert); tcase_add_test(tc, eina_cxx_ptrlist_constructors); tcase_add_test(tc, eina_cxx_ptrlist_erase); + tcase_add_test(tc, eina_cxx_ptrlist_range); }