forked from enlightenment/efl
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
630 lines
18 KiB
630 lines
18 KiB
#ifndef EINA_LIST_HH_ |
|
#define EINA_LIST_HH_ |
|
|
|
#include <Eo.h> |
|
|
|
#include <eina_ptrlist.hh> |
|
|
|
namespace efl { namespace eina { |
|
|
|
/** |
|
* @internal |
|
*/ |
|
template <typename T> |
|
struct _ptr_eo_list_iterator : _ptr_list_iterator<Eo> |
|
{ |
|
typedef _ptr_list_iterator<Eo> _base_type; |
|
typedef _ptr_eo_list_iterator<T> _self_type; |
|
typedef typename remove_cv<T>::type value_type; |
|
typedef value_type* pointer; |
|
typedef value_type& reference; |
|
|
|
_base_type& _base() { return *this; } |
|
_base_type const& _base() const { return *this; } |
|
|
|
_ptr_eo_list_iterator(_base_type const& base) : _base_type(base) {} |
|
_ptr_eo_list_iterator() {} |
|
explicit _ptr_eo_list_iterator(Eina_List* list, Eina_List* node) |
|
: _base_type(list, node) |
|
{ |
|
} |
|
_ptr_eo_list_iterator(_ptr_eo_list_iterator<value_type> const& other) |
|
: _base_type(static_cast<_base_type const&>(other)) |
|
{ |
|
} |
|
_self_type& operator=(_self_type const& other) |
|
{ |
|
this->_base_type::operator=(other); |
|
return *this; |
|
} |
|
|
|
_self_type& operator++() |
|
{ |
|
++_base(); |
|
return *this; |
|
} |
|
_self_type operator++(int) |
|
{ |
|
_self_type tmp(*this); |
|
++_base(); |
|
return tmp; |
|
} |
|
_self_type& operator--() |
|
{ |
|
--_base(); |
|
return *this; |
|
} |
|
_self_type operator--(int) |
|
{ |
|
_self_type tmp(*this); |
|
--_base(); |
|
return tmp; |
|
} |
|
reference operator*() const |
|
{ |
|
void* data = reinterpret_cast<void*>(&this->_node->data); |
|
return *static_cast<pointer>(data); |
|
} |
|
pointer operator->() const |
|
{ |
|
return &**this; |
|
} |
|
|
|
using _base_type::native_handle; |
|
}; |
|
|
|
/** |
|
* @internal |
|
*/ |
|
struct _eo_list_access_traits : _ptr_list_access_traits |
|
{ |
|
template <typename T> |
|
struct iterator |
|
{ |
|
typedef _ptr_eo_list_iterator<T> type; |
|
}; |
|
template <typename T> |
|
struct const_iterator : iterator<T const> {}; |
|
template <typename T> |
|
static T& back(Eina_List* list) |
|
{ |
|
return *static_cast<T*>(static_cast<void*>(&eina_list_last(list)->data)); |
|
} |
|
template <typename T> |
|
static T const& back(Eina_List const* list) |
|
{ |
|
return _eo_list_access_traits::back<T>(const_cast<Eina_List*>(list)); |
|
} |
|
template <typename T> |
|
static T& front(Eina_List* list) |
|
{ |
|
return *static_cast<T*>(static_cast<void*>(&list->data)); |
|
} |
|
template <typename T> |
|
static T const& front(Eina_List const* list) |
|
{ |
|
return _eo_list_access_traits::front<T>(const_cast<Eina_List*>(list)); |
|
} |
|
template <typename T> |
|
static typename iterator<T>::type begin(Eina_List* list) |
|
{ |
|
return typename iterator<T>::type(list, list); |
|
} |
|
template <typename T> |
|
static typename iterator<T>::type end(Eina_List* list) |
|
{ |
|
return typename iterator<T>::type(list, nullptr); |
|
} |
|
template <typename T> |
|
static typename const_iterator<T>::type begin(Eina_List const* list) |
|
{ |
|
return _eo_list_access_traits::begin<T>(const_cast<Eina_List*>(list)); |
|
} |
|
template <typename T> |
|
static typename const_iterator<T>::type end(Eina_List const* list) |
|
{ |
|
return _eo_list_access_traits::end<T>(const_cast<Eina_List*>(list)); |
|
} |
|
template <typename T> |
|
static std::reverse_iterator<typename iterator<T>::type> rbegin(Eina_List* list) |
|
{ |
|
return std::reverse_iterator<typename iterator<T>::type>(_eo_list_access_traits::end<T>(list)); |
|
} |
|
template <typename T> |
|
static std::reverse_iterator<typename iterator<T>::type> rend(Eina_List* list) |
|
{ |
|
return std::reverse_iterator<typename iterator<T>::type>(_eo_list_access_traits::begin<T>(list)); |
|
} |
|
template <typename T> |
|
static std::reverse_iterator<typename const_iterator<T>::type> rbegin(Eina_List const* list) |
|
{ |
|
return _eo_list_access_traits::rbegin<T>(const_cast<Eina_List*>(list)); |
|
} |
|
template <typename T> |
|
static std::reverse_iterator<typename const_iterator<T>::type> rend(Eina_List const* list) |
|
{ |
|
return _eo_list_access_traits::rend<T>(const_cast<Eina_List*>(list)); |
|
} |
|
template <typename T> |
|
static typename const_iterator<T>::type cbegin(Eina_List const* list) |
|
{ |
|
return _eo_list_access_traits::begin<T>(list); |
|
} |
|
template <typename T> |
|
static typename const_iterator<T>::type cend(Eina_List const* list) |
|
{ |
|
return _eo_list_access_traits::end<T>(list); |
|
} |
|
template <typename T> |
|
static std::reverse_iterator<typename const_iterator<T>::type> crbegin(Eina_List const* list) |
|
{ |
|
return _eo_list_access_traits::rbegin<T>(list); |
|
} |
|
template <typename T> |
|
static std::reverse_iterator<typename const_iterator<T>::type> crend(Eina_List const* list) |
|
{ |
|
return _eo_list_access_traits::rend<T>(list); |
|
} |
|
}; |
|
|
|
template <typename T, typename CloneAllocator = default_clone_allocator_placeholder, typename Enable = void> |
|
class list : ptr_list<T, typename std::conditional |
|
<std::is_same<CloneAllocator, default_clone_allocator_placeholder>::value |
|
, heap_no_copy_allocator, CloneAllocator>::type> |
|
{ |
|
typedef ptr_list<T, typename std::conditional |
|
<std::is_same<CloneAllocator, default_clone_allocator_placeholder>::value |
|
, heap_no_copy_allocator, CloneAllocator>::type> _base_type; |
|
public: |
|
typedef typename _base_type::value_type value_type; |
|
typedef typename _base_type::reference reference; |
|
typedef typename _base_type::const_reference const_reference; |
|
typedef typename _base_type::const_iterator const_iterator; |
|
typedef typename _base_type::iterator iterator; |
|
typedef typename _base_type::pointer pointer; |
|
typedef typename _base_type::const_pointer const_pointer; |
|
typedef typename _base_type::size_type size_type; |
|
typedef typename _base_type::difference_type difference_type; |
|
typedef typename _base_type::clone_allocator_type clone_allocator_type; |
|
|
|
typedef typename _base_type::reverse_iterator reverse_iterator; |
|
typedef typename _base_type::const_reverse_iterator const_reverse_iterator; |
|
|
|
typedef typename _base_type::native_handle_type native_handle_type; |
|
|
|
list& operator=(list&& other) = default; |
|
list(list&& other) = default; |
|
list() = default; |
|
|
|
using _base_type::_base_type; |
|
using _base_type::clear; |
|
using _base_type::size; |
|
using _base_type::empty; |
|
using _base_type::get_clone_allocator; |
|
using _base_type::push_back; |
|
using _base_type::push_front; |
|
using _base_type::pop_back; |
|
using _base_type::pop_front; |
|
using _base_type::insert; |
|
using _base_type::erase; |
|
using _base_type::assign; |
|
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::ibegin; |
|
using _base_type::iend; |
|
using _base_type::cibegin; |
|
using _base_type::ciend; |
|
using _base_type::swap; |
|
using _base_type::max_size; |
|
using _base_type::native_handle; |
|
using _base_type::accessor; |
|
using _base_type::release_native_handle; |
|
}; |
|
|
|
template <typename T, typename CloneAllocator> |
|
class list<T, CloneAllocator, typename std::enable_if< ::efl::eo::is_eolian_object<T>::value>::type> |
|
: ptr_list<Eo, typename std::conditional |
|
<std::is_same<CloneAllocator, default_clone_allocator_placeholder>::value |
|
, eo_clone_allocator, CloneAllocator>::type> |
|
{ |
|
typedef ptr_list<Eo, typename std::conditional |
|
<std::is_same<CloneAllocator, default_clone_allocator_placeholder>::value |
|
, eo_clone_allocator, CloneAllocator>::type> _base_type; |
|
typedef list<T, CloneAllocator> _self_type; |
|
public: |
|
typedef T value_type; |
|
typedef value_type& reference; |
|
typedef value_type const& const_reference; |
|
typedef _ptr_eo_list_iterator<value_type const> const_iterator; |
|
typedef _ptr_eo_list_iterator<value_type> iterator; |
|
typedef value_type* pointer; |
|
typedef value_type const* const_pointer; |
|
typedef std::size_t size_type; |
|
typedef std::ptrdiff_t difference_type; |
|
typedef typename _base_type::clone_allocator_type clone_allocator_type; |
|
|
|
typedef std::reverse_iterator<iterator> reverse_iterator; |
|
typedef std::reverse_iterator<const_iterator> const_reverse_iterator; |
|
|
|
typedef typename _base_type::native_handle_type native_handle_type; |
|
|
|
explicit list(typename _self_type::native_handle_type handle) |
|
: _base_type(handle) {} |
|
list(clone_allocator_type alloc) : _base_type(alloc) {} |
|
list() {} |
|
list(size_type n, const_reference t) |
|
{ |
|
while(n--) |
|
push_back(t); |
|
} |
|
template <typename InputIterator> |
|
list(InputIterator i, InputIterator const& j |
|
, clone_allocator_type const& alloc = clone_allocator_type() |
|
, typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0) |
|
: _base_type(alloc) |
|
{ |
|
while(i != j) |
|
{ |
|
push_back(*i); |
|
++i; |
|
} |
|
} |
|
list(list<T, CloneAllocator> const& other) |
|
: _base_type() |
|
{ |
|
insert(end(), other.begin(), other.end()); |
|
} |
|
~list() |
|
{ |
|
} |
|
list<T, CloneAllocator>& operator=(list<T, CloneAllocator>const& other) |
|
{ |
|
clear(); |
|
insert(end(), other.begin(), other.end()); |
|
return *this; |
|
} |
|
list& operator=(list&& other) = default; |
|
list(list&& other) = default; |
|
|
|
using _base_type::clear; |
|
using _base_type::size; |
|
using _base_type::empty; |
|
using _base_type::get_clone_allocator; |
|
using _base_type::pop_back; |
|
using _base_type::pop_front; |
|
using _base_type::release_native_handle; |
|
|
|
void push_back(const_reference w) |
|
{ |
|
this->_base_type::push_back(* w._eo_ptr()); |
|
} |
|
void push_front(const_reference w) |
|
{ |
|
this->_base_type::push_front(* w._eo_ptr()); |
|
} |
|
iterator insert(iterator i, const_reference v) |
|
{ |
|
return this->_base_type::insert(i, * v._eo_ptr()); |
|
} |
|
iterator insert(iterator i, size_t n, const_reference v) |
|
{ |
|
return this->_base_type::insert(i, n, * v._eo_ptr()); |
|
} |
|
template <typename InputIterator> |
|
iterator insert(iterator p, InputIterator i, InputIterator j |
|
, typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0) |
|
{ |
|
iterator r = p; |
|
if(i != j) |
|
{ |
|
r = insert(p, *i); |
|
++i; |
|
} |
|
while(i != j) |
|
{ |
|
insert(p, *i); |
|
++i; |
|
} |
|
return r; |
|
} |
|
iterator erase(iterator p) |
|
{ |
|
return _base_type::erase(p); |
|
} |
|
iterator erase(iterator i, iterator j) |
|
{ |
|
return _base_type::erase(i, j); |
|
} |
|
template <typename InputIterator> |
|
void assign(InputIterator i, InputIterator j |
|
, typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0) |
|
{ |
|
clear(); |
|
insert(end(), i, j); |
|
} |
|
|
|
void assign(size_type n, value_type const& t) |
|
{ |
|
clear(); |
|
insert(end(), n, t); |
|
} |
|
|
|
reference front() |
|
{ |
|
return _eo_list_access_traits::front<value_type>(native_handle()); |
|
} |
|
reference back() |
|
{ |
|
return _eo_list_access_traits::back<value_type>(native_handle()); |
|
} |
|
const_reference front() const { return const_cast<_self_type*>(this)->front(); } |
|
const_reference back() const { return const_cast<_self_type*>(this)->back(); } |
|
iterator begin() |
|
{ |
|
return _eo_list_access_traits::begin<value_type>(native_handle()); |
|
} |
|
iterator end() |
|
{ |
|
return _eo_list_access_traits::end<value_type>(native_handle()); |
|
} |
|
const_iterator begin() const |
|
{ |
|
return const_cast<_self_type*>(this)->begin(); |
|
} |
|
const_iterator end() const |
|
{ |
|
return const_cast<_self_type*>(this)->end(); |
|
} |
|
const_iterator cbegin() const |
|
{ |
|
return begin(); |
|
} |
|
const_iterator cend() const |
|
{ |
|
return end(); |
|
} |
|
reverse_iterator rbegin() |
|
{ |
|
return _eo_list_access_traits::rbegin<value_type>(native_handle()); |
|
} |
|
reverse_iterator rend() |
|
{ |
|
return _eo_list_access_traits::rend<value_type>(native_handle()); |
|
} |
|
const_reverse_iterator rbegin() const |
|
{ |
|
return const_cast<_self_type*>(this)->rbegin(); |
|
} |
|
const_reverse_iterator rend() const |
|
{ |
|
return const_cast<_self_type*>(this)->rend(); |
|
} |
|
const_reverse_iterator crbegin() const |
|
{ |
|
return rbegin(); |
|
} |
|
const_reverse_iterator crend() const |
|
{ |
|
return rend(); |
|
} |
|
eina::iterator<value_type> ibegin() |
|
{ |
|
return _eo_list_access_traits::ibegin<value_type>(this->_impl._list); |
|
} |
|
eina::iterator<value_type> iend() |
|
{ |
|
return _eo_list_access_traits::iend<value_type>(this->_impl._list); |
|
} |
|
eina::iterator<value_type const> ibegin() const |
|
{ |
|
return _eo_list_access_traits::ibegin<value_type>(this->_impl._list); |
|
} |
|
eina::iterator<value_type const> iend() const |
|
{ |
|
return _eo_list_access_traits::iend<value_type>(this->_impl._list); |
|
} |
|
eina::iterator<value_type const> cibegin() const |
|
{ |
|
return _eo_list_access_traits::cibegin<value_type>(this->_impl._list); |
|
} |
|
eina::iterator<value_type const> ciend() const |
|
{ |
|
return _eo_list_access_traits::ciend<value_type>(this->_impl._list); |
|
} |
|
using _base_type::swap; |
|
using _base_type::max_size; |
|
using _base_type::native_handle; |
|
|
|
/** |
|
* @brief Get a constant @ref eina::accessor for the list. |
|
* @return Constant <tt>eina::accessor</tt> to the list. |
|
* |
|
* Version of @ref accessor() to const-qualified inline lists. Returns |
|
* a const-qualified <tt>eina::accessor</tt> instead. |
|
*/ |
|
eina::accessor<T const> accessor() const |
|
{ |
|
return eina::accessor<T const>(eina_list_accessor_new(this->_impl._list)); |
|
} |
|
|
|
/** |
|
* @brief Get a @ref eina::accessor for the list. |
|
* @return <tt>eina::accessor</tt> to the list. |
|
*/ |
|
eina::accessor<T> accessor() |
|
{ |
|
return eina::accessor<T>(eina_list_accessor_new(this->_impl._list)); |
|
} |
|
|
|
friend bool operator==(list<T, CloneAllocator> const& rhs, list<T, CloneAllocator> const& lhs) |
|
{ |
|
return rhs.size() == lhs.size() && std::equal(rhs.begin(), rhs.end(), lhs.begin()); |
|
} |
|
}; |
|
|
|
template <typename T, typename CloneAllocator> |
|
bool operator!=(list<T, CloneAllocator> const& rhs, list<T, CloneAllocator> const& lhs) |
|
{ |
|
return !(rhs == lhs); |
|
} |
|
|
|
template <typename T, typename Enable = void> |
|
class range_list : range_ptr_list<T> |
|
{ |
|
typedef range_ptr_list<T> _base_type; |
|
public: |
|
typedef typename _base_type::value_type value_type; |
|
typedef typename _base_type::reference reference; |
|
typedef typename _base_type::const_reference const_reference; |
|
typedef typename _base_type::const_iterator const_iterator; |
|
typedef typename _base_type::iterator iterator; |
|
typedef typename _base_type::pointer pointer; |
|
typedef typename _base_type::const_pointer const_pointer; |
|
typedef typename _base_type::size_type size_type; |
|
typedef typename _base_type::difference_type difference_type; |
|
|
|
typedef typename _base_type::reverse_iterator reverse_iterator; |
|
typedef typename _base_type::const_reverse_iterator const_reverse_iterator; |
|
|
|
typedef typename _base_type::native_handle_type native_handle_type; |
|
|
|
using _base_type::_base_type; |
|
using _base_type::size; |
|
using _base_type::empty; |
|
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::swap; |
|
using _base_type::native_handle; |
|
using _base_type::release_native_handle; |
|
}; |
|
|
|
template <typename T> |
|
class range_list<T, typename std::enable_if< ::efl::eo::is_eolian_object<T>::value>::type> |
|
: range_ptr_list<typename std::conditional<std::is_const<T>::value, Eo const, Eo>::type> |
|
{ |
|
typedef range_ptr_list<typename std::conditional<std::is_const<T>::value, Eo const, Eo>::type> _base_type; |
|
typedef range_list<T> _self_type; |
|
public: |
|
typedef T value_type; |
|
typedef value_type& reference; |
|
typedef value_type const& const_reference; |
|
typedef _ptr_eo_list_iterator<value_type const> const_iterator; |
|
typedef _ptr_eo_list_iterator<value_type> iterator; |
|
typedef value_type* pointer; |
|
typedef value_type const* const_pointer; |
|
typedef std::size_t size_type; |
|
typedef std::ptrdiff_t difference_type; |
|
|
|
typedef std::reverse_iterator<iterator> reverse_iterator; |
|
typedef std::reverse_iterator<const_iterator> const_reverse_iterator; |
|
|
|
typedef typename _base_type::native_handle_type native_handle_type; |
|
|
|
explicit range_list(typename _self_type::native_handle_type handle) |
|
: _base_type(handle) {} |
|
range_list() {} |
|
range_list(range_list<T> const& other) |
|
: _base_type(other.native_handle()) |
|
{ |
|
} |
|
range_list<T>& operator=(range_list<T>const& other) |
|
{ |
|
_base_type::_handle = other._handle; |
|
return *this; |
|
} |
|
range_list& operator=(range_list&& other) = default; |
|
range_list(range_list&& other) = default; |
|
|
|
using _base_type::size; |
|
using _base_type::empty; |
|
|
|
reference front() |
|
{ |
|
return _eo_list_access_traits::front<value_type>(native_handle()); |
|
} |
|
reference back() |
|
{ |
|
return _eo_list_access_traits::back<value_type>(native_handle()); |
|
} |
|
const_reference front() const { return const_cast<_self_type*>(this)->front(); } |
|
const_reference back() const { return const_cast<_self_type*>(this)->back(); } |
|
iterator begin() |
|
{ |
|
return _eo_list_access_traits::begin<value_type>(native_handle()); |
|
} |
|
iterator end() |
|
{ |
|
return _eo_list_access_traits::end<value_type>(native_handle()); |
|
} |
|
const_iterator begin() const |
|
{ |
|
return const_cast<_self_type*>(this)->begin(); |
|
} |
|
const_iterator end() const |
|
{ |
|
return const_cast<_self_type*>(this)->end(); |
|
} |
|
const_iterator cbegin() const |
|
{ |
|
return begin(); |
|
} |
|
const_iterator cend() const |
|
{ |
|
return end(); |
|
} |
|
reverse_iterator rbegin() |
|
{ |
|
return _eo_list_access_traits::rbegin<value_type>(native_handle()); |
|
} |
|
reverse_iterator rend() |
|
{ |
|
return _eo_list_access_traits::rend<value_type>(native_handle()); |
|
} |
|
const_reverse_iterator rbegin() const |
|
{ |
|
return const_cast<_self_type*>(this)->rbegin(); |
|
} |
|
const_reverse_iterator rend() const |
|
{ |
|
return const_cast<_self_type*>(this)->rend(); |
|
} |
|
const_reverse_iterator crbegin() const |
|
{ |
|
return rbegin(); |
|
} |
|
const_reverse_iterator crend() const |
|
{ |
|
return rend(); |
|
} |
|
using _base_type::swap; |
|
using _base_type::native_handle; |
|
using _base_type::release_native_handle; |
|
|
|
friend bool operator==(range_list<T> const& rhs, range_list<T> const& lhs) |
|
{ |
|
return rhs.size() == lhs.size() && std::equal(rhs.begin(), rhs.end(), lhs.begin()); |
|
} |
|
}; |
|
|
|
template <typename T> |
|
using crange_list = range_list<typename std::add_const<T>::type>; |
|
|
|
} } |
|
|
|
#endif
|
|
|