/* -*- c++ -*- */ /* * Copyright (C) 2010 The Android Open Source Project * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef ANDROID_ASTL_LIST__ #define ANDROID_ASTL_LIST__ #include #include #include #include // Double linked list. In the android NS we declare the nodes and // iterators. The list declaration in the std NS follows that. namespace android { struct ListNodeBase { ListNodeBase *mNext; ListNodeBase *mPrev; // Swap 2 nodes. static void swap(ListNodeBase& a, ListNodeBase& b); // Insert this node BEFORE pos. void hook(ListNodeBase * const pos); // Remove this node and link prev and next together. void unhook(); }; template struct ListNode: public ListNodeBase { _T mData; }; // iterators: ListIterator and ListConstIterator are bidirectional ones. template struct ListIterator { typedef ListIterator<_T> iterator_type; typedef android::ListNode<_T> node_type; public: typedef ptrdiff_t difference_type; typedef std::bidirectional_iterator_tag iterator_category; typedef _T value_type; typedef _T* pointer; typedef _T& reference; ListIterator(): mNode() { } explicit ListIterator(android::ListNodeBase* node): mNode(node) { } reference operator*() const { return static_cast(mNode)->mData; } pointer operator->() const { return &operator*(); } iterator_type& operator++() { mNode = mNode->mNext; return *this; } iterator_type& operator++(int) { iterator_type tmp = *this; mNode = mNode->mNext; return *tmp; } iterator_type& operator--() { mNode = mNode->mPrev; return *this; } iterator_type& operator--(int) { iterator_type tmp = *this; mNode = mNode->mPrev; return *tmp; } bool operator==(const iterator_type& o) const { return mNode == o.mNode; } bool operator!=(const iterator_type& o) const { return mNode != o.mNode; } ListNodeBase *mNode; }; template struct ListConstIterator { typedef ListConstIterator<_T> iterator_type; typedef android::ListNode<_T> node_type; public: typedef ptrdiff_t difference_type; typedef std::bidirectional_iterator_tag iterator_category; typedef _T value_type; typedef _T* pointer; typedef _T& reference; ListConstIterator(): mNode() { } explicit ListConstIterator(ListNodeBase* node): mNode(node) { } ListConstIterator(const ListIterator<_T>& it): mNode(it.mNode) { } reference operator*() const { return static_cast(mNode)->mData; } pointer operator->() const { return &operator*(); } iterator_type& operator++() { mNode = mNode->mNext; return *this; } iterator_type& operator++(int) { iterator_type tmp = *this; mNode = mNode->mNext; return *tmp; } iterator_type& operator--() { mNode = mNode->mPrev; return *this; } iterator_type& operator--(int) { iterator_type tmp = *this; mNode = mNode->mPrev; return *tmp; } bool operator==(const iterator_type& o) const { return mNode == o.mNode; } bool operator!=(const iterator_type& o) const { return mNode != o.mNode; } ListNodeBase *mNode; }; } // namespace android namespace std { // std::list template class list { public: typedef _T value_type; typedef _T* pointer; typedef const _T* const_pointer; typedef _T& reference; typedef const _T& const_reference; typedef android::ListIterator<_T> iterator; typedef android::ListConstIterator<_T> const_iterator; typedef size_t size_type; typedef ptrdiff_t difference_type; // Default constructor, no element. list() { init(); } ~list() { clear(); } // Empty the list. void clear(); // Element access. reference front() { return *iterator(mHead.mNext); } const_reference front() const { return *iterator(mHead.mNext); } reference back() { return *iterator(mHead.mPrev); } const_reference back() const { return *iterator(mHead.mPrev); } // Iterators. iterator begin() { return iterator(mHead.mNext); } const_iterator begin() const { return const_iterator(mHead.mNext); } iterator end() { return iterator(&mHead); } const_iterator end() const { return const_iterator(&mHead); } // Add data at the begin of the list. // @param elt To be added. void push_front(const value_type& elt) { insert(begin(), elt); } void push_back(const value_type& elt) { insert(end(), elt); } // Removes first element. Invalidated the iterators/references to begin. void pop_front() { eraseAtPos(iterator(mHead.mNext)); } // Removes last element. Invalidated the iterators/references to // the last element. void pop_back() { eraseAtPos(iterator(mHead.mPrev)); } bool empty() const { return mLength == 0; } // @eturn the number of elements in the list. size_type size() const { return mLength; } // @return the maximum size for a list size_type max_size() const { return numeric_limits::max(); } // Insert the element BEFORE the 'pos' iterator. // @param pos Iterator in the list. // @param elt Element to be inserted. // @return an iterator that points to the inserted element. iterator insert(iterator pos, const value_type& elt); // Remove the element pointed by the iterator. Constant in time, // calls once to _T's destructor. // @param pos Iterator pointing to the elt to be removed. // @return An iterator pointing to the next elt or end(). iterator erase(iterator position); // Remove a range of elements [first, last) // @param first Iterator pointing to the first element to be removed. // @param last Iterator pointing to one past the last element to be removed. // @return An iterator pointing to the elt next to 'last' or end(). iterator erase(iterator first, iterator last); private: void init() { mHead.mNext = &mHead; mHead.mPrev = &mHead; mLength = 0; } // Erase, don't return anything. void eraseAtPos(iterator pos); size_type mLength; // mHead does not contain any data, it represents end(). android::ListNodeBase mHead; }; template void list<_T>::clear() { while (mHead.mNext != &mHead) { // Upcast so delete will reclaim all the memory. android::ListNode<_T> *node = static_cast *>(mHead.mNext); mHead.mNext = node->mNext; delete node; } init(); } template typename list<_T>::iterator list<_T>::insert(iterator pos, const value_type& elt) { if (mLength + 1 > mLength) { android::ListNode<_T> *node = new android::ListNode<_T>(); node->mData = elt; node->hook(pos.mNode); ++mLength; return iterator(node); } else { return end(); } } template typename list<_T>::iterator list<_T>::erase(iterator pos) { iterator res = iterator(pos.mNode->mNext); eraseAtPos(pos); return res; } template typename list<_T>::iterator list<_T>::erase(iterator first, iterator last) { while (first != last) { first = erase(first); // erase returns an iterator to the next elt. } return last; } template void list<_T>::eraseAtPos(iterator pos) { if (pos.mNode != &mHead) { pos.mNode->unhook(); android::ListNode<_T>* node = static_cast*>(pos.mNode); delete node; --mLength; } } } // namespace std #endif // ANDROID_ASTL_LIST__