cartobase 6.0.6
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 <algorithm>
39#include <cstddef>
40#include <vector>
41
42
43namespace carto
44{
45
52 {
53 public:
54 NDIterator_base( const std::vector<int> & dims );
55 NDIterator_base( const std::vector<int> & dims,
56 const std::vector<int> & strides );
57 NDIterator_base( const std::vector<int> & dims,
58 const std::vector<std::size_t> & strides );
59 NDIterator_base( const std::vector<int> & dims,
60 const std::vector<std::ptrdiff_t> & strides );
61 // virtual ~NDIterator_base() {}
62 const std::vector<int> & position() const;
63 std::ptrdiff_t offset() const;
64
66
67 bool ended() const;
68 void reset();
69
70 protected:
71 template <typename T>
72 static std::vector<std::ptrdiff_t> to_ptrdiff_v( const std::vector<T> & v );
73
74 std::vector<int> _dims;
75 std::vector<std::ptrdiff_t> _strides;
76 std::vector<int> _position;
77 std::ptrdiff_t _offset;
78 bool _ended;
79 };
80
81
83 {
84 public:
85 line_NDIterator_base( const std::vector<int> & dims );
86 line_NDIterator_base( const std::vector<int> & dims,
87 const std::vector<int> & strides,
88 bool optimize_direction = false );
89 line_NDIterator_base( const std::vector<int> & dims,
90 const std::vector<std::size_t> & strides,
91 bool optimize_direction = false );
92 line_NDIterator_base( const std::vector<int> & dims,
93 const std::vector<std::ptrdiff_t> & strides,
94 bool optimize_direction = false );
95 // virtual ~line_NDIterator_base() {}
96
98
99 int line_size() const;
100 int line_direction() const;
101 bool is_contiguous() const;
102
103 protected:
104 void set_optimized_direction( bool optimize_direction = false );
105
107 std::ptrdiff_t _line_stride;
109 };
110
111
134 template <typename T> class NDIterator : public NDIterator_base
135 {
136 public:
137 NDIterator( T* buffer, const std::vector<int> & dims );
138 NDIterator( T* buffer, const std::vector<int> & dims,
139 const std::vector<int> & strides );
140 NDIterator( T*buffer, const std::vector<int> & dims,
141 const std::vector<std::size_t> & strides );
142 NDIterator( T* buffer, const std::vector<int> & dims,
143 const std::vector<std::ptrdiff_t> & strides );
144 // virtual ~NDIterator() {}
145
146 T & operator * () const;
147 T * operator -> () const;
148
149 protected:
151 };
152
153
155 template <typename T> class const_NDIterator : public NDIterator_base
156 {
157 public:
158 const_NDIterator( const T* buffer, const std::vector<int> & dims );
159 const_NDIterator( const T* buffer, const std::vector<int> & dims,
160 const std::vector<int> & strides );
161 const_NDIterator( const T* buffer, const std::vector<int> & dims,
162 const std::vector<std::size_t> & strides );
163 const_NDIterator( const T* buffer, const std::vector<int> & dims,
164 const std::vector<std::ptrdiff_t> & strides );
165 // virtual ~const_NDIterator() {}
166
167 const T & operator * () const;
168 const T * operator -> () const;
169
170 protected:
171 const T* _buffer;
172 };
173
174
201 template <typename T> class line_NDIterator : public line_NDIterator_base
202 {
203 public:
204 line_NDIterator( T* buffer, const std::vector<int> & dims );
210 line_NDIterator( T* buffer, const std::vector<int> & dims,
211 const std::vector<int> & strides,
212 bool optimize_direction = false );
213 line_NDIterator( T* buffer, const std::vector<int> & dims,
214 const std::vector<std::size_t> & strides,
215 bool optimize_direction = false );
216 line_NDIterator( T* buffer, const std::vector<int> & dims,
217 const std::vector<std::ptrdiff_t> & strides,
218 bool optimize_direction = false );
219 // virtual ~line_NDIterator() {}
220
221 T & operator * () const;
222 T * operator -> () const;
224 void inc_line_ptr( T* & p ) const;
226 void inc_line_ptr( const T* & p ) const;
228 std::ptrdiff_t line_length() const;
229
230 protected:
232 };
233
234
236 template <typename T> class const_line_NDIterator
237 : public line_NDIterator_base
238 {
239 public:
240 const_line_NDIterator( const T* buffer, const std::vector<int> & dims );
246 const_line_NDIterator( const T* buffer, const std::vector<int> & dims,
247 const std::vector<int> & strides,
248 bool optimize_direction = false );
249 const_line_NDIterator( const T* buffer, const std::vector<int> & dims,
250 const std::vector<std::size_t> & strides,
251 bool optimize_direction = false );
252 const_line_NDIterator( const T* buffer, const std::vector<int> & dims,
253 const std::vector<std::ptrdiff_t> & strides,
254 bool optimize_direction = false );
255 // virtual ~const_line_NDIterator() {}
256
257 const T & operator * () const;
258 const T * operator -> () const;
260 void inc_line_ptr( const T* & p ) const;
262 std::ptrdiff_t line_length() const;
263
264 protected:
265 const T* _buffer;
266 };
267
268
269 // -- implementation --
270
271 inline NDIterator_base::NDIterator_base( const std::vector<int> & dims )
272 : _dims( dims ), _position( dims.size(), 0 ), _offset( 0 ), _ended( false )
273 {
274 if( dims.empty() )
275 _ended = true;
276 }
277
278
279 inline NDIterator_base::NDIterator_base( const std::vector<int> & dims,
280 const std::vector<int> & strides )
281 : _dims( dims ), _strides( NDIterator_base::to_ptrdiff_v( strides ) ),
282 _position( dims.size(), 0 ),
283 _offset( 0 ), _ended( false )
284 {
285 if( dims.empty() )
286 _ended = true;
287 }
288
289
290 inline NDIterator_base::NDIterator_base( const std::vector<int> & dims,
291 const std::vector<std::size_t> & strides )
292 : _dims( dims ), _strides( NDIterator_base::to_ptrdiff_v( strides ) ), _position( dims.size(), 0 ),
293 _offset( 0 ), _ended( false )
294 {
295 if( dims.empty() )
296 _ended = true;
297 }
298
299
300 inline NDIterator_base::NDIterator_base( const std::vector<int> & dims,
301 const std::vector<std::ptrdiff_t> & strides )
302 : _dims( dims ), _strides( NDIterator_base::to_ptrdiff_v( strides ) ),
303 _position( dims.size(), 0 ),
304 _offset( 0 ), _ended( false )
305 {
306 if( dims.empty() )
307 _ended = true;
308 }
309
310
311 inline const std::vector<int> & NDIterator_base::position() const
312 {
313 return _position;
314 }
315
316
317 inline std::ptrdiff_t NDIterator_base::offset() const
318 {
319 return _offset;
320 }
321
322
323 inline bool NDIterator_base::ended() const
324 {
325 return _ended;
326 }
327
328
330 {
331 _offset = 0;
332 _position = std::vector<int>( _dims.size(), 0 );
333 }
334
335
336 template <typename T> inline
337 std::vector<std::ptrdiff_t> NDIterator_base::to_ptrdiff_v( const std::vector<T> & v )
338 {
339 std::vector<std::ptrdiff_t> ov( v.size() );
340 std::copy(begin(v), end(v), begin(ov));
341 return ov;
342 }
343
344
346 {
347 std::size_t dim, ndim = _dims.size();
348 bool nextrow = true, stride = !_strides.empty();
349 for( dim=0; nextrow && dim<ndim; ++dim )
350 {
351 if( nextrow )
352 {
353 ++_position[dim];
354 if( stride )
355 _offset += _strides[dim];
356 if( _position[dim] == _dims[dim] )
357 {
358 if( dim == ndim - 1 )
359 _ended = true;
360 _position[dim] = 0;
361 if( stride )
362 _offset -= _strides[dim] * _dims[dim];
363 }
364 else
365 nextrow = false;
366 }
367 }
368 return *this;
369 }
370
371 // --
372
374 const std::vector<int> & dims )
375 : NDIterator_base( dims ), _line_directon( 0 ), _line_stride( 1 ),
376 _contiguous( true )
377 {
378 if( dims.size() < 2 )
379 _ended = true;
380 }
381
382
384 const std::vector<int> & dims, const std::vector<int> & strides,
385 bool optimize_direction )
386 : NDIterator_base( dims, strides ), _line_directon( 0 ), _line_stride( 1 ),
387 _contiguous( true )
388 {
389 if( dims.size() < 2 )
390 _ended = true;
391 set_optimized_direction( optimize_direction );
392 }
393
394
396 const std::vector<int> & dims, const std::vector<std::size_t> & strides,
397 bool optimize_direction )
398 : NDIterator_base( dims, strides ), _line_directon( 0 ), _line_stride( 1 ),
399 _contiguous( true )
400 {
401 if( dims.size() < 2 )
402 _ended = true;
403 set_optimized_direction( optimize_direction );
404 }
405
406
408 const std::vector<int> & dims, const std::vector<std::ptrdiff_t> & strides,
409 bool optimize_direction )
410 : NDIterator_base( dims, strides ), _line_directon( 0 ), _line_stride( 1 ),
411 _contiguous( true )
412 {
413 if( dims.size() < 2 )
414 _ended = true;
415 set_optimized_direction( optimize_direction );
416 }
417
418
420 bool optimize_direction )
421 {
422 if( !_strides.empty() )
423 {
425 if( optimize_direction )
426 {
427 std::size_t dim, ndim = _strides.size();
428 for( dim=0; dim<ndim; ++dim )
429 if( _strides[dim] == 1 )
430 {
431 // elements are contiguous along this direction
432 _line_directon = dim;
433 _line_stride = 1;
434 break;
435 }
436 }
437 }
438 else
439 _line_stride = 1;
440 _contiguous = ( _strides.empty() || _strides[_line_directon] == 1 );
441 }
442
443
445 {
446 return _contiguous;
447 }
448
449
451 {
452 return _line_directon;
453 }
454
455
457 {
458 return _dims[_line_directon];
459 }
460
461
463 {
464 std::size_t dim, ndim = _dims.size();
465 bool nextrow = true, stride = !_strides.empty();
466 for( dim=0; nextrow && dim<ndim; ++dim )
467 {
468 if( dim == (unsigned) _line_directon )
469 continue;
470 ++_position[dim];
471 if( stride )
472 _offset += _strides[dim];
473 if( _position[dim] == _dims[dim] )
474 {
475 if( dim == ndim - 1
476 || ( dim == ndim - 2 && (unsigned) _line_directon == ndim - 1 ) )
477 _ended = true;
478 _position[dim] = 0;
479 if( stride )
480 _offset -= _strides[dim] * _dims[dim];
481 }
482 else
483 nextrow = false;
484 }
485 return *this;
486 }
487
488 // --
489
490 template <typename T> inline
491 NDIterator<T>::NDIterator( T* buffer, const std::vector<int> & dims )
492 : NDIterator_base( dims ), _buffer( buffer )
493 {
494 }
495
496
497 template <typename T> inline
498 NDIterator<T>::NDIterator( T* buffer, const std::vector<int> & dims,
499 const std::vector<int> & strides )
500 : NDIterator_base( dims, strides ), _buffer( buffer )
501 {
502 }
503
504
505 template <typename T> inline
506 NDIterator<T>::NDIterator( T* buffer, const std::vector<int> & dims,
507 const std::vector<std::size_t> & strides )
508 : NDIterator_base( dims, strides ), _buffer( buffer )
509 {
510 }
511
512
513 template <typename T> inline
514 NDIterator<T>::NDIterator( T* buffer, const std::vector<int> & dims,
515 const std::vector<std::ptrdiff_t> & strides )
516 : NDIterator_base( dims, strides ), _buffer( buffer )
517 {
518 }
519
520
521 template <typename T> inline T & NDIterator<T>::operator * () const
522 {
523 return _buffer[ _offset ];
524 }
525
526 template <typename T> inline T * NDIterator<T>::operator -> () const
527 {
528 return _buffer + _offset;
529 }
530
531 // --
532
533 template <typename T> inline
535 const T* buffer, const std::vector<int> & dims )
536 : NDIterator_base( dims ), _buffer( buffer )
537 {
538 }
539
540
541 template <typename T> inline
543 const T* buffer, const std::vector<int> & dims,
544 const std::vector<int> & strides )
545 : NDIterator_base( dims, strides ), _buffer( buffer )
546 {
547 }
548
549
550 template <typename T> inline
552 const T* buffer, const std::vector<int> & dims,
553 const std::vector<std::ptrdiff_t> & strides )
554 : NDIterator_base( dims, strides ), _buffer( buffer )
555 {
556 }
557
558
559 template <typename T> inline
561 const T* buffer, const std::vector<int> & dims,
562 const std::vector<std::size_t> & strides )
563 : NDIterator_base( dims, strides ), _buffer( buffer )
564 {
565 }
566
567
568 template <typename T> const inline T &
570 {
571 return _buffer[ _offset ];
572 }
573
574 template <typename T> const inline T *
576 {
577 return _buffer + _offset;
578 }
579
580 // --
581
582 template <typename T> inline
584 T* buffer, const std::vector<int> & dims )
585 : line_NDIterator_base( dims ), _buffer( buffer )
586 {
587 }
588
589
590 template <typename T> inline
592 const std::vector<int> & dims,
593 const std::vector<int> & strides,
594 bool optimize_direction )
595 : line_NDIterator_base( dims, strides, optimize_direction ),
596 _buffer( buffer )
597 {
598 }
599
600
601 template <typename T> inline
603 const std::vector<int> & dims,
604 const std::vector<std::size_t> & strides,
605 bool optimize_direction )
606 : line_NDIterator_base( dims, strides, optimize_direction ),
607 _buffer( buffer )
608 {
609 }
610
611
612 template <typename T> inline
614 const std::vector<int> & dims,
615 const std::vector<std::ptrdiff_t> & strides,
616 bool optimize_direction )
617 : line_NDIterator_base( dims, strides, optimize_direction ),
618 _buffer( buffer )
619 {
620 }
621
622
623 template <typename T> inline T & line_NDIterator<T>::operator * () const
624 {
625 return _buffer[ _offset ];
626 }
627
628
629 template <typename T> inline T * line_NDIterator<T>::operator -> () const
630 {
631 return _buffer + _offset;
632 }
633
634
635 template <typename T> inline
637 {
638 if( _contiguous )
639 ++p;
640 else
641 p += _line_stride;
642 }
643
644
645 template <typename T> inline
646 void line_NDIterator<T>::inc_line_ptr( const T* & p ) const
647 {
648 if( _contiguous )
649 ++p;
650 else
651 p += _line_stride;
652 }
653
654
655 template <typename T> inline
656 std::ptrdiff_t line_NDIterator<T>::line_length() const
657 {
658 if( is_contiguous() )
659 return line_size();
660 else
662 }
663
664 // --
665
666 template <typename T> inline
668 const T* buffer, const std::vector<int> & dims )
669 : line_NDIterator_base( dims ), _buffer( buffer )
670 {
671 }
672
673
674 template <typename T> inline
676 const T* buffer, const std::vector<int> & dims,
677 const std::vector<int> & strides, bool optimize_direction )
678 : line_NDIterator_base( dims, strides, optimize_direction ),
679 _buffer( buffer )
680 {
681 }
682
683
684 template <typename T> inline
686 const T* buffer, const std::vector<int> & dims,
687 const std::vector<std::size_t> & strides, bool optimize_direction )
688 : line_NDIterator_base( dims, strides, optimize_direction ),
689 _buffer( buffer )
690 {
691 }
692
693
694 template <typename T> inline
696 const T* buffer, const std::vector<int> & dims,
697 const std::vector<std::ptrdiff_t> & strides, bool optimize_direction )
698 : line_NDIterator_base( dims, strides, optimize_direction ),
699 _buffer( buffer )
700 {
701 }
702
703
704 template <typename T> inline const T &
706 {
707 return _buffer[ _offset ];
708 }
709
710
711 template <typename T> inline const T *
713 {
714 return _buffer + _offset;
715 }
716
717
718 template <typename T> inline
719 void const_line_NDIterator<T>::inc_line_ptr( const T* & p ) const
720 {
721 if( _contiguous )
722 ++p;
723 else
724 p += _line_stride;
725 }
726
727
728 template <typename T> inline
730 {
731 if( is_contiguous() )
732 return line_size();
733 else
735 }
736
737}
738
739#endif
std::vector< int > _dims
Definition nditerator.h:74
NDIterator_base(const std::vector< int > &dims)
Definition nditerator.h:271
std::vector< std::ptrdiff_t > _strides
Definition nditerator.h:75
std::ptrdiff_t offset() const
Definition nditerator.h:317
static std::vector< std::ptrdiff_t > to_ptrdiff_v(const std::vector< T > &v)
Definition nditerator.h:337
const std::vector< int > & position() const
Definition nditerator.h:311
std::ptrdiff_t _offset
Definition nditerator.h:77
NDIterator_base & operator++()
Definition nditerator.h:345
std::vector< int > _position
Definition nditerator.h:76
NDIterator(T *buffer, const std::vector< int > &dims)
Definition nditerator.h:491
T * operator->() const
Definition nditerator.h:526
T & operator*() const
Definition nditerator.h:521
const_NDIterator(const T *buffer, const std::vector< int > &dims)
Definition nditerator.h:534
const T & operator*() const
Definition nditerator.h:569
const T * operator->() const
Definition nditerator.h:575
const T & operator*() const
Definition nditerator.h:705
const_line_NDIterator(const T *buffer, const std::vector< int > &dims)
Definition nditerator.h:667
std::ptrdiff_t line_length() const
line_size * line stride: end of line
Definition nditerator.h:729
void inc_line_ptr(const T *&p) const
increment a "line" pointer (advancing through the line)
Definition nditerator.h:719
const T * operator->() const
Definition nditerator.h:712
std::ptrdiff_t _line_stride
Definition nditerator.h:107
line_NDIterator_base(const std::vector< int > &dims)
Definition nditerator.h:373
void set_optimized_direction(bool optimize_direction=false)
Definition nditerator.h:419
NDIterator_base & operator++()
Definition nditerator.h:462
std::ptrdiff_t line_length() const
line_size * line stride: end of line
Definition nditerator.h:656
line_NDIterator(T *buffer, const std::vector< int > &dims)
Definition nditerator.h:583
void inc_line_ptr(T *&p) const
increment a "line" pointer (advancing through the line)
Definition nditerator.h:636