diff options
Diffstat (limited to 'include/EASTL/bonus/intrusive_sdlist.h')
-rw-r--r-- | include/EASTL/bonus/intrusive_sdlist.h | 694 |
1 files changed, 0 insertions, 694 deletions
diff --git a/include/EASTL/bonus/intrusive_sdlist.h b/include/EASTL/bonus/intrusive_sdlist.h deleted file mode 100644 index 1b126d4..0000000 --- a/include/EASTL/bonus/intrusive_sdlist.h +++ /dev/null @@ -1,694 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (c) Electronic Arts Inc. All rights reserved. -///////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// intrusive_sdlist is a special kind of intrusive list which we say is -// "singly-doubly" linked. Instead of having a typical intrusive list node -// which looks like this: -// -// struct intrusive_sdlist_node { -// intrusive_sdlist_node *mpNext; -// intrusive_sdlist_node *mpPrev; -// }; -// -// We instead have one that looks like this: -// -// struct intrusive_sdlist_node { -// intrusive_sdlist_node* mpNext; -// intrusive_sdlist_node** mppPrevNext; -// }; -// -// This may seem to be suboptimal, but it has one specific advantage: it allows -// the intrusive_sdlist class to be the size of only one pointer instead of two. -// This may seem like a minor optimization, but some users have wanted to create -// thousands of empty instances of these. -// This is because while an intrusive_list class looks like this: -// -// class intrusive_list { -// intrusive_list_node mBaseNode; -// }; -// -// an intrusive_sdlist class looks like this: -// -// class intrusive_sdlist { -// intrusive_sdlist_node* mpNext; -// }; -// -// So here we make a list of plusses and minuses of intrusive sdlists -// compared to intrusive_lists and intrusive_slists: -// -// | list | slist | sdlist -// --------------------------------------------------------- -// min size | 8 | 4 | 4 -// node size | 8 | 4 | 8 -// anonymous erase | yes | no | yes -// reverse iteration | yes | no | no -// -/////////////////////////////////////////////////////////////////////////////// - - -#ifndef EASTL_INTRUSIVE_SDLIST_H -#define EASTL_INTRUSIVE_SDLIST_H - - -#include <EASTL/internal/config.h> -#include <EASTL/iterator.h> -#include <EASTL/algorithm.h> - -#if defined(EA_PRAGMA_ONCE_SUPPORTED) - #pragma once // Some compilers (e.g. VC++) benefit significantly from using this. We've measured 3-4% build speed improvements in apps as a result. -#endif - - - -namespace eastl -{ - - - /// intrusive_sdlist_node - /// - struct intrusive_sdlist_node - { - intrusive_sdlist_node* mpNext; - intrusive_sdlist_node** mppPrevNext; - }; - - - /// IntrusiveSDListIterator - /// - template <typename T, typename Pointer, typename Reference> - struct IntrusiveSDListIterator - { - typedef IntrusiveSDListIterator<T, Pointer, Reference> this_type; - typedef IntrusiveSDListIterator<T, T*, T&> iterator; - typedef IntrusiveSDListIterator<T, const T*, const T&> const_iterator; - typedef eastl_size_t size_type; // See config.h for the definition of eastl_size_t, which defaults to size_t. - typedef ptrdiff_t difference_type; - typedef T value_type; - typedef T node_type; - typedef Pointer pointer; - typedef Reference reference; - typedef EASTL_ITC_NS::forward_iterator_tag iterator_category; - - public: - pointer mpNode; - - public: - IntrusiveSDListIterator(); - explicit IntrusiveSDListIterator(pointer pNode); // Note that you can also construct an iterator from T via this, since value_type == node_type. - IntrusiveSDListIterator(const iterator& x); - - reference operator*() const; - pointer operator->() const; - - this_type& operator++(); - this_type operator++(int); - - }; // struct IntrusiveSDListIterator - - - - - /// intrusive_sdlist_base - /// - /// Provides a template-less base class for intrusive_sdlist. - /// - class intrusive_sdlist_base - { - public: - typedef eastl_size_t size_type; // See config.h for the definition of eastl_size_t, which defaults to size_t. - typedef ptrdiff_t difference_type; - - protected: - intrusive_sdlist_node* mpNext; - - public: - intrusive_sdlist_base(); - - bool empty() const; ///< Returns true if the container is empty. - size_type size() const; ///< Returns the number of elements in the list; O(n). - - void clear(); ///< Clears the list; O(1). No deallocation occurs. - void pop_front(); ///< Removes an element from the front of the list; O(1). The element must be present, but is not deallocated. - void reverse(); ///< Reverses a list so that front and back are swapped; O(n). - - //bool validate() const; ///< Scans a list for linkage inconsistencies; O(n) time, O(1) space. Returns false if errors are detected, such as loops or branching. - - }; // class intrusive_sdlist_base - - - - /// intrusive_sdlist - /// - template <typename T = intrusive_sdlist_node> - class intrusive_sdlist : public intrusive_sdlist_base - { - public: - typedef intrusive_sdlist<T> this_type; - typedef intrusive_sdlist_base base_type; - typedef T node_type; - typedef T value_type; - typedef typename base_type::size_type size_type; - typedef typename base_type::difference_type difference_type; - typedef T& reference; - typedef const T& const_reference; - typedef T* pointer; - typedef const T* const_pointer; - typedef IntrusiveSDListIterator<T, T*, T&> iterator; - typedef IntrusiveSDListIterator<T, const T*, const T&> const_iterator; - typedef eastl::reverse_iterator<iterator> reverse_iterator; - typedef eastl::reverse_iterator<const_iterator> const_reverse_iterator; - - public: - intrusive_sdlist(); ///< Creates an empty list. - intrusive_sdlist(const this_type& x); ///< Creates an empty list; ignores the argument. - this_type& operator=(const this_type& x); ///< Clears the list; ignores the argument. - - iterator begin(); ///< Returns an iterator pointing to the first element in the list. - const_iterator begin() const; ///< Returns a const_iterator pointing to the first element in the list. - const_iterator cbegin() const; ///< Returns a const_iterator pointing to the first element in the list. - - iterator end(); ///< Returns an iterator pointing one-after the last element in the list. - const_iterator end() const; ///< Returns a const_iterator pointing one-after the last element in the list. - const_iterator cend() const; ///< Returns a const_iterator pointing one-after the last element in the list. - - reference front(); ///< Returns a reference to the first element. The list must be empty. - const_reference front() const; ///< Returns a const reference to the first element. The list must be empty. - - void push_front(value_type& value); ///< Adds an element to the front of the list; O(1). The element is not copied. The element must not be in any other list. - void push_back(value_type& value); ///< Adds an element to the back of the list; O(N). The element is not copied. The element must not be in any other list. - void pop_back(); ///< Removes an element from the back of the list; O(N). The element must be present, but is not deallocated. - - bool contains(const value_type& value) const; ///< Returns true if the given element is in the list; O(n). Equivalent to (locate(x) != end()). - - iterator locate(value_type& value); ///< Converts a reference to an object in the list back to an iterator, or returns end() if it is not part of the list. O(n) - const_iterator locate(const value_type& value) const; ///< Converts a const reference to an object in the list back to a const iterator, or returns end() if it is not part of the list. O(n) - - iterator insert(iterator position, value_type& value); ///< Inserts an element before the element pointed to by the iterator. O(1) - iterator erase(iterator position); ///< Erases the element pointed to by the iterator. O(1) - iterator erase(iterator first, iterator last); ///< Erases elements within the iterator range [first, last). O(1). - void swap(intrusive_sdlist& x); ///< Swaps the contents of two intrusive lists; O(1). - - static void remove(value_type& value); ///< Erases an element from a list; O(1). Note that this is static so you don't need to know which list the element, although it must be in some list. - - void splice(iterator position, value_type& value); ///< Moves the given element into this list before the element pointed to by position; O(1). - ///< Required: x must be in some list or have first/next pointers that point it itself. - - void splice(iterator position, this_type& x); ///< Moves the contents of a list into this list before the element pointed to by position; O(1). - ///< Required: &x != this (same as std::list). - - void splice(iterator position, this_type& x, iterator xPosition); ///< Moves the given element pointed to i within the list x into the current list before - ///< the element pointed to by position; O(1). - - void splice(iterator position, this_type& x, iterator first, iterator last); ///< Moves the range of elements [first, last) from list x into the current list before - ///< the element pointed to by position; O(1). - ///< Required: position must not be in [first, last). (same as std::list). - bool validate() const; - int validate_iterator(const_iterator i) const; - - }; // intrusive_sdlist - - - - - /////////////////////////////////////////////////////////////////////// - // IntrusiveSDListIterator functions - /////////////////////////////////////////////////////////////////////// - - template <typename T, typename Pointer, typename Reference> - inline IntrusiveSDListIterator<T, Pointer, Reference>::IntrusiveSDListIterator() - { - #if EASTL_DEBUG - mpNode = NULL; - #endif - } - - template <typename T, typename Pointer, typename Reference> - inline IntrusiveSDListIterator<T, Pointer, Reference>::IntrusiveSDListIterator(pointer pNode) - : mpNode(pNode) - { - } - - template <typename T, typename Pointer, typename Reference> - inline IntrusiveSDListIterator<T, Pointer, Reference>::IntrusiveSDListIterator(const iterator& x) - : mpNode(x.mpNode) - { - } - - template <typename T, typename Pointer, typename Reference> - inline typename IntrusiveSDListIterator<T, Pointer, Reference>::reference - IntrusiveSDListIterator<T, Pointer, Reference>::operator*() const - { - return *mpNode; - } - - template <typename T, typename Pointer, typename Reference> - inline typename IntrusiveSDListIterator<T, Pointer, Reference>::pointer - IntrusiveSDListIterator<T, Pointer, Reference>::operator->() const - { - return mpNode; - } - - template <typename T, typename Pointer, typename Reference> - inline typename IntrusiveSDListIterator<T, Pointer, Reference>::this_type& - IntrusiveSDListIterator<T, Pointer, Reference>::operator++() - { - mpNode = static_cast<node_type*>(mpNode->mpNext); - return *this; - } - - template <typename T, typename Pointer, typename Reference> - inline typename IntrusiveSDListIterator<T, Pointer, Reference>::this_type - IntrusiveSDListIterator<T, Pointer, Reference>::operator++(int) - { - this_type temp = *this; - mpNode = static_cast<node_type*>(mpNode->mpNext); - return temp; - } - - // The C++ defect report #179 requires that we support comparisons between const and non-const iterators. - // Thus we provide additional template paremeters here to support this. The defect report does not - // require us to support comparisons between reverse_iterators and const_reverse_iterators. - template <typename T, typename PointerA, typename ReferenceA, typename PointerB, typename ReferenceB> - inline bool operator==(const IntrusiveSDListIterator<T, PointerA, ReferenceA>& a, - const IntrusiveSDListIterator<T, PointerB, ReferenceB>& b) - { - return a.mpNode == b.mpNode; - } - - - template <typename T, typename PointerA, typename ReferenceA, typename PointerB, typename ReferenceB> - inline bool operator!=(const IntrusiveSDListIterator<T, PointerA, ReferenceA>& a, - const IntrusiveSDListIterator<T, PointerB, ReferenceB>& b) - { - return a.mpNode != b.mpNode; - } - - - // We provide a version of operator!= for the case where the iterators are of the - // same type. This helps prevent ambiguity errors in the presence of rel_ops. - template <typename T, typename Pointer, typename Reference> - inline bool operator!=(const IntrusiveSDListIterator<T, Pointer, Reference>& a, - const IntrusiveSDListIterator<T, Pointer, Reference>& b) - { - return a.mpNode != b.mpNode; - } - - - - /////////////////////////////////////////////////////////////////////// - // intrusive_sdlist_base - /////////////////////////////////////////////////////////////////////// - - inline intrusive_sdlist_base::intrusive_sdlist_base() - { mpNext = NULL; } - - - inline bool intrusive_sdlist_base::empty() const - { return mpNext == NULL; } - - - inline intrusive_sdlist_base::size_type intrusive_sdlist_base::size() const - { - size_type n = 0; - for(const intrusive_sdlist_node* pCurrent = mpNext; pCurrent; pCurrent = pCurrent->mpNext) - n++; - return n; - } - - - inline void intrusive_sdlist_base::clear() - { mpNext = NULL; } // Note that we don't do anything with the list nodes. - - - inline void intrusive_sdlist_base::pop_front() - { - // To consider: Set mpNext's pointers to NULL in debug builds. - mpNext = mpNext->mpNext; - mpNext->mppPrevNext = &mpNext; - } - - - - /////////////////////////////////////////////////////////////////////// - // intrusive_sdlist - /////////////////////////////////////////////////////////////////////// - - template <typename T> - inline intrusive_sdlist<T>::intrusive_sdlist() - { - } - - - template <typename T> - inline intrusive_sdlist<T>::intrusive_sdlist(const this_type& /*x*/) - : intrusive_sdlist_base() - { - // We intentionally ignore argument x. - } - - - template <typename T> - inline typename intrusive_sdlist<T>::this_type& intrusive_sdlist<T>::operator=(const this_type& /*x*/) - { - return *this; // We intentionally ignore argument x. - } - - - template <typename T> - inline typename intrusive_sdlist<T>::iterator intrusive_sdlist<T>::begin() - { return iterator(static_cast<T*>(mpNext)); } - - - template <typename T> - inline typename intrusive_sdlist<T>::const_iterator intrusive_sdlist<T>::begin() const - { return const_iterator(static_cast<T*>(const_cast<intrusive_sdlist_node*>(mpNext))); } - - - template <typename T> - inline typename intrusive_sdlist<T>::const_iterator intrusive_sdlist<T>::cbegin() const - { return const_iterator(static_cast<T*>(const_cast<intrusive_sdlist_node*>(mpNext))); } - - - template <typename T> - inline typename intrusive_sdlist<T>::iterator intrusive_sdlist<T>::end() - { return iterator(static_cast<T*>(NULL)); } - - - template <typename T> - inline typename intrusive_sdlist<T>::const_iterator intrusive_sdlist<T>::end() const - { return const_iterator(static_cast<const T*>(NULL)); } - - - template <typename T> - inline typename intrusive_sdlist<T>::const_iterator intrusive_sdlist<T>::cend() const - { return const_iterator(static_cast<const T*>(NULL)); } - - - template <typename T> - inline typename intrusive_sdlist<T>::reference intrusive_sdlist<T>::front() - { return *static_cast<T*>(mpNext); } - - - template <typename T> - inline typename intrusive_sdlist<T>::const_reference intrusive_sdlist<T>::front() const - { return *static_cast<const T*>(mpNext); } - - - template <typename T> - inline void intrusive_sdlist<T>::push_front(value_type& value) - { - value.mpNext = mpNext; - value.mppPrevNext = &mpNext; - if(mpNext) - mpNext->mppPrevNext = &value.mpNext; - mpNext = &value; - } - - - template <typename T> - inline void intrusive_sdlist<T>::push_back(value_type& value) - { - intrusive_sdlist_node* pNext = mpNext; - intrusive_sdlist_node** ppPrevNext = &mpNext; - - while(pNext) - { - ppPrevNext = &pNext->mpNext; - pNext = pNext->mpNext; - } - - *ppPrevNext = &value; - value.mppPrevNext = ppPrevNext; - value.mpNext = NULL; - } - - - template <typename T> - inline void intrusive_sdlist<T>::pop_back() - { - node_type* pCurrent = static_cast<node_type*>(mpNext); - - while(pCurrent->mpNext) - pCurrent = static_cast<node_type*>(pCurrent->mpNext); - - *pCurrent->mppPrevNext = NULL; - } - - template <typename T> - inline bool intrusive_sdlist<T>::contains(const value_type& value) const - { - const intrusive_sdlist_node* pCurrent; - - for(pCurrent = mpNext; pCurrent; pCurrent = pCurrent->mpNext) - { - if(pCurrent == &value) - break; - } - - return (pCurrent != NULL); - } - - - template <typename T> - inline typename intrusive_sdlist<T>::iterator intrusive_sdlist<T>::locate(value_type& value) - { - intrusive_sdlist_node* pCurrent; - - for(pCurrent = static_cast<value_type*>(mpNext); pCurrent; pCurrent = pCurrent->mpNext) - { - if(pCurrent == &value) - break; - } - - return iterator(static_cast<value_type*>(pCurrent)); - } - - - template <typename T> - inline typename intrusive_sdlist<T>::const_iterator intrusive_sdlist<T>::locate(const T& value) const - { - const intrusive_sdlist_node* pCurrent; - - for(pCurrent = static_cast<value_type*>(mpNext); pCurrent; pCurrent = pCurrent->mpNext) - { - if(pCurrent == &value) - break; - } - - return const_iterator(static_cast<value_type*>(const_cast<intrusive_sdlist_node*>(pCurrent))); - } - - - template <typename T> - inline typename intrusive_sdlist<T>::iterator - intrusive_sdlist<T>::insert(iterator position, value_type& value) - { - value.mppPrevNext = position.mpNode->mppPrevNext; - value.mpNext = position.mpNode; - *value.mppPrevNext = &value; - position.mpNode->mppPrevNext = &value.mpNext; - - return iterator(&value); - } - - - template <typename T> - inline typename intrusive_sdlist<T>::iterator - intrusive_sdlist<T>::erase(iterator position) - { - *position.mpNode->mppPrevNext = position.mpNode->mpNext; - position.mpNode->mpNext->mppPrevNext = position.mpNode->mppPrevNext; - - return iterator(position.mpNode); - } - - - template <typename T> - inline typename intrusive_sdlist<T>::iterator - intrusive_sdlist<T>::erase(iterator first, iterator last) - { - if(first.mpNode) // If not erasing the end... - { - *first.mpNode->mppPrevNext = last.mpNode; - - if(last.mpNode) // If not erasing to the end... - last.mpNode->mppPrevNext = first.mpNode->mppPrevNext; - } - - return last; - } - - - template <typename T> - inline void intrusive_sdlist<T>::remove(value_type& value) - { - *value.mppPrevNext = value.mpNext; - if(value.mpNext) - value.mpNext->mppPrevNext = value.mppPrevNext; - } - - - template <typename T> - void intrusive_sdlist<T>::swap(intrusive_sdlist& x) - { - // swap anchors - intrusive_sdlist_node* const temp(mpNext); - mpNext = x.mpNext; - x.mpNext = temp; - - if(x.mpNext) - x.mpNext->mppPrevNext = &mpNext; - - if(mpNext) - mpNext->mppPrevNext = &x.mpNext; - } - - - - - - // To do: Complete these splice functions. Might want to look at intrusive_sdlist for help. - - template <typename T> - void intrusive_sdlist<T>::splice(iterator /*position*/, value_type& /*value*/) - { - EASTL_ASSERT(false); // If you need this working, ask Paul Pedriana or submit a working version for inclusion. - } - - - template <typename T> - void intrusive_sdlist<T>::splice(iterator /*position*/, intrusive_sdlist& /*x*/) - { - EASTL_ASSERT(false); // If you need this working, ask Paul Pedriana or submit a working version for inclusion. - } - - - template <typename T> - void intrusive_sdlist<T>::splice(iterator /*position*/, intrusive_sdlist& /*x*/, iterator /*xPosition*/) - { - EASTL_ASSERT(false); // If you need this working, ask Paul Pedriana or submit a working version for inclusion. - } - - - template <typename T> - void intrusive_sdlist<T>::splice(iterator /*position*/, intrusive_sdlist& /*x*/, iterator /*first*/, iterator /*last*/) - { - EASTL_ASSERT(false); // If you need this working, ask Paul Pedriana or submit a working version for inclusion. - } - - - template <typename T> - inline bool intrusive_sdlist<T>::validate() const - { - return true; // To do. - } - - - template <typename T> - inline int intrusive_sdlist<T>::validate_iterator(const_iterator i) const - { - // To do: Come up with a more efficient mechanism of doing this. - - for(const_iterator temp = begin(), tempEnd = end(); temp != tempEnd; ++temp) - { - if(temp == i) - return (isf_valid | isf_current | isf_can_dereference); - } - - if(i == end()) - return (isf_valid | isf_current); - - return isf_none; - } - - - - - /////////////////////////////////////////////////////////////////////// - // global operators - /////////////////////////////////////////////////////////////////////// - - template <typename T> - bool operator==(const intrusive_sdlist<T>& a, const intrusive_sdlist<T>& b) - { - // If we store an mSize member for intrusive_sdlist, we want to take advantage of it here. - typename intrusive_sdlist<T>::const_iterator ia = a.begin(); - typename intrusive_sdlist<T>::const_iterator ib = b.begin(); - typename intrusive_sdlist<T>::const_iterator enda = a.end(); - typename intrusive_sdlist<T>::const_iterator endb = b.end(); - - while((ia != enda) && (ib != endb) && (*ia == *ib)) - { - ++ia; - ++ib; - } - return (ia == enda) && (ib == endb); - } - - template <typename T> - bool operator<(const intrusive_sdlist<T>& a, const intrusive_sdlist<T>& b) - { - return eastl::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end()); - } - - template <typename T> - bool operator!=(const intrusive_sdlist<T>& a, const intrusive_sdlist<T>& b) - { - return !(a == b); - } - - template <typename T> - bool operator>(const intrusive_sdlist<T>& a, const intrusive_sdlist<T>& b) - { - return b < a; - } - - template <typename T> - bool operator<=(const intrusive_sdlist<T>& a, const intrusive_sdlist<T>& b) - { - return !(b < a); - } - - template <typename T> - bool operator>=(const intrusive_sdlist<T>& a, const intrusive_sdlist<T>& b) - { - return !(a < b); - } - - template <typename T> - void swap(intrusive_sdlist<T>& a, intrusive_sdlist<T>& b) - { - a.swap(b); - } - - -} // namespace eastl - - -#endif // Header include guard - - - - - - - - - - - - - - - - - - - - - - - - |