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<int const> and the mutable doesn't have the const, so: range_ptr_list<int>.

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
This commit is contained in:
Felipe Magno de Almeida 2014-03-10 12:24:29 +09:00 committed by Cedric BAIL
parent 6bd0392339
commit 5942207b25
9 changed files with 1252 additions and 138 deletions

View File

@ -3,6 +3,7 @@
#include <Eina.h> #include <Eina.h>
#include <eina_type_traits.hh> #include <eina_type_traits.hh>
#include <eina_range_types.hh>
#include <iterator> #include <iterator>
#include <cstring> #include <cstring>
@ -10,10 +11,170 @@
namespace efl { namespace eina { namespace efl { namespace eina {
struct _inarray_access_traits {
template <typename T>
struct const_iterator
{
typedef T const* type;
};
template <typename T>
struct iterator
{
typedef T* type;
};
template <typename T>
struct const_native_handle
{
typedef Eina_Inarray const* type;
};
template <typename T>
struct native_handle
{
typedef Eina_Inarray* type;
};
template <typename T>
static Eina_Inarray* native_handle_from_const(Eina_Inarray const* array)
{
return const_cast<Eina_Inarray*>(array);
}
template <typename T>
static T& back(Eina_Inarray* raw)
{
assert(!_inarray_access_traits::empty<T>(raw));
return *static_cast<T*>( ::eina_inarray_nth(raw, _inarray_access_traits::size<T>(raw)-1u));
}
template <typename T>
static T const& back(Eina_Inarray const* raw)
{
return _inarray_access_traits::back<T>(const_cast<Eina_Inarray*>(raw));
}
template <typename T>
static T& front(Eina_Inarray* raw)
{
assert(!empty<T>(raw));
return *static_cast<T*>( ::eina_inarray_nth(raw, 0u));
}
template <typename T>
static T const& front(Eina_Inarray const* raw)
{
return _inarray_access_traits::front<T>(const_cast<Eina_Inarray*>(raw));
}
template <typename T>
static T* begin(Eina_Inarray* raw)
{
return !raw->members ? 0 : static_cast<T*>( ::eina_inarray_nth(raw, 0u));
}
template <typename T>
static T* end(Eina_Inarray* raw)
{
return !raw->members ? 0
: static_cast<T*>( ::eina_inarray_nth(raw, _inarray_access_traits::size<T>(raw) -1)) + 1;
}
template <typename T>
static T const* begin(Eina_Inarray const* raw)
{
return _inarray_access_traits::begin<T>(const_cast<Eina_Inarray*>(raw));
}
template <typename T>
static T const* end(Eina_Inarray const* raw)
{
return _inarray_access_traits::end<T>(const_cast<Eina_Inarray*>(raw));
}
template <typename T>
static std::reverse_iterator<T const*> rbegin(Eina_Inarray const* raw)
{
return std::reverse_iterator<T const*>(_inarray_access_traits::begin<T>(raw));
}
template <typename T>
static std::reverse_iterator<T const*> rend(Eina_Inarray const* raw)
{
return std::reverse_iterator<T const*>(_inarray_access_traits::end<T>(raw));
}
template <typename T>
static std::reverse_iterator<T*> rbegin(Eina_Inarray* raw)
{
return std::reverse_iterator<T*>(_inarray_access_traits::begin<T>(raw));
}
template <typename T>
static std::reverse_iterator<T*> rend(Eina_Inarray* raw)
{
return std::reverse_iterator<T*>(_inarray_access_traits::end<T>(raw));
}
template <typename T>
static T const* cbegin(Eina_Inarray const* raw)
{
return _inarray_access_traits::begin<T>(raw);
}
template <typename T>
static T const* cend(Eina_Inarray const* raw)
{
return _inarray_access_traits::end<T>(raw);
}
template <typename T>
static std::reverse_iterator<T const*> crbegin(Eina_Inarray const* raw)
{
return _inarray_access_traits::rbegin<T const*>(raw);
}
template <typename T>
static std::reverse_iterator<T const*> crend(Eina_Inarray const* raw)
{
return _inarray_access_traits::rend<T const*>(raw);
}
template <typename T>
static inline bool empty(Eina_Inarray const* raw)
{
return _inarray_access_traits::size<T>(raw) == 0;
}
template <typename T>
static inline std::size_t size(Eina_Inarray const* raw)
{
return ::eina_inarray_count(raw);
}
template <typename T>
static T const& index(Eina_Inarray const* raw, std::size_t i)
{
return *(_inarray_access_traits::begin<T>(raw) + i);
}
template <typename T>
static T& index(Eina_Inarray* raw, std::size_t i)
{
return *(_inarray_access_traits::begin<T>(raw) + i);
}
};
template <typename T>
struct inarray;
template <typename T>
struct range_inarray : _range_template<T, _inarray_access_traits>
{
typedef _range_template<T, _inarray_access_traits> _base_type;
typedef typename std::remove_const<T>::type value_type;
range_inarray(Eina_Inarray* array)
: _base_type(array)
{}
range_inarray(inarray<T>& array)
: _base_type(array.native_handle())
{}
value_type& operator[](std::size_t index) const
{
return _inarray_access_traits::index<T>(this->native_handle(), index);
}
};
struct _inarray_common_base struct _inarray_common_base
{ {
typedef std::size_t size_type; 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) explicit _inarray_common_base(size_type member_size)
: _array( ::eina_inarray_new(member_size, 0) ) : _array( ::eina_inarray_new(member_size, 0) )
{ {
@ -25,12 +186,14 @@ struct _inarray_common_base
size_type size() const size_type size() const
{ {
return ::eina_inarray_count(_array); return _inarray_access_traits::size<void>(_array);
} }
bool empty() const bool empty() const
{ {
return size() == 0u; return _inarray_access_traits::empty<void>(_array);
} }
native_handle_type native_handle() { return _array; }
const_native_handle_type native_handle() const { return _array; }
Eina_Inarray* _array; Eina_Inarray* _array;
private: private:
@ -52,13 +215,18 @@ public:
typedef const_pointer const_iterator; typedef const_pointer const_iterator;
typedef std::size_t size_type; typedef std::size_t size_type;
typedef std::ptrdiff_t difference_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<iterator> reverse_iterator; typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
using _base_type::size; using _base_type::size;
using _base_type::empty; using _base_type::empty;
using _base_type::native_handle;
_pod_inarray(Eina_Inarray* array)
: _base_type(array) {}
_pod_inarray() : _base_type(sizeof(T)) _pod_inarray() : _base_type(sizeof(T))
{ {
} }
@ -98,7 +266,10 @@ public:
} }
void push_back(T const& value) void push_back(T const& value)
{ {
size_type s = size();
eina_inarray_push(_array, &value); eina_inarray_push(_array, &value);
assert(size() != s);
assert(size() == s + 1u);
} }
void pop_back() void pop_back()
{ {
@ -166,71 +337,77 @@ public:
void assign(InputIterator i, InputIterator j void assign(InputIterator i, InputIterator j
, typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0); , typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0);
void assign(size_type n, value_type const& t); 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<inarray<T>&>(*this)[i];
}
value_type& back() value_type& back()
{ {
assert(!empty()); return _inarray_access_traits::back<value_type>(_array);
return *static_cast<value_type*>(eina_inarray_nth(_array, size()-1u));
} }
value_type const& back() const value_type const& back() const
{ {
return const_cast<_pod_inarray<T>&>(*this).back(); return _inarray_access_traits::back<value_type>(_array);
} }
value_type& front() value_type& front()
{ {
assert(!empty()); return _inarray_access_traits::front<value_type>(_array);
return *static_cast<value_type*>(eina_inarray_nth(_array, 0u));
} }
value_type const& front() const value_type const& front() const
{ {
return const_cast<_pod_inarray<T>&>(*this).front(); return _inarray_access_traits::front<value_type>(_array);
} }
iterator begin() iterator begin()
{ {
return !_array->members ? 0 : static_cast<iterator>(::eina_inarray_nth(_array, 0u)); return _inarray_access_traits::begin<value_type>(_array);
} }
iterator end() iterator end()
{ {
return !_array->members ? 0 : static_cast<iterator>(::eina_inarray_nth(_array, size()-1)) + 1; return _inarray_access_traits::end<value_type>(_array);
} }
const_iterator begin() const const_iterator begin() const
{ {
return const_cast< _pod_inarray<T>&>(*this).begin(); return _inarray_access_traits::begin<value_type>(_array);
} }
const_iterator end() const const_iterator end() const
{ {
return const_cast< _pod_inarray<T>&>(*this).end(); return _inarray_access_traits::end<value_type>(_array);
} }
const_reverse_iterator rbegin() const const_reverse_iterator rbegin() const
{ {
return const_reverse_iterator(begin()); return _inarray_access_traits::rbegin<value_type>(_array);
} }
const_reverse_iterator rend() const const_reverse_iterator rend() const
{ {
return const_reverse_iterator(end()); return _inarray_access_traits::rend<value_type>(_array);
} }
reverse_iterator rbegin() reverse_iterator rbegin()
{ {
return reverse_iterator(begin()); return _inarray_access_traits::rbegin<value_type>(_array);
} }
reverse_iterator rend() reverse_iterator rend()
{ {
return reverse_iterator(end()); return _inarray_access_traits::rend<value_type>(_array);
} }
const_iterator cbegin() const const_iterator cbegin() const
{ {
return begin(); return _inarray_access_traits::cbegin<value_type>(_array);
} }
const_iterator cend() const const_iterator cend() const
{ {
return end(); return _inarray_access_traits::cend<value_type>(_array);
} }
const_reverse_iterator crbegin() const const_reverse_iterator crbegin() const
{ {
return rbegin(); return _inarray_access_traits::crbegin<value_type>(_array);
} }
const_reverse_iterator crend() const const_reverse_iterator crend() const
{ {
return rend(); return _inarray_access_traits::crend<value_type>(_array);
} }
void swap(_pod_inarray<T>& other) void swap(_pod_inarray<T>& other)
{ {
@ -269,6 +446,8 @@ public:
using _base_type::size; using _base_type::size;
using _base_type::empty; using _base_type::empty;
_nonpod_inarray(Eina_Inarray* array)
: _base_type(array) {}
_nonpod_inarray() : _base_type(sizeof(T)) _nonpod_inarray() : _base_type(sizeof(T))
{ {
} }
@ -419,71 +598,77 @@ public:
void assign(InputIterator i, InputIterator j void assign(InputIterator i, InputIterator j
, typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0); , typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0);
void assign(size_type n, value_type const& t); 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<inarray<T>&>(*this)[i];
}
value_type& back() value_type& back()
{ {
assert(!empty()); return _inarray_access_traits::back<value_type>(_array);
return *static_cast<value_type*>(eina_inarray_nth(_array, size()-1u));
} }
value_type const& back() const value_type const& back() const
{ {
return const_cast<_nonpod_inarray<T>&>(*this).back(); return _inarray_access_traits::back<value_type>(_array);
} }
value_type& front() value_type& front()
{ {
assert(!empty()); return _inarray_access_traits::front<value_type>(_array);
return *static_cast<value_type*>(eina_inarray_nth(_array, 0u));
} }
value_type const& front() const value_type const& front() const
{ {
return const_cast<_nonpod_inarray<T>&>(*this).front(); return _inarray_access_traits::front<value_type>(_array);
} }
iterator begin() iterator begin()
{ {
return static_cast<iterator>(_array->members); return _inarray_access_traits::begin<value_type>(_array);
} }
iterator end() iterator end()
{ {
return static_cast<iterator>(_array->members) + _array->len; return _inarray_access_traits::end<value_type>(_array);
} }
const_iterator begin() const const_iterator begin() const
{ {
return const_cast< _nonpod_inarray<T>&>(*this).begin(); return _inarray_access_traits::begin<value_type>(_array);
} }
const_iterator end() const const_iterator end() const
{ {
return const_cast< _nonpod_inarray<T>&>(*this).end(); return _inarray_access_traits::end<value_type>(_array);
} }
const_reverse_iterator rbegin() const const_reverse_iterator rbegin() const
{ {
return const_reverse_iterator(begin()); return _inarray_access_traits::rbegin<value_type>(_array);
} }
const_reverse_iterator rend() const const_reverse_iterator rend() const
{ {
return const_reverse_iterator(end()); return _inarray_access_traits::rend<value_type>(_array);
} }
reverse_iterator rbegin() reverse_iterator rbegin()
{ {
return reverse_iterator(begin()); return _inarray_access_traits::rbegin<value_type>(_array);
} }
reverse_iterator rend() reverse_iterator rend()
{ {
return reverse_iterator(end()); return _inarray_access_traits::rend<value_type>(_array);
} }
const_iterator cbegin() const const_iterator cbegin() const
{ {
return begin(); return _inarray_access_traits::cbegin<value_type>(_array);
} }
const_iterator cend() const const_iterator cend() const
{ {
return end(); return _inarray_access_traits::cend<value_type>(_array);
} }
const_reverse_iterator crbegin() const const_reverse_iterator crbegin() const
{ {
return rbegin(); return _inarray_access_traits::crbegin<value_type>(_array);
} }
const_reverse_iterator crend() const const_reverse_iterator crend() const
{ {
return rend(); return _inarray_access_traits::crend<value_type>(_array);
} }
void swap(_nonpod_inarray<T>& other) void swap(_nonpod_inarray<T>& other)
{ {
@ -508,6 +693,8 @@ class inarray : public eina::if_<eina::is_pod<T>, _pod_inarray<T>
typedef typename eina::if_<eina::is_pod<T>, _pod_inarray<T> typedef typename eina::if_<eina::is_pod<T>, _pod_inarray<T>
, _nonpod_inarray<T> >::type _base_type; , _nonpod_inarray<T> >::type _base_type;
public: public:
inarray(Eina_Inarray* array)
: _base_type(array) {}
inarray() : _base_type() {} inarray() : _base_type() {}
inarray(typename _base_type::size_type n, typename _base_type::value_type const& t) inarray(typename _base_type::size_type n, typename _base_type::value_type const& t)
: _base_type(n, t) {} : _base_type(n, t) {}
@ -539,7 +726,6 @@ void swap(inarray<T>& lhs, inarray<T>& rhs)
} }
} } } }
#endif #endif

View File

@ -5,8 +5,10 @@
#include <eina_lists_auxiliary.hh> #include <eina_lists_auxiliary.hh>
#include <eina_type_traits.hh> #include <eina_type_traits.hh>
#include <eina_accessor.hh> #include <eina_accessor.hh>
#include <eina_range_types.hh>
#include <iterator> #include <iterator>
#include <algorithm>
namespace efl { namespace eina { namespace efl { namespace eina {
@ -47,19 +49,21 @@ Eina_Inlist const* _get_list(_inlist_node<T> const* n)
template <typename T> template <typename T>
struct _inlist_iterator struct _inlist_iterator
{ {
typedef T value_type; typedef typename std::remove_const<T>::type value_type;
typedef T* pointer; typedef value_type* pointer;
typedef T& reference; typedef value_type& reference;
typedef std::ptrdiff_t difference_type; typedef std::ptrdiff_t difference_type;
typedef std::bidirectional_iterator_tag iterator_category; typedef std::bidirectional_iterator_tag iterator_category;
_inlist_iterator() {} _inlist_iterator() {}
explicit _inlist_iterator(_inlist_node<T>* list, _inlist_node<T>* node) explicit _inlist_iterator(_inlist_node<value_type>* list, _inlist_node<value_type>* node)
: _list(list), _node(node) {} : _list(list), _node(node) {}
_inlist_iterator(_inlist_iterator<typename std::remove_const<T>::type> const& other)
: _list(other._list), _node(other._node) {}
_inlist_iterator<T>& operator++() _inlist_iterator<T>& operator++()
{ {
_node = _get_node<T>(_node->__in_list.next); _node = _get_node<value_type>(_node->__in_list.next);
return *this; return *this;
} }
_inlist_iterator<T> operator++(int) _inlist_iterator<T> operator++(int)
@ -71,9 +75,9 @@ struct _inlist_iterator
_inlist_iterator<T>& operator--() _inlist_iterator<T>& operator--()
{ {
if(_node) if(_node)
_node = _get_node<T>(_node->__in_list.prev); _node = _get_node<value_type>(_node->__in_list.prev);
else else
_node = _get_node<T>(_list->__in_list.last); _node = _get_node<value_type>(_list->__in_list.last);
return *this; return *this;
} }
_inlist_iterator<T> operator--(int) _inlist_iterator<T> operator--(int)
@ -82,26 +86,28 @@ struct _inlist_iterator
--*this; --*this;
return tmp; return tmp;
} }
T const& operator*() const T& operator*() const
{ {
return _node->object; return _node->object;
} }
T const* operator->() const T* operator->() const
{ {
return &_node->object; return &_node->object;
} }
_inlist_node<T>* native_handle() _inlist_node<value_type>* native_handle()
{ {
return _node; return _node;
} }
_inlist_node<T> const* native_handle() const _inlist_node<value_type> const* native_handle() const
{ {
return _node; return _node;
} }
private: private:
_inlist_node<T>* _list; _inlist_node<value_type>* _list;
_inlist_node<T>* _node; _inlist_node<value_type>* _node;
template <typename U>
friend struct _inlist_iterator;
friend bool operator==(_inlist_iterator<T> lhs, _inlist_iterator<T> rhs) friend bool operator==(_inlist_iterator<T> lhs, _inlist_iterator<T> rhs)
{ {
return lhs._node == rhs._node; return lhs._node == rhs._node;
@ -114,6 +120,154 @@ bool operator!=(_inlist_iterator<T> lhs, _inlist_iterator<T> rhs)
return !(lhs == rhs); return !(lhs == rhs);
} }
struct _inlist_access_traits {
template <typename T>
struct const_iterator
{
typedef _inlist_iterator<T const> type;
};
template <typename T>
struct iterator
{
typedef _inlist_iterator<T> type;
};
template <typename T>
struct const_native_handle
{
typedef Eina_Inlist const* type;
};
template <typename T>
struct native_handle
{
typedef Eina_Inlist* type;
};
template <typename T>
static Eina_Inlist* native_handle_from_const(Eina_Inlist const* list)
{
return const_cast<Eina_Inlist*>(list);
}
template <typename T>
static std::size_t size(Eina_Inlist const* list)
{
return ::eina_inlist_count(list);
}
template <typename T>
static bool empty(Eina_Inlist const* list)
{
return list == 0;
}
template <typename T>
static T& back(Eina_Inlist* list)
{
return _get_node<T>(list->last)->object;
}
template <typename T>
static T const& back(Eina_Inlist const* list)
{
return _inlist_access_traits::back<T>(const_cast<Eina_Inlist*>(list));
}
template <typename T>
static T& front(Eina_Inlist* list)
{
return _get_node<T>(list)->object;
}
template <typename T>
static T const& front(Eina_Inlist const* list)
{
return _inlist_access_traits::front<T>(const_cast<Eina_Inlist*>(list));
}
template <typename T>
static _inlist_iterator<T const> begin(Eina_Inlist const* list)
{
return _inlist_access_traits::begin<T>(const_cast<Eina_Inlist*>(list));
}
template <typename T>
static _inlist_iterator<T const> end(Eina_Inlist const* list)
{
return _inlist_access_traits::end<T>(const_cast<Eina_Inlist*>(list));
}
template <typename T>
static _inlist_iterator<T> begin(Eina_Inlist* list)
{
return _inlist_iterator<T>(_get_node<T>(list), _get_node<T>(list));
}
template <typename T>
static _inlist_iterator<T> end(Eina_Inlist* list)
{
return _inlist_iterator<T>(_get_node<T>(list), 0);
}
template <typename T>
static std::reverse_iterator<_inlist_iterator<T> > rbegin(Eina_Inlist* list)
{
return std::reverse_iterator<_inlist_iterator<T> >(_inlist_access_traits::begin<T>(list));
}
template <typename T>
static std::reverse_iterator<_inlist_iterator<T> > rend(Eina_Inlist* list)
{
return std::reverse_iterator<_inlist_iterator<T> >(_inlist_access_traits::end<T>(list));
}
template <typename T>
static std::reverse_iterator<_inlist_iterator<T const> > rbegin(Eina_Inlist const* list)
{
return _inlist_access_traits::rbegin<T>(const_cast<Eina_Inlist*>(list));
}
template <typename T>
static std::reverse_iterator<_inlist_iterator<T const> > rend(Eina_Inlist const* list)
{
return _inlist_access_traits::rend<T>(const_cast<Eina_Inlist*>(list));
}
template <typename T>
static _inlist_iterator<T const> cbegin(Eina_Inlist const* list)
{
return _inlist_access_traits::begin<T>(list);
}
template <typename T>
static _inlist_iterator<T const> cend(Eina_Inlist const* list)
{
return _inlist_access_traits::end<T>(list);
}
template <typename T>
static std::reverse_iterator<_inlist_iterator<T const> > crbegin(Eina_Inlist const* list)
{
return _inlist_access_traits::rbegin<T>(list);
}
template <typename T>
static std::reverse_iterator<_inlist_iterator<T const> > crend(Eina_Inlist const* list)
{
return _inlist_access_traits::rend<T>(list);
}
};
template <typename T, typename Allocator>
struct inlist;
template <typename T>
struct range_inlist : _range_template<T, _inlist_access_traits>
{
typedef _range_template<T, _inlist_access_traits> _base_type;
typedef typename _base_type::value_type value_type;
range_inlist(Eina_Inlist* list)
: _base_type(list) {}
template <typename Allocator>
range_inlist(inlist<value_type, Allocator>& list)
: _base_type(list.native_handle())
{}
};
template <typename T>
bool operator==(range_inlist<T>const& lhs, range_inlist<T>const& rhs)
{
return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin());
}
template <typename U>
bool operator!=(range_inlist<U> const& lhs, range_inlist<U>const& rhs)
{
return !(lhs == rhs);
}
template <typename T, typename Allocator> template <typename T, typename Allocator>
struct _inlist_common_base struct _inlist_common_base
{ {
@ -221,11 +375,11 @@ public:
} }
size_type size() const size_type size() const
{ {
return ::eina_inlist_count(this->_impl._list); return _inlist_access_traits::size<T>(native_handle());
} }
bool empty() const bool empty() const
{ {
return this->_impl._list == 0; return _inlist_access_traits::empty<T>(native_handle());
} }
allocator_type get_allocator() const allocator_type get_allocator() const
{ {
@ -351,42 +505,41 @@ public:
clear(); clear();
insert(end(), n, t); insert(end(), n, t);
} }
value_type& back() value_type& back()
{ {
return _get_node<T>(this->_impl._list->last)->object; return _inlist_access_traits::back<T>(native_handle());
} }
value_type const& back() const value_type const& back() const
{ {
return const_cast<inlist<T, Allocator>&>(*this).back(); return _inlist_access_traits::back<T>(native_handle());
} }
value_type& front() value_type& front()
{ {
return _get_node<T>(this->_impl._list)->object; return _inlist_access_traits::front<T>(native_handle());
} }
value_type const& front() const value_type const& front() const
{ {
return const_cast<inlist<T, Allocator>&>(*this).front(); return _inlist_access_traits::front<T>(native_handle());
} }
const_iterator begin() const const_iterator begin() const
{ {
return const_iterator(_get_node<T const>(this->_impl._list), _get_node<T const>(this->_impl._list)); return _inlist_access_traits::begin<T>(native_handle());
} }
const_iterator end() const const_iterator end() const
{ {
return const_iterator(_get_node<T const>(this->_impl._list), 0); return _inlist_access_traits::end<T>(native_handle());
} }
iterator begin() iterator begin()
{ {
return iterator(_get_node<T>(this->_impl._list), _get_node<T>(this->_impl._list)); return _inlist_access_traits::begin<T>(native_handle());
} }
iterator end() iterator end()
{ {
return iterator(_get_node<T>(this->_impl._list), 0); return _inlist_access_traits::end<T>(native_handle());
} }
const_reverse_iterator rbegin() const const_reverse_iterator rbegin() const
{ {
return const_reverse_iterator(begin()); return _inlist_access_traits::end<T>(this->_impl._list);
} }
const_reverse_iterator rend() const const_reverse_iterator rend() const
{ {

View File

@ -3,8 +3,8 @@
#include <Eina.h> #include <Eina.h>
#include <eina_clone_allocators.hh> #include <eina_clone_allocators.hh>
#include <eina_lists_auxiliary.hh>
#include <eina_type_traits.hh> #include <eina_type_traits.hh>
#include <eina_range_types.hh>
#include <memory> #include <memory>
#include <iterator> #include <iterator>
@ -13,18 +13,8 @@
namespace efl { namespace eina { 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 <typename T> template <typename T>
struct _ptr_array_iterator : protected _ptr_array_iterator_base struct _ptr_array_iterator
{ {
typedef T value_type; typedef T value_type;
typedef value_type* pointer; 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::ptrdiff_t difference_type;
typedef std::bidirectional_iterator_tag iterator_category; typedef std::bidirectional_iterator_tag iterator_category;
_ptr_array_iterator() {} _ptr_array_iterator() : _ptr(0) {}
explicit _ptr_array_iterator(void** ptr) explicit _ptr_array_iterator(void** ptr)
: _ptr_array_iterator_base(ptr) : _ptr(ptr)
{ {
} }
_ptr_array_iterator(_ptr_array_iterator<typename remove_cv<value_type>::type> const& other) _ptr_array_iterator(_ptr_array_iterator<typename remove_cv<value_type>::type> const& other)
: _ptr_array_iterator_base(static_cast<_ptr_array_iterator_base const&>(other)) : _ptr(other._ptr)
{ {
} }
_ptr_array_iterator<T>& operator++() _ptr_array_iterator<T>& operator++()
{ {
++_ptr; ++_ptr;
@ -77,6 +66,9 @@ struct _ptr_array_iterator : protected _ptr_array_iterator_base
{ {
return _ptr; return _ptr;
} }
private:
template <typename U>
friend struct _ptr_array_iterator;
friend inline bool operator==(_ptr_array_iterator<T> lhs, _ptr_array_iterator<T> rhs) friend inline bool operator==(_ptr_array_iterator<T> lhs, _ptr_array_iterator<T> rhs)
{ {
return lhs._ptr == rhs._ptr; return lhs._ptr == rhs._ptr;
@ -102,6 +94,190 @@ struct _ptr_array_iterator : protected _ptr_array_iterator_base
{ {
return lhs._ptr - rhs._ptr; return lhs._ptr - rhs._ptr;
} }
void** _ptr;
};
struct _ptr_array_access_traits {
template <typename T>
struct iterator
{
typedef _ptr_array_iterator<T> type;
};
template <typename T>
struct const_iterator : iterator<T const>
{
};
template <typename T>
struct native_handle
{
typedef Eina_Array* type;
};
template <typename T>
struct const_native_handle
{
typedef Eina_Array const* type;
};
template <typename T>
static Eina_Array* native_handle_from_const(Eina_Array const* array)
{
return const_cast<Eina_Array*>(array);
}
template <typename T>
static T& back(Eina_Array* array)
{
return *static_cast<T*>(array->data[size<T>(array)-1]);
}
template <typename T>
static T const& back(Eina_Array const* array)
{
return _ptr_array_access_traits::back<T>(const_cast<Eina_Array*>(array));
}
template <typename T>
static T& front(Eina_Array* array)
{
return *static_cast<T*>(array->data[0]);
}
template <typename T>
static T const& front(Eina_Array const* array)
{
return _ptr_array_access_traits::front<T>(const_cast<Eina_Array*>(array));
}
template <typename T>
static T& index(Eina_Array* array, std::size_t index)
{
return *static_cast<T*>(array->data[index]);
}
template <typename T>
static T const& index(Eina_Array const* array, std::size_t index)
{
return _ptr_array_access_traits::index<T>(const_cast<Eina_Array*>(array), index);
}
template <typename T>
static _ptr_array_iterator<T> begin(Eina_Array* array)
{
return _ptr_array_iterator<T>(array->data);
}
template <typename T>
static _ptr_array_iterator<T> end(Eina_Array* array)
{
return _ptr_array_iterator<T>(array->data + size<T>(array));
}
template <typename T>
static _ptr_array_iterator<T> begin(Eina_Array const* array)
{
return _ptr_array_access_traits::begin<T>(const_cast<Eina_Array*>(array));
}
template <typename T>
static _ptr_array_iterator<T> end(Eina_Array const* array)
{
return _ptr_array_access_traits::end<T>(const_cast<Eina_Array*>(array));
}
template <typename T>
static std::reverse_iterator<_ptr_array_iterator<T> > rbegin(Eina_Array* array)
{
return std::reverse_iterator<_ptr_array_iterator<T> >(_ptr_array_access_traits::begin<T>(array));
}
template <typename T>
static std::reverse_iterator<_ptr_array_iterator<T> > rend(Eina_Array* array)
{
return std::reverse_iterator<_ptr_array_iterator<T> >(_ptr_array_access_traits::end<T>(array));
}
template <typename T>
static std::reverse_iterator<_ptr_array_iterator<T const> > rbegin(Eina_Array const* array)
{
return std::reverse_iterator<_ptr_array_iterator<T const> >(_ptr_array_access_traits::begin<T>(const_cast<Eina_Array*>(array)));
}
template <typename T>
static std::reverse_iterator<_ptr_array_iterator<T const> > rend(Eina_Array const* array)
{
return std::reverse_iterator<_ptr_array_iterator<T const> >(_ptr_array_access_traits::end<T>(const_cast<Eina_Array*>(array)));
}
template <typename T>
static _ptr_array_iterator<T const> cbegin(Eina_Array const* array)
{
return _ptr_array_access_traits::begin<T>(array);
}
template <typename T>
static _ptr_array_iterator<T const> cend(Eina_Array const* array)
{
return _ptr_array_access_traits::end<T>(array);
}
template <typename T>
static std::reverse_iterator<_ptr_array_iterator<T const> > crbegin(Eina_Array const* array)
{
return _ptr_array_access_traits::rbegin<T>(array);
}
template <typename T>
static std::reverse_iterator<_ptr_array_iterator<T const> > crend(Eina_Array const* array)
{
return _ptr_array_access_traits::rend<T>(array);
}
template <typename T>
static eina::iterator<T> ibegin(Eina_Array* array)
{
return eina::iterator<T>( ::eina_array_iterator_new(array) );
}
template <typename T>
static eina::iterator<T> iend(Eina_Array* array)
{
return eina::iterator<T>();
}
template <typename T>
static eina::iterator<T const> ibegin(Eina_Array const* array)
{
return eina::iterator<T const>( ::eina_array_iterator_new(array) );
}
template <typename T>
static eina::iterator<T const> iend(Eina_Array const* array)
{
return eina::iterator<T const>();
}
template <typename T>
static eina::iterator<T const> cibegin(Eina_Array const* array)
{
return _ptr_array_access_traits::ibegin<T>(array);
}
template <typename T>
static eina::iterator<T const> ciend(Eina_Array const* array)
{
return _ptr_array_access_traits::iend<T>(array);
}
template <typename T>
static std::size_t size(Eina_Array const* array)
{
return eina_array_count(array);
}
template <typename T>
static bool empty(Eina_Array const* array)
{
return size<T>(array) == 0u;
}
};
template <typename T, typename Allocator>
struct ptr_array;
template <typename T>
struct range_ptr_array : _range_template<T, _ptr_array_access_traits>
{
typedef _range_template<T, _ptr_array_access_traits> _base_type;
typedef typename _base_type::value_type value_type;
range_ptr_array(Eina_Array* array)
: _base_type(array)
{}
template <typename Allocator>
range_ptr_array(ptr_array<value_type, Allocator>& array)
: _base_type(array.native_handle())
{}
value_type& operator[](std::size_t index) const
{
return _ptr_array_access_traits::index<T>(this->native_handle(), index);
}
}; };
template <typename T, typename CloneAllocator> template <typename T, typename CloneAllocator>
@ -344,107 +520,101 @@ public:
clear(); clear();
insert(end(), n, t); insert(end(), n, t);
} }
value_type& back() value_type& back()
{ {
return *static_cast<pointer>(this->_impl._array->data[size()-1]); return _ptr_array_access_traits::back<T>(this->_impl._array);
} }
value_type const& back() const value_type const& back() const
{ {
return const_cast<ptr_array<T, CloneAllocator>&>(*this).back(); return _ptr_array_access_traits::back<T>(this->_impl._array);
} }
value_type& front() value_type& front()
{ {
return *static_cast<pointer>(this->_impl._array->data[0]); return _ptr_array_access_traits::front<T>(this->_impl._array);
} }
value_type const& front() const value_type const& front() const
{ {
return const_cast<ptr_array<T, CloneAllocator>&>(*this).front(); return _ptr_array_access_traits::front<T>(this->_impl._array);
} }
const_reference operator[](size_type index) const const_reference operator[](size_type index) const
{ {
pointer data = static_cast<pointer> return _ptr_array_access_traits::index<T>(this->_impl._array, index);
(this->_impl._array->data[index]);
return *data;
} }
reference operator[](size_type index) reference operator[](size_type index)
{ {
return const_cast<reference> return _ptr_array_access_traits::index<T>(this->_impl._array, index);
(const_cast<ptr_array<T, CloneAllocator>const&>(*this)[index]);
} }
const_iterator begin() const const_iterator begin() const
{ {
return const_iterator(this->_impl._array->data); return _ptr_array_access_traits::begin<T>(this->_impl._array);
} }
const_iterator end() const const_iterator end() const
{ {
return const_iterator(this->_impl._array->data + size()); return _ptr_array_access_traits::end<T>(this->_impl._array);
} }
iterator begin() iterator begin()
{ {
return iterator(this->_impl._array->data); return _ptr_array_access_traits::begin<T>(this->_impl._array);
} }
iterator end() iterator end()
{ {
return iterator(this->_impl._array->data + size()); return _ptr_array_access_traits::end<T>(this->_impl._array);
} }
const_reverse_iterator rbegin() const const_reverse_iterator rbegin() const
{ {
return const_reverse_iterator(begin()); return _ptr_array_access_traits::rbegin<T>(this->_impl._array);
} }
const_reverse_iterator rend() const const_reverse_iterator rend() const
{ {
return const_reverse_iterator(end()); return _ptr_array_access_traits::rend<T>(this->_impl._array);
} }
reverse_iterator rbegin() reverse_iterator rbegin()
{ {
return reverse_iterator(begin()); return _ptr_array_access_traits::rbegin<T>(this->_impl._array);
} }
reverse_iterator rend() reverse_iterator rend()
{ {
return reverse_iterator(end()); return _ptr_array_access_traits::rend<T>(this->_impl._array);
} }
const_iterator cbegin() const const_iterator cbegin() const
{ {
return begin(); return _ptr_array_access_traits::cbegin<T>(this->_impl._array);
} }
const_iterator cend() const const_iterator cend() const
{ {
return end(); return _ptr_array_access_traits::cend<T>(this->_impl._array);
} }
const_reverse_iterator crbegin() const const_reverse_iterator crbegin() const
{ {
return rbegin(); return _ptr_array_access_traits::crbegin<T>(this->_impl._array);
} }
const_reverse_iterator crend() const const_reverse_iterator crend() const
{ {
return rend(); return _ptr_array_access_traits::crend<T>(this->_impl._array);
} }
eina::iterator<T> ibegin() eina::iterator<T> ibegin()
{ {
return eina::iterator<T>( ::eina_array_iterator_new(this->_impl._array) ); return _ptr_array_access_traits::ibegin<T>(this->_impl._array);
} }
eina::iterator<T> iend() eina::iterator<T> iend()
{ {
return eina::iterator<T>(); return _ptr_array_access_traits::iend<T>(this->_impl._array);
} }
eina::iterator<T const> ibegin() const eina::iterator<T const> ibegin() const
{ {
return eina::iterator<T const>( ::eina_array_iterator_new(this->_impl._array) ); return _ptr_array_access_traits::ibegin<T>(this->_impl._array);
} }
eina::iterator<T const> iend() const eina::iterator<T const> iend() const
{ {
return eina::iterator<T const>(); return _ptr_array_access_traits::iend<T>(this->_impl._array);
} }
eina::iterator<T const> cibegin() const eina::iterator<T const> cibegin() const
{ {
return ibegin(); return _ptr_array_access_traits::cibegin<T>(this->_impl._array);
} }
eina::iterator<T const> ciend() const eina::iterator<T const> ciend() const
{ {
return iend(); return _ptr_array_access_traits::ciend<T>(this->_impl._array);
} }
void swap(ptr_array<T, CloneAllocator>& other) void swap(ptr_array<T, CloneAllocator>& other)
{ {

View File

@ -29,7 +29,7 @@ protected:
template <typename T> template <typename T>
struct _ptr_list_iterator : _ptr_list_iterator_base struct _ptr_list_iterator : _ptr_list_iterator_base
{ {
typedef T value_type; typedef typename remove_cv<T>::type value_type;
typedef value_type* pointer; typedef value_type* pointer;
typedef value_type& reference; 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_base(list, node)
{ {
} }
_ptr_list_iterator(_ptr_list_iterator<typename remove_cv<value_type>::type> const& other) _ptr_list_iterator(_ptr_list_iterator<value_type> const& other)
: _ptr_list_iterator_base(static_cast<_ptr_list_iterator_base 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 <typename T>
struct iterator
{
typedef _ptr_list_iterator<T> type;
};
template <typename T>
struct const_iterator : iterator<T const> {};
template <typename T>
struct native_handle
{
typedef Eina_List* type;
};
template <typename T>
struct const_native_handle
{
typedef Eina_List const* type;
};
template <typename T>
static Eina_List* native_handle_from_const(Eina_List const* list)
{
return const_cast<Eina_List*>(list);
}
template <typename T>
static T& back(Eina_List* list)
{
return *static_cast<T*>(eina_list_data_get(eina_list_last(list)));
}
template <typename T>
static T const& back(Eina_List const* list)
{
return _ptr_list_access_traits::back<T>(const_cast<Eina_List*>(list));
}
template <typename T>
static T& front(Eina_List* list)
{
return *static_cast<T*>(eina_list_data_get(list));
}
template <typename T>
static T const& front(Eina_List const* list)
{
return _ptr_list_access_traits::front<T>(const_cast<Eina_List*>(list));
}
template <typename T>
static _ptr_list_iterator<T> begin(Eina_List* list)
{
return _ptr_list_iterator<T>(list, list);
}
template <typename T>
static _ptr_list_iterator<T> end(Eina_List* list)
{
return _ptr_list_iterator<T>(list, 0);
}
template <typename T>
static _ptr_list_iterator<T const> begin(Eina_List const* list)
{
return _ptr_list_access_traits::begin<T>(const_cast<Eina_List*>(list));
}
template <typename T>
static _ptr_list_iterator<T const> end(Eina_List const* list)
{
return _ptr_list_access_traits::end<T>(const_cast<Eina_List*>(list));
}
template <typename T>
static std::reverse_iterator<_ptr_list_iterator<T> > rbegin(Eina_List* list)
{
return std::reverse_iterator<_ptr_list_iterator<T> >(_ptr_list_access_traits::begin<T>(list));
}
template <typename T>
static std::reverse_iterator<_ptr_list_iterator<T> > rend(Eina_List* list)
{
return std::reverse_iterator<_ptr_list_iterator<T> >(_ptr_list_access_traits::end<T>(list));
}
template <typename T>
static std::reverse_iterator<_ptr_list_iterator<T const> > rbegin(Eina_List const* list)
{
return _ptr_list_access_traits::rbegin<T>(const_cast<Eina_List*>(list));
}
template <typename T>
static std::reverse_iterator<_ptr_list_iterator<T const> > rend(Eina_List const* list)
{
return _ptr_list_access_traits::rend<T>(const_cast<Eina_List*>(list));
}
template <typename T>
static _ptr_list_iterator<T const> cbegin(Eina_List const* list)
{
return _ptr_list_access_traits::begin<T>(list);
}
template <typename T>
static _ptr_list_iterator<T const> cend(Eina_List const* list)
{
return _ptr_list_access_traits::end<T>(list);
}
template <typename T>
static std::reverse_iterator<_ptr_list_iterator<T const> > crbegin(Eina_List const* list)
{
return _ptr_list_access_traits::rbegin<T>(list);
}
template <typename T>
static std::reverse_iterator<_ptr_list_iterator<T const> > crend(Eina_List const* list)
{
return _ptr_list_access_traits::rend<T>(list);
}
template <typename T>
static eina::iterator<T> ibegin(Eina_List* list)
{
return eina::iterator<T>( ::eina_list_iterator_new(list) );
}
template <typename T>
static eina::iterator<T> iend(Eina_List*)
{
return eina::iterator<T>();
}
template <typename T>
static eina::iterator<T const> ibegin(Eina_List const* list)
{
return eina::iterator<T const>( ::eina_list_iterator_new(list) );
}
template <typename T>
static eina::iterator<T const> iend(Eina_List const* list)
{
return eina::iterator<T const>();
}
template <typename T>
static eina::iterator<T const> cibegin(Eina_List const* list)
{
return _ptr_list_access_traits::ibegin<T>(list);
}
template <typename T>
static eina::iterator<T const> ciend(Eina_List const* list)
{
return _ptr_list_access_traits::iend<T>(list);
}
template <typename T>
static std::size_t size(Eina_List const* list)
{
return eina_list_count(list);
}
template <typename T>
static bool empty(Eina_List const* list)
{
return _ptr_list_access_traits::size<T>(list) == 0u;
}
};
template <typename T>
struct _const_range_ptr_list
{
typedef _ptr_list_iterator<T const> 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_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<T> _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<value_type>(_list);
}
value_type const& front() const
{
return _ptr_list_access_traits::front<value_type>(_list);
}
const_iterator begin() const
{
return _ptr_list_access_traits::begin<value_type>(_list);
}
const_iterator end() const
{
return _ptr_list_access_traits::end<value_type>(_list);
}
const_reverse_iterator rbegin() const
{
return _ptr_list_access_traits::rbegin<value_type>(_list);
}
const_reverse_iterator rend() const
{
return _ptr_list_access_traits::rend<value_type>(_list);
}
const_iterator cbegin() const
{
return _ptr_list_access_traits::cbegin<value_type>(_list);
}
const_iterator cend() const
{
return _ptr_list_access_traits::cend<value_type>(_list);
}
const_reverse_iterator crbegin() const
{
return _ptr_list_access_traits::crbegin<value_type>(_list);
}
const_reverse_iterator crend() const
{
return _ptr_list_access_traits::crend<value_type>(_list);
}
void swap(_self_type& other)
{
std::swap(_list, other._list);
}
bool empty() const
{
return _ptr_list_access_traits::empty<T>(_list);
}
size_type size() const
{
return _ptr_list_access_traits::size<T>(_list);
}
native_handle_type _list;
};
template <typename T>
void swap(_const_range_ptr_list<T>& lhs, _const_range_ptr_list<T>& rhs)
{
lhs.swap(rhs);
}
template <typename T>
struct _mutable_range_ptr_list : _const_range_ptr_list<T>
{
typedef _const_range_ptr_list<T> _base_type;
typedef T value_type;
typedef _ptr_list_iterator<T> iterator;
typedef T& reference;
typedef T* pointer;
typedef std::reverse_iterator<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<T> _self_type;
_mutable_range_ptr_list(native_handle_type list)
: _base_type(list) {}
native_handle_type native_handle() const
{
return const_cast<native_handle_type>(_base_type::native_handle());
}
value_type& back() const
{
return _ptr_list_access_traits::back<value_type>(native_handle());
}
value_type& front() const
{
return _ptr_list_access_traits::front<value_type>(native_handle());
}
iterator begin() const
{
return _ptr_list_access_traits::begin<value_type>(native_handle());
}
iterator end() const
{
return _ptr_list_access_traits::end<value_type>(native_handle());
}
reverse_iterator rbegin() const
{
return _ptr_list_access_traits::rbegin<value_type>(native_handle());
}
reverse_iterator rend() const
{
return _ptr_list_access_traits::rend<value_type>(native_handle());
}
};
template <typename T, typename Allocator>
struct ptr_list;
template <typename T>
struct range_ptr_list : _range_template<T, _ptr_list_access_traits>
{
typedef _range_template<T, _ptr_list_access_traits> _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 <typename Allocator>
range_ptr_list(ptr_list<value_type, Allocator>& list)
: _base_type(list.native_handle())
{}
};
template <typename T, typename CloneAllocator> template <typename T, typename CloneAllocator>
struct _ptr_list_common_base struct _ptr_list_common_base
{ {
@ -209,11 +511,11 @@ public:
} }
std::size_t size() const std::size_t size() const
{ {
return eina_list_count(this->_impl._list); return _ptr_list_access_traits::size<T>(this->_impl._list);
} }
bool empty() const bool empty() const
{ {
return size() == 0u; return _ptr_list_access_traits::empty<T>(this->_impl._list);
} }
clone_allocator_type get_clone_allocator() const clone_allocator_type get_clone_allocator() const
{ {
@ -357,95 +659,93 @@ public:
clear(); clear();
insert(end(), n, t); insert(end(), n, t);
} }
value_type& back() value_type& back()
{ {
return *static_cast<pointer>(eina_list_data_get(eina_list_last(this->_impl._list))); return _ptr_list_access_traits::back<T>(this->_impl._list);
} }
value_type const& back() const value_type const& back() const
{ {
return const_cast<ptr_list<T, CloneAllocator>&>(*this).back(); return _ptr_list_access_traits::back<T>(this->_impl._list);
} }
value_type& front() value_type& front()
{ {
return *static_cast<pointer>(eina_list_data_get(this->_impl._list)); return _ptr_list_access_traits::front<T>(this->_impl._list);
} }
value_type const& front() const value_type const& front() const
{ {
return const_cast<ptr_list<T, CloneAllocator>&>(*this).front(); return _ptr_list_access_traits::front<T>(this->_impl._list);
} }
const_iterator begin() const const_iterator begin() const
{ {
return const_iterator(this->_impl._list, this->_impl._list); return _ptr_list_access_traits::cbegin<T>(this->_impl._list);
} }
const_iterator end() const const_iterator end() const
{ {
return const_iterator(this->_impl._list, 0); return _ptr_list_access_traits::cend<T>(this->_impl._list);
} }
iterator begin() iterator begin()
{ {
return iterator(this->_impl._list, this->_impl._list); return _ptr_list_access_traits::begin<T>(this->_impl._list);
} }
iterator end() iterator end()
{ {
return iterator(this->_impl._list, 0); return _ptr_list_access_traits::end<T>(this->_impl._list);
} }
const_reverse_iterator rbegin() const const_reverse_iterator rbegin() const
{ {
return const_reverse_iterator(begin()); return _ptr_list_access_traits::rbegin<T>(this->_impl._list);
} }
const_reverse_iterator rend() const const_reverse_iterator rend() const
{ {
return const_reverse_iterator(end()); return _ptr_list_access_traits::rend<T>(this->_impl._list);
} }
reverse_iterator rbegin() reverse_iterator rbegin()
{ {
return reverse_iterator(begin()); return _ptr_list_access_traits::rbegin<T>(this->_impl._list);
} }
reverse_iterator rend() reverse_iterator rend()
{ {
return reverse_iterator(end()); return _ptr_list_access_traits::rend<T>(this->_impl._list);
} }
const_iterator cbegin() const const_iterator cbegin() const
{ {
return begin(); return _ptr_list_access_traits::cbegin<T>(this->_impl._list);
} }
const_iterator cend() const const_iterator cend() const
{ {
return end(); return _ptr_list_access_traits::cend<T>(this->_impl._list);
} }
const_reverse_iterator crbegin() const const_reverse_iterator crbegin() const
{ {
return rbegin(); return _ptr_list_access_traits::crbegin<T>(this->_impl._list);
} }
const_reverse_iterator crend() const const_reverse_iterator crend() const
{ {
return rend(); return _ptr_list_access_traits::crend<T>(this->_impl._list);
} }
eina::iterator<T> ibegin() eina::iterator<T> ibegin()
{ {
return eina::iterator<T>( ::eina_list_iterator_new(this->_impl._list) ); return _ptr_list_access_traits::ibegin<T>(this->_impl._list);
} }
eina::iterator<T> iend() eina::iterator<T> iend()
{ {
return eina::iterator<T>(); return _ptr_list_access_traits::iend<T>(this->_impl._list);
} }
eina::iterator<T const> ibegin() const eina::iterator<T const> ibegin() const
{ {
return eina::iterator<T const>( ::eina_list_iterator_new(this->_impl._list) ); return _ptr_list_access_traits::ibegin<T>(this->_impl._list);
} }
eina::iterator<T const> iend() const eina::iterator<T const> iend() const
{ {
return eina::iterator<T const>(); return _ptr_list_access_traits::iend<T>(this->_impl._list);
} }
eina::iterator<T const> cibegin() const eina::iterator<T const> cibegin() const
{ {
return ibegin(); return _ptr_list_access_traits::cibegin<T>(this->_impl._list);
} }
eina::iterator<T const> ciend() const eina::iterator<T const> ciend() const
{ {
return iend(); return _ptr_list_access_traits::ciend<T>(this->_impl._list);
} }
void swap(ptr_list<T, CloneAllocator>& other) void swap(ptr_list<T, CloneAllocator>& other)
{ {

View File

@ -0,0 +1,180 @@
#ifndef EINA_RANGE_TYPES_HH_
#define EINA_RANGE_TYPES_HH_
namespace efl { namespace eina {
template <typename T, typename Traits>
struct _const_range_template
{
typedef typename Traits::template const_iterator<T>::type const_iterator;
typedef typename Traits::template iterator<T>::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<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef typename Traits::template const_native_handle<T>::type native_handle_type;
typedef _const_range_template<T, Traits> _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<value_type>(_handle);
}
value_type const& front() const
{
return Traits::template front<value_type>(_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<value_type>(_handle));
}
const_reverse_iterator crend() const
{
return const_reverse_iterator(Traits::template rend<value_type>(_handle));
}
const_iterator cbegin() const
{
return Traits::template cbegin<value_type>(_handle);
}
const_iterator cend() const
{
return Traits::template cend<value_type>(_handle);
}
const_reverse_iterator rbegin()
{
return crbegin();
}
const_reverse_iterator rend()
{
return crend();
}
bool empty() const
{
return Traits::template empty<value_type>(_handle);
}
size_type size() const
{
return Traits::template size<value_type>(_handle);
}
void swap(_self_type& other)
{
std::swap(_handle, other._handle);
}
protected:
native_handle_type _handle;
};
template <typename T, typename Traits>
void swap(_const_range_template<T, Traits>& lhs, _const_range_template<T, Traits>& rhs)
{
lhs.swap(rhs);
}
template <typename T, typename Traits>
struct _mutable_range_template : _const_range_template<T, Traits>
{
typedef T value_type;
typedef typename Traits::template iterator<T>::type iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef typename Traits::template native_handle<T>::type native_handle_type;
typedef _const_range_template<T, Traits> _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<T>(_base_type::native_handle());
}
value_type& back() const
{
return Traits::template back<value_type>(native_handle());
}
value_type& front() const
{
return Traits::template front<value_type>(native_handle());
}
iterator begin() const
{
return Traits::template begin<value_type>(native_handle());
}
iterator end() const
{
return Traits::template end<value_type>(native_handle());
}
reverse_iterator rbegin() const
{
return Traits::template rbegin<value_type>(native_handle());
}
reverse_iterator rend() const
{
return Traits::template rend<value_type>(native_handle());
}
protected:
using _base_type::_handle;
};
template <typename T, typename Traits>
struct _range_template : private std::conditional
<std::is_const<T>::value
, _const_range_template<typename std::remove_const<T>::type, Traits>
, _mutable_range_template<T, Traits> >::type
{
typedef std::integral_constant<bool, !std::is_const<T>::value> is_mutable;
typedef typename std::remove_const<T>::type value_type;
typedef typename std::conditional<is_mutable::value, _mutable_range_template<value_type, Traits>
, _const_range_template<value_type, Traits> >::type _base_type;
typedef typename Traits::template native_handle<T>::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<T>::type const_iterator;
typedef typename _base_type::const_reverse_iterator const_reverse_iterator;
typedef typename Traits::template iterator<T>::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

View File

@ -15,7 +15,9 @@ START_TEST(eina_cxx_inarray_pod_push_back)
efl::eina::inarray<int> array; efl::eina::inarray<int> array;
array.push_back(5); array.push_back(5);
std::cout << "array size: " << array.size() << std::endl;
array.push_back(10); array.push_back(10);
std::cout << "array size: " << array.size() << std::endl;
array.push_back(15); array.push_back(15);
int result[] = {5, 10, 15}; int result[] = {5, 10, 15};
@ -372,6 +374,35 @@ START_TEST(eina_cxx_inarray_nonpod_erase)
} }
END_TEST END_TEST
START_TEST(eina_cxx_range_inarray)
{
efl::eina::eina_init eina_init;
efl::eina::inarray<int> array;
array.push_back(5);
array.push_back(10);
array.push_back(15);
int result[] = {5, 10, 15};
efl::eina::range_inarray<int> 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 void
eina_test_inarray(TCase *tc) 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_insert);
tcase_add_test(tc, eina_cxx_inarray_nonpod_erase); tcase_add_test(tc, eina_cxx_inarray_nonpod_erase);
tcase_add_test(tc, eina_cxx_inarray_nonpod_constructors); tcase_add_test(tc, eina_cxx_inarray_nonpod_constructors);
tcase_add_test(tc, eina_cxx_range_inarray);
} }

View File

@ -199,6 +199,36 @@ START_TEST(eina_cxx_inlist_erase)
} }
END_TEST END_TEST
START_TEST(eina_cxx_inlist_range)
{
efl::eina::eina_init eina_init;
efl::eina::inlist<int> 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<int> 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<int const> 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 void
eina_test_inlist(TCase *tc) 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_insert);
tcase_add_test(tc, eina_cxx_inlist_erase); tcase_add_test(tc, eina_cxx_inlist_erase);
tcase_add_test(tc, eina_cxx_inlist_constructors); tcase_add_test(tc, eina_cxx_inlist_constructors);
tcase_add_test(tc, eina_cxx_inlist_range);
} }

View File

@ -169,6 +169,36 @@ START_TEST(eina_cxx_ptrarray_erase)
} }
END_TEST END_TEST
START_TEST(eina_cxx_ptrarray_range)
{
efl::eina::eina_init eina_init;
efl::eina::ptr_array<int> 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<int> 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<int const> 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 void
eina_test_ptrarray(TCase* tc) 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_insert);
tcase_add_test(tc, eina_cxx_ptrarray_constructors); tcase_add_test(tc, eina_cxx_ptrarray_constructors);
tcase_add_test(tc, eina_cxx_ptrarray_erase); tcase_add_test(tc, eina_cxx_ptrarray_erase);
tcase_add_test(tc, eina_cxx_ptrarray_range);
} }

View File

@ -199,6 +199,36 @@ START_TEST(eina_cxx_ptrlist_erase)
} }
END_TEST END_TEST
START_TEST(eina_cxx_ptrlist_range)
{
efl::eina::eina_init eina_init;
efl::eina::ptr_list<int> 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<int> 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<int const> 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 void
eina_test_ptrlist(TCase* tc) 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_insert);
tcase_add_test(tc, eina_cxx_ptrlist_constructors); tcase_add_test(tc, eina_cxx_ptrlist_constructors);
tcase_add_test(tc, eina_cxx_ptrlist_erase); tcase_add_test(tc, eina_cxx_ptrlist_erase);
tcase_add_test(tc, eina_cxx_ptrlist_range);
} }