File indexing completed on 2025-01-18 10:01:56
0001
0002
0003
0004
0005
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 #
0029 class Qhull;
0030
0031 #
0032 class QhullSetBase;
0033
0034
0035
0036
0037
0038
0039 class QhullSetBase {
0040
0041 private:
0042 #
0043 setT * qh_set;
0044 QhullQh * qh_qh;
0045
0046 #
0047 static setT s_empty_set;
0048
0049 public:
0050 #
0051 QhullSetBase(const Qhull &q, setT *s);
0052 QhullSetBase(QhullQh *qqh, setT *s) : qh_set(s ? s : &s_empty_set), qh_qh(qqh) {}
0053
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
0060 QhullSetBase() : qh_set(NULL), qh_qh(NULL) {}
0061 public:
0062
0063 #
0064 countT count() const { return QhullSetBase::count(qh_set); }
0065 void defineAs(setT *s) { qh_set= s ? s : &s_empty_set; }
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 #
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
0078 void ** endPointer() const { return qh_setendpointer(qh_set); }
0079
0080 #
0081 public:
0082 static countT count(const setT *set);
0083
0084 static bool isEmpty(const setT *s) { return SETempty_(s); }
0085 };
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096 template <typename T>
0097 class QhullSet : public QhullSetBase {
0098
0099 private:
0100 #
0101
0102 #
0103 static setT s_empty_set;
0104
0105 public:
0106 #
0107 class iterator;
0108 class const_iterator;
0109 typedef typename QhullSet<T>::iterator Iterator;
0110 typedef typename QhullSet<T>::const_iterator ConstIterator;
0111
0112 #
0113 QhullSet<T>(const Qhull &q, setT *s) : QhullSetBase(q, s) { }
0114 QhullSet<T>(QhullQh *qqh, setT *s) : QhullSetBase(qqh, s) { }
0115
0116
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
0123 QhullSet<T>();
0124 public:
0125
0126 #
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 #
0136 using QhullSetBase::count;
0137 using QhullSetBase::isEmpty;
0138
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 #
0143
0144 const T at(countT idx) const { return operator[](idx); }
0145
0146 const T back() const { return last(); }
0147 T back() { return last(); }
0148
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
0155 const T first() const { QHULL_ASSERT(!isEmpty()); return T(qh(), *data()); }
0156 T first() { QHULL_ASSERT(!isEmpty()); return T(qh(), *data()); }
0157
0158 const T front() const { return first(); }
0159 T front() { return first(); }
0160
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
0164
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 #
0173
0174 #
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 #
0183 bool contains(const T &t) const;
0184 countT count(const T &t) const;
0185 countT indexOf(const T &t) const { return qh_setindex(getSetT(), t.getBaseT()); }
0186 countT lastIndexOf(const T &t) const;
0187
0188
0189 class iterator {
0190 friend class const_iterator;
0191 private:
0192 typename T::base_type * i;
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
0205 T operator*() const { return T(qh_qh, *i); }
0206
0207
0208 T operator[](countT idx) const { return T(qh_qh, *(i+idx)); }
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
0215 countT operator-(const iterator &o) const { return static_cast<countT>(i-o.i); }
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
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 };
0235
0236 class const_iterator {
0237 private:
0238 const typename T::base_type * i;
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
0252 const T operator*() const { return T(qh_qh, *i); }
0253 const T operator[](countT idx) const { return T(qh_qh, *(i+idx)); }
0254
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
0259 countT operator-(const const_iterator &o) { return static_cast<countT>(i-o.i); }
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
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 };
0275
0276 };
0277
0278
0279
0280
0281
0282 template <typename T>
0283 class QhullSetIterator {
0284
0285 #
0286 typedef typename QhullSet<T>::const_iterator const_iterator;
0287
0288 private:
0289 #
0290 const typename T::base_type * i;
0291 const typename T::base_type * begin_i;
0292 const typename T::base_type * end_i;
0293 QhullQh * qh_qh;
0294
0295 public:
0296 #
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 #
0302 countT countRemaining() { return static_cast<countT>(end_i-i); }
0303
0304 #
0305 bool findNext(const T &t);
0306 bool findPrevious(const T &t);
0307
0308 #
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 };
0318
0319 #
0320
0321 #
0322
0323
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 }
0338 #endif
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 }
0353 #endif
0354
0355 #
0356
0357 template <typename T>
0358 T QhullSet<T>::
0359 value(countT idx) const
0360 {
0361
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 }
0365
0366 template <typename T>
0367 T QhullSet<T>::
0368 value(countT idx, const T &defaultValue) const
0369 {
0370
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 }
0374
0375 #
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();
0383 int result= qh_setin(s, p);
0384 return result!=0;
0385 }
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 }
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);
0417 }
0418
0419 #
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 }
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 }
0446
0447 }
0448
0449
0450 #
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 }
0463
0464 #endif