GetFEM  5.4.2
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 <Yves.Renard@insa-lyon.fr>
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 
160 // tab_ref_index_iterator_(void) {}
161 // tab_ref_index_iterator_(const ITER &iter, const dnas_iterator_ &dnas_iter)
162 // : dnas_iterator_(dnas_iter), piter(iter) {}
163 // };
164 
165 
166 // template<typename ITER> class tab_ref_index
167 // {
168 // public :
169 
170 // typedef typename std::iterator_traits<ITER>::value_type value_type;
171 // typedef typename std::iterator_traits<ITER>::pointer pointer;
172 // typedef typename std::iterator_traits<ITER>::pointer const_pointer;
173 // typedef typename std::iterator_traits<ITER>::reference reference;
174 // typedef typename std::iterator_traits<ITER>::reference const_reference;
175 // typedef typename std::iterator_traits<ITER>::difference_type
176 // difference_type;
177 // typedef size_t size_type;
178 // typedef tab_ref_index_iterator_<ITER> iterator;
179 // typedef iterator const_iterator;
180 // typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
181 // typedef std::reverse_iterator<iterator> reverse_iterator;
182 
183 // protected :
184 
185 // ITER begin_;
186 // dynamic_array<size_type> index_;
187 
188 // public :
189 
190 // bool empty(void) const { return index_.empty(); }
191 // size_type size(void) const { return index_.size(); }
192 
193 
194 // iterator begin(void) { return iterator(begin_, index_.begin()); }
195 // const_iterator begin(void) const
196 // { return iterator(begin_, index_.begin()); }
197 // iterator end(void) { return iterator(begin_, index_.end()); }
198 // const_iterator end(void) const { return iterator(begin_, index_.end()); }
199 // reverse_iterator rbegin(void) { return reverse_iterator(end()); }
200 // const_reverse_iterator rbegin(void) const
201 // { return const_reverse_iterator(end()); }
202 // reverse_iterator rend(void) { return reverse_iterator(begin()); }
203 // const_reverse_iterator rend(void) const
204 // { return const_reverse_iterator(begin()); }
205 
206 
207 // reference front(void) { return *(begin_ +index_[0]); }
208 // const_reference front(void) const { return *(begin_ +index_[0]); }
209 // reference back(void) { return *(--(end())); }
210 // const_reference back(void) const { return *(--(end())); }
211 
212 // tab_ref_index(void) {}
213 // tab_ref_index(const ITER &b, const dynamic_array<size_type> &ind)
214 // { begin_ = b; index_ = ind; }
215 
216 // // to be changed in a const_reference ?
217 // value_type operator [](size_type ii) const
218 // { return *(begin_ + index_[ii]);}
219 // reference operator [](size_type ii) { return *(begin_ + index_[ii]); }
220 
221 // };
222 
223 
224  /// iterator over a gmm::tab_ref_index_ref<ITER,ITER_INDEX>
225  template<typename ITER, typename ITER_INDEX>
227  {
228  typedef typename std::iterator_traits<ITER>::value_type value_type;
229  typedef typename std::iterator_traits<ITER>::pointer pointer;
230  typedef typename std::iterator_traits<ITER>::reference reference;
231  typedef typename std::iterator_traits<ITER>::difference_type
232  difference_type;
233  typedef std::random_access_iterator_tag iterator_category;
235  typedef size_t size_type;
236 
237  ITER piter;
238  ITER_INDEX iter_index;
239 
240  iterator operator ++(int)
241  { iterator tmp = *this; ++iter_index; return tmp; }
242  iterator operator --(int)
243  { iterator tmp = *this; --iter_index; return tmp; }
244  iterator &operator ++() { ++iter_index; return *this; }
245  iterator &operator --() { --iter_index; return *this; }
246  iterator &operator +=(difference_type i)
247  { iter_index += i; return *this; }
248  iterator &operator -=(difference_type i)
249  { iter_index -= i; return *this; }
250  iterator operator +(difference_type i) const
251  { iterator it = *this; return (it += i); }
252  iterator operator -(difference_type i) const
253  { iterator it = *this; return (it -= i); }
254  difference_type operator -(const iterator &i) const
255  { return iter_index - i.iter_index; }
256 
257  reference operator *() const
258  { return *(piter + *iter_index); }
259  reference operator [](size_type ii) const
260  { return *(piter + *(iter_index+ii)); }
261 
262  bool operator ==(const iterator &i) const
263  { return ((piter) == ((i.piter)) && iter_index == i.iter_index); }
264  bool operator !=(const iterator &i) const { return !(i == *this); }
265  bool operator < (const iterator &i) const
266  { return ((piter) == ((i.piter)) && iter_index < i.iter_index); }
267 
269  tab_ref_index_ref_iterator_(const ITER &iter,
270  const ITER_INDEX &dnas_iter)
271  : piter(iter), iter_index(dnas_iter) {}
272 
273  };
274 
275  /**
276  convenience template function for quick obtention of a indexed iterator
277  without having to specify its (long) typename
278  */
279  template<typename ITER, typename ITER_INDEX>
281  index_ref_iterator(ITER it, ITER_INDEX it_i) {
283  }
284 
285  /** indexed array reference (given a container X, and a set of indexes I,
286  this class provides a pseudo-container Y such that
287  @code Y[i] = X[I[i]] @endcode
288  */
289  template<typename ITER, typename ITER_INDEX> class tab_ref_index_ref {
290  public :
291 
292  typedef std::iterator_traits<ITER> traits_type;
293  typedef typename traits_type::value_type value_type;
294  typedef typename traits_type::pointer pointer;
295  typedef typename traits_type::pointer const_pointer;
296  typedef typename traits_type::reference reference;
297  typedef typename traits_type::reference const_reference;
298  typedef typename traits_type::difference_type difference_type;
299  typedef size_t size_type;
301  typedef iterator const_iterator;
302  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
303  typedef std::reverse_iterator<iterator> reverse_iterator;
304 
305  protected :
306 
307  ITER begin_;
308  ITER_INDEX index_begin_, index_end_;
309 
310  public :
311 
312  bool empty(void) const { return index_begin_ == index_end_; }
313  size_type size(void) const { return index_end_ - index_begin_; }
314 
315  iterator begin(void) { return iterator(begin_, index_begin_); }
316  const_iterator begin(void) const
317  { return iterator(begin_, index_begin_); }
318  iterator end(void) { return iterator(begin_, index_end_); }
319  const_iterator end(void) const { return iterator(begin_, index_end_); }
320  reverse_iterator rbegin(void) { return reverse_iterator(end()); }
321  const_reverse_iterator rbegin(void) const
322  { return const_reverse_iterator(end()); }
323  reverse_iterator rend(void) { return reverse_iterator(begin()); }
324  const_reverse_iterator rend(void) const
325  { return const_reverse_iterator(begin()); }
326 
327  reference front(void) { return *(begin_ + *index_begin_); }
328  const_reference front(void) const { return *(begin_ + *index_begin_); }
329  reference back(void) { return *(--(end())); }
330  const_reference back(void) const { return *(--(end())); }
331  void pop_front(void) { ++index_begin_; }
332 
333  tab_ref_index_ref(void) {}
334  tab_ref_index_ref(const ITER &b, const ITER_INDEX &bi,
335  const ITER_INDEX &ei)
336  : begin_(b), index_begin_(bi), index_end_(ei) {}
337 
338  // to be changed in a const_reference ?
339  const_reference operator [](size_type ii) const
340  { return *(begin_ + index_begin_[ii]);}
341  reference operator [](size_type ii)
342  { return *(begin_ + index_begin_[ii]); }
343 
344  };
345 
346 
347  /* ********************************************************************* */
348  /* Reference on regularly spaced elements. */
349  /* ********************************************************************* */
350 
351  template<typename ITER> struct tab_ref_reg_spaced_iterator_ {
352 
353  typedef typename std::iterator_traits<ITER>::value_type value_type;
354  typedef typename std::iterator_traits<ITER>::pointer pointer;
355  typedef typename std::iterator_traits<ITER>::reference reference;
356  typedef typename std::iterator_traits<ITER>::difference_type
357  difference_type;
358  typedef typename std::iterator_traits<ITER>::iterator_category
359  iterator_category;
360  typedef size_t size_type;
361  typedef tab_ref_reg_spaced_iterator_<ITER> iterator;
362 
363  ITER it;
364  size_type N, i;
365 
366  iterator operator ++(int) { iterator tmp = *this; i++; return tmp; }
367  iterator operator --(int) { iterator tmp = *this; i--; return tmp; }
368  iterator &operator ++() { i++; return *this; }
369  iterator &operator --() { i--; return *this; }
370  iterator &operator +=(difference_type ii) { i+=ii; return *this; }
371  iterator &operator -=(difference_type ii) { i-=ii; return *this; }
372  iterator operator +(difference_type ii) const
373  { iterator itt = *this; return (itt += ii); }
374  iterator operator -(difference_type ii) const
375  { iterator itt = *this; return (itt -= ii); }
376  difference_type operator -(const iterator &ii) const
377  { return (N ? (it - ii.it) / N : 0) + i - ii.i; }
378 
379  reference operator *() const { return *(it + i*N); }
380  reference operator [](size_type ii) const { return *(it + (i+ii)*N); }
381 
382  bool operator ==(const iterator &ii) const
383  { return (*this - ii) == difference_type(0); }
384  bool operator !=(const iterator &ii) const
385  { return (*this - ii) != difference_type(0); }
386  bool operator < (const iterator &ii) const
387  { return (*this - ii) < difference_type(0); }
388 
389  tab_ref_reg_spaced_iterator_(void) {}
390  tab_ref_reg_spaced_iterator_(const ITER &iter, size_type n, size_type ii)
391  : it(iter), N(n), i(ii) { }
392 
393  };
394 
395  /**
396  convenience template function for quick obtention of a strided iterator
397  without having to specify its (long) typename
398  */
399  template<typename ITER> tab_ref_reg_spaced_iterator_<ITER>
400  reg_spaced_iterator(ITER it, size_t stride) {
401  return tab_ref_reg_spaced_iterator_<ITER>(it, stride);
402  }
403 
404  /**
405  provide a "strided" view a of container
406  */
407  template<typename ITER> class tab_ref_reg_spaced {
408  public :
409 
410  typedef typename std::iterator_traits<ITER>::value_type value_type;
411  typedef typename std::iterator_traits<ITER>::pointer pointer;
412  typedef typename std::iterator_traits<ITER>::pointer const_pointer;
413  typedef typename std::iterator_traits<ITER>::reference reference;
414  typedef typename std::iterator_traits<ITER>::reference const_reference;
415  typedef typename std::iterator_traits<ITER>::difference_type
416  difference_type;
417  typedef size_t size_type;
418  typedef tab_ref_reg_spaced_iterator_<ITER> iterator;
419  typedef iterator const_iterator;
420  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
421  typedef std::reverse_iterator<iterator> reverse_iterator;
422 
423  protected :
424 
425  ITER begin_;
426  size_type N, size_;
427 
428  public :
429 
430  bool empty(void) const { return size_ == 0; }
431  size_type size(void) const { return size_; }
432 
433  iterator begin(void) { return iterator(begin_, N, 0); }
434  const_iterator begin(void) const { return iterator(begin_, N, 0); }
435  iterator end(void) { return iterator(begin_, N, size_); }
436  const_iterator end(void) const { return iterator(begin_, N, size_); }
437  reverse_iterator rbegin(void) { return reverse_iterator(end()); }
438  const_reverse_iterator rbegin(void) const
439  { return const_reverse_iterator(end()); }
440  reverse_iterator rend(void) { return reverse_iterator(begin()); }
441  const_reverse_iterator rend(void) const
442  { return const_reverse_iterator(begin()); }
443 
444  reference front(void) { return *begin_; }
445  const_reference front(void) const { return *begin_; }
446  reference back(void) { return *(begin_ + N * (size_-1)); }
447  const_reference back(void) const { return *(begin_ + N * (size_-1)); }
448  void pop_front(void) { begin_ += N; }
449 
450  tab_ref_reg_spaced(void) {}
451  tab_ref_reg_spaced(const ITER &b, size_type n, size_type s)
452  : begin_(b), N(n), size_(s) {}
453 
454 
455  const_reference operator [](size_type ii) const
456  { return *(begin_ + ii * N);}
457  reference operator [](size_type ii) { return *(begin_ + ii * N); }
458 
459  };
460 
461  /// iterator over a tab_ref_with_selection
462  template<typename ITER, typename COND>
463  struct tab_ref_with_selection_iterator_ : public ITER {
464  typedef typename std::iterator_traits<ITER>::value_type value_type;
465  typedef typename std::iterator_traits<ITER>::pointer pointer;
466  typedef typename std::iterator_traits<ITER>::reference reference;
467  typedef typename std::iterator_traits<ITER>::difference_type
468  difference_type;
469  typedef std::forward_iterator_tag iterator_category;
471  const COND cond;
472 
473  void forward(void) { while (!(cond)(*this)) ITER::operator ++(); }
474  iterator &operator ++()
475  { ITER::operator ++(); forward(); return *this; }
476  iterator operator ++(int)
477  { iterator tmp = *this; ++(*this); return tmp; }
478 
480  tab_ref_with_selection_iterator_(const ITER &iter, const COND c)
481  : ITER(iter), cond(c) {}
482 
483  };
484 
485  /**
486  given a container X and a predicate P, provide pseudo-container Y
487  of all elements of X such that P(X[i]).
488  */
489  template<typename ITER, typename COND> class tab_ref_with_selection {
490 
491  protected :
492 
493  ITER begin_, end_;
494  COND cond;
495 
496  public :
497 
498  typedef typename std::iterator_traits<ITER>::value_type value_type;
499  typedef typename std::iterator_traits<ITER>::pointer pointer;
500  typedef typename std::iterator_traits<ITER>::pointer const_pointer;
501  typedef typename std::iterator_traits<ITER>::reference reference;
502  typedef typename std::iterator_traits<ITER>::reference const_reference;
503  typedef size_t size_type;
505  typedef iterator const_iterator;
506 
507  iterator begin(void) const
508  { iterator it(begin_, cond); it.forward(); return it; }
509  iterator end(void) const { return iterator(end_, cond); }
510  bool empty(void) const { return begin_ == end_; }
511 
512  value_type front(void) const { return *begin(); }
513  void pop_front(void) { ++begin_; begin_ = begin(); }
514 
515  COND &condition(void) { return cond; }
516  const COND &condition(void) const { return cond; }
517 
518  tab_ref_with_selection(void) {}
519  tab_ref_with_selection(const ITER &b, const ITER &e, const COND &c)
520  : begin_(b), end_(e), cond(c) { begin_ = begin(); }
521 
522  };
523 
524 }
525 
526 #endif /* GMM_REF_H__ */
gmm::tab_ref_reg_spaced
provide a "strided" view a of container
Definition: gmm_ref.h:407
bgeot::size_type
size_t size_type
used as the common size type in the library
Definition: bgeot_poly.h:49
gmm::tab_ref_with_selection_iterator_
iterator over a tab_ref_with_selection
Definition: gmm_ref.h:463
gmm_except.h
Definition of basic exceptions.
gmm::tab_ref_index_ref_iterator_
iterator over a gmm::tab_ref_index_ref<ITER,ITER_INDEX>
Definition: gmm_ref.h:226
bgeot::operator+
rational_fraction< T > operator+(const polynomial< T > &P, const rational_fraction< T > &Q)
Add Q to P.
Definition: bgeot_poly.h:749
bgeot::operator-
rational_fraction< T > operator-(const polynomial< T > &P, const rational_fraction< T > &Q)
Subtract Q from P.
Definition: bgeot_poly.h:756
gmm::reg_spaced_iterator
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:400
gmm::tab_ref_with_selection
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:489
gmm::tab_ref_index_ref
indexed array reference (given a container X, and a set of indexes I, this class provides a pseudo-co...
Definition: gmm_ref.h:289
gmm::index_ref_iterator
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:281