cartobase  5.1.2
nditerator.h
Go to the documentation of this file.
1 /* This software and supporting documentation are distributed by
2  * Institut Federatif de Recherche 49
3  * CEA/NeuroSpin, Batiment 145,
4  * 91191 Gif-sur-Yvette cedex
5  * France
6  *
7  * This software is governed by the CeCILL-B license under
8  * French law and abiding by the rules of distribution of free software.
9  * You can use, modify and/or redistribute the software under the
10  * terms of the CeCILL-B license as circulated by CEA, CNRS
11  * and INRIA at the following URL "http://www.cecill.info".
12  *
13  * As a counterpart to the access to the source code and rights to copy,
14  * modify and redistribute granted by the license, users are provided only
15  * with a limited warranty and the software's author, the holder of the
16  * economic rights, and the successive licensors have only limited
17  * liability.
18  *
19  * In this respect, the user's attention is drawn to the risks associated
20  * with loading, using, modifying and/or developing or reproducing the
21  * software by the user in light of its specific status of free software,
22  * that may mean that it is complicated to manipulate, and that also
23  * therefore means that it is reserved for developers and experienced
24  * professionals having in-depth computer knowledge. Users are therefore
25  * encouraged to load and test the software's suitability as regards their
26  * requirements in conditions enabling the security of their systems and/or
27  * data to be ensured and, more generally, to use and operate it in the
28  * same conditions as regards security.
29  *
30  * The fact that you are presently reading this means that you have had
31  * knowledge of the CeCILL-B license and that you accept its terms.
32  */
33 
34 #ifndef CARTOBASE_CONTAINER_NDITERATOR_H
35 #define CARTOBASE_CONTAINER_NDITERATOR_H
36 
38 #include <vector>
39 #include <iostream>
40 
41 
42 namespace carto
43 {
44 
51  {
52  public:
53  NDIterator_base( const std::vector<int> & dims );
54  NDIterator_base( const std::vector<int> & dims,
55  const std::vector<int> & strides );
56  NDIterator_base( const std::vector<int> & dims,
57  const std::vector<size_t> & strides );
58  NDIterator_base( const std::vector<int> & dims,
59  const std::vector<long> & strides );
60  // virtual ~NDIterator_base() {}
61  const std::vector<int> & position() const;
62  uint64_t offset() const;
63 
65 
66  bool ended() const;
67  void reset();
68 
69  protected:
70  template <typename T>
71  static std::vector<size_t> to_int_v( const std::vector<T> & v );
72 
73  std::vector<int> _dims;
74  std::vector<size_t> _strides;
75  std::vector<int> _position;
76  uint64_t _offset;
77  bool _ended;
78  };
79 
80 
82  {
83  public:
84  line_NDIterator_base( const std::vector<int> & dims );
85  line_NDIterator_base( const std::vector<int> & dims,
86  const std::vector<int> & strides,
87  bool optimize_direction = false );
88  line_NDIterator_base( const std::vector<int> & dims,
89  const std::vector<size_t> & strides,
90  bool optimize_direction = false );
91  line_NDIterator_base( const std::vector<int> & dims,
92  const std::vector<long> & strides,
93  bool optimize_direction = false );
94  // virtual ~line_NDIterator_base() {}
95 
97 
98  int line_size() const;
99  int line_direction() const;
100  bool is_contiguous() const;
101 
102  protected:
103  void set_optimized_direction( bool optimize_direction = false );
104 
108  };
109 
110 
133  template <typename T> class NDIterator : public NDIterator_base
134  {
135  public:
136  NDIterator( T* buffer, const std::vector<int> & dims );
137  NDIterator( T* buffer, const std::vector<int> & dims,
138  const std::vector<int> & strides );
139  NDIterator( T*buffer, const std::vector<int> & dims,
140  const std::vector<size_t> & strides );
141  NDIterator( T* buffer, const std::vector<int> & dims,
142  const std::vector<long> & strides );
143  // virtual ~NDIterator() {}
144 
145  T & operator * () const;
146  T * operator -> () const;
147 
148  protected:
150  };
151 
152 
154  template <typename T> class const_NDIterator : public NDIterator_base
155  {
156  public:
157  const_NDIterator( const T* buffer, const std::vector<int> & dims );
158  const_NDIterator( const T* buffer, const std::vector<int> & dims,
159  const std::vector<int> & strides );
160  const_NDIterator( const T* buffer, const std::vector<int> & dims,
161  const std::vector<size_t> & strides );
162  const_NDIterator( const T* buffer, const std::vector<int> & dims,
163  const std::vector<long> & strides );
164  // virtual ~const_NDIterator() {}
165 
166  const T & operator * () const;
167  const T * operator -> () const;
168 
169  protected:
170  const T* _buffer;
171  };
172 
173 
200  template <typename T> class line_NDIterator : public line_NDIterator_base
201  {
202  public:
203  line_NDIterator( T* buffer, const std::vector<int> & dims );
209  line_NDIterator( T* buffer, const std::vector<int> & dims,
210  const std::vector<int> & strides,
211  bool optimize_direction = false );
212  line_NDIterator( T* buffer, const std::vector<int> & dims,
213  const std::vector<size_t> & strides,
214  bool optimize_direction = false );
215  line_NDIterator( T* buffer, const std::vector<int> & dims,
216  const std::vector<long> & strides,
217  bool optimize_direction = false );
218  // virtual ~line_NDIterator() {}
219 
220  T & operator * () const;
221  T * operator -> () const;
223  void inc_line_ptr( T* & p ) const;
225  void inc_line_ptr( const T* & p ) const;
227  long line_length() const;
228 
229  protected:
231  };
232 
233 
235  template <typename T> class const_line_NDIterator
236  : public line_NDIterator_base
237  {
238  public:
239  const_line_NDIterator( const T* buffer, const std::vector<int> & dims );
245  const_line_NDIterator( const T* buffer, const std::vector<int> & dims,
246  const std::vector<int> & strides,
247  bool optimize_direction = false );
248  const_line_NDIterator( const T* buffer, const std::vector<int> & dims,
249  const std::vector<size_t> & strides,
250  bool optimize_direction = false );
251  const_line_NDIterator( const T* buffer, const std::vector<int> & dims,
252  const std::vector<long> & strides,
253  bool optimize_direction = false );
254  // virtual ~const_line_NDIterator() {}
255 
256  const T & operator * () const;
257  const T * operator -> () const;
259  void inc_line_ptr( const T* & p ) const;
261  long line_length() const;
262 
263  protected:
264  const T* _buffer;
265  };
266 
267 
268  // -- implementation --
269 
270  inline NDIterator_base::NDIterator_base( const std::vector<int> & dims )
271  : _dims( dims ), _position( dims.size(), 0 ), _offset( 0 ), _ended( false )
272  {
273  if( dims.empty() )
274  _ended = true;
275  }
276 
277 
278  inline NDIterator_base::NDIterator_base( const std::vector<int> & dims,
279  const std::vector<int> & strides )
280  : _dims( dims ), _strides( NDIterator_base::to_int_v( strides ) ),
281  _position( dims.size(), 0 ),
282  _offset( 0 ), _ended( false )
283  {
284  if( dims.empty() )
285  _ended = true;
286  }
287 
288 
289  inline NDIterator_base::NDIterator_base( const std::vector<int> & dims,
290  const std::vector<size_t> & strides )
291  : _dims( dims ), _strides( strides ), _position( dims.size(), 0 ),
292  _offset( 0 ), _ended( false )
293  {
294  if( dims.empty() )
295  _ended = true;
296  }
297 
298 
299  inline NDIterator_base::NDIterator_base( const std::vector<int> & dims,
300  const std::vector<long> & strides )
301  : _dims( dims ), _strides( NDIterator_base::to_int_v( strides ) ),
302  _position( dims.size(), 0 ),
303  _offset( 0 ), _ended( false )
304  {
305  if( dims.empty() )
306  _ended = true;
307  }
308 
309 
310  inline const std::vector<int> & NDIterator_base::position() const
311  {
312  return _position;
313  }
314 
315 
316  inline uint64_t NDIterator_base::offset() const
317  {
318  return _offset;
319  }
320 
321 
322  inline bool NDIterator_base::ended() const
323  {
324  return _ended;
325  }
326 
327 
329  {
330  _offset = 0;
331  _position = std::vector<int>( _dims.size(), 0 );
332  }
333 
334 
335  template <typename T> inline
336  std::vector<size_t> NDIterator_base::to_int_v( const std::vector<T> & v )
337  {
338  std::vector<size_t> ov( v.size() );
339  std::vector<size_t>::iterator io = ov.begin();
340  typename std::vector<T>::const_iterator i, e = v.end();
341  for( i=v.begin(); i!=e; ++i, ++io )
342  *io = (size_t) *i;
343  return ov;
344  }
345 
346 
348  {
349  size_t dim, ndim = _dims.size();
350  bool nextrow = true, stride = !_strides.empty();
351  for( dim=0; nextrow && dim<ndim; ++dim )
352  {
353  if( nextrow )
354  {
355  ++_position[dim];
356  if( stride )
357  _offset += _strides[dim];
358  if( _position[dim] == _dims[dim] )
359  {
360  if( dim == ndim - 1 )
361  _ended = true;
362  _position[dim] = 0;
363  if( stride )
364  _offset -= _strides[dim] * _dims[dim];
365  }
366  else
367  nextrow = false;
368  }
369  }
370  return *this;
371  }
372 
373  // --
374 
376  const std::vector<int> & dims )
377  : NDIterator_base( dims ), _line_directon( 0 ), _line_stride( 1 ),
378  _contiguous( true )
379  {
380  if( dims.size() < 2 )
381  _ended = true;
382  }
383 
384 
386  const std::vector<int> & dims, const std::vector<int> & strides,
387  bool optimize_direction )
388  : NDIterator_base( dims, strides ), _line_directon( 0 ), _line_stride( 1 ),
389  _contiguous( true )
390  {
391  if( dims.size() < 2 )
392  _ended = true;
393  set_optimized_direction( optimize_direction );
394  }
395 
396 
398  const std::vector<int> & dims, const std::vector<size_t> & strides,
399  bool optimize_direction )
400  : NDIterator_base( dims, strides ), _line_directon( 0 ), _line_stride( 1 ),
401  _contiguous( true )
402  {
403  if( dims.size() < 2 )
404  _ended = true;
405  set_optimized_direction( optimize_direction );
406  }
407 
408 
410  const std::vector<int> & dims, const std::vector<long> & strides,
411  bool optimize_direction )
412  : NDIterator_base( dims, strides ), _line_directon( 0 ), _line_stride( 1 ),
413  _contiguous( true )
414  {
415  if( dims.size() < 2 )
416  _ended = true;
417  set_optimized_direction( optimize_direction );
418  }
419 
420 
422  bool optimize_direction )
423  {
424  if( !_strides.empty() )
425  {
427  if( optimize_direction )
428  {
429  size_t dim, ndim = _strides.size();
430  for( dim=0; dim<ndim; ++dim )
431  if( _strides[dim] == 1 )
432  {
433  // elements are contiguous along this direction
434  _line_directon = dim;
435  _line_stride = 1;
436  break;
437  }
438  }
439  }
440  else
441  _line_stride = 1;
442  _contiguous = ( _strides.empty() || _strides[_line_directon] == 1 );
443  }
444 
445 
447  {
448  return _contiguous;
449  }
450 
451 
453  {
454  return _line_directon;
455  }
456 
457 
459  {
460  return _dims[_line_directon];
461  }
462 
463 
465  {
466  size_t dim, ndim = _dims.size();
467  bool nextrow = true, stride = !_strides.empty();
468  for( dim=0; nextrow && dim<ndim; ++dim )
469  {
470  if( dim == (unsigned) _line_directon )
471  continue;
472  ++_position[dim];
473  if( stride )
474  _offset += _strides[dim];
475  if( _position[dim] == _dims[dim] )
476  {
477  if( dim == ndim - 1
478  || ( dim == ndim - 2 && (unsigned) _line_directon == ndim - 1 ) )
479  _ended = true;
480  _position[dim] = 0;
481  if( stride )
482  _offset -= _strides[dim] * _dims[dim];
483  }
484  else
485  nextrow = false;
486  }
487  return *this;
488  }
489 
490  // --
491 
492  template <typename T> inline
493  NDIterator<T>::NDIterator( T* buffer, const std::vector<int> & dims )
494  : NDIterator_base( dims ), _buffer( buffer )
495  {
496  }
497 
498 
499  template <typename T> inline
500  NDIterator<T>::NDIterator( T* buffer, const std::vector<int> & dims,
501  const std::vector<int> & strides )
502  : NDIterator_base( dims, strides ), _buffer( buffer )
503  {
504  }
505 
506 
507  template <typename T> inline
508  NDIterator<T>::NDIterator( T* buffer, const std::vector<int> & dims,
509  const std::vector<size_t> & strides )
510  : NDIterator_base( dims, strides ), _buffer( buffer )
511  {
512  }
513 
514 
515  template <typename T> inline
516  NDIterator<T>::NDIterator( T* buffer, const std::vector<int> & dims,
517  const std::vector<long> & strides )
518  : NDIterator_base( dims, strides ), _buffer( buffer )
519  {
520  }
521 
522 
523  template <typename T> inline T & NDIterator<T>::operator * () const
524  {
525  return _buffer[ _offset ];
526  }
527 
528  template <typename T> inline T * NDIterator<T>::operator -> () const
529  {
530  return _buffer + _offset;
531  }
532 
533  // --
534 
535  template <typename T> inline
537  const T* buffer, const std::vector<int> & dims )
538  : NDIterator_base( dims ), _buffer( buffer )
539  {
540  }
541 
542 
543  template <typename T> inline
545  const T* buffer, const std::vector<int> & dims,
546  const std::vector<int> & strides )
547  : NDIterator_base( dims, strides ), _buffer( buffer )
548  {
549  }
550 
551 
552  template <typename T> inline
554  const T* buffer, const std::vector<int> & dims,
555  const std::vector<long> & strides )
556  : NDIterator_base( dims, strides ), _buffer( buffer )
557  {
558  }
559 
560 
561  template <typename T> inline
563  const T* buffer, const std::vector<int> & dims,
564  const std::vector<size_t> & strides )
565  : NDIterator_base( dims, strides ), _buffer( buffer )
566  {
567  }
568 
569 
570  template <typename T> const inline T &
572  {
573  return _buffer[ _offset ];
574  }
575 
576  template <typename T> const inline T *
578  {
579  return _buffer + _offset;
580  }
581 
582  // --
583 
584  template <typename T> inline
586  T* buffer, const std::vector<int> & dims )
587  : line_NDIterator_base( dims ), _buffer( buffer )
588  {
589  }
590 
591 
592  template <typename T> inline
594  const std::vector<int> & dims,
595  const std::vector<int> & strides,
596  bool optimize_direction )
597  : line_NDIterator_base( dims, strides, optimize_direction ),
598  _buffer( buffer )
599  {
600  }
601 
602 
603  template <typename T> inline
605  const std::vector<int> & dims,
606  const std::vector<size_t> & strides,
607  bool optimize_direction )
608  : line_NDIterator_base( dims, strides, optimize_direction ),
609  _buffer( buffer )
610  {
611  }
612 
613 
614  template <typename T> inline
616  const std::vector<int> & dims,
617  const std::vector<long> & strides,
618  bool optimize_direction )
619  : line_NDIterator_base( dims, strides, optimize_direction ),
620  _buffer( buffer )
621  {
622  }
623 
624 
625  template <typename T> inline T & line_NDIterator<T>::operator * () const
626  {
627  return _buffer[ _offset ];
628  }
629 
630 
631  template <typename T> inline T * line_NDIterator<T>::operator -> () const
632  {
633  return _buffer + _offset;
634  }
635 
636 
637  template <typename T> inline
638  void line_NDIterator<T>::inc_line_ptr( T* & p ) const
639  {
640  if( _contiguous )
641  ++p;
642  else
643  p += _line_stride;
644  }
645 
646 
647  template <typename T> inline
648  void line_NDIterator<T>::inc_line_ptr( const T* & p ) const
649  {
650  if( _contiguous )
651  ++p;
652  else
653  p += _line_stride;
654  }
655 
656 
657  template <typename T> inline
659  {
660  if( is_contiguous() )
661  return line_size();
662  else
663  return line_size() * _strides[_line_directon];
664  }
665 
666  // --
667 
668  template <typename T> inline
670  const T* buffer, const std::vector<int> & dims )
671  : line_NDIterator_base( dims ), _buffer( buffer )
672  {
673  }
674 
675 
676  template <typename T> inline
678  const T* buffer, const std::vector<int> & dims,
679  const std::vector<int> & strides, bool optimize_direction )
680  : line_NDIterator_base( dims, strides, optimize_direction ),
681  _buffer( buffer )
682  {
683  }
684 
685 
686  template <typename T> inline
688  const T* buffer, const std::vector<int> & dims,
689  const std::vector<size_t> & strides, bool optimize_direction )
690  : line_NDIterator_base( dims, strides, optimize_direction ),
691  _buffer( buffer )
692  {
693  }
694 
695 
696  template <typename T> inline
698  const T* buffer, const std::vector<int> & dims,
699  const std::vector<long> & strides, bool optimize_direction )
700  : line_NDIterator_base( dims, strides, optimize_direction ),
701  _buffer( buffer )
702  {
703  }
704 
705 
706  template <typename T> inline const T &
708  {
709  return _buffer[ _offset ];
710  }
711 
712 
713  template <typename T> inline const T *
715  {
716  return _buffer + _offset;
717  }
718 
719 
720  template <typename T> inline
721  void const_line_NDIterator<T>::inc_line_ptr( const T* & p ) const
722  {
723  if( _contiguous )
724  ++p;
725  else
726  p += _line_stride;
727  }
728 
729 
730  template <typename T> inline
732  {
733  if( is_contiguous() )
734  return line_size();
735  else
736  return line_size() * _strides[_line_directon];
737  }
738 
739 }
740 
741 #endif
Base class for N-dimensional array iterators.
Definition: nditerator.h:51
std::vector< int > _dims
Definition: nditerator.h:73
NDIterator_base(const std::vector< int > &dims)
Definition: nditerator.h:270
bool ended() const
Definition: nditerator.h:322
const std::vector< int > & position() const
Definition: nditerator.h:310
static std::vector< size_t > to_int_v(const std::vector< T > &v)
Definition: nditerator.h:336
uint64_t offset() const
Definition: nditerator.h:316
std::vector< size_t > _strides
Definition: nditerator.h:74
NDIterator_base & operator++()
Definition: nditerator.h:347
std::vector< int > _position
Definition: nditerator.h:75
N-dimensional array iterator.
Definition: nditerator.h:134
NDIterator(T *buffer, const std::vector< int > &dims)
Definition: nditerator.h:493
T * operator->() const
Definition: nditerator.h:528
T & operator*() const
Definition: nditerator.h:523
const variant of the NDIterator
Definition: nditerator.h:155
const_NDIterator(const T *buffer, const std::vector< int > &dims)
Definition: nditerator.h:536
const T & operator*() const
Definition: nditerator.h:571
const T * operator->() const
Definition: nditerator.h:577
const variant of the line_NDIterator
Definition: nditerator.h:237
const T & operator*() const
Definition: nditerator.h:707
long line_length() const
line_size * line stride: end of line
Definition: nditerator.h:731
const_line_NDIterator(const T *buffer, const std::vector< int > &dims)
Definition: nditerator.h:669
void inc_line_ptr(const T *&p) const
increment a "line" pointer (advancing through the line)
Definition: nditerator.h:721
const T * operator->() const
Definition: nditerator.h:714
line_NDIterator_base(const std::vector< int > &dims)
Definition: nditerator.h:375
void set_optimized_direction(bool optimize_direction=false)
Definition: nditerator.h:421
NDIterator_base & operator++()
Definition: nditerator.h:464
N-dimensional array line iterator.
Definition: nditerator.h:201
T & operator*() const
Definition: nditerator.h:625
long line_length() const
line_size * line stride: end of line
Definition: nditerator.h:658
line_NDIterator(T *buffer, const std::vector< int > &dims)
Definition: nditerator.h:585
void inc_line_ptr(T *&p) const
increment a "line" pointer (advancing through the line)
Definition: nditerator.h:638
T * operator->() const
Definition: nditerator.h:631