#ifndef EINA_LIST_HH_ #define EINA_LIST_HH_ #include #include namespace efl { namespace eina { /** * @internal */ template struct _ptr_eo_list_iterator : _ptr_list_iterator { typedef _ptr_list_iterator _base_type; typedef _ptr_eo_list_iterator _self_type; typedef typename remove_cv::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 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(&this->_node->data); return *static_cast(data); } pointer operator->() const { return &**this; } using _base_type::native_handle; }; /** * @internal */ struct _eo_list_access_traits : _ptr_list_access_traits { template struct iterator { typedef _ptr_eo_list_iterator type; }; template struct const_iterator : iterator {}; template static T& back(Eina_List* list) { return *static_cast(static_cast(&eina_list_last(list)->data)); } template static T const& back(Eina_List const* list) { return _eo_list_access_traits::back(const_cast(list)); } template static T& front(Eina_List* list) { return *static_cast(static_cast(&list->data)); } template static T const& front(Eina_List const* list) { return _eo_list_access_traits::front(const_cast(list)); } template static typename iterator::type begin(Eina_List* list) { return typename iterator::type(list, list); } template static typename iterator::type end(Eina_List* list) { return typename iterator::type(list, nullptr); } template static typename const_iterator::type begin(Eina_List const* list) { return _eo_list_access_traits::begin(const_cast(list)); } template static typename const_iterator::type end(Eina_List const* list) { return _eo_list_access_traits::end(const_cast(list)); } template static std::reverse_iterator::type> rbegin(Eina_List* list) { return std::reverse_iterator::type>(_eo_list_access_traits::end(list)); } template static std::reverse_iterator::type> rend(Eina_List* list) { return std::reverse_iterator::type>(_eo_list_access_traits::begin(list)); } template static std::reverse_iterator::type> rbegin(Eina_List const* list) { return _eo_list_access_traits::rbegin(const_cast(list)); } template static std::reverse_iterator::type> rend(Eina_List const* list) { return _eo_list_access_traits::rend(const_cast(list)); } template static typename const_iterator::type cbegin(Eina_List const* list) { return _eo_list_access_traits::begin(list); } template static typename const_iterator::type cend(Eina_List const* list) { return _eo_list_access_traits::end(list); } template static std::reverse_iterator::type> crbegin(Eina_List const* list) { return _eo_list_access_traits::rbegin(list); } template static std::reverse_iterator::type> crend(Eina_List const* list) { return _eo_list_access_traits::rend(list); } }; template class list : ptr_list::value , heap_no_copy_allocator, CloneAllocator>::type> { typedef ptr_list::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 class list::value>::type> : ptr_list::value , eo_clone_allocator, CloneAllocator>::type> { typedef ptr_list::value , eo_clone_allocator, CloneAllocator>::type> _base_type; typedef list _self_type; public: typedef T value_type; typedef value_type& reference; typedef value_type const& const_reference; typedef _ptr_eo_list_iterator const_iterator; typedef _ptr_eo_list_iterator 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 reverse_iterator; typedef std::reverse_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 list(InputIterator i, InputIterator const& j , clone_allocator_type const& alloc = clone_allocator_type() , typename eina::enable_if::value>::type* = 0) : _base_type(alloc) { while(i != j) { push_back(*i); ++i; } } list(list const& other) : _base_type() { insert(end(), other.begin(), other.end()); } ~list() { } list& operator=(listconst& 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 iterator insert(iterator p, InputIterator i, InputIterator j , typename eina::enable_if::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 void assign(InputIterator i, InputIterator j , typename eina::enable_if::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(native_handle()); } reference back() { return _eo_list_access_traits::back(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(native_handle()); } iterator end() { return _eo_list_access_traits::end(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(native_handle()); } reverse_iterator rend() { return _eo_list_access_traits::rend(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 ibegin() { return _eo_list_access_traits::ibegin(this->_impl._list); } eina::iterator iend() { return _eo_list_access_traits::iend(this->_impl._list); } eina::iterator ibegin() const { return _eo_list_access_traits::ibegin(this->_impl._list); } eina::iterator iend() const { return _eo_list_access_traits::iend(this->_impl._list); } eina::iterator cibegin() const { return _eo_list_access_traits::cibegin(this->_impl._list); } eina::iterator ciend() const { return _eo_list_access_traits::ciend(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 eina::accessor to the list. * * Version of @ref accessor() to const-qualified inline lists. Returns * a const-qualified eina::accessor instead. */ eina::accessor accessor() const { return eina::accessor(eina_list_accessor_new(this->_impl._list)); } /** * @brief Get a @ref eina::accessor for the list. * @return eina::accessor to the list. */ eina::accessor accessor() { return eina::accessor(eina_list_accessor_new(this->_impl._list)); } friend bool operator==(list const& rhs, list const& lhs) { return rhs.size() == lhs.size() && std::equal(rhs.begin(), rhs.end(), lhs.begin()); } }; template bool operator!=(list const& rhs, list const& lhs) { return !(rhs == lhs); } template class range_list : range_ptr_list { typedef range_ptr_list _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 class range_list::value>::type> : range_ptr_list::value, Eo const, Eo>::type> { typedef range_ptr_list::value, Eo const, Eo>::type> _base_type; typedef range_list _self_type; public: typedef T value_type; typedef value_type& reference; typedef value_type const& const_reference; typedef _ptr_eo_list_iterator const_iterator; typedef _ptr_eo_list_iterator 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 reverse_iterator; typedef std::reverse_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 const& other) : _base_type(other.native_handle()) { } range_list& operator=(range_listconst& 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(native_handle()); } reference back() { return _eo_list_access_traits::back(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(native_handle()); } iterator end() { return _eo_list_access_traits::end(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(native_handle()); } reverse_iterator rend() { return _eo_list_access_traits::rend(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 const& rhs, range_list const& lhs) { return rhs.size() == lhs.size() && std::equal(rhs.begin(), rhs.end(), lhs.begin()); } }; template using crange_list = range_list::type>; } } #endif