Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Analysis.AlgorithmBehavior/qhull-2012.1/src/libqhullcpp/QhullSet.h @ 10207

Last change on this file since 10207 was 10207, checked in by ascheibe, 11 years ago

#1886 added a unit test for volume calculation and the qhull library

File size: 11.7 KB
Line 
1/****************************************************************************
2**
3** Copyright (c) 2008-2012 C.B. Barber. All rights reserved.
4** $Id: //main/2011/qhull/src/libqhullcpp/QhullSet.h#7 $$Change: 1464 $
5** $DateTime: 2012/01/25 22:58:41 $$Author: bbarber $
6**
7****************************************************************************/
8
9#ifndef QhullSet_H
10#define QhullSet_H
11
12#include "QhullError.h"
13extern "C" {
14    #include "libqhull/qhull_a.h"
15}
16
17
18#ifndef QHULL_NO_STL
19#include <vector>
20#endif
21
22#ifdef QHULL_USES_QT
23 #include <QtCore/QList>
24#endif
25
26namespace orgQhull {
27
28#//Type
29    class QhullSetBase;  //! Base class for QhullSet<T>
30    //! QhullSet<T> -- A read-only wrapper to Qhull's collection class, setT.
31    //!  QhullSet is similar to STL's <vector> and Qt's QVector.
32    //!  QhullSet is unrelated to STL and Qt's set and map types (e.g., QSet and QMap)
33    //!  For STL efficiency, QhullSet caches endPointer()
34    //!  T must be a pointer type
35    //!  A QhullSet does not own its contents -- erase(), clear(), removeFirst(), removeLast(), pop_back(), pop_front(), fromStdList() not defined
36    //!  Qhull's FOREACHelement_() [qset.h] is more efficient than QhullSet.  It uses a NULL terminator instead of an end pointer.  STL requires an end pointer.
37    //!  Derived from QhullLinkedList.h and Qt/core/tools/qvector.h
38
39    //! QhullSetIterator<T> defined below
40    //See: QhullPointSet, QhullLinkedList<T>
41
42class QhullSetBase {
43
44private:
45#//Fields --
46    setT               *qh_set;
47
48#//Class objects
49    static setT         s_empty_set;  //! Workaround for no setT allocator.  Used if setT* is NULL
50
51public:
52#//Class methods
53    static int          count(const setT *set);
54    //s may be null
55    static bool         isEmpty(const setT *s) { return SETempty_(s); }
56
57
58#//Constructors
59                        //! Copy constructor copies the pointer but not the set.  Needed for return by value and parameter passing.
60                        QhullSetBase(const QhullSetBase &o) : qh_set(o.qh_set) {}
61    explicit            QhullSetBase(setT *s) : qh_set(s ? s : &s_empty_set) {}
62                       ~QhullSetBase() {}
63
64private:
65                        //!disabled since memory allocation for QhullSet not defined
66                        QhullSetBase() {}
67                        //!disabled since qs= qs2 is ambiguous (pointer vs. contents)
68    QhullSetBase       &operator=(const QhullSetBase &);
69public:
70
71#//Conversions
72                        //! Not type-safe since setT may contain any type
73    void                defineAs(setT *s) { qh_set= s ? s : &s_empty_set; }
74    setT               *getSetT() const { return qh_set; }
75    setT              **referenceSetT() { return &qh_set; }
76
77#//Read-only
78    int                 count() const { return QhullSetBase::count(qh_set); }
79    bool                empty() const { return SETfirst_(qh_set)==0; }
80    bool                isEmpty() const { return empty(); }
81    size_t              size() const { return count(); }
82
83#//Element
84protected:
85    void              **beginPointer() const { return &qh_set->e[0].p; }
86    void              **elementPointer(int idx) const { QHULL_ASSERT(idx>=0 && idx<qh_set->maxsize); return &SETelem_(qh_set, idx); }
87                        //! Always points to 0
88    void              **endPointer() const { return qh_setendpointer(qh_set); }
89};//QhullSetBase
90
91
92//! set of pointers to baseT, T.getBaseT()
93template <typename T>
94class QhullSet : public QhullSetBase {
95
96private:
97#//Fields -- see QhullSetBase
98
99#//Class objects
100    static setT         s_empty_set;  //! Workaround for no setT allocator.  Used if setT* is NULL
101
102public:
103#//Subtypes
104    typedef T         *iterator;
105    typedef const T   *const_iterator;
106    typedef typename QhullSet<T>::iterator Iterator;
107    typedef typename QhullSet<T>::const_iterator ConstIterator;
108
109#//Class methods
110    static int          count(const setT *set);
111                        //s may be null
112    static bool         isEmpty(const setT *s) { return SETempty_(s); }
113
114#//Constructors
115                        //Copy constructor copies pointer but not contents.  Needed for return by value.
116                        QhullSet<T>(const QhullSet<T> &o) : QhullSetBase(o) {}
117                        //Conversion from setT* is not type-safe.  Implicit conversion for void* to T
118    explicit            QhullSet<T>(setT *s) : QhullSetBase(s) { QHULL_ASSERT(sizeof(T)==sizeof(void *)); }
119                       ~QhullSet<T>() {}
120
121private:
122                        //!Disable default constructor and copy assignment.  See QhullSetBase
123                        QhullSet<T>();
124    QhullSet<T>        &operator=(const QhullSet<T> &);
125public:
126
127#//Conversion
128
129#ifndef QHULL_NO_STL
130    std::vector<T>      toStdVector() const;
131#endif
132#ifdef QHULL_USES_QT
133    QList<T>            toQList() const;
134#endif
135
136#//Read-only -- see QhullSetBase for count(), empty(), isEmpty(), size()
137    using QhullSetBase::count;
138    using QhullSetBase::isEmpty;
139    // operator== defined for QhullSets of the same type
140    bool                operator==(const QhullSet<T> &other) const { return qh_setequal(getSetT(), other.getSetT()); }
141    bool                operator!=(const QhullSet<T> &other) const { return !operator==(other); }
142
143#//Element access
144    const T            &at(int idx) const { return operator[](idx); }
145    T                  &back() { return last(); }
146    T                  &back() const { return last(); }
147    //! end element is NULL
148    const T            *constData() const { return constBegin(); }
149    T                  *data() { return begin(); }
150    const T            *data() const { return begin(); }
151    T                  &first() { QHULL_ASSERT(!isEmpty()); return *begin(); }
152    const T            &first() const { QHULL_ASSERT(!isEmpty()); return *begin(); }
153    T                  &front() { return first(); }
154    const T            &front() const { return first(); }
155    T                  &last() { QHULL_ASSERT(!isEmpty()); return *(end()-1); }
156    const T            &last() const {  QHULL_ASSERT(!isEmpty()); return *(end()-1); }
157    // mid() not available.  No setT constructor
158    T                  &operator[](int idx) { T *n= reinterpret_cast<T *>(elementPointer(idx)); QHULL_ASSERT(idx>=0 && n < reinterpret_cast<T *>(endPointer())); return *n; }
159    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; }
160    T                  &second() { return operator[](1); }
161    const T            &second() const { return operator[](1); }
162    T                   value(int idx) const;
163    T                   value(int idx, const T &defaultValue) const;
164
165#//Read-write -- Not available, no setT constructor
166
167#//iterator
168    iterator            begin() { return iterator(beginPointer()); }
169    const_iterator      begin() const { return const_iterator(beginPointer()); }
170    const_iterator      constBegin() const { return const_iterator(beginPointer()); }
171    const_iterator      constEnd() const { return const_iterator(endPointer()); }
172    iterator            end() { return iterator(endPointer()); }
173    const_iterator      end() const { return const_iterator(endPointer()); }
174
175#//Search
176    bool                contains(const T &t) const;
177    int                 count(const T &t) const;
178    int                 indexOf(const T &t) const { /* no qh_qh */ return qh_setindex(getSetT(), t.getBaseT()); }
179    int                 lastIndexOf(const T &t) const;
180
181};//class QhullSet
182
183// FIXUP? can't use QHULL_DECLARE_SEQUENTIAL_ITERATOR because it is not a template
184
185template <typename T>
186class QhullSetIterator {
187
188#//Subtypes
189    typedef typename QhullSet<T>::const_iterator const_iterator;
190
191private:
192#//Fields
193    const_iterator      i;
194    const_iterator      begin_i;
195    const_iterator      end_i;
196
197public:
198#//Constructors
199                        QhullSetIterator<T>(const QhullSet<T> &s) : i(s.begin()), begin_i(i), end_i(s.end()) {}
200                        QhullSetIterator<T>(const QhullSetIterator<T> &o) : i(o.i), begin_i(o.begin_i), end_i(o.end_i) {}
201    QhullSetIterator<T> &operator=(const QhullSetIterator<T> &o) { i= o.i; begin_i= o.begin_i; end_i= o.end_i; return *this; }
202
203#//ReadOnly
204    int                 countRemaining() { return (int)(end_i-begin_i); } // WARN64
205
206#//Search
207    bool                findNext(const T &t);
208    bool                findPrevious(const T &t);
209
210#//Foreach
211    bool                hasNext() const { return i != end_i; }
212    bool                hasPrevious() const { return i != begin_i; }
213    T                   next() { return *i++; }
214    T                   peekNext() const { return *i; }
215    T                   peekPrevious() const { const_iterator p = i; return *--p; }
216    T                   previous() { return *--i; }
217    void                toBack() { i = end_i; }
218    void                toFront() { i = begin_i; }
219};//class QhullSetIterator
220
221#//== Definitions =========================================
222
223#//Conversion
224
225#ifndef QHULL_NO_STL
226template <typename T>
227std::vector<T> QhullSet<T>::
228toStdVector() const
229{
230    QhullSetIterator<T> i(*this);
231    std::vector<T> vs;
232    vs.reserve(i.countRemaining());
233    while(i.hasNext()){
234        vs.push_back(i.next());
235    }
236    return vs;
237}//toStdVector
238#endif
239
240#ifdef QHULL_USES_QT
241template <typename T>
242QList<T> QhullSet<T>::
243toQList() const
244{
245    QhullSetIterator<T> i(*this);
246    QList<T> vs;
247    while(i.hasNext()){
248        vs.append(i.next());
249    }
250    return vs;
251}//toQList
252#endif
253
254#//Element
255
256template <typename T>
257T QhullSet<T>::
258value(int idx) const
259{
260    // Avoid call to qh_setsize() and assert in elementPointer()
261    const T *n= reinterpret_cast<const T *>(&SETelem_(getSetT(), idx));
262    return (idx>=0 && n<end()) ? *n : T();
263}//value
264
265template <typename T>
266T QhullSet<T>::
267value(int idx, const T &defaultValue) const
268{
269    // Avoid call to qh_setsize() and assert in elementPointer()
270    const T *n= reinterpret_cast<const T *>(&SETelem_(getSetT(), idx));
271    return (idx>=0 && n<end()) ? *n : defaultValue;
272}//value
273
274#//Search
275
276template <typename T>
277bool QhullSet<T>::
278contains(const T &t) const
279{
280    setT *s= getSetT();
281    void *e= t.getBaseT();  // contains() is not inline for better error reporting
282    int result= qh_setin(s, e);
283    return result!=0;
284}//contains
285
286template <typename T>
287int QhullSet<T>::
288count(const T &t) const
289{
290    int c= 0;
291    const T *i= data();
292    const T *e= end();
293    while(i<e){
294        if(*i==t){
295            c++;
296        }
297        i++;
298    }
299    return c;
300}//count
301
302template <typename T>
303int QhullSet<T>::
304lastIndexOf(const T &t) const
305{
306    const T *b= begin();
307    const T *i= end();
308    while(--i>=b){
309        if(*i==t){
310            break;
311        }
312    }
313    return (int)(i-b); // WARN64
314}//lastIndexOf
315
316#//QhullSetIterator
317
318template <typename T>
319bool QhullSetIterator<T>::
320findNext(const T &t)
321{
322    while(i!=end_i){
323        if(*(++i)==t){
324            return true;
325        }
326    }
327    return false;
328}//findNext
329
330template <typename T>
331bool QhullSetIterator<T>::
332findPrevious(const T &t)
333{
334    while(i!=begin_i){
335        if(*(--i)==t){
336            return true;
337        }
338    }
339    return false;
340}//findPrevious
341
342}//namespace orgQhull
343
344
345#//== Global namespace =========================================
346
347template <typename T>
348std::ostream &
349operator<<(std::ostream &os, const orgQhull::QhullSet<T> &qs)
350{
351    const T *i= qs.begin();
352    const T *e= qs.end();
353    while(i!=e){
354        os << *i;
355        ++i;
356    }
357    return os;
358}//operator<<
359
360#endif // QhullSet_H
Note: See TracBrowser for help on using the repository browser.