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