GetFEM  5.5
gmm_ref.h
Go to the documentation of this file.
1 /* -*- c++ -*- (enables emacs c++ mode) */
2 /*===========================================================================
3 
4  Copyright (C) 2000-2026 Yves Renard
5 
6  This file is a part of GetFEM
7 
8  GetFEM is free software; you can redistribute it and/or modify it
9  under the terms of the GNU Lesser General Public License as published
10  by the Free Software Foundation; either version 3 of the License, or
11  (at your option) any later version along with the GCC Runtime Library
12  Exception either version 3.1 or (at your option) any later version.
13  This program is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16  License and GCC Runtime Library Exception for more details.
17  You should have received a copy of the GNU Lesser General Public License
18  along with this program. If not, see https://www.gnu.org/licenses/.
19 
20  As a special exception, you may use this file as it is a part of a free
21  software library without restriction. Specifically, if other files
22  instantiate templates or use macros or inline functions from this file,
23  or you compile this file and link it with other files to produce an
24  executable, this file does not by itself cause the resulting executable
25  to be covered by the GNU Lesser General Public License. This exception
26  does not however invalidate any other reasons why the executable file
27  might be covered by the GNU Lesser General Public License.
28 
29 ===========================================================================*/
30 
31 
32 #ifndef GMM_REF_H__
33 #define GMM_REF_H__
34 
35 /** @file gmm_ref.h
36  @author Yves Renard <Yves.Renard@insa-lyon.fr>
37  @date August 26, 2000.
38  * @brief Provide some simple pseudo-containers.
39  *
40  * WARNING : modifiying the container infirm the validity of references.
41  */
42 
43 
44 #include <iterator>
45 #include "gmm_except.h"
46 
47 namespace gmm {
48 
49  /* ********************************************************************* */
50  /* Simple reference. */
51  /* ********************************************************************* */
52 
53  template<typename ITER> class tab_ref {
54 
55  protected :
56 
57  ITER begin_, end_;
58 
59  public :
60 
61  typedef typename std::iterator_traits<ITER>::value_type value_type;
62  typedef typename std::iterator_traits<ITER>::pointer pointer;
63  typedef typename std::iterator_traits<ITER>::pointer const_pointer;
64  typedef typename std::iterator_traits<ITER>::reference reference;
65  typedef typename std::iterator_traits<ITER>::reference const_reference;
66  typedef typename std::iterator_traits<ITER>::difference_type
67  difference_type;
68  typedef ITER iterator;
69  typedef ITER const_iterator;
70  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
71  typedef std::reverse_iterator<iterator> reverse_iterator;
72  typedef size_t size_type;
73 
74  bool empty(void) const { return begin_ == end_; }
75  size_type size(void) const { return end_ - begin_; }
76 
77  const iterator &begin(void) { return begin_; }
78  const const_iterator &begin(void) const { return begin_; }
79  const iterator &end(void) { return end_; }
80  const const_iterator &end(void) const { return end_; }
81  reverse_iterator rbegin(void) { return reverse_iterator(end()); }
82  const_reverse_iterator rbegin(void) const
83  { return const_reverse_iterator(end()); }
84  reverse_iterator rend(void) { return reverse_iterator(begin()); }
85  const_reverse_iterator rend(void) const
86  { return const_reverse_iterator(begin()); }
87 
88  reference front(void) { return *begin(); }
89  const_reference front(void) const { return *begin(); }
90  reference back(void) { return *(--(end())); }
91  const_reference back(void) const { return *(--(end())); }
92  void pop_front(void) { ++begin_; }
93 
94  const_reference operator [](size_type ii) const { return *(begin_ + ii);}
95  reference operator [](size_type ii) { return *(begin_ + ii); }
96 
97  tab_ref(void) {}
98  tab_ref(const ITER &b, const ITER &e) : begin_(b), end_(e) {}
99  };
100 
101 
102  /* ********************************************************************* */
103  /* Reference with index. */
104  /* ********************************************************************* */
105 
106 // template<typename ITER> struct tab_ref_index_iterator_
107 // : public dynamic_array<size_t>::const_iterator
108 // {
109 // typedef typename std::iterator_traits<ITER>::value_type value_type;
110 // typedef typename std::iterator_traits<ITER>::pointer pointer;
111 // typedef typename std::iterator_traits<ITER>::reference reference;
112 // typedef typename std::iterator_traits<ITER>::difference_type
113 // difference_type;
114 // typedef std::random_access_iterator_tag iterator_category;
115 // typedef size_t size_type;
116 // typedef dynamic_array<size_type>::const_iterator dnas_iterator_;
117 // typedef tab_ref_index_iterator_<ITER> iterator;
118 
119 
120 // ITER piter;
121 
122 // iterator operator ++(int)
123 // { iterator tmp = *this; ++(*((dnas_iterator_ *)(this))); return tmp; }
124 // iterator operator --(int)
125 // { iterator tmp = *this; --(*((dnas_iterator_ *)(this))); return tmp; }
126 // iterator &operator ++()
127 // { ++(*((dnas_iterator_ *)(this))); return *this; }
128 // iterator &operator --()
129 // { --(*((dnas_iterator_ *)(this))); return *this; }
130 // iterator &operator +=(difference_type i)
131 // { (*((dnas_iterator_ *)(this))) += i; return *this; }
132 // iterator &operator -=(difference_type i)
133 // { (*((dnas_iterator_ *)(this))) -= i; return *this; }
134 // iterator operator +(difference_type i) const
135 // { iterator it = *this; return (it += i); }
136 // iterator operator -(difference_type i) const
137 // { iterator it = *this; return (it -= i); }
138 // difference_type operator -(const iterator &i) const
139 // { return *((dnas_iterator_ *)(this)) - *((dnas_iterator_ *)(&i)); }
140 
141 // reference operator *() const
142 // { return *(piter + *((*((dnas_iterator_ *)(this))))); }
143 // reference operator [](int ii)
144 // { return *(piter + *((*((dnas_iterator_ *)(this+ii))))); }
145 
146 // bool operator ==(const iterator &i) const
147 // {
148 // return ((piter) == ((i.piter))
149 // && *((dnas_iterator_ *)(this)) == *((*((dnas_iterator_ *)(this)))));
150 // }
151 // bool operator !=(const iterator &i) const
152 // { return !(i == *this); }
153 // bool operator < (const iterator &i) const
154 // {
155 // return ((piter) == ((i.piter))
156 // && *((dnas_iterator_ *)(this)) < *((*((dnas_iterator_ *)(this)))));
157 // }
158 // bool operator > (const iterator &i) const
159 // {
160 // return ((piter) == ((i.piter))
161 // && *((dnas_iterator_ *)(this)) > *((*((dnas_iterator_ *)(this)))));
162 // }
163 // bool operator >= (const iterator &i) const
164 // {
165 // return ((piter) == ((i.piter))
166 // && *((dnas_iterator_ *)(this)) >= *((*((dnas_iterator_ *)(this)))));
167 // }
168 
169 // tab_ref_index_iterator_(void) {}
170 // tab_ref_index_iterator_(const ITER &iter, const dnas_iterator_ &dnas_iter)
171 // : dnas_iterator_(dnas_iter), piter(iter) {}
172 // };
173 
174 
175 // template<typename ITER> class tab_ref_index
176 // {
177 // public :
178 
179 // typedef typename std::iterator_traits<ITER>::value_type value_type;
180 // typedef typename std::iterator_traits<ITER>::pointer pointer;
181 // typedef typename std::iterator_traits<ITER>::pointer const_pointer;
182 // typedef typename std::iterator_traits<ITER>::reference reference;
183 // typedef typename std::iterator_traits<ITER>::reference const_reference;
184 // typedef typename std::iterator_traits<ITER>::difference_type
185 // difference_type;
186 // typedef size_t size_type;
187 // typedef tab_ref_index_iterator_<ITER> iterator;
188 // typedef iterator const_iterator;
189 // typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
190 // typedef std::reverse_iterator<iterator> reverse_iterator;
191 
192 // protected :
193 
194 // ITER begin_;
195 // dynamic_array<size_type> index_;
196 
197 // public :
198 
199 // bool empty(void) const { return index_.empty(); }
200 // size_type size(void) const { return index_.size(); }
201 
202 
203 // iterator begin(void) { return iterator(begin_, index_.begin()); }
204 // const_iterator begin(void) const
205 // { return iterator(begin_, index_.begin()); }
206 // iterator end(void) { return iterator(begin_, index_.end()); }
207 // const_iterator end(void) const { return iterator(begin_, index_.end()); }
208 // reverse_iterator rbegin(void) { return reverse_iterator(end()); }
209 // const_reverse_iterator rbegin(void) const
210 // { return const_reverse_iterator(end()); }
211 // reverse_iterator rend(void) { return reverse_iterator(begin()); }
212 // const_reverse_iterator rend(void) const
213 // { return const_reverse_iterator(begin()); }
214 
215 
216 // reference front(void) { return *(begin_ +index_[0]); }
217 // const_reference front(void) const { return *(begin_ +index_[0]); }
218 // reference back(void) { return *(--(end())); }
219 // const_reference back(void) const { return *(--(end())); }
220 
221 // tab_ref_index(void) {}
222 // tab_ref_index(const ITER &b, const dynamic_array<size_type> &ind)
223 // { begin_ = b; index_ = ind; }
224 
225 // // to be changed in a const_reference ?
226 // value_type operator [](size_type ii) const
227 // { return *(begin_ + index_[ii]);}
228 // reference operator [](size_type ii) { return *(begin_ + index_[ii]); }
229 
230 // };
231 
232 
233  /// iterator over a gmm::tab_ref_index_ref<ITER,ITER_INDEX>
234  template<typename ITER, typename ITER_INDEX>
236  {
237  typedef typename std::iterator_traits<ITER>::value_type value_type;
238  typedef typename std::iterator_traits<ITER>::pointer pointer;
239  typedef typename std::iterator_traits<ITER>::reference reference;
240  typedef typename std::iterator_traits<ITER>::difference_type
241  difference_type;
242  typedef std::random_access_iterator_tag iterator_category;
244  typedef size_t size_type;
245 
246  ITER piter;
247  ITER_INDEX iter_index;
248 
249  iterator operator ++(int)
250  { iterator tmp = *this; ++iter_index; return tmp; }
251  iterator operator --(int)
252  { iterator tmp = *this; --iter_index; return tmp; }
253  iterator &operator ++() { ++iter_index; return *this; }
254  iterator &operator --() { --iter_index; return *this; }
255  iterator &operator +=(difference_type i)
256  { iter_index += i; return *this; }
257  iterator &operator -=(difference_type i)
258  { iter_index -= i; return *this; }
259  iterator operator +(difference_type i) const
260  { iterator it = *this; return (it += i); }
261  iterator operator -(difference_type i) const
262  { iterator it = *this; return (it -= i); }
263  difference_type operator -(const iterator &i) const
264  { return iter_index - i.iter_index; }
265 
266  reference operator *() const
267  { return *(piter + *iter_index); }
268  reference operator [](size_type ii) const
269  { return *(piter + *(iter_index+ii)); }
270 
271  bool operator ==(const iterator &i) const
272  // { return (piter == i.piter && iter_index == i.iter_index); }
273  { return (iter_index == i.iter_index); }
274  bool operator !=(const iterator &i) const { return !(i == *this); }
275  bool operator < (const iterator &i) const
276  { return (iter_index < i.iter_index); }
277  bool operator > (const iterator &i) const
278  { return (iter_index > i.iter_index); }
279  bool operator >=(const iterator &i) const
280  { return (iter_index >= i.iter_index); }
281 
283  tab_ref_index_ref_iterator_(const ITER &iter,
284  const ITER_INDEX &dnas_iter)
285  : piter(iter), iter_index(dnas_iter) {}
286 
287  };
288 
289  /**
290  convenience template function for quick obtention of a indexed iterator
291  without having to specify its (long) typename
292  */
293  template<typename ITER, typename ITER_INDEX>
295  index_ref_iterator(ITER it, ITER_INDEX it_i) {
297  }
298 
299  /** indexed array reference (given a container X, and a set of indexes I,
300  this class provides a pseudo-container Y such that
301  @code Y[i] = X[I[i]] @endcode
302  */
303  template<typename ITER, typename ITER_INDEX> class tab_ref_index_ref {
304  public :
305 
306  typedef std::iterator_traits<ITER> traits_type;
307  typedef typename traits_type::value_type value_type;
308  typedef typename traits_type::pointer pointer;
309  typedef typename traits_type::pointer const_pointer;
310  typedef typename traits_type::reference reference;
311  typedef typename traits_type::reference const_reference;
312  typedef typename traits_type::difference_type difference_type;
313  typedef size_t size_type;
315  typedef iterator const_iterator;
316  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
317  typedef std::reverse_iterator<iterator> reverse_iterator;
318 
319  protected :
320 
321  ITER begin_;
322  ITER_INDEX index_begin_, index_end_;
323 
324  public :
325 
326  bool empty(void) const { return index_begin_ == index_end_; }
327  size_type size(void) const { return index_end_ - index_begin_; }
328 
329  iterator begin(void) { return iterator(begin_, index_begin_); }
330  const_iterator begin(void) const
331  { return iterator(begin_, index_begin_); }
332  iterator end(void) { return iterator(begin_, index_end_); }
333  const_iterator end(void) const { return iterator(begin_, index_end_); }
334  reverse_iterator rbegin(void) { return reverse_iterator(end()); }
335  const_reverse_iterator rbegin(void) const
336  { return const_reverse_iterator(end()); }
337  reverse_iterator rend(void) { return reverse_iterator(begin()); }
338  const_reverse_iterator rend(void) const
339  { return const_reverse_iterator(begin()); }
340 
341  reference front(void) { return *(begin_ + *index_begin_); }
342  const_reference front(void) const { return *(begin_ + *index_begin_); }
343  reference back(void) { return *(--(end())); }
344  const_reference back(void) const { return *(--(end())); }
345  void pop_front(void) { ++index_begin_; }
346 
347  tab_ref_index_ref(void) {}
348  tab_ref_index_ref(const ITER &b, const ITER_INDEX &bi,
349  const ITER_INDEX &ei)
350  : begin_(b), index_begin_(bi), index_end_(ei) {}
351 
352  // to be changed in a const_reference ?
353  const_reference operator [](size_type ii) const
354  { return *(begin_ + index_begin_[ii]);}
355  reference operator [](size_type ii)
356  { return *(begin_ + index_begin_[ii]); }
357 
358  };
359 
360 
361  /* ********************************************************************* */
362  /* Reference on regularly spaced elements. */
363  /* ********************************************************************* */
364 
365  template<typename ITER> struct tab_ref_reg_spaced_iterator_ {
366 
367  typedef typename std::iterator_traits<ITER>::value_type value_type;
368  typedef typename std::iterator_traits<ITER>::pointer pointer;
369  typedef typename std::iterator_traits<ITER>::reference reference;
370  typedef typename std::iterator_traits<ITER>::difference_type
371  difference_type;
372  typedef typename std::iterator_traits<ITER>::iterator_category
373  iterator_category;
374  typedef size_t size_type;
375  typedef tab_ref_reg_spaced_iterator_<ITER> iterator;
376 
377  ITER it;
378  size_type N, i;
379 
380  iterator operator ++(int) { iterator tmp = *this; i++; return tmp; }
381  iterator operator --(int) { iterator tmp = *this; i--; return tmp; }
382  iterator &operator ++() { i++; return *this; }
383  iterator &operator --() { i--; return *this; }
384  iterator &operator +=(difference_type ii) { i+=ii; return *this; }
385  iterator &operator -=(difference_type ii) { i-=ii; return *this; }
386  iterator operator +(difference_type ii) const
387  { iterator itt = *this; return (itt += ii); }
388  iterator operator -(difference_type ii) const
389  { iterator itt = *this; return (itt -= ii); }
390  difference_type operator -(const iterator &ii) const
391  { return (N ? (it - ii.it) / N : 0) + i - ii.i; }
392 
393  reference operator *() const { return *(it + i*N); }
394  reference operator [](size_type ii) const { return *(it + (i+ii)*N); }
395 
396  bool operator ==(const iterator &ii) const
397  { return (*this - ii) == difference_type(0); }
398  bool operator !=(const iterator &ii) const
399  { return (*this - ii) != difference_type(0); }
400  bool operator < (const iterator &ii) const
401  { return (*this - ii) < difference_type(0); }
402  bool operator >=(const iterator &ii) const
403  { return (*this - ii) >= difference_type(0); }
404  bool operator > (const iterator &ii) const
405  { return (*this - ii) > difference_type(0); }
406 
407  tab_ref_reg_spaced_iterator_(void) {}
408  tab_ref_reg_spaced_iterator_(const ITER &iter, size_type n, size_type ii)
409  : it(iter), N(n), i(ii) { }
410 
411  };
412 
413  /**
414  convenience template function for quick obtention of a strided iterator
415  without having to specify its (long) typename
416  */
417  template<typename ITER> tab_ref_reg_spaced_iterator_<ITER>
418  reg_spaced_iterator(ITER it, size_t stride) {
419  return tab_ref_reg_spaced_iterator_<ITER>(it, stride);
420  }
421 
422  /**
423  provide a "strided" view a of container
424  */
425  template<typename ITER> class tab_ref_reg_spaced {
426  public :
427 
428  typedef typename std::iterator_traits<ITER>::value_type value_type;
429  typedef typename std::iterator_traits<ITER>::pointer pointer;
430  typedef typename std::iterator_traits<ITER>::pointer const_pointer;
431  typedef typename std::iterator_traits<ITER>::reference reference;
432  typedef typename std::iterator_traits<ITER>::reference const_reference;
433  typedef typename std::iterator_traits<ITER>::difference_type
434  difference_type;
435  typedef size_t size_type;
436  typedef tab_ref_reg_spaced_iterator_<ITER> iterator;
437  typedef iterator const_iterator;
438  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
439  typedef std::reverse_iterator<iterator> reverse_iterator;
440 
441  protected :
442 
443  ITER begin_;
444  size_type N, size_;
445 
446  public :
447 
448  bool empty(void) const { return size_ == 0; }
449  size_type size(void) const { return size_; }
450 
451  iterator begin(void) { return iterator(begin_, N, 0); }
452  const_iterator begin(void) const { return iterator(begin_, N, 0); }
453  iterator end(void) { return iterator(begin_, N, size_); }
454  const_iterator end(void) const { return iterator(begin_, N, size_); }
455  reverse_iterator rbegin(void) { return reverse_iterator(end()); }
456  const_reverse_iterator rbegin(void) const
457  { return const_reverse_iterator(end()); }
458  reverse_iterator rend(void) { return reverse_iterator(begin()); }
459  const_reverse_iterator rend(void) const
460  { return const_reverse_iterator(begin()); }
461 
462  reference front(void) { return *begin_; }
463  const_reference front(void) const { return *begin_; }
464  reference back(void) { return *(begin_ + N * (size_-1)); }
465  const_reference back(void) const { return *(begin_ + N * (size_-1)); }
466  void pop_front(void) { begin_ += N; }
467 
468  tab_ref_reg_spaced(void) {}
469  tab_ref_reg_spaced(const ITER &b, size_type n, size_type s)
470  : begin_(b), N(n), size_(s) {}
471 
472 
473  const_reference operator [](size_type ii) const
474  { return *(begin_ + ii * N);}
475  reference operator [](size_type ii) { return *(begin_ + ii * N); }
476 
477  };
478 
479  /// iterator over a tab_ref_with_selection
480  template<typename ITER, typename COND>
481  struct tab_ref_with_selection_iterator_ : public ITER {
482  typedef typename std::iterator_traits<ITER>::value_type value_type;
483  typedef typename std::iterator_traits<ITER>::pointer pointer;
484  typedef typename std::iterator_traits<ITER>::reference reference;
485  typedef typename std::iterator_traits<ITER>::difference_type
486  difference_type;
487  typedef std::forward_iterator_tag iterator_category;
489  const COND cond;
490 
491  void forward(void) { while (!(cond)(*this)) ITER::operator ++(); }
492  iterator &operator ++()
493  { ITER::operator ++(); forward(); return *this; }
494  iterator operator ++(int)
495  { iterator tmp = *this; ++(*this); return tmp; }
496 
498  tab_ref_with_selection_iterator_(const ITER &iter, const COND c)
499  : ITER(iter), cond(c) {}
500 
501  };
502 
503  /**
504  given a container X and a predicate P, provide pseudo-container Y
505  of all elements of X such that P(X[i]).
506  */
507  template<typename ITER, typename COND> class tab_ref_with_selection {
508 
509  protected :
510 
511  ITER begin_, end_;
512  COND cond;
513 
514  public :
515 
516  typedef typename std::iterator_traits<ITER>::value_type value_type;
517  typedef typename std::iterator_traits<ITER>::pointer pointer;
518  typedef typename std::iterator_traits<ITER>::pointer const_pointer;
519  typedef typename std::iterator_traits<ITER>::reference reference;
520  typedef typename std::iterator_traits<ITER>::reference const_reference;
521  typedef size_t size_type;
523  typedef iterator const_iterator;
524 
525  iterator begin(void) const
526  { iterator it(begin_, cond); it.forward(); return it; }
527  iterator end(void) const { return iterator(end_, cond); }
528  bool empty(void) const { return begin_ == end_; }
529 
530  value_type front(void) const { return *begin(); }
531  void pop_front(void) { ++begin_; begin_ = begin(); }
532 
533  COND &condition(void) { return cond; }
534  const COND &condition(void) const { return cond; }
535 
536  tab_ref_with_selection(void) {}
537  tab_ref_with_selection(const ITER &b, const ITER &e, const COND &c)
538  : begin_(b), end_(e), cond(c) { begin_ = begin(); }
539 
540  };
541 
542 }
543 
544 #endif /* GMM_REF_H__ */
indexed array reference (given a container X, and a set of indexes I, this class provides a pseudo-co...
Definition: gmm_ref.h:303
provide a "strided" view a of container
Definition: gmm_ref.h:425
given a container X and a predicate P, provide pseudo-container Y of all elements of X such that P(X[...
Definition: gmm_ref.h:507
Definition of basic exceptions.
tab_ref_index_ref_iterator_< ITER, ITER_INDEX > index_ref_iterator(ITER it, ITER_INDEX it_i)
convenience template function for quick obtention of a indexed iterator without having to specify its...
Definition: gmm_ref.h:295
tab_ref_reg_spaced_iterator_< ITER > reg_spaced_iterator(ITER it, size_t stride)
convenience template function for quick obtention of a strided iterator without having to specify its...
Definition: gmm_ref.h:418
rational_fraction< T > operator-(const polynomial< T > &P, const rational_fraction< T > &Q)
Subtract Q from P.
Definition: bgeot_poly.h:755
rational_fraction< T > operator+(const polynomial< T > &P, const rational_fraction< T > &Q)
Add Q to P.
Definition: bgeot_poly.h:748
size_t size_type
used as the common size type in the library
Definition: bgeot_poly.h:48
iterator over a gmm::tab_ref_index_ref<ITER,ITER_INDEX>
Definition: gmm_ref.h:236
iterator over a tab_ref_with_selection
Definition: gmm_ref.h:481