G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
gsKnotIterator.h
Go to the documentation of this file.
1
14#pragma once
15
16namespace gismo {
17
18namespace internal {
19
20 template<typename T> class gsKnotIterator;
21
29template <typename T>
30class gsUKnotIterator
31{
32public:
33 friend class gsKnotVector<T>;
34 friend class gsKnotIterator<T>;
35
36 typedef typename gsKnotVector<T>::mult_t mult_t; //index_t, gsKnotVector.h:85
37 typedef std::random_access_iterator_tag iterator_category;
38 typedef const gsKnotVector<T> knotVector;
39 typedef T value_type;
40 typedef std::ptrdiff_t difference_type;
41 typedef const T& reference;
42 typedef const T* pointer;
43 typedef const mult_t* mltpointer;
44
45private:
46 mltpointer m_mlt ;
47 pointer m_raw ;
48 mult_t m_upos;
49 mult_t m_sh ;
50
51//#if defined(_GLIBCXX_DEBUG) || _SECURE_SCL != 0
52 mult_t m_dbg;// iteration limit: extra member for iterator debugging mode
53//#endif
54
55protected:
56
57 // Change the value of the knot - access restricted to friend classes
58 // Warning: call GISMO_ASSERT(check()) after using.
59 void setValue(const T val)
60 {
61 std::fill(const_cast<T*>(m_raw) + firstAppearance(),
62 const_cast<T*>(m_raw) + multSum(), val);
63 }
64
65public:
66
71 gsUKnotIterator()
72 : m_mlt(NULL), m_raw(NULL), m_upos(0), m_sh(0), m_dbg(0)
73 { }
74
84 explicit gsUKnotIterator(knotVector & KV, const mult_t upos = 0, const index_t s = 0)
85 : m_mlt ( KV.multSumData() ), m_raw ( KV.data() ),
86 m_upos( upos ), m_sh (s )
87 {
88 m_dbg = KV.uSize()+1;
89# if defined(_GLIBCXX_DEBUG) || _SECURE_SCL != 0
90 //m_dbg = KV.uSize()+1;
91 GISMO_ENSURE(upos < m_dbg, "Invalid iterator position "<< upos
92 <<" for knot vector with "<<KV.uSize()<<" unique knots");
93# endif
94 }
95
100 static inline gsUKnotIterator End(knotVector & KV)
101 { // the past-the-end position occurs for upos=KV.uSize()
102 return gsUKnotIterator(KV, KV.uSize(),KV.numLeftGhosts());
103 }
104
105public:
106
108 reference operator* () const
109 {
110# if defined(_GLIBCXX_DEBUG) || _SECURE_SCL != 0
111 GISMO_ENSURE(m_upos >= 0 && m_upos + 1 < m_dbg, "Access to invalid knot position.");
112# endif
113 return m_raw[m_mlt[m_upos]-1];
114 }
115
116 pointer operator-> () const {return m_raw+m_mlt[m_upos]-1 ;}
117
118 gsUKnotIterator& operator++()
119 {
120 ++m_upos;
121# if defined(_GLIBCXX_DEBUG) || _SECURE_SCL != 0
122 GISMO_ENSURE(m_upos < m_dbg, "Invalid knot-iterator increment: "
123 << m_upos <<" is past the end position ("<<m_dbg-1<<").");
124# endif
125 return *this;
126 }
127
128 gsUKnotIterator& operator--()
129 {
130# if defined(_GLIBCXX_DEBUG) || _SECURE_SCL != 0
131 GISMO_ENSURE(m_upos > 0 && m_upos < m_dbg, "Invalid knot-iterator decrement");
132# endif
133 --m_upos;
134 return *this;
135 }
136
137 gsUKnotIterator operator++(int) { gsUKnotIterator tmp(*this); ++(*this); return tmp; }
138 gsUKnotIterator operator--(int) { gsUKnotIterator tmp(*this); --(*this); return tmp; }
139
152 bool operator == (const gsUKnotIterator& other) const
153 { return m_upos == other.m_upos;}// && m_raw == other.m_raw;}
154
167 bool operator != (const gsUKnotIterator& other) const {return m_upos != other.m_upos;}
168 bool operator < (const gsUKnotIterator& other) const {return m_upos < other.m_upos;}
169 bool operator > (const gsUKnotIterator& other) const {return m_upos > other.m_upos;}
170 bool operator <= (const gsUKnotIterator& other) const {return m_upos <= other.m_upos;}
171 bool operator >= (const gsUKnotIterator& other) const {return m_upos >= other.m_upos;}
172
177 reference operator[] (ptrdiff_t a) const
178 {
179# if defined(_GLIBCXX_DEBUG) || _SECURE_SCL != 0
180 GISMO_ENSURE(m_upos+a>=0 && m_upos+a+1 < m_dbg, "Invalid access to non-existent knot.");
181# endif
182 return m_raw[m_mlt[m_upos+a]-1];
183 }
184
189 gsUKnotIterator& operator+=(const difference_type & a)
190 {
191 m_upos += a;
192# if defined(_GLIBCXX_DEBUG) || _SECURE_SCL != 0
193 // Note: we allow invalid position for iterators on empty knot-vectors
194 GISMO_ENSURE(m_dbg<2 || (m_upos >= 0 && m_upos < m_dbg),
195 "Iterator jumped to invalid knot position.");
196# endif
197 return *this;
198 }
199
204 gsUKnotIterator operator+(const difference_type & a) const
205 {
206 gsUKnotIterator tmp(*this);
207 return tmp+=a;
208 }
209
214 gsUKnotIterator& operator-=(const difference_type & a)
215 {
216 return operator+=(-a);
217 }
218
223 gsUKnotIterator operator-(const difference_type & a) const
224 {
225 gsUKnotIterator tmp(*this);
226 return tmp-=a;
227 }
228
229 friend difference_type operator-(const gsUKnotIterator & l, const gsUKnotIterator & r)
230 {return l.m_upos - r.m_upos; }
231
235 reference value() const
236 {
237# if defined(_GLIBCXX_DEBUG) || _SECURE_SCL != 0
238 GISMO_ENSURE(m_upos >= 0 && m_upos + 1< m_dbg, "Access to invalid knot position.");
239# endif
240 return this->operator*();
241 }
242
247 mult_t multiplicity() const
248 {
249# if defined(_GLIBCXX_DEBUG) || _SECURE_SCL != 0
250 GISMO_ENSURE(m_upos >= 0 && m_upos + 1< m_dbg, "Access to invalid knot position.");
251# endif
252 if ( 0 == m_upos )//is it the first unique knot?
253 return *m_mlt;
254 else
255 {
256 mltpointer mp = m_mlt + m_upos;
257 return *mp - *(mp-1);
258 }
259 }
260
265 mult_t uIndex() const {return m_upos-m_sh;}
266
272 mult_t uCardinalIndex() const {return m_upos;}
273
282 mult_t firstAppearance() const
283 {
284 return 0 == m_upos ? 0 : m_mlt[m_upos-1];
285 }
286
295 mult_t lastAppearance() const
296 {
297# if defined(_GLIBCXX_DEBUG) || _SECURE_SCL != 0
298 GISMO_ENSURE(m_upos >= 0 && m_upos + 1< m_dbg, "Access to invalid knot position.");
299# endif
300 return m_mlt[m_upos] - 1;
301 }
302
311 mult_t multSum() const
312 { return m_mlt[m_upos];}
313
314private:
315
316 /*
317 \brief Sets the iterator to the first (without repetitions)
318 knot in the knot sequence
319
320 // needed ?
321 void reset()
322 {
323 m_upos = 0;
324 }
325 */
326};
327
335template <typename T>
336class gsKnotIterator
337{
338public:
339 friend class gsKnotVector<T>;
340
341 typedef typename gsKnotVector<T>::mult_t mult_t;
342 typedef std::random_access_iterator_tag iterator_category;
343 typedef const gsKnotVector<T> knotVector;
344 typedef T value_type;
345 typedef std::ptrdiff_t difference_type;
346 typedef const T& reference;
347 typedef const T* pointer;
348 typedef const mult_t* mltpointer;
349
350private:
351 gsUKnotIterator<T> m_uit;
352 mult_t m_pos;
353
354#if defined(_GLIBCXX_DEBUG) || _SECURE_SCL != 0
355 mult_t m_dbg;// iteration limit: extra member for iterator debugging mode
356#endif
357
358public:
359
363 gsKnotIterator()
364 : m_uit(), m_pos(0)
365 { }
366
376 explicit gsKnotIterator(knotVector & KV, const mult_t upos = 0, const index_t s = 0)
377 : m_uit(KV,upos,s), m_pos(firstAppearance())
378 {
379# if defined(_GLIBCXX_DEBUG) || _SECURE_SCL != 0
380 m_dbg = KV.size()+1;
381 GISMO_ENSURE(static_cast<size_t>(upos) <= KV.uSize(),
382 "Invalid iterator position "<< upos
383 <<" for knot vector with "<<KV.uSize()<<" unique knots");
384# endif
385 }
386
391 static inline gsKnotIterator End(const gsKnotVector<T> & KV)
392 { // the past-the-end position occurs for upos=KV.uSize()
393 return gsKnotIterator(KV, KV.uSize(),KV.numLeftGhosts());
394 }
395
396public:
397
399 reference operator* () const
400 {
401# if defined(_GLIBCXX_DEBUG) || _SECURE_SCL != 0
402 GISMO_ENSURE(m_pos >= 0 && m_pos + 1< m_dbg,
403 "Access to invalid knot position.");
404# endif
405 return m_uit.m_raw[m_pos];
406 }
407
408 pointer get() const {return m_uit.m_raw+m_pos;}
409 pointer operator-> () const {return get();}
410
411 gsKnotIterator& operator++()
412 {
413 if (++m_pos == m_uit.multSum())//crossing interval?
414 ++m_uit;
415# if defined(_GLIBCXX_DEBUG) || _SECURE_SCL != 0
416 GISMO_ENSURE(m_pos < m_dbg, "Invalid knot-iterator increment: "
417 << m_pos <<" is past the end position ("<<m_dbg-1<<").");
418# endif
419 return *this;
420 }
421
422 gsKnotIterator& operator--()
423 {
424# if defined(_GLIBCXX_DEBUG) || _SECURE_SCL != 0
425 GISMO_ENSURE(m_pos > 0 && m_pos < m_dbg, "Invalid knot-iterator decrement");
426# endif
427 if ( m_pos-- == firstAppearance() )//crossing interval?
428 --m_uit;
429 return *this;
430 }
431
432 gsKnotIterator operator++(int) { gsKnotIterator tmp(*this); ++(*this); return tmp; }
433 gsKnotIterator operator--(int) { gsKnotIterator tmp(*this); --(*this); return tmp; }
434
447 bool operator == (const gsKnotIterator& other) const
448 { return m_pos == other.m_pos;}// && m_raw == other.m_raw;}
449
462 bool operator != (const gsKnotIterator& other) const {return m_pos != other.m_pos;}
463 bool operator < (const gsKnotIterator& other) const {return m_pos < other.m_pos;}
464 bool operator > (const gsKnotIterator& other) const {return m_pos > other.m_pos;}
465 bool operator <= (const gsKnotIterator& other) const {return m_pos <= other.m_pos;}
466 bool operator >= (const gsKnotIterator& other) const {return m_pos >= other.m_pos;}
467
472 reference operator[] (ptrdiff_t a) const
473 {
474# if defined(_GLIBCXX_DEBUG) || _SECURE_SCL != 0
475 GISMO_ENSURE(m_pos+a>=0 && m_pos+a+1 < m_dbg, "Invalid access to non-existent knot.");
476# endif
477 return m_uit.m_raw[m_pos+a];
478 }
479
484 reference operator() (ptrdiff_t a) const
485 {
486# if defined(_GLIBCXX_DEBUG) || _SECURE_SCL != 0
487 GISMO_ENSURE(m_pos+a>=0 && m_pos+a+1 < m_dbg, "Invalid access to non-existent knot.");
488# endif
489 return m_uit[a];
490 }
491
497 const gsUKnotIterator<T> & uIterator() const
498 { return m_uit; }
499
505 void uNext()
506 {
507 ++m_uit;
508 m_pos = firstAppearance();
509 //m_pos = (m_uit++).multSum();//advance unique position and update m_pos
510 }
511
517 void uPrev()
518 {
519 --m_uit;
520 m_pos = firstAppearance();
521 }
522
524 void uAdd(const difference_type & a)
525 {
526 m_uit += a;
527 m_pos = firstAppearance();
528 }
529
534 gsKnotIterator& operator+=(const difference_type & a)
535 {
536 m_pos += a;
537# if defined(_GLIBCXX_DEBUG) || _SECURE_SCL != 0
538 GISMO_ENSURE((m_pos >= 0 && m_pos < m_dbg),
539 "Iterator jumped to invalid knot position.");
540# endif
541
542 if (a<0) //substracting ?
543 {
544 mltpointer end = m_uit.m_mlt + m_uit.m_upos;
545 mltpointer beg = end + a;
546 if (beg < m_uit.m_mlt) beg = m_uit.m_mlt;
547 //note: [beg, end) is a valid sorted range, complexity: O(log a)
548 m_uit.m_upos = std::upper_bound(beg, end, m_pos) - m_uit.m_mlt;
549 }
550 else //incrementing
551 {
552 mltpointer beg = m_uit.m_mlt + m_uit.m_upos;
553 // O(log a) efficient version
554 mltpointer end = std::min(m_uit.m_mlt + m_uit.m_dbg-1, beg + a);
555 m_uit.m_upos = std::upper_bound(beg, end, m_pos) - m_uit.m_mlt;
556
557 // unsafe version withoud m_dbg
558 //mltpointer end = beg + a; // note: could be over the end of m_mlt
559 // while (beg!=end && (*beg)<=m_pos) { ++beg; }
560 // m_uit.m_upos = beg - m_uit.m_mlt;
561 }
562
563 return *this;
564 }
565
570 gsKnotIterator operator+(const difference_type & a) const
571 {
572 gsKnotIterator tmp(*this);
573 return tmp+=a;
574 }
575
576
581 gsKnotIterator& operator-=(const difference_type & a)
582 {
583 return operator+=(-a);
584 }
585
590 gsKnotIterator operator-(const difference_type & a) const
591 {
592 gsKnotIterator tmp(*this);
593 return tmp-=a;
594 }
595
596 friend difference_type operator-(const gsKnotIterator & l, const gsKnotIterator & r)
597 {return l.m_pos - r.m_pos; }
598
602 reference value() const {return this->operator*();}
603
608 mult_t multiplicity() const
609 {
610 return m_uit.multiplicity();
611 }
612
617 mult_t index() const {return m_pos;}
618
623 mult_t uIndex() const {return m_uit.uIndex();}
624
630 mult_t uCardinalIndex() const {return m_uit.uCardinalIndex();}
631
639 mult_t firstAppearance() const
640 { return m_uit.firstAppearance();}
641
649 mult_t lastAppearance() const
650 { return m_uit.lastAppearance();}
651
660 mult_t multSum() const
661 { return m_uit.multSum();}
662
667 void backToFirstAppearance()
668 { m_pos = m_uit.firstAppearance();}
669
670 /*
671 \brief Sets the iterator to the first knot in the knot sequence
672 // needed ?
673 void reset()
674 {
675 m_pos = 0;
676 m_upos = 0;
677 }
678 */
679
680};
681
682
683} // namespace internal
684
685
686
687}// namespace gismo
688
#define index_t
Definition gsConfig.h:32
#define GISMO_ENSURE(cond, message)
Definition gsDebug.h:102
EIGEN_STRONG_INLINE add_expr< E1, E2 > const operator+(_expr< E1 > const &u, _expr< E2 > const &v)
Addition operator for expressions.
Definition gsExpressions.h:4607
EIGEN_STRONG_INLINE mult_expr< E1, E2 > const operator*(_expr< E1 > const &u, _expr< E2 > const &v)
Multiplication operator for expressions.
Definition gsExpressions.h:4559
The G+Smo namespace, containing all definitions for the library.