/* * 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_INLIST_HH_ #define EINA_INLIST_HH_ #include #include #include #include #include #include #include /** * @addtogroup Eina_Cxx_Containers_Group * * @{ */ namespace efl { namespace eina { /** * @defgroup Eina_Cxx_Inline_List_Group Inline List * @ingroup Eina_Cxx_Containers_Group * * @{ */ /** * @internal */ template struct _inlist_node { EINA_INLIST; T object; }; /** * @internal */ template _inlist_node* _get_node(Eina_Inlist* l) { return static_cast<_inlist_node*>(static_cast(l)); } /** * @internal */ template _inlist_node const* _get_node(Eina_Inlist const* l) { return const_cast(l); } /** * @internal */ template Eina_Inlist* _get_list(_inlist_node* n) { if(n) return EINA_INLIST_GET(n); else return 0; } /** * @internal */ template Eina_Inlist const* _get_list(_inlist_node const* n) { return _get_list(const_cast<_inlist_node*>(n)); } /** * @internal * Iterator for Inline List */ template struct _inlist_iterator { typedef typename std::remove_const::type value_type; /**< Type for the list elements. */ typedef value_type* pointer; /**< Type for a pointer to an element. */ typedef value_type& reference; /**< Type for a reference to an element. */ typedef std::ptrdiff_t difference_type; /**< Type to represent the distance between two iterators. */ typedef std::bidirectional_iterator_tag iterator_category; /**< Defines the iterator as being a bidirectional iterator. */ /** * @brief Default constructor. Creates an uninitialized iterator. */ _inlist_iterator() {} /** * @brief Creates an iterator from a inline list and a node. * @param list Pointer to the inline list. * @param node Pointer to the node. */ explicit _inlist_iterator(_inlist_node* list, _inlist_node* node) : _list(list), _node(node) {} /** * @brief Create a const iterator from this one. * @param other Other iterator. */ operator _inlist_iterator() { return _inlist_iterator{_list, _node}; } /** * @brief Move the iterator to the next position in the list. * @return The iterator itself. * * This operator increments the iterator, making it point to the * position right after the current one. * At the end, it returns a reference to itself. */ _inlist_iterator& operator++() { _node = _get_node(_node->__in_list.next); return *this; } /** * @brief Move the iterator to the next position in the list. * @return Copy of the iterator before the increment. * * This operator increments the iterator, making it point to the next * position right after the current one. * At the end, it returns a copy of the iterator before the increment. */ _inlist_iterator operator++(int) { _inlist_iterator tmp(*this); ++*this; return tmp; } /** * @brief Move the iterator to the previous position in the list. * @return The iterator itself. * * This operator decrements the iterator, making it point to the * position right before the current one. * At the end, it returns a reference to itself. */ _inlist_iterator& operator--() { if(_node) _node = _get_node(_node->__in_list.prev); else _node = _get_node(_list->__in_list.last); return *this; } /** * @brief Move the iterator to the previous position in the list. * @return Copy of the iterator before the decrement. * * This operator decrements the iterator, making it point to the * position right before the current one. * At the end, it returns a copy of the iterator before the decrement. */ _inlist_iterator operator--(int) { _inlist_iterator tmp(*this); --*this; return tmp; } /** * @brief Get a reference to the element currently pointed by the iterator. * @return Reference to the current element. */ T& operator*() const { return _node->object; } /** * @brief Return a pointer to the current element, which member will be accessed. * @return Pointer to the element currently pointed by the iterator. */ T* operator->() const { return &_node->object; } /** * @internal */ _inlist_node* native_handle() { return _node; } /** * @internal */ _inlist_node const* native_handle() const { return _node; } private: _inlist_node* _list; /**< Handle to the original list. */ _inlist_node* _node; /**< Handle to the current node. */ /** * @brief Check if both iterators are pointing to the same node. * @param lhs First iterator to be compared. * @param rhs Second iterator to be compared. * @return @c true if both iterators are pointing to the same node, @c false otherwise. */ template friend struct _inlist_iterator; friend bool operator==(_inlist_iterator lhs, _inlist_iterator rhs) { return lhs._node == rhs._node; } }; /** * @brief Check if iterators are not pointing to the same node. * @param lhs First iterator to be compared. * @param rhs Second iterator to be compared. * @return @c true if iterators are not pointing to the same node, @c false otherwise. */ template bool operator!=(_inlist_iterator lhs, _inlist_iterator rhs) { return !(lhs == rhs); } /** * @internal */ struct _inlist_access_traits { template struct const_iterator { typedef _inlist_iterator type; }; template struct iterator { typedef _inlist_iterator type; }; template struct const_native_handle { typedef Eina_Inlist const* type; }; template struct native_handle { typedef Eina_Inlist* type; }; template static Eina_Inlist* native_handle_from_const(Eina_Inlist const* list) { return const_cast(list); } template static std::size_t size(Eina_Inlist const* list) { return ::eina_inlist_count(list); } template static bool empty(Eina_Inlist const* list) { return list == 0; } template static T& back(Eina_Inlist* list) { return _get_node(list->last)->object; } template static T const& back(Eina_Inlist const* list) { return _inlist_access_traits::back(const_cast(list)); } template static T& front(Eina_Inlist* list) { return _get_node(list)->object; } template static T const& front(Eina_Inlist const* list) { return _inlist_access_traits::front(const_cast(list)); } template static _inlist_iterator begin(Eina_Inlist const* list) { return _inlist_access_traits::begin(const_cast(list)); } template static _inlist_iterator end(Eina_Inlist const* list) { return _inlist_access_traits::end(const_cast(list)); } template static _inlist_iterator begin(Eina_Inlist* list) { return _inlist_iterator(_get_node(list), _get_node(list)); } template static _inlist_iterator end(Eina_Inlist* list) { return _inlist_iterator(_get_node(list), 0); } template static std::reverse_iterator<_inlist_iterator > rbegin(Eina_Inlist* list) { return std::reverse_iterator<_inlist_iterator >(_inlist_access_traits::end(list)); } template static std::reverse_iterator<_inlist_iterator > rend(Eina_Inlist* list) { return std::reverse_iterator<_inlist_iterator >(_inlist_access_traits::begin(list)); } template static std::reverse_iterator<_inlist_iterator > rbegin(Eina_Inlist const* list) { return _inlist_access_traits::rbegin(const_cast(list)); } template static std::reverse_iterator<_inlist_iterator > rend(Eina_Inlist const* list) { return _inlist_access_traits::rend(const_cast(list)); } template static _inlist_iterator cbegin(Eina_Inlist const* list) { return _inlist_access_traits::begin(list); } template static _inlist_iterator cend(Eina_Inlist const* list) { return _inlist_access_traits::end(list); } template static std::reverse_iterator<_inlist_iterator > crbegin(Eina_Inlist const* list) { return _inlist_access_traits::rbegin(list); } template static std::reverse_iterator<_inlist_iterator > crend(Eina_Inlist const* list) { return _inlist_access_traits::rend(list); } }; template class inlist; /** * @ingroup Eina_Cxx_Range_Group * * Range for inline list elements. */ template struct range_inlist : _range_template { typedef _range_template _base_type; /**< Type for the base class. */ typedef typename _base_type::value_type value_type; /**< The type of each element. */ typedef typename _base_type::native_handle_type native_handle_type; /** Type for the native Eina inline list handle. */ /** * @brief Creates a range from a native Eina inline list handle. */ range_inlist(native_handle_type list) : _base_type(list) {} /** * @brief Creates a range from a inline list object. */ template range_inlist(inlist& list) : _base_type(list.native_handle()) {} }; /** * @brief Check the given ranges are equal to each other. * @param lhs Range object at the left side of the expression. * @param rhs Range object at the right side of the expression. * @return @c true if the ranges are equal, @c false otherwise. * * This operator checks if the given ranges are equal to each other. To * be considered equal both ranges need to have the same size, and each * element in one range must be equal to the element at the same * position in the other. */ template bool operator==(range_inlistconst& lhs, range_inlistconst& rhs) { return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin()); } /** * @brief Returns the opposite of @ref operator==(range_inlistconst& lhs, range_inlistconst& rhs). */ template bool operator!=(range_inlist const& lhs, range_inlistconst& rhs) { return !(lhs == rhs); } /** * Common implementations for inline list. */ template struct _inlist_common_base { typedef typename Allocator::template rebind<_inlist_node >::other node_allocator_type; /**< Type for the allocator of the node. */ typedef Allocator allocator_type; /**< Type for the allocator. */ typedef _inlist_node node_type; /**< Type for the list node. */ typedef Eina_Inlist* native_handle_type; /**< Native type. */ /** * @brief Creates a list with the given allocator. * @param allocator Allocator object. */ _inlist_common_base(Allocator allocator) : _impl(allocator) {} /** * @brief Wraps the native object. * @param inlist The native inlist object (Eina_Inlist*). */ _inlist_common_base(native_handle_type inlist) : _impl(inlist) {} /** * @brief Creates an empty inline list. */ _inlist_common_base() {} /** * @brief Destructor. Deallocate all nodes of the list. */ ~_inlist_common_base() { clear(); } /** * @brief Deallocate all nodes of the list. */ void clear() { Eina_Inlist* p = _impl._list; Eina_Inlist* q; while(p) { q = p->next; _inlist_node* node = _get_node(p); node->~_inlist_node(); get_node_allocator().deallocate(node, 1); p = q; } _impl._list = 0; } /** * @brief Get the allocator used by the list. */ node_allocator_type& get_node_allocator() { return _impl; } /** * @internal */ // For EBO struct _inlist_impl : node_allocator_type { _inlist_impl(Allocator allocator_) : node_allocator_type(allocator_), _list(0) {} explicit _inlist_impl(native_handle_type list) : _list(list) {} _inlist_impl() : _list(0) {} native_handle_type _list; }; _inlist_impl _impl; /**< @internal */ private: /** Disabled copy constructor. */ _inlist_common_base(_inlist_common_base const& other); /** Disabled assignment operator. */ _inlist_common_base& operator=(_inlist_common_base const& other); }; /** * C++ wrapper for the native Eina inline list. * * It provides an OOP interface to the @c Eina_Inlist functions, and * automatically take care of allocating and deallocating resources using * the RAII programming idiom. * * It also provides additional member functions to facilitate the access * to the list content, much like a STL list. */ template > class inlist : protected _inlist_common_base { typedef _inlist_common_base _base_type; /**< Type for the base class. */ typedef typename _base_type::node_type _node_type; /**< Type for each node */ public: typedef typename _base_type::allocator_type allocator_type; /**< Type for the allocator. */ typedef typename allocator_type::value_type value_type; /**< The type of each element. */ typedef typename allocator_type::reference reference; /**< Type for a reference to an element. */ typedef typename allocator_type::const_reference const_reference; /**< Type for a constant reference to an element. */ typedef _inlist_iterator const_iterator; /**< Type for constant iterator for this kind of container. */ typedef _inlist_iterator iterator; /**< Type for iterator for this kind of container. */ typedef typename allocator_type::pointer pointer; /**< Type for a pointer to an element. */ typedef typename allocator_type::const_pointer const_pointer; /**< Type for a constant pointer for an element. */ typedef std::size_t size_type; /**< Type for size information. */ typedef std::ptrdiff_t difference_type; /**< Type to represent the distance between two iterators. */ typedef typename _base_type::native_handle_type native_handle_type; /**< The native handle type. */ typedef std::reverse_iterator reverse_iterator; /**< Type for reverse iterator for this kind of container. */ typedef std::reverse_iterator const_reverse_iterator; /**< Type for constant reverse iterator for this kind of container. */ using _base_type::clear; /** * @brief Default constructor. Creates an empty inline list. */ inlist() {} /** * @brief Construct an inlist from a native object. * @param list The native object. */ inlist(native_handle_type list) : _inlist_common_base(list) {} /** * @brief Construct an inline list object with @p n copies of @p t. * @param n Number of elements. * @param t Value to be copied to each element. * * This constructor creates an inline list with @p n elements, each * one as a copy of @p t. */ inlist(size_type n, value_type const& t) { while(n--) push_back(t); } /** * @brief Create a inline list coping the elements from the given range. * @param i Iterator to the initial position. The element pointed by this iterator will be copied. * @param j Iterator to the final position. The element pointed by this iterator will NOT be copied. * * This constructor creates a inline list with copies of the elements * between @p i and @p j in the same order. * * @note The ending element (pointed by @p j) is not copied. */ template inlist(InputIterator i, InputIterator const& j , allocator_type const& alloc = allocator_type() , typename eina::enable_if::value>::type* = 0) : _base_type(alloc) { while(i != j) { push_back(*i); ++i; } } /** * @brief Copy constructor. Creates a copy of the given inline list. * @param other Another inline list of the same type. * * This constructor creates an inline list containing a copy of each * element inside @p other in the same order. */ inlist(inlistconst& other) : _base_type() { insert(end(), other.begin(), other.end()); } /** * @brief Replace current content with the content of another inline list. * @param other Another inline list of the same type. * * This assignment operator replaces the content of the list by a copy * of the content of @p other. The list size is adjusted accordingly * and the newly copied elements keep their original order. */ inlist& operator=(inlistconst& other) { clear(); insert(end(), other.begin(), other.end()); return *this; } /** * @brief Get the current size of the inline list. * @return Number of elements in the inline list. * * This member function returns the current number of elements inside * the inline list. */ size_type size() const { return _inlist_access_traits::size(native_handle()); } /** * @brief Check if the inline list is empty. * @return @c true if the inline list is empty, @c false otherwise. * * This member function returns @c true if the inline list does not * contain any elements, otherwise it returns @c false. */ bool empty() const { return _inlist_access_traits::empty(native_handle()); } /** * @brief Get the allocator used in this inline list. */ allocator_type get_allocator() const { return allocator_type(this->get_node_allocator()); } /** * @brief Add a copy of the given element at the end of the inline list. * @param value Element to be added at the end of the inline list. * * This member function allocates a new element at the end of the * inline list, the content of @p value is copied to the new element. */ void push_back(T const& value) { _node_type* node ( this->get_node_allocator().allocate(1) ); try { new (&node->object) T(value); // eina_inlist_append can't fail this->_impl._list = eina_inlist_append(this->_impl._list, _get_list(node)); } catch(...) { this->get_node_allocator().deallocate(node, 1); throw; } } /** * @brief Add a copy of the given element at the beginning of the inline list. * @param value Element to be added at the beginning of the inline list. * * This member function allocates a new element at the beginning of * the inline list, the content of @p value is copied to the new * element. */ void push_front(T const& value) { _node_type* node ( this->get_node_allocator().allocate(1) ); try { new (&node->object) T(value); // eina_inlist_prepend can't fail this->_impl._list = eina_inlist_prepend(this->_impl._list, _get_list(node)); } catch(...) { this->get_node_allocator().deallocate(node, 1); throw; } } /** * @brief Remove the last element of the inline list. */ void pop_back() { this->_impl._list = eina_inlist_remove(this->_impl._list, this->_impl._list->last); } /** * @brief Remove the first element of the inline list. */ void pop_front() { this->_impl._list = eina_inlist_remove(this->_impl._list, this->_impl._list); } /** * @brief Insert a new element at the given position. * @param i Iterator pointing to the position where the new element will be inserted. * @param t Value to be copied to the new element. * @return Iterator pointing to the new element inserted. * * This member function inserts a copy of the element @p t at the * position @p i. The new element comes right before the element * originally pointed by @p i. * * At the end, a valid iterator pointing to the element just inserted * is returned. */ iterator insert(iterator i, value_type const& t) { _node_type* node ( this->get_node_allocator().allocate(1) ); try { new (&node->object) T(t); // eina_inlist_prepend_relative can't fail this->_impl._list = _eina_inlist_prepend_relative (this->_impl._list, _get_list(node) , _get_list(i.native_handle())); return iterator(_get_node(this->_impl._list), node); } catch(...) { this->get_node_allocator().deallocate(node, 1); throw; } } /** * @brief Insert @p n copies of @p t at the given position. * @param i Iterator pointing to the position where the new elements will be inserted. * @param n Number of elements to be inserted. * @param t Value to be copied to each new inserted element. * @return Iterator pointing to the first inserted element. * * This member function inserts @p n new elements at position @p i * in the inline list, each one as a copy of @p t. The new elements * come right before the element originally pointed by @p i. * * At the end, a valid iterator pointing to the first element inserted * is returned. */ iterator insert(iterator i, size_t n, value_type const& t) { iterator r = i; if(n--) r = insert(i, t); while(n--) insert(i, t); return r; } /** * @brief Insert the elements between the given range at the given position. * @param p Iterator pointing to the position where the new elements will be inserted. * @param i Iterator to the initial position. The element pointed by this iterator will be copied. * @param j Iterator to the final position. The element pointed by this iterator will NOT be copied. * @return Iterator pointing to the first inserted element. * * This member function inserts a copy of the elements between @p i * and @p j at the position @p p. The new elements come right before * the element originally pointed by @p p. Note that the element * pointed by @p j is not copied. */ template iterator insert(iterator p, InputIterator i, InputIterator j , typename eina::enable_if::value>::type* = 0) { iterator r = p; if(i != j) { value_type v = *i; r = insert(p, v); ++i; } while(i != j) { insert(p, *i); ++i; } return r; } /** * @brief Remove the element at the given position. * @param q Iterator pointing to the element to be removed. * @return Iterator pointing to the element after the removed one. * * This member function removes the element pointed by the iterator * @p q, reducing the list size by one. At the end, a valid iterator * pointing to the element right after the removed one is returned. */ iterator erase(iterator q) { if(q.native_handle()) { iterator r(_get_node(this->_impl._list), _get_node(_get_list(q.native_handle())->next)); this->_impl._list = eina_inlist_remove(this->_impl._list, _get_list(q.native_handle())); return r; } else return q; } /** * @brief Remove the elements between the given range. * @param i Iterator pointing to the starting position to be removed. * @param j Iterator pointing to the ending position to be removed. * The element pointed by this iterator is not removed. * @return Iterator pointing to the new position of the first * non-removed element after the removed ones (i.e. the one * originally pointed by @p j). * * This member function removes the elements between the iterators * @p i and @p j, including the element pointed by @p i but not the * element pointed by @j. */ iterator erase(iterator i, iterator j) { while(i != j) i = erase(i); if(j.native_handle()) return j; else return end(); } /** * @brief Replace the content of the inline list by the elements in the given range. * @param i Iterator pointing to the beginning of the elements to be copied. * @param j Iterator pointing to the end of the elements to be copied. * Note that the element pointed by j will NOT be copied. * * This member function replaces the current elements by copies of the * elements between the iterators @p i and @p j, including the element * pointed by @p i but not the one pointed by @p j. The size of the * list is adjusted accordingly and the newly copied elements remain * in their original order. */ template void assign(InputIterator i, InputIterator j , typename eina::enable_if::value>::type* = 0) { clear(); insert(end(), i, j); } /** * @brief Replace the content of the inline list by @p n copies @p t. * @param n Number of elements. * @param t Value to be copied to each element. */ void assign(size_type n, value_type const& t) { clear(); insert(end(), n, t); } /** * @brief Get a reference to the last element. * @return Reference to the last element in the inline list. */ value_type& back() { return _inlist_access_traits::back(native_handle()); } /** * @brief Get a constant reference to the last element. * @return Constant reference to the last element in the inline list. * * Version of @ref back() for const-qualified inline list objects. * Returns a constant reference instead. */ value_type const& back() const { return _inlist_access_traits::back(native_handle()); } /** * @brief Get a reference to the first element. * @return Reference to the first element of the inline list. */ value_type& front() { return _inlist_access_traits::front(native_handle()); } /** * @brief Get a constant reference to the first element. * @return Constant reference to the first element of the inline list. * * Version of @ref front() for const-qualified inline list objects. * Returns a constant reference instead. */ value_type const& front() const { return _inlist_access_traits::front(native_handle()); } /** * @brief Get a constant iterator pointing to the first element of the inline list. * @return Constant iterator to the initial position of the inline list. * * Version of @ref begin() for const-qualified inline list objects. * Returns a constant iterator instead. */ const_iterator begin() const { return _inlist_access_traits::begin(native_handle()); } /** * @brief Get a constant iterator to the position following the last element of the inline list. * @return Constant iterator to the final position of the inline list. * * Version of @ref end() for const-qualified inline list objects. * Returns a constant iterator instead. */ const_iterator end() const { return _inlist_access_traits::end(native_handle()); } /** * @brief Get an iterator pointing to the first element of the inline list. * @return Iterator to the initial position of the inline list. * * This member function returns an iterator pointing to the first * element of the inline list. If the list is empty the returned * iterator is the same as the one returned by @ref end(). */ iterator begin() { return _inlist_access_traits::begin(native_handle()); } /** * @brief Get an iterator to the position following the last element of the inline list. * @return Iterator to the final position of the inline list. * * This member function returns an iterator to the position following * the last element in the inline list. If the list is empty the * returned iterator is the same as the one returned by @ref begin(). * * @note Note that attempting to access this position causes undefined * behavior. */ iterator end() { return _inlist_access_traits::end(native_handle()); } /** * @brief Get a constant reverse iterator pointing to the reverse begin of the inline list. * @return Constant reverse iterator pointing to the reverse begin of the inline list. * * Version of @ref rbegin() for const-qualified inline list objects. * Returns a constant reverse iterator instead. */ const_reverse_iterator rbegin() const { return reverse_iterator(end()); } /** * @brief Get a constant reverse iterator pointing to the reverse end of the inline list. * @return Constant reverse iterator pointing to the reverse end of the inline list. * * Version of @ref rend() for const-qualified inline list objects. * Returns a constant reverse iterator instead. */ const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } /** * @brief Get a reverse iterator pointing to the reverse begin of the inline list. * @return Reverse iterator pointing to the reverse begin of the inline list. * * This member function returns a reverse iterator pointing to the * last element of the inline list. If the list is empty the returned * reverse iterator is the same as the one returned by @ref rend(). */ reverse_iterator rbegin() { return reverse_iterator(end()); } /** * @brief Get a reverse iterator pointing to the reverse end of the inline list. * @return Reverse iterator pointing to the reverse end of the inline list. * * This member function returns a reverse iterator pointing to the * position before the first element of the inline list. If the list * is empty the returned iterator is the same as the one returned by * @ref rbegin(). * * @note Note that attempting to access this position causes undefined * behavior. */ reverse_iterator rend() { return reverse_iterator(begin()); } /** * @brief Get a constant iterator pointing to the first element of the inline list. * @return Constant iterator to the initial position of the inline list. * * This member function works like @ref begin() const but is granted * to return a constant iterator even for lists that are not * const-qualified. */ const_iterator cbegin() const { return begin(); } /** * @brief Get a constant iterator to the position following the last element of the inline list. * @return Constant iterator to the final position of the inline list. * * This member function works like @ref end() const but is granted to * return a constant iterator even for lists that are not * const-qualified. */ const_iterator cend() const { return end(); } /** * @brief Get a constant reverse iterator pointing to the reverse begin of the inline list. * @return Constant reverse iterator pointing to the reverse begin of the inline list. * * This member function works like @ref rbegin() const but is granted * to return a constant reverse iterator even for lists that are not * const-qualified. */ const_reverse_iterator crbegin() const { return rbegin(); } /** * @brief Get a constant reverse iterator pointing to the reverse end of the inline list. * @return Constant reverse iterator pointing to the reverse end of the inline list. * * This member function works like @ref rend() const but is granted to * return a constant reverse iterator even for lists that are not * const-qualified. */ const_reverse_iterator crend() const { return rend(); } /** * @brief Swap content between two inline lists. * @param other Other inline list of the same type. */ void swap(inlist& other) { std::swap(this->_impl._list, other._impl._list); } /** * @brief Get the maximum number of elements a inline list can hold. * @return Maximum number of elements a inline list can hold. */ size_type max_size() const { return -1; } /** * @brief Get the handle for the wrapped Eina_Inlist. * @return Internal handle for the native Eina inline list. * * This member function returns the native Eina_Inlist handle that is * wrapped inside this object. * * @warning It is important to take care when using it, since the * handle will be automatically release upon object destruction. */ Eina_Inlist* native_handle() { return this->_impl._list; } /** * @brief Get the handle for the wrapped Eina_Inlist. * @return Internal handle for the native Eina inline list. * * This member function returns the native Eina_Inlist handle that is * wrapped inside this object. * * @warning It is important to take care when using it, since the * handle will be automatically release upon object destruction. */ Eina_Inlist const* native_handle() const { return this->_impl._list; } /** * @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_inlist_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_inlist_accessor_new(this->_impl._list)); } }; /** * @brief Check if two inline lists are equal. * @param lhs Inline list at the left side of the expression. * @param rhs Inline list at the right side of the expression. * @return @c true if the lists are equals, @c false otherwise. * * This operator checks if the given inline lists are equal. To be * considered equal both lists need to have the same number of elements, * and each element in one list must be equal to the element at the same * position in the other list. */ template bool operator==(inlist const& lhs, inlist const& rhs) { return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin()); } /** * @brief Return the opposite of @ref operator==(inlist const& lhs, inlist const& rhs). */ template bool operator!=(inlist const& lhs, inlist const& rhs) { return !(lhs == rhs); } /** * @brief Swap content between two inline lists. * @param other Other inline list of the same type. */ template void swap(inlist& lhs, inlist& rhs) { lhs.swap(rhs); } /** * @} */ } } /** * @} */ #endif