/**************************************************************************** ** ** Copyright (c) 2008-2020 C.B. Barber. All rights reserved. ** $Id: //main/2019/qhull/src/libqhullcpp/QhullLinkedList.h#6 $$Change: 3009 $ ** $DateTime: 2020/07/30 19:25:22 $$Author: bbarber $ ** ****************************************************************************/ #ifndef QHULLLINKEDLIST_H #define QHULLLINKEDLIST_H #include "libqhull_r/qhull_ra.h" #include "libqhullcpp/QhullError.h" #include // ptrdiff_t, size_t #ifdef QHULL_USES_QT #include #endif #ifndef QHULL_NO_STL #include #include #include #endif namespace orgQhull { #//!\name Defined here //! QhullLinkedList -- A linked list modeled on QLinkedList. //! T is an opaque type with T(B *b), b=t.getBaseT(), t=t.next(), and t=t.prev(). The end node is a sentinel. //! QhullQh/qhT owns the contents. //! QhullLinkedList does not define erase(), clear(), removeFirst(), removeLast(), pop_back(), pop_front(), fromStdList() //! Derived from Qt/core/tools/qlinkedlist.h and libqhull_r.h/FORALLfacets_() //! QhullLinkedList::const_iterator -- STL-style iterator //! QhullLinkedList::iterator -- STL-style iterator //! QhullLinkedListIterator -- Java-style iterator //! Derived from Qt/core/tools/qiterator.h //! Works with Qt's foreach keyword [Qt/src/corelib/global/qglobal.h] template class QhullLinkedList { #//!\name Defined here public: class const_iterator; class iterator; typedef const_iterator ConstIterator; typedef iterator Iterator; typedef ptrdiff_t difference_type; typedef countT size_type; typedef T value_type; typedef const value_type *const_pointer; typedef const value_type &const_reference; typedef value_type *pointer; typedef value_type &reference; #//!\name Fields private: T begin_node; T end_node; //! Sentinel node at end of list #//!\name Constructors public: QhullLinkedList(T b, T e) : begin_node(b), end_node(e) {} //! Copy constructor copies begin_node and end_node, but not the list elements. Needed for return by value and parameter passing. QhullLinkedList(const QhullLinkedList &other) : begin_node(other.begin_node), end_node(other.end_node) {} //! Copy assignment copies begin_node and end_node, but not the list elements. QhullLinkedList & operator=(const QhullLinkedList &other) { begin_node= other.begin_node; end_node= other.end_node; return *this; } ~QhullLinkedList() {} private: //!disabled since a sentinel must be allocated as the private type QhullLinkedList() {} public: #//!\name Conversions #ifndef QHULL_NO_STL std::vector toStdVector() const; #endif #ifdef QHULL_USES_QT QList toQList() const; #endif #//!\name GetSet countT count() const; //count(t) under #//!\name Search bool isEmpty() const { return (begin_node==end_node); } bool operator==(const QhullLinkedList &o) const; bool operator!=(const QhullLinkedList &o) const { return !operator==(o); } size_t size() const { return count(); } #//!\name Element access //! For back() and last(), return T instead of T& (T is computed) const T back() const { return last(); } T back() { return last(); } const T & first() const { QHULL_ASSERT(!isEmpty()); return begin_node; } T & first() { QHULL_ASSERT(!isEmpty()); return begin_node; } const T & front() const { return first(); } T & front() { return first(); } const T last() const { QHULL_ASSERT(!isEmpty()); return *--end(); } T last() { QHULL_ASSERT(!isEmpty()); return *--end(); } #//!\name Modify -- Allocation of opaque types not implemented. #//!\name Search bool contains(const T &t) const; countT count(const T &t) const; #//!\name Iterator iterator begin() { return begin_node; } const_iterator begin() const { return begin_node; } const_iterator constBegin() const { return begin_node; } const_iterator constEnd() const { return end_node; } iterator end() { return end_node; } const_iterator end() const { return end_node; } class iterator { private: T i; friend class const_iterator; public: typedef std::bidirectional_iterator_tag iterator_category; typedef T value_type; typedef value_type *pointer; typedef value_type &reference; typedef ptrdiff_t difference_type; iterator() : i() {} iterator(const T &t) : i(t) {} //!< Automatic conversion to iterator iterator(const iterator &o) : i(o.i) {} iterator & operator=(const iterator &o) { i= o.i; return *this; } const T & operator*() const { return i; } T & operator*() { return i; } // Do not define operator[] const T * operator->() const { return &i; } T * operator->() { return &i; } bool operator==(const iterator &o) const { return i == o.i; } bool operator!=(const iterator &o) const { return !operator==(o); } bool operator==(const const_iterator &o) const { return i==reinterpret_cast(o).i; } bool operator!=(const const_iterator &o) const { return !operator==(o); } iterator & operator++() { i= i.next(); return *this; } iterator operator++(int) { iterator o= i; i= i.next(); return o; } iterator & operator--() { i= i.previous(); return *this; } iterator operator--(int) { iterator o= i; i= i.previous(); return o; } iterator operator+(int j) const; iterator operator-(int j) const { return operator+(-j); } iterator & operator+=(int j) { return (*this= *this + j); } iterator & operator-=(int j) { return (*this= *this - j); } };//QhullLinkedList::iterator class const_iterator { private: T i; public: typedef std::bidirectional_iterator_tag iterator_category; typedef T value_type; typedef const value_type *pointer; typedef const value_type &reference; typedef ptrdiff_t difference_type; const_iterator() : i() {} const_iterator(const T &t) : i(t) {} //!< Automatic conversion to const_iterator const_iterator(const iterator &o) : i(o.i) {} const_iterator(const const_iterator &o) : i(o.i) {} const_iterator &operator=(const const_iterator &o) { i= o.i; return *this; } const T & operator*() const { return i; } const T * operator->() const { return &i; } bool operator==(const const_iterator &o) const { return i == o.i; } bool operator!=(const const_iterator &o) const { return !operator==(o); } // No comparisons or iterator diff const_iterator &operator++() { i= i.next(); return *this; } const_iterator operator++(int) { const_iterator o= i; i= i.next(); return o; } const_iterator &operator--() { i= i.previous(); return *this; } const_iterator operator--(int) { const_iterator o= i; i= i.previous(); return o; } const_iterator operator+(int j) const; const_iterator operator-(int j) const { return operator+(-j); } const_iterator &operator+=(int j) { return (*this= *this + j); } const_iterator &operator-=(int j) { return (*this= *this - j); } };//QhullLinkedList::const_iterator };//QhullLinkedList template class QhullLinkedListIterator // QH11016 FIX: define QhullMutableLinkedListIterator { typedef typename QhullLinkedList::const_iterator const_iterator; QhullLinkedList c; const_iterator i; public: QhullLinkedListIterator(const QhullLinkedList &container) : c(container), i(c.constBegin()) {} QhullLinkedListIterator & operator=(const QhullLinkedList &container) { c= container; i= c.constBegin(); return *this; } bool findNext(const T &t); bool findPrevious(const T &t); bool hasNext() const { return i != c.constEnd(); } bool hasPrevious() const { return i != c.constBegin(); } T next() { return *i++; } T peekNext() const { return *i; } T peekPrevious() const { const_iterator p= i; return *--p; } T previous() { return *--i; } void toFront() { i= c.constBegin(); } void toBack() { i= c.constEnd(); } };//QhullLinkedListIterator #//!\name == Definitions ========================================= #//!\name Conversion #ifndef QHULL_NO_STL template std::vector QhullLinkedList:: toStdVector() const { std::vector tmp; std::copy(constBegin(), constEnd(), std::back_inserter(tmp)); return tmp; }//toStdVector #endif #ifdef QHULL_USES_QT template QList QhullLinkedList:: toQList() const { QhullLinkedListIterator i(*this); QList ls; while(i.hasNext()){ ls.append(i.next()); } return ls; }//toQList #endif #//!\name GetSet template countT QhullLinkedList:: count() const { const_iterator i= begin_node; countT c= 0; while(i != end_node){ c++; i++; } return c; }//count #//!\name Search template bool QhullLinkedList:: contains(const T &t) const { const_iterator i= begin_node; while(i != end_node){ if(i==t){ return true; } i++; } return false; }//contains template countT QhullLinkedList:: count(const T &t) const { const_iterator i= begin_node; countT c= 0; while(i != end_node){ if(i==t){ c++; } i++; } return c; }//count template bool QhullLinkedList:: operator==(const QhullLinkedList &l) const { if(begin_node==l.begin_node){ return (end_node==l.end_node); } T i= begin_node; T il= l.begin_node; while(i != end_node){ if(i != il){ return false; } i= static_cast(i.next()); il= static_cast(il.next()); } if(il != l.end_node){ return false; } return true; }//operator== #//!\name Iterator template typename QhullLinkedList::iterator QhullLinkedList::iterator:: operator+(int j) const { T n= i; if(j>0){ while(j--){ n= n.next(); } }else{ while(j++){ n= n.previous(); } } return iterator(n); }//operator+ template typename QhullLinkedList::const_iterator QhullLinkedList::const_iterator:: operator+(int j) const { T n= i; if(j>0){ while(j--){ n= n.next(); } }else{ while(j++){ n= n.previous(); } } return const_iterator(n); }//operator+ #//!\name QhullLinkedListIterator template bool QhullLinkedListIterator:: findNext(const T &t) { while(i != c->constEnd()){ if(*i++ == t){ return true; } } return false; }//findNext template bool QhullLinkedListIterator:: findPrevious(const T &t) { while(i!=c->constBegin()){ if(*(--i)==t){ return true; } } return false; }//findNext }//namespace orgQhull #//!\name Global template std::ostream & operator<<(std::ostream &os, const orgQhull::QhullLinkedList &qs) { typename orgQhull::QhullLinkedList::const_iterator i; for(i= qs.begin(); i != qs.end(); ++i){ os << *i; } return os; }//operator<< #endif // QHULLLINKEDLIST_H