/**************************************************************************** ** ** Copyright (c) 2009-2020 C.B. Barber. All rights reserved. ** $Id: //main/2019/qhull/src/libqhullcpp/Coordinates.h#5 $$Change: 3001 $ ** $DateTime: 2020/07/24 20:43:28 $$Author: bbarber $ ** ****************************************************************************/ #ifndef QHCOORDINATES_H #define QHCOORDINATES_H #include "libqhull_r/qhull_ra.h" #include "libqhullcpp/QhullError.h" #include // ptrdiff_t, size_t #include // Requires STL vector class. Can use with another vector class such as QList. #include namespace orgQhull { #//!\name Defined here //! An std::vector of point coordinates independent of dimension //! Used by PointCoordinates for RboxPoints and by Qhull for feasiblePoint //! A QhullPoint refers to previously allocated coordinates class Coordinates; //! Java-style iterators are not implemented for Coordinates. std::vector has an expensive copy constructor and copy assignment. //! A pointer to Coordinates is vulnerable to mysterious overwrites (e.g., deleting a returned value and reusing its memory) //! Qt's 'foreach' should not be used. It makes a copy of the std::vector class Coordinates { private: #//!\name Fields std::vector coordinate_array; public: #//!\name Subtypes class const_iterator; class iterator; typedef iterator Iterator; typedef const_iterator ConstIterator; typedef coordT value_type; typedef const value_type *const_pointer; typedef const value_type & const_reference; typedef value_type * pointer; typedef value_type & reference; typedef ptrdiff_t difference_type; typedef countT size_type; #//!\name Construct Coordinates() : coordinate_array() {} explicit Coordinates(const std::vector &other) : coordinate_array(other) {} Coordinates(const Coordinates &other) : coordinate_array(other.coordinate_array) {} Coordinates & operator=(const Coordinates &other) { coordinate_array= other.coordinate_array; return *this; } Coordinates & operator=(const std::vector &other) { coordinate_array= other; return *this; } ~Coordinates() {} #//!\name Conversion #ifndef QHULL_NO_STL std::vector toStdVector() const { return coordinate_array; } #endif //QHULL_NO_STL #ifdef QHULL_USES_QT QList toQList() const; #endif //QHULL_USES_QT #//!\name GetSet countT count() const { return static_cast(size()); } coordT * data() { return (isEmpty() ? NULL : &at(0)); } const coordT * data() const { return (isEmpty() ? NULL : &at(0)); } bool isEmpty() const { return coordinate_array.empty(); } bool operator==(const Coordinates &other) const { return coordinate_array==other.coordinate_array; } bool operator!=(const Coordinates &other) const { return coordinate_array!=other.coordinate_array; } size_t size() const { return coordinate_array.size(); } #//!\name Element access coordT & at(countT idx) { return coordinate_array.at(idx); } const coordT & at(countT idx) const { return coordinate_array.at(idx); } coordT & back() { return coordinate_array.back(); } const coordT & back() const { return coordinate_array.back(); } coordT & first() { return front(); } const coordT & first() const { return front(); } coordT & front() { return coordinate_array.front(); } const coordT & front() const { return coordinate_array.front(); } coordT & last() { return back(); } const coordT & last() const { return back(); } Coordinates mid(countT idx, countT length= -1) const; //!<\todo countT -1 indicates coordT & operator[](countT idx) { return coordinate_array.operator[](idx); } const coordT & operator[](countT idx) const { return coordinate_array.operator[](idx); } coordT value(countT idx, const coordT &defaultValue) const; #//!\name Iterator iterator begin() { return iterator(coordinate_array.begin()); } const_iterator begin() const { return const_iterator(coordinate_array.begin()); } const_iterator constBegin() const { return begin(); } const_iterator constEnd() const { return end(); } iterator end() { return iterator(coordinate_array.end()); } const_iterator end() const { return const_iterator(coordinate_array.end()); } #//!\name GetSet Coordinates operator+(const Coordinates &other) const; #//!\name Modify void append(int pointDimension, coordT *c); void append(const coordT &c) { push_back(c); } void clear() { coordinate_array.clear(); } iterator erase(iterator idx) { return iterator(coordinate_array.erase(idx.base())); } iterator erase(iterator beginIterator, iterator endIterator) { return iterator(coordinate_array.erase(beginIterator.base(), endIterator.base())); } void insert(countT before, const coordT &c) { insert(begin()+before, c); } iterator insert(iterator before, const coordT &c) { return iterator(coordinate_array.insert(before.base(), c)); } void move(countT from, countT to) { insert(to, takeAt(from)); } Coordinates & operator+=(const Coordinates &other); Coordinates & operator+=(const coordT &c) { append(c); return *this; } Coordinates & operator<<(const Coordinates &other) { return *this += other; } Coordinates & operator<<(const coordT &c) { return *this += c; } void pop_back() { coordinate_array.pop_back(); } void pop_front() { removeFirst(); } void prepend(const coordT &c) { insert(begin(), c); } void push_back(const coordT &c) { coordinate_array.push_back(c); } void push_front(const coordT &c) { insert(begin(), c); } //removeAll below void removeAt(countT idx) { erase(begin()+idx); } void removeFirst() { erase(begin()); } void removeLast() { erase(--end()); } void replace(countT idx, const coordT &c) { (*this)[idx]= c; } void reserve(countT i) { coordinate_array.reserve(i); } void swap(countT idx, countT other); coordT takeAt(countT idx); coordT takeFirst() { return takeAt(0); } coordT takeLast(); #//!\name Search bool contains(const coordT &t) const; countT count(const coordT &t) const; countT indexOf(const coordT &t, countT from= 0) const; countT lastIndexOf(const coordT &t, countT from= -1) const; void removeAll(const coordT &t); #//!\name Coordinates::iterator -- from QhullPoints, forwarding to coordinate_array // before const_iterator for conversion with comparison operators // Reviewed corelib/tools/qlist.h and corelib/tools/qvector.h w/o QT_STRICT_ITERATORS class iterator { private: std::vector::iterator i; friend class const_iterator; public: typedef std::random_access_iterator_tag iterator_category; typedef coordT value_type; typedef value_type *pointer; typedef value_type &reference; typedef ptrdiff_t difference_type; iterator() : i() {} iterator(const iterator &other) : i() { i= other.i; } explicit iterator(const std::vector::iterator &vi) : i() { i= vi; } iterator & operator=(const iterator &other) { i= other.i; return *this; } std::vector::iterator &base() { return i; } coordT & operator*() const { return *i; } // No operator->() when the base type is double coordT & operator[](countT idx) const { return i[idx]; } bool operator==(const iterator &other) const { return i==other.i; } bool operator!=(const iterator &other) const { return i!=other.i; } bool operator<(const iterator &other) const { return i(const iterator &other) const { return i>other.i; } bool operator>=(const iterator &other) const { return i>=other.i; } // reinterpret_cast to break circular dependency bool operator==(const Coordinates::const_iterator &other) const { return *this==reinterpret_cast(other); } bool operator!=(const Coordinates::const_iterator &other) const { return *this!=reinterpret_cast(other); } bool operator<(const Coordinates::const_iterator &other) const { return *this(other); } bool operator<=(const Coordinates::const_iterator &other) const { return *this<=reinterpret_cast(other); } bool operator>(const Coordinates::const_iterator &other) const { return *this>reinterpret_cast(other); } bool operator>=(const Coordinates::const_iterator &other) const { return *this>=reinterpret_cast(other); } iterator & operator++() { ++i; return *this; } iterator operator++(int) { return iterator(i++); } iterator & operator--() { --i; return *this; } iterator operator--(int) { return iterator(i--); } iterator & operator+=(countT idx) { i += idx; return *this; } iterator & operator-=(countT idx) { i -= idx; return *this; } iterator operator+(countT idx) const { return iterator(i+idx); } iterator operator-(countT idx) const { return iterator(i-idx); } difference_type operator-(iterator other) const { return i-other.i; } };//Coordinates::iterator #//!\name Coordinates::const_iterator class const_iterator { private: std::vector::const_iterator i; public: typedef std::random_access_iterator_tag iterator_category; typedef coordT value_type; typedef const value_type *pointer; typedef const value_type &reference; typedef ptrdiff_t difference_type; const_iterator() : i() {} const_iterator(const const_iterator &other) : i() { i= other.i; } const_iterator(const iterator &o) : i(o.i) {} explicit const_iterator(const std::vector::const_iterator &vi) : i() { i= vi; } const_iterator &operator=(const const_iterator &other) { i= other.i; return *this; } const coordT & operator*() const { return *i; } // No operator->() when the base type is double const coordT & operator[](countT idx) const { return i[idx]; } bool operator==(const const_iterator &other) const { return i==other.i; } bool operator!=(const const_iterator &other) const { return i!=other.i; } bool operator<(const const_iterator &other) const { return i(const const_iterator &other) const { return i>other.i; } bool operator>=(const const_iterator &other) const { return i>=other.i; } const_iterator & operator++() { ++i; return *this; } const_iterator operator++(int) { return const_iterator(i++); } const_iterator & operator--() { --i; return *this; } const_iterator operator--(int) { return const_iterator(i--); } const_iterator & operator+=(countT idx) { i += idx; return *this; } const_iterator & operator-=(countT idx) { i -= idx; return *this; } const_iterator operator+(countT idx) const { return const_iterator(i+idx); } const_iterator operator-(countT idx) const { return const_iterator(i-idx); } difference_type operator-(const_iterator other) const { return i-other.i; } };//Coordinates::const_iterator };//Coordinates }//namespace orgQhull #//!\name Global std::ostream &operator<<(std::ostream &os, const orgQhull::Coordinates &c); #endif // QHCOORDINATES_H