Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef QhullSet_H
00010 #define QhullSet_H
00011
00012 #include "QhullError.h"
00013 extern "C" {
00014 #include "libqhull/qhull_a.h"
00015 }
00016
00017
00018 #ifndef QHULL_NO_STL
00019 #include <vector>
00020 #endif
00021
00022 #ifdef QHULL_USES_QT
00023 #include <QtCore/QList>
00024 #endif
00025
00026 namespace orgQhull {
00027
00028 #//Type
00029 class QhullSetBase;
00030
00031
00032
00033
00034
00035
00036
00037
00038
00040
00041
00042 class QhullSetBase {
00043
00044 private:
00045 #//Fields --
00046 setT *qh_set;
00047
00048 #//Class objects
00049 static setT s_empty_set;
00050
00051 public:
00052 #//Class methods
00053 static int count(const setT *set);
00054
00055 static bool isEmpty(const setT *s) { return SETempty_(s); }
00056
00057
00058 #//Constructors
00059
00060 QhullSetBase(const QhullSetBase &o) : qh_set(o.qh_set) {}
00061 explicit QhullSetBase(setT *s) : qh_set(s ? s : &s_empty_set) {}
00062 ~QhullSetBase() {}
00063
00064 private:
00066 QhullSetBase() {}
00068 QhullSetBase &operator=(const QhullSetBase &);
00069 public:
00070
00071 #//Conversions
00072
00073 void defineAs(setT *s) { qh_set= s ? s : &s_empty_set; }
00074 setT *getSetT() const { return qh_set; }
00075 setT **referenceSetT() { return &qh_set; }
00076
00077 #//Read-only
00078 int count() const { return QhullSetBase::count(qh_set); }
00079 bool empty() const { return SETfirst_(qh_set)==0; }
00080 bool isEmpty() const { return empty(); }
00081 size_t size() const { return count(); }
00082
00083 #//Element
00084 protected:
00085 void **beginPointer() const { return &qh_set->e[0].p; }
00086 void **elementPointer(int idx) const { QHULL_ASSERT(idx>=0 && idx<qh_set->maxsize); return &SETelem_(qh_set, idx); }
00088 void **endPointer() const { int *i=SETsizeaddr_(qh_set); return (*i ? &qh_set->e[(*i)-1].p : reinterpret_cast<void **>(i)); }
00089 };
00090
00091
00093 template <typename T>
00094 class QhullSet : public QhullSetBase {
00095
00096 private:
00097 #//Fields -- see QhullSetBase
00098
00099 #//Class objects
00100 static setT s_empty_set;
00101
00102 public:
00103 #//Subtypes
00104 typedef T *iterator;
00105 typedef const T *const_iterator;
00106 typedef typename QhullSet<T>::iterator Iterator;
00107 typedef typename QhullSet<T>::const_iterator ConstIterator;
00108
00109 #//Class methods
00110 static int count(const setT *set);
00111
00112 static bool isEmpty(const setT *s) { return SETempty_(s); }
00113
00114 #//Constructors
00115
00116 QhullSet<T>(const QhullSet<T> &o) : QhullSetBase(o) {}
00117
00118 explicit QhullSet<T>(setT *s) : QhullSetBase(s) { QHULL_ASSERT(sizeof(T)==sizeof(void *)); }
00119 ~QhullSet<T>() {}
00120
00121 private:
00123 QhullSet<T>();
00124 QhullSet<T> &operator=(const QhullSet<T> &);
00125 public:
00126
00127 #//Conversion
00128
00129 #ifndef QHULL_NO_STL
00130 std::vector<T> toStdVector() const;
00131 #endif
00132 #ifdef QHULL_USES_QT
00133 QList<T> toQList() const;
00134 #endif
00135
00136 #//Read-only -- see QhullSetBase for count(), empty(), isEmpty(), size()
00137 using QhullSetBase::count;
00138 using QhullSetBase::isEmpty;
00139
00140 bool operator==(const QhullSet<T> &other) const { return qh_setequal(getSetT(), other.getSetT()); }
00141 bool operator!=(const QhullSet<T> &other) const { return !operator==(other); }
00142
00143 #//Element access
00144 const T &at(int idx) const { return operator[](idx); }
00145 T &back() { return last(); }
00146 T &back() const { return last(); }
00148 const T *constData() const { return constBegin(); }
00149 T *data() { return begin(); }
00150 const T *data() const { return begin(); }
00151 T &first() { QHULL_ASSERT(!isEmpty()); return *begin(); }
00152 const T &first() const { QHULL_ASSERT(!isEmpty()); return *begin(); }
00153 T &front() { return first(); }
00154 const T &front() const { return first(); }
00155 T &last() { QHULL_ASSERT(!isEmpty()); return *(end()-1); }
00156 const T &last() const { QHULL_ASSERT(!isEmpty()); return *(end()-1); }
00157
00158 T &operator[](int idx) { T *n= reinterpret_cast<T *>(elementPointer(idx)); QHULL_ASSERT(idx>=0 && n < reinterpret_cast<T *>(endPointer())); return *n; }
00159 const T &operator[](int idx) const { const T *n= reinterpret_cast<const T *>(elementPointer(idx)); QHULL_ASSERT(idx>=0 && n < reinterpret_cast<T *>(endPointer())); return *n; }
00160 T &second() { return operator[](1); }
00161 const T &second() const { return operator[](1); }
00162 T value(int idx) const;
00163 T value(int idx, const T &defaultValue) const;
00164
00165 #//Read-write -- Not available, no setT constructor
00166
00167 #//iterator
00168 iterator begin() { return iterator(beginPointer()); }
00169 const_iterator begin() const { return const_iterator(beginPointer()); }
00170 const_iterator constBegin() const { return const_iterator(beginPointer()); }
00171 const_iterator constEnd() const { return const_iterator(endPointer()); }
00172 iterator end() { return iterator(endPointer()); }
00173 const_iterator end() const { return const_iterator(endPointer()); }
00174
00175 #//Search
00176 bool contains(const T &t) const;
00177 int count(const T &t) const;
00178 int indexOf(const T &t) const { return qh_setindex(getSetT(), t.getBaseT()); }
00179 int lastIndexOf(const T &t) const;
00180
00181 };
00182
00183
00184
00185 template <typename T>
00186 class QhullSetIterator {
00187
00188 #//Subtypes
00189 typedef typename QhullSet<T>::const_iterator const_iterator;
00190
00191 private:
00192 #//Fields
00193 const_iterator i;
00194 const_iterator begin_i;
00195 const_iterator end_i;
00196
00197 public:
00198 #//Constructors
00199 QhullSetIterator<T>(const QhullSet<T> &s) : i(s.begin()), begin_i(i), end_i(s.end()) {}
00200 QhullSetIterator<T>(const QhullSetIterator<T> &o) : i(o.i), begin_i(o.begin_i), end_i(o.end_i) {}
00201 QhullSetIterator<T> &operator=(const QhullSetIterator<T> &o) { i= o.i; begin_i= o.begin_i; end_i= o.end_i; return *this; }
00202
00203 #//ReadOnly
00204 int countRemaining() { return (int)(end_i-begin_i); }
00205
00206 #//Search
00207 bool findNext(const T &t);
00208 bool findPrevious(const T &t);
00209
00210 #//Foreach
00211 bool hasNext() const { return i != end_i; }
00212 bool hasPrevious() const { return i != begin_i; }
00213 T next() { return *i++; }
00214 T peekNext() const { return *i; }
00215 T peekPrevious() const { const_iterator p = i; return *--p; }
00216 T previous() { return *--i; }
00217 void toBack() { i = end_i; }
00218 void toFront() { i = begin_i; }
00219 };
00220
00221 #//== Definitions =========================================
00222
00223 #//Conversion
00224
00225 #ifndef QHULL_NO_STL
00226 template <typename T>
00227 std::vector<T> QhullSet<T>::
00228 toStdVector() const
00229 {
00230 QhullSetIterator<T> i(*this);
00231 std::vector<T> vs;
00232 vs.reserve(i.countRemaining());
00233 while(i.hasNext()){
00234 vs.push_back(i.next());
00235 }
00236 return vs;
00237 }
00238 #endif
00239
00240 #ifdef QHULL_USES_QT
00241 template <typename T>
00242 QList<T> QhullSet<T>::
00243 toQList() const
00244 {
00245 QhullSetIterator<T> i(*this);
00246 QList<T> vs;
00247 while(i.hasNext()){
00248 vs.append(i.next());
00249 }
00250 return vs;
00251 }
00252 #endif
00253
00254 #//Element
00255
00256 template <typename T>
00257 T QhullSet<T>::
00258 value(int idx) const
00259 {
00260
00261 const T *n= reinterpret_cast<const T *>(&SETelem_(getSetT(), idx));
00262 return (idx>=0 && n<end()) ? *n : T();
00263 }
00264
00265 template <typename T>
00266 T QhullSet<T>::
00267 value(int idx, const T &defaultValue) const
00268 {
00269
00270 const T *n= reinterpret_cast<const T *>(&SETelem_(getSetT(), idx));
00271 return (idx>=0 && n<end()) ? *n : defaultValue;
00272 }
00273
00274 #//Search
00275
00276 template <typename T>
00277 bool QhullSet<T>::
00278 contains(const T &t) const
00279 {
00280 setT *s= getSetT();
00281 void *e= t.getBaseT();
00282 int result= qh_setin(s, e);
00283 return result!=0;
00284 }
00285
00286 template <typename T>
00287 int QhullSet<T>::
00288 count(const T &t) const
00289 {
00290 int c= 0;
00291 const T *i= data();
00292 const T *e= end();
00293 while(i<e){
00294 if(*i==t){
00295 c++;
00296 }
00297 i++;
00298 }
00299 return c;
00300 }
00301
00302 template <typename T>
00303 int QhullSet<T>::
00304 lastIndexOf(const T &t) const
00305 {
00306 const T *b= begin();
00307 const T *i= end();
00308 while(--i>=b){
00309 if(*i==t){
00310 break;
00311 }
00312 }
00313 return (int)(i-b);
00314 }
00315
00316 #//QhullSetIterator
00317
00318 template <typename T>
00319 bool QhullSetIterator<T>::
00320 findNext(const T &t)
00321 {
00322 while(i!=end_i){
00323 if(*(++i)==t){
00324 return true;
00325 }
00326 }
00327 return false;
00328 }
00329
00330 template <typename T>
00331 bool QhullSetIterator<T>::
00332 findPrevious(const T &t)
00333 {
00334 while(i!=begin_i){
00335 if(*(--i)==t){
00336 return true;
00337 }
00338 }
00339 return false;
00340 }
00341
00342 }
00343
00344
00345 #//== Global namespace =========================================
00346
00347 template <typename T>
00348 std::ostream &
00349 operator<<(std::ostream &os, const orgQhull::QhullSet<T> &qs)
00350 {
00351 const T *i= qs.begin();
00352 const T *e= qs.end();
00353 while(i!=e){
00354 os << *i;
00355 ++i;
00356 }
00357 return os;
00358 }
00359
00360 #endif // QhullSet_H