summaryrefslogtreecommitdiffstats
path: root/include/utils/List.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/utils/List.h')
-rw-r--r--include/utils/List.h332
1 files changed, 0 insertions, 332 deletions
diff --git a/include/utils/List.h b/include/utils/List.h
deleted file mode 100644
index 403cd7f..0000000
--- a/include/utils/List.h
+++ /dev/null
@@ -1,332 +0,0 @@
-/*
- * Copyright (C) 2005 The Android Open Source Project
- *
- * 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.
- */
-
-//
-// Templated list class. Normally we'd use STL, but we don't have that.
-// This class mimics STL's interfaces.
-//
-// Objects are copied into the list with the '=' operator or with copy-
-// construction, so if the compiler's auto-generated versions won't work for
-// you, define your own.
-//
-// The only class you want to use from here is "List".
-//
-#ifndef _LIBS_UTILS_LIST_H
-#define _LIBS_UTILS_LIST_H
-
-#include <stddef.h>
-#include <stdint.h>
-
-namespace android {
-
-/*
- * Doubly-linked list. Instantiate with "List<MyClass> myList".
- *
- * Objects added to the list are copied using the assignment operator,
- * so this must be defined.
- */
-template<typename T>
-class List
-{
-protected:
- /*
- * One element in the list.
- */
- class _Node {
- public:
- explicit _Node(const T& val) : mVal(val) {}
- ~_Node() {}
- inline T& getRef() { return mVal; }
- inline const T& getRef() const { return mVal; }
- inline _Node* getPrev() const { return mpPrev; }
- inline _Node* getNext() const { return mpNext; }
- inline void setVal(const T& val) { mVal = val; }
- inline void setPrev(_Node* ptr) { mpPrev = ptr; }
- inline void setNext(_Node* ptr) { mpNext = ptr; }
- private:
- friend class List;
- friend class _ListIterator;
- T mVal;
- _Node* mpPrev;
- _Node* mpNext;
- };
-
- /*
- * Iterator for walking through the list.
- */
-
- template <typename TYPE>
- struct CONST_ITERATOR {
- typedef _Node const * NodePtr;
- typedef const TYPE Type;
- };
-
- template <typename TYPE>
- struct NON_CONST_ITERATOR {
- typedef _Node* NodePtr;
- typedef TYPE Type;
- };
-
- template<
- typename U,
- template <class> class Constness
- >
- class _ListIterator {
- typedef _ListIterator<U, Constness> _Iter;
- typedef typename Constness<U>::NodePtr _NodePtr;
- typedef typename Constness<U>::Type _Type;
-
- explicit _ListIterator(_NodePtr ptr) : mpNode(ptr) {}
-
- public:
- _ListIterator() {}
- _ListIterator(const _Iter& rhs) : mpNode(rhs.mpNode) {}
- ~_ListIterator() {}
-
- // this will handle conversions from iterator to const_iterator
- // (and also all convertible iterators)
- // Here, in this implementation, the iterators can be converted
- // if the nodes can be converted
- template<typename V> explicit
- _ListIterator(const V& rhs) : mpNode(rhs.mpNode) {}
-
-
- /*
- * Dereference operator. Used to get at the juicy insides.
- */
- _Type& operator*() const { return mpNode->getRef(); }
- _Type* operator->() const { return &(mpNode->getRef()); }
-
- /*
- * Iterator comparison.
- */
- inline bool operator==(const _Iter& right) const {
- return mpNode == right.mpNode; }
-
- inline bool operator!=(const _Iter& right) const {
- return mpNode != right.mpNode; }
-
- /*
- * handle comparisons between iterator and const_iterator
- */
- template<typename OTHER>
- inline bool operator==(const OTHER& right) const {
- return mpNode == right.mpNode; }
-
- template<typename OTHER>
- inline bool operator!=(const OTHER& right) const {
- return mpNode != right.mpNode; }
-
- /*
- * Incr/decr, used to move through the list.
- */
- inline _Iter& operator++() { // pre-increment
- mpNode = mpNode->getNext();
- return *this;
- }
- const _Iter operator++(int) { // post-increment
- _Iter tmp(*this);
- mpNode = mpNode->getNext();
- return tmp;
- }
- inline _Iter& operator--() { // pre-increment
- mpNode = mpNode->getPrev();
- return *this;
- }
- const _Iter operator--(int) { // post-increment
- _Iter tmp(*this);
- mpNode = mpNode->getPrev();
- return tmp;
- }
-
- inline _NodePtr getNode() const { return mpNode; }
-
- _NodePtr mpNode; /* should be private, but older gcc fails */
- private:
- friend class List;
- };
-
-public:
- List() {
- prep();
- }
- List(const List<T>& src) { // copy-constructor
- prep();
- insert(begin(), src.begin(), src.end());
- }
- virtual ~List() {
- clear();
- delete[] (unsigned char*) mpMiddle;
- }
-
- typedef _ListIterator<T, NON_CONST_ITERATOR> iterator;
- typedef _ListIterator<T, CONST_ITERATOR> const_iterator;
-
- List<T>& operator=(const List<T>& right);
-
- /* returns true if the list is empty */
- inline bool empty() const { return mpMiddle->getNext() == mpMiddle; }
-
- /* return #of elements in list */
- size_t size() const {
- return size_t(distance(begin(), end()));
- }
-
- /*
- * Return the first element or one past the last element. The
- * _Node* we're returning is converted to an "iterator" by a
- * constructor in _ListIterator.
- */
- inline iterator begin() {
- return iterator(mpMiddle->getNext());
- }
- inline const_iterator begin() const {
- return const_iterator(const_cast<_Node const*>(mpMiddle->getNext()));
- }
- inline iterator end() {
- return iterator(mpMiddle);
- }
- inline const_iterator end() const {
- return const_iterator(const_cast<_Node const*>(mpMiddle));
- }
-
- /* add the object to the head or tail of the list */
- void push_front(const T& val) { insert(begin(), val); }
- void push_back(const T& val) { insert(end(), val); }
-
- /* insert before the current node; returns iterator at new node */
- iterator insert(iterator posn, const T& val)
- {
- _Node* newNode = new _Node(val); // alloc & copy-construct
- newNode->setNext(posn.getNode());
- newNode->setPrev(posn.getNode()->getPrev());
- posn.getNode()->getPrev()->setNext(newNode);
- posn.getNode()->setPrev(newNode);
- return iterator(newNode);
- }
-
- /* insert a range of elements before the current node */
- void insert(iterator posn, const_iterator first, const_iterator last) {
- for ( ; first != last; ++first)
- insert(posn, *first);
- }
-
- /* remove one entry; returns iterator at next node */
- iterator erase(iterator posn) {
- _Node* pNext = posn.getNode()->getNext();
- _Node* pPrev = posn.getNode()->getPrev();
- pPrev->setNext(pNext);
- pNext->setPrev(pPrev);
- delete posn.getNode();
- return iterator(pNext);
- }
-
- /* remove a range of elements */
- iterator erase(iterator first, iterator last) {
- while (first != last)
- erase(first++); // don't erase than incr later!
- return iterator(last);
- }
-
- /* remove all contents of the list */
- void clear() {
- _Node* pCurrent = mpMiddle->getNext();
- _Node* pNext;
-
- while (pCurrent != mpMiddle) {
- pNext = pCurrent->getNext();
- delete pCurrent;
- pCurrent = pNext;
- }
- mpMiddle->setPrev(mpMiddle);
- mpMiddle->setNext(mpMiddle);
- }
-
- /*
- * Measure the distance between two iterators. On exist, "first"
- * will be equal to "last". The iterators must refer to the same
- * list.
- *
- * FIXME: This is actually a generic iterator function. It should be a
- * template function at the top-level with specializations for things like
- * vector<>, which can just do pointer math). Here we limit it to
- * _ListIterator of the same type but different constness.
- */
- template<
- typename U,
- template <class> class CL,
- template <class> class CR
- >
- ptrdiff_t distance(
- _ListIterator<U, CL> first, _ListIterator<U, CR> last) const
- {
- ptrdiff_t count = 0;
- while (first != last) {
- ++first;
- ++count;
- }
- return count;
- }
-
-private:
- /*
- * I want a _Node but don't need it to hold valid data. More
- * to the point, I don't want T's constructor to fire, since it
- * might have side-effects or require arguments. So, we do this
- * slightly uncouth storage alloc.
- */
- void prep() {
- mpMiddle = (_Node*) new unsigned char[sizeof(_Node)];
- mpMiddle->setPrev(mpMiddle);
- mpMiddle->setNext(mpMiddle);
- }
-
- /*
- * This node plays the role of "pointer to head" and "pointer to tail".
- * It sits in the middle of a circular list of nodes. The iterator
- * runs around the circle until it encounters this one.
- */
- _Node* mpMiddle;
-};
-
-/*
- * Assignment operator.
- *
- * The simplest way to do this would be to clear out the target list and
- * fill it with the source. However, we can speed things along by
- * re-using existing elements.
- */
-template<class T>
-List<T>& List<T>::operator=(const List<T>& right)
-{
- if (this == &right)
- return *this; // self-assignment
- iterator firstDst = begin();
- iterator lastDst = end();
- const_iterator firstSrc = right.begin();
- const_iterator lastSrc = right.end();
- while (firstSrc != lastSrc && firstDst != lastDst)
- *firstDst++ = *firstSrc++;
- if (firstSrc == lastSrc) // ran out of elements in source?
- erase(firstDst, lastDst); // yes, erase any extras
- else
- insert(lastDst, firstSrc, lastSrc); // copy remaining over
- return *this;
-}
-
-}; // namespace android
-
-#endif // _LIBS_UTILS_LIST_H