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.
 
 
 
 
 
 

645 lines
18 KiB

/*
* Copyright 2019 by its authors. See AUTHORS.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#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