Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:01:56

0001 /****************************************************************************
0002 **
0003 ** Copyright (c) 2008-2020 C.B. Barber. All rights reserved.
0004 ** $Id: //main/2019/qhull/src/libqhullcpp/QhullSet.h#5 $$Change: 3018 $
0005 ** $DateTime: 2020/08/15 19:58:23 $$Author: bbarber $
0006 **
0007 ****************************************************************************/
0008 
0009 #ifndef QhullSet_H
0010 #define QhullSet_H
0011 
0012 #include "libqhull_r/qhull_ra.h"
0013 #include "libqhullcpp/QhullError.h"
0014 #include "libqhullcpp/QhullQh.h"
0015 
0016 #include <cstddef>  // ptrdiff_t, size_t
0017 
0018 #ifndef QHULL_NO_STL
0019 #include <vector>
0020 #endif
0021 
0022 #ifdef QHULL_USES_QT
0023  #include <QtCore/QList>
0024 #endif
0025 
0026 namespace orgQhull {
0027 
0028 #//!\name Used here
0029     class Qhull;
0030 
0031 #//!\name Defined here
0032     class QhullSetBase;  //! Base class for QhullSet<T>
0033     //! QhullSet<T> defined below
0034     //! QhullSetIterator<T> defined below
0035     //! \see QhullPointSet, QhullLinkedList<T>
0036 
0037 //! QhullSetBase is a wrapper for Qhull's setT of void* pointers
0038 //! \see libqhull_r/qset.h
0039 class QhullSetBase {
0040 
0041 private:
0042 #//!\name Fields --
0043     setT *              qh_set;
0044     QhullQh *           qh_qh;             //! Provides access to setT memory allocator
0045 
0046 #//!\name Class objects
0047     static setT         s_empty_set;  //! Used if setT* is NULL
0048 
0049 public:
0050 #//!\name Constructors
0051                         QhullSetBase(const Qhull &q, setT *s);
0052                         QhullSetBase(QhullQh *qqh, setT *s) : qh_set(s ? s : &s_empty_set), qh_qh(qqh) {}
0053                         //! Copy constructor copies the pointer but not the set.  Needed for return by value and parameter passing.
0054                         QhullSetBase(const QhullSetBase &other) : qh_set(other.qh_set), qh_qh(other.qh_qh) {}
0055     QhullSetBase &      operator=(const QhullSetBase &other) { qh_set= other.qh_set; qh_qh= other.qh_qh; return *this; }
0056                         ~QhullSetBase() {}
0057 
0058 private:
0059                         //!disabled since memory allocation for QhullSet not defined
0060                         QhullSetBase()  : qh_set(NULL), qh_qh(NULL) {}
0061 public:
0062 
0063 #//!\name GetSet
0064     countT              count() const { return QhullSetBase::count(qh_set); }
0065     void                defineAs(setT *s) { qh_set= s ? s : &s_empty_set; } //!< Not type-safe since setT may contain any type
0066     void                forceEmpty() { qh_set= &s_empty_set; }
0067     setT *              getSetT() const { return qh_set; }
0068     bool                isEmpty() const { return SETempty_(qh_set); }
0069     QhullQh *           qh() const { return qh_qh; }
0070     setT **             referenceSetT() { return &qh_set; }
0071     size_t              size() const { return QhullSetBase::count(qh_set); }
0072 
0073 #//!\name Element
0074 protected:
0075     void **             beginPointer() const { return &qh_set->e[0].p; }
0076     void **             elementPointer(countT idx) const { QHULL_ASSERT(idx>=0 && idx<qh_set->maxsize); return &SETelem_(qh_set, idx); }
0077                         //! Always points to 0
0078     void **             endPointer() const { return qh_setendpointer(qh_set); }
0079 
0080 #//!\name Class methods
0081 public:
0082     static countT       count(const setT *set);
0083     //s may be null
0084     static bool         isEmpty(const setT *s) { return SETempty_(s); }
0085 };//QhullSetBase
0086 
0087 
0088 //! QhullSet<T> -- A read-only wrapper to Qhull's collection class, setT.
0089 //!  QhullSet is similar to STL's <vector> and Qt's QVector
0090 //!  QhullSet is unrelated to STL and Qt's set and map types (e.g., QSet and QMap)
0091 //!  T is a Qhull type that defines 'base_type' and getBaseT() (e.g., QhullFacet with base_type 'facetT *'
0092 //!  A QhullSet does not own its contents -- erase(), clear(), removeFirst(), removeLast(), pop_back(), pop_front(), fromStdList() not defined
0093 //!  QhullSetIterator is faster than STL-style iterator/const_iterator
0094 //!  Qhull's FOREACHelement_() [qset_r.h] maybe more efficient than QhullSet.  It uses a NULL terminator instead of an end pointer.  STL requires an end pointer.
0095 //!  Derived from QhullLinkedList.h and Qt/core/tools/qlist.h w/o QT_STRICT_ITERATORS
0096 template <typename T>
0097 class QhullSet : public QhullSetBase {
0098 
0099 private:
0100 #//!\name Fields -- see QhullSetBase
0101 
0102 #//!\name Class objects
0103     static setT         s_empty_set;  //! Workaround for no setT allocator.  Used if setT* is NULL
0104 
0105 public:
0106 #//!\name Defined here
0107     class iterator;
0108     class const_iterator;
0109     typedef typename QhullSet<T>::iterator Iterator;
0110     typedef typename QhullSet<T>::const_iterator ConstIterator;
0111 
0112 #//!\name Constructors
0113                         QhullSet<T>(const Qhull &q, setT *s) : QhullSetBase(q, s) { }
0114                         QhullSet<T>(QhullQh *qqh, setT *s) : QhullSetBase(qqh, s) { }
0115                         //Conversion from setT* is not type-safe.  Implicit conversion for void* to T
0116                         //Copy constructor copies pointer but not contents.  Needed for return by value.
0117                         QhullSet<T>(const QhullSet<T> &other) : QhullSetBase(other) {}
0118     QhullSet<T> &       operator=(const QhullSet<T> &other) { QhullSetBase::operator=(other); return *this; }
0119                         ~QhullSet<T>() {}
0120 
0121 private:
0122                         //!Disable default constructor.  See QhullSetBase
0123                         QhullSet<T>();
0124 public:
0125 
0126 #//!\name Conversion
0127 
0128 #ifndef QHULL_NO_STL
0129     std::vector<T> toStdVector() const;
0130 #endif
0131 #ifdef QHULL_USES_QT
0132     QList<T>            toQList() const;
0133 #endif
0134 
0135 #//!\name GetSet -- see QhullSetBase for count(), empty(), isEmpty(), size()
0136     using QhullSetBase::count;
0137     using QhullSetBase::isEmpty;
0138     // operator== defined for QhullSets of the same type
0139     bool                operator==(const QhullSet<T> &other) const { return qh_setequal(getSetT(), other.getSetT()); }
0140     bool                operator!=(const QhullSet<T> &other) const { return !operator==(other); }
0141 
0142 #//!\name Element access
0143     // Constructs T.  Cannot return reference.
0144     const T             at(countT idx) const { return operator[](idx); }
0145     // Constructs T.  Cannot return reference.
0146     const T             back() const { return last(); }
0147     T                   back() { return last(); }
0148     //! end element is NULL
0149     const typename T::base_type * constData() const { return reinterpret_cast<const typename T::base_type *>(beginPointer()); }
0150     typename T::base_type *     data() { return reinterpret_cast<typename T::base_type *>(beginPointer()); }
0151     const typename T::base_type *data() const { return reinterpret_cast<const typename T::base_type *>(beginPointer()); }
0152     typename T::base_type *     endData() { return reinterpret_cast<typename T::base_type *>(endPointer()); }
0153     const typename T::base_type * endData() const { return reinterpret_cast<const typename T::base_type *>(endPointer()); }
0154     // Constructs T.  Cannot return reference.
0155     const T             first() const { QHULL_ASSERT(!isEmpty()); return T(qh(), *data()); }
0156     T                   first() { QHULL_ASSERT(!isEmpty()); return T(qh(), *data()); }
0157     // Constructs T.  Cannot return reference.
0158     const T             front() const { return first(); }
0159     T                   front() { return first(); }
0160     // Constructs T.  Cannot return reference.
0161     const T             last() const { QHULL_ASSERT(!isEmpty()); return T(qh(), *(endData()-1)); }
0162     T                   last() { QHULL_ASSERT(!isEmpty()); return T(qh(), *(endData()-1)); }
0163     // mid() not available.  No setT constructor
0164     // Constructs T.  Cannot return reference.
0165     const T             operator[](countT idx) const { const typename T::base_type *p= reinterpret_cast<typename T::base_type *>(elementPointer(idx)); QHULL_ASSERT(idx>=0 && p < endData()); return T(qh(), *p); }
0166     T                   operator[](countT idx) { typename T::base_type *p= reinterpret_cast<typename T::base_type *>(elementPointer(idx)); QHULL_ASSERT(idx>=0 && p < endData()); return T(qh(), *p); }
0167     const T             second() const { return operator[](1); }
0168     T                   second() { return operator[](1); }
0169     T                   value(countT idx) const;
0170     T                   value(countT idx, const T &defaultValue) const;
0171 
0172 #//!\name Read-write -- Not available, no setT constructor
0173 
0174 #//!\name iterator
0175     iterator            begin() { return iterator(qh(), reinterpret_cast<typename T::base_type *>(beginPointer())); }
0176     const_iterator      begin() const { return const_iterator(qh(), data()); }
0177     const_iterator      constBegin() const { return const_iterator(qh(), data()); }
0178     const_iterator      constEnd() const { return const_iterator(qh(), endData()); }
0179     iterator            end() { return iterator(qh(), endData()); }
0180     const_iterator      end() const { return const_iterator(qh(), endData()); }
0181 
0182 #//!\name Search
0183     bool                contains(const T &t) const;
0184     countT              count(const T &t) const;
0185     countT              indexOf(const T &t) const { /* no qh_qh */ return qh_setindex(getSetT(), t.getBaseT()); }
0186     countT              lastIndexOf(const T &t) const;
0187 
0188     // before const_iterator for conversion with comparison operators
0189     class iterator {
0190         friend class const_iterator;
0191     private:
0192         typename T::base_type *  i;  // e.g., facetT**, first for debugger
0193         QhullQh *       qh_qh;
0194 
0195     public:
0196         typedef ptrdiff_t       difference_type;
0197         typedef std::bidirectional_iterator_tag  iterator_category;
0198         typedef T               value_type;
0199 
0200                         iterator(QhullQh *qqh, typename T::base_type *p) : i(p), qh_qh(qqh) {}
0201                         iterator(const iterator &o) : i(o.i), qh_qh(o.qh_qh) {}
0202         iterator &      operator=(const iterator &o) { i= o.i; qh_qh= o.qh_qh; return *this; }
0203 
0204         // Constructs T.  Cannot return reference.  
0205         T               operator*() const { return T(qh_qh, *i); }
0206         //operator->() n/a, value-type
0207         // Constructs T.  Cannot return reference.  
0208         T               operator[](countT idx) const { return T(qh_qh, *(i+idx)); } //!< No error checking
0209         bool            operator==(const iterator &o) const { return i == o.i; }
0210         bool            operator!=(const iterator &o) const { return !operator==(o); }
0211         bool            operator==(const const_iterator &o) const { return (i==reinterpret_cast<const iterator &>(o).i); }
0212         bool            operator!=(const const_iterator &o) const { return !operator==(o); }
0213 
0214         //! Assumes same point set
0215         countT          operator-(const iterator &o) const { return static_cast<countT>(i-o.i); } //WARN64
0216         bool            operator>(const iterator &o) const { return i>o.i; }
0217         bool            operator<=(const iterator &o) const { return !operator>(o); }
0218         bool            operator<(const iterator &o) const { return i<o.i; }
0219         bool            operator>=(const iterator &o) const { return !operator<(o); }
0220         bool            operator>(const const_iterator &o) const { return (i > reinterpret_cast<const iterator &>(o).i); }
0221         bool            operator<=(const const_iterator &o) const { return !operator>(o); }
0222         bool            operator<(const const_iterator &o) const { return (i < reinterpret_cast<const iterator &>(o).i); }
0223         bool            operator>=(const const_iterator &o) const { return !operator<(o); }
0224 
0225         //! No error checking
0226         iterator &      operator++() { ++i; return *this; }
0227         iterator        operator++(int) { iterator o= *this; ++i; return o; }
0228         iterator &      operator--() { --i; return *this; }
0229         iterator        operator--(int) { iterator o= *this; --i; return o; }
0230         iterator        operator+(countT j) const { return iterator(qh_qh, i+j); }
0231         iterator        operator-(countT j) const { return operator+(-j); }
0232         iterator &      operator+=(countT j) { i += j; return *this; }
0233         iterator &      operator-=(countT j) { i -= j; return *this; }
0234     };//QhullPointSet::iterator
0235 
0236     class const_iterator {
0237     private:
0238         const typename T::base_type *  i;  // e.g., const facetT**, first for debugger
0239         QhullQh *       qh_qh;
0240 
0241     public:
0242         typedef ptrdiff_t       difference_type;
0243         typedef std::random_access_iterator_tag  iterator_category;
0244         typedef T               value_type;
0245 
0246                         const_iterator(QhullQh *qqh, const typename T::base_type * p) : i(p), qh_qh(qqh) {}
0247                         const_iterator(const const_iterator &o) : i(o.i), qh_qh(o.qh_qh) {}
0248                         const_iterator(const iterator &o) : i(o.i), qh_qh(o.qh_qh) {}
0249         const_iterator &operator=(const const_iterator &o) { i= o.i; qh_qh= o.qh_qh; return *this; }
0250 
0251         // Constructs T.  Cannot return reference.  Retaining 'const T' return type for consistency with QList/QVector
0252         const T         operator*() const { return T(qh_qh, *i); }
0253         const T         operator[](countT idx) const { return T(qh_qh, *(i+idx)); }  //!< No error checking
0254         //operator->() n/a, value-type
0255         bool            operator==(const const_iterator &o) const { return i == o.i; }
0256         bool            operator!=(const const_iterator &o) const { return !operator==(o); }
0257 
0258         //! Assumes same point set
0259         countT          operator-(const const_iterator &o) { return static_cast<countT>(i-o.i); } //WARN64
0260         bool            operator>(const const_iterator &o) const { return i>o.i; }
0261         bool            operator<=(const const_iterator &o) const { return !operator>(o); }
0262         bool            operator<(const const_iterator &o) const { return i<o.i; }
0263         bool            operator>=(const const_iterator &o) const { return !operator<(o); }
0264 
0265         //!< No error checking
0266         const_iterator &operator++() { ++i; return *this; }
0267         const_iterator  operator++(int) { const_iterator o= *this; ++i; return o; }
0268         const_iterator &operator--() { --i; return *this; }
0269         const_iterator  operator--(int) { const_iterator o= *this; --i; return o; }
0270         const_iterator  operator+(int j) const { return const_iterator(qh_qh, i+j); }
0271         const_iterator  operator-(int j) const { return operator+(-j); }
0272         const_iterator &operator+=(int j) { i += j; return *this; }
0273         const_iterator &operator-=(int j) { i -= j; return *this; }
0274     };//QhullPointSet::const_iterator
0275 
0276 };//class QhullSet
0277 
0278 
0279 //! QhullSetIterator is a Java-style iterator.  It may be used on temporary results.
0280 //! QhullSetIterator copies the qh_set and qh_qh pointers in QhullSetBase
0281 //! Faster then interator/const_iterator due to T::base_type
0282 template <typename T>
0283 class QhullSetIterator {
0284 
0285 #//!\name Subtypes
0286     typedef typename QhullSet<T>::const_iterator const_iterator;
0287 
0288 private:
0289 #//!\name Fields
0290     const typename T::base_type *  i;        // e.g., facetT**, first for debugger
0291     const typename T::base_type *  begin_i;  // must be initialized after i
0292     const typename T::base_type *  end_i;
0293     QhullQh *                qh_qh;
0294 
0295 public:
0296 #//!\name Constructors
0297                         QhullSetIterator<T>(const QhullSet<T> &s) : i(s.data()), begin_i(i), end_i(s.endData()), qh_qh(s.qh()) {}
0298                         QhullSetIterator<T>(const QhullSetIterator<T> &o) : i(o.i), begin_i(o.begin_i), end_i(o.end_i), qh_qh(o.qh_qh) {}
0299     QhullSetIterator<T> &operator=(const QhullSetIterator<T> &o) { i= o.i; begin_i= o.begin_i; end_i= o.end_i; qh_qh= o.qh_qh; return *this; }
0300 
0301 #//!\name ReadOnly
0302     countT              countRemaining() { return static_cast<countT>(end_i-i); } // WARN64
0303 
0304 #//!\name Search
0305     bool                findNext(const T &t);
0306     bool                findPrevious(const T &t);
0307 
0308 #//!\name Foreach
0309     bool                hasNext() const { return i != end_i; }
0310     bool                hasPrevious() const { return i != begin_i; }
0311     T                   next() { return T(qh_qh, *i++); }
0312     T                   peekNext() const { return T(qh_qh, *i); }
0313     T                   peekPrevious() const { const typename T::base_type *p= i; return T(qh_qh, *--p); }
0314     T                   previous() { return T(qh_qh, *--i); }
0315     void                toBack() { i= end_i; }
0316     void                toFront() { i= begin_i; }
0317 };//class QhullSetIterator
0318 
0319 #//!\name == Definitions =========================================
0320 
0321 #//!\name Conversions
0322 
0323 // See qt-qhull.cpp for QList conversion
0324 
0325 #ifndef QHULL_NO_STL
0326 template <typename T>
0327 std::vector<T> QhullSet<T>::
0328 toStdVector() const
0329 {
0330     typename QhullSet<T>::const_iterator i= begin();
0331     typename QhullSet<T>::const_iterator e= end();
0332     std::vector<T> vs;
0333     while(i!=e){
0334         vs.push_back(*i++);
0335     }
0336     return vs;
0337 }//toStdVector
0338 #endif //QHULL_NO_STL
0339 
0340 #ifdef QHULL_USES_QT
0341 template <typename T>
0342 QList<T> QhullSet<T>::
0343 toQList() const
0344 {
0345     typename QhullSet<T>::const_iterator i= begin();
0346     typename QhullSet<T>::const_iterator e= end();
0347     QList<T> vs;
0348     while(i!=e){
0349         vs.append(*i++);
0350     }
0351     return vs;
0352 }//toQList
0353 #endif
0354 
0355 #//!\name Element
0356 
0357 template <typename T>
0358 T QhullSet<T>::
0359 value(countT idx) const
0360 {
0361     // Avoid call to qh_setsize() and assert in elementPointer()
0362     const typename T::base_type *p= reinterpret_cast<const typename T::base_type *>(&SETelem_(getSetT(), idx));
0363     return (idx>=0 && p<endData()) ? T(qh(), *p) : T(qh());
0364 }//value
0365 
0366 template <typename T>
0367 T QhullSet<T>::
0368 value(countT idx, const T &defaultValue) const
0369 {
0370     // Avoid call to qh_setsize() and assert in elementPointer()
0371     const typename T::base_type *p= reinterpret_cast<const typename T::base_type *>(&SETelem_(getSetT(), idx));
0372     return (idx>=0 && p<endData() ? T(qh(), *p) : defaultValue);
0373 }//value
0374 
0375 #//!\name Search
0376 
0377 template <typename T>
0378 bool QhullSet<T>::
0379 contains(const T &t) const
0380 {
0381     setT *s= getSetT();
0382     void *p= t.getBaseT();  // contains() is not inline for better error reporting
0383     int result= qh_setin(s, p);
0384     return result!=0;
0385 }//contains
0386 
0387 template <typename T>
0388 countT QhullSet<T>::
0389 count(const T &t) const
0390 {
0391     countT n= 0;
0392     const typename T::base_type *i= data();
0393     const typename T::base_type *e= endData();
0394     typename T::base_type p= t.getBaseT();
0395     while(i<e){
0396         if(*i==p){
0397             n++;
0398         }
0399         i++;
0400     }
0401     return n;
0402 }//count
0403 
0404 template <typename T>
0405 countT QhullSet<T>::
0406 lastIndexOf(const T &t) const
0407 {
0408     const typename T::base_type *b= data();
0409     const typename T::base_type *i= endData();
0410     typename T::base_type p= t.getBaseT();
0411     while(--i>=b){
0412         if(*i==p){
0413             break;
0414         }
0415     }
0416     return static_cast<countT>(i-b); // WARN64
0417 }//lastIndexOf
0418 
0419 #//!\name QhullSetIterator
0420 
0421 template <typename T>
0422 bool QhullSetIterator<T>::
0423 findNext(const T &t)
0424 {
0425     typename T::base_type p= t.getBaseT();
0426     while(i!=end_i){
0427         if(*(++i)==p){
0428             return true;
0429         }
0430     }
0431     return false;
0432 }//findNext
0433 
0434 template <typename T>
0435 bool QhullSetIterator<T>::
0436 findPrevious(const T &t)
0437 {
0438     typename T::base_type p= t.getBaseT();
0439     while(i!=begin_i){
0440         if(*(--i)==p){
0441             return true;
0442         }
0443     }
0444     return false;
0445 }//findPrevious
0446 
0447 }//namespace orgQhull
0448 
0449 
0450 #//!\name == Global namespace =========================================
0451 
0452 template <typename T>
0453 std::ostream &
0454 operator<<(std::ostream &os, const orgQhull::QhullSet<T> &qs)
0455 {
0456     const typename T::base_type *i= qs.data();
0457     const typename T::base_type *e= qs.endData();
0458     while(i!=e){
0459         os << T(qs.qh(), *i++);
0460     }
0461     return os;
0462 }//operator<<
0463 
0464 #endif // QhullSet_H