NumCpp  2.11.0
A Templatized Header Only C++ Implementation of the Python NumPy Library
NdArrayIterators.hpp
Go to the documentation of this file.
1 #pragma once
29 
30 #include <iterator>
31 
32 #include "NumCpp/Core/Types.hpp"
33 
34 namespace nc
35 {
36  //================================================================================
37  // Class Description:
39  template<typename dtype, typename PointerType, typename DifferenceType>
41  {
42  private:
44 
45  public:
46  using iterator_category = std::random_access_iterator_tag;
47  using value_type = dtype;
48  using pointer = PointerType;
49  using reference = const value_type&;
50  using difference_type = DifferenceType;
51 
52  //============================================================================
53  // Method Description:
56  NdArrayConstIterator() = default;
57 
58  //============================================================================
59  // Method Description:
64  explicit NdArrayConstIterator(pointer ptr) noexcept :
65  ptr_(ptr)
66  {
67  }
68 
69  //============================================================================
70  // Method Description:
75  reference operator*() const noexcept
76  {
77  return *ptr_;
78  }
79 
80  //============================================================================
81  // Method Description:
86  pointer operator->() const noexcept
87  {
88  return ptr_;
89  }
90 
91  //============================================================================
92  // Method Description:
97  self_type& operator++() noexcept
98  {
99  ++ptr_;
100  return *this;
101  }
102 
103  //============================================================================
104  // Method Description:
109  self_type operator++(int) noexcept
110  {
111  self_type tmp = *this;
112  ++*this;
113  return tmp;
114  }
115 
116  //============================================================================
117  // Method Description:
122  self_type& operator--() noexcept
123  {
124  --ptr_;
125  return *this;
126  }
127 
128  //============================================================================
129  // Method Description:
134  self_type operator--(int) noexcept
135  {
136  self_type tmp = *this;
137  --*this;
138  return tmp;
139  }
140 
141  //============================================================================
142  // Method Description:
148  self_type& operator+=(const difference_type offset) noexcept
149  {
150  ptr_ += offset;
151  return *this;
152  }
153 
154  //============================================================================
155  // Method Description:
161  self_type operator+(const difference_type offset) const noexcept
162  {
163  self_type tmp = *this;
164  return tmp += offset;
165  }
166 
167  //============================================================================
168  // Method Description:
174  self_type& operator-=(const difference_type offset) noexcept
175  {
176  return *this += -offset;
177  }
178 
179  //============================================================================
180  // Method Description:
186  self_type operator-(const difference_type offset) const noexcept
187  {
188  self_type tmp = *this;
189  return tmp -= offset;
190  }
191 
192  //============================================================================
193  // Method Description:
199  difference_type operator-(const self_type& rhs) const noexcept
200  {
201  return ptr_ - rhs.ptr_;
202  }
203 
204  //============================================================================
205  // Method Description:
211  reference operator[](const difference_type offset) const noexcept
212  {
213  return *(*this + offset);
214  }
215 
216  //============================================================================
217  // Method Description:
223  bool operator==(const self_type& rhs) const noexcept
224  {
225  return ptr_ == rhs.ptr_;
226  }
227 
228  //============================================================================
229  // Method Description:
235  bool operator!=(const self_type& rhs) const noexcept
236  {
237  return !(*this == rhs);
238  }
239 
240  //============================================================================
241  // Method Description:
247  bool operator<(const self_type& rhs) const noexcept
248  {
249  return ptr_ < rhs.ptr_;
250  }
251 
252  //============================================================================
253  // Method Description:
259  bool operator>(const self_type& rhs) const noexcept
260  {
261  return rhs < *this;
262  }
263 
264  //============================================================================
265  // Method Description:
271  bool operator<=(const self_type& rhs) const noexcept
272  {
273  return !(rhs < *this);
274  }
275 
276  //============================================================================
277  // Method Description:
283  bool operator>=(const self_type& rhs) const noexcept
284  {
285  return !(*this < rhs);
286  }
287 
288  private:
289  pointer ptr_{ nullptr };
290  };
291 
292  //============================================================================
293  // Method Description:
300  template<class dtype, typename PointerType, typename DifferenceType>
301  NdArrayConstIterator<dtype, PointerType, DifferenceType>
304  {
305  return next += offset;
306  }
307 
308  //================================================================================
309  // Class Description:
311  template<typename dtype, typename PointerType, typename DifferenceType>
312  class NdArrayIterator : public NdArrayConstIterator<dtype, PointerType, DifferenceType>
313  {
314  private:
317 
318  public:
319  using iterator_category = std::random_access_iterator_tag;
320  using value_type = dtype;
321  using pointer = PointerType;
323  using difference_type = DifferenceType;
324 
325  using MyBase::MyBase;
326 
327  //============================================================================
328  // Method Description:
333  reference operator*() const noexcept
334  {
335  return const_cast<reference>(MyBase::operator*());
336  }
337 
338  //============================================================================
339  // Method Description:
344  pointer operator->() const noexcept
345  {
346  return const_cast<pointer>(MyBase::operator->());
347  }
348 
349  //============================================================================
350  // Method Description:
355  self_type& operator++() noexcept
356  {
358  return *this;
359  }
360 
361  //============================================================================
362  // Method Description:
367  self_type operator++(int) noexcept
368  {
369  self_type tmp = *this;
371  return tmp;
372  }
373 
374  //============================================================================
375  // Method Description:
380  self_type& operator--() noexcept
381  {
383  return *this;
384  }
385 
386  //============================================================================
387  // Method Description:
392  self_type operator--(int) noexcept
393  {
394  self_type tmp = *this;
396  return tmp;
397  }
398 
399  //============================================================================
400  // Method Description:
406  self_type& operator+=(const difference_type offset) noexcept
407  {
408  MyBase::operator+=(offset);
409  return *this;
410  }
411 
412  //============================================================================
413  // Method Description:
419  self_type operator+(const difference_type offset) const noexcept
420  {
421  self_type tmp = *this;
422  return tmp += offset;
423  }
424 
425  //============================================================================
426  // Method Description:
432  self_type& operator-=(const difference_type offset) noexcept
433  {
434  MyBase::operator-=(offset);
435  return *this;
436  }
437 
438  using MyBase::operator-;
439 
440  //============================================================================
441  // Method Description:
447  self_type operator-(const difference_type offset) const noexcept
448  {
449  self_type tmp = *this;
450  return tmp -= offset;
451  }
452 
453  //============================================================================
454  // Method Description:
460  reference operator[](const difference_type offset) const noexcept
461  {
462  return const_cast<reference>(MyBase::operator[](offset));
463  }
464  };
465 
466  //============================================================================
467  // Method Description:
474  template<class dtype, typename PointerType, typename DifferenceType>
475  NdArrayIterator<dtype, PointerType, DifferenceType>
478  {
479  return next += offset;
480  }
481 
482  //================================================================================
483  // Class Description:
485  template<typename dtype, typename SizeType, typename PointerType, typename DifferenceType>
487  {
488  private:
490 
491  public:
492  using iterator_category = std::random_access_iterator_tag;
493  using value_type = dtype;
494  using size_type = SizeType;
495  using pointer = PointerType;
496  using reference = const value_type&;
497  using difference_type = DifferenceType;
498 
499  //============================================================================
500  // Method Description:
504 
505  //============================================================================
506  // Method Description:
513  NdArrayConstColumnIterator(pointer ptr, SizeType numRows, SizeType numCols) noexcept :
514  ptr_(ptr),
515  currPtr_(ptr),
516  numRows_(static_cast<difference_type>(numRows)),
517  numCols_(static_cast<difference_type>(numCols)),
518  size_(numRows_ * numCols_)
519  {
520  }
521 
522  //============================================================================
523  // Method Description:
528  reference operator*() const noexcept
529  {
530  return *currPtr_;
531  }
532 
533  //============================================================================
534  // Method Description:
539  pointer operator->() const noexcept
540  {
541  return currPtr_;
542  }
543 
544  //============================================================================
545  // Method Description:
550  self_type& operator++() noexcept
551  {
552  return *this += 1;
553  }
554 
555  //============================================================================
556  // Method Description:
561  self_type operator++(int) noexcept
562  {
563  self_type tmp = *this;
564  ++*this;
565  return tmp;
566  }
567 
568  //============================================================================
569  // Method Description:
574  self_type& operator--() noexcept
575  {
576  return *this -= 1;
577  }
578 
579  //============================================================================
580  // Method Description:
585  self_type operator--(int) noexcept
586  {
587  self_type tmp = *this;
588  --*this;
589  return tmp;
590  }
591 
592  //============================================================================
593  // Method Description:
599  self_type& operator+=(const difference_type offset) noexcept
600  {
601  currPtr_ = colIdx2Ptr(ptr2ColIdx(currPtr_) + offset);
602  return *this;
603  }
604 
605  //============================================================================
606  // Method Description:
612  self_type operator+(const difference_type offset) const noexcept
613  {
614  self_type tmp = *this;
615  return tmp += offset;
616  }
617 
618  //============================================================================
619  // Method Description:
625  self_type& operator-=(const difference_type offset) noexcept
626  {
627  return *this += -offset;
628  }
629 
630  //============================================================================
631  // Method Description:
637  self_type operator-(const difference_type offset) const noexcept
638  {
639  self_type tmp = *this;
640  return tmp -= offset;
641  }
642 
643  //============================================================================
644  // Method Description:
650  difference_type operator-(const self_type& rhs) const noexcept
651  {
652  return ptr2ColIdx(currPtr_) - ptr2ColIdx(rhs.currPtr_);
653  }
654 
655  //============================================================================
656  // Method Description:
662  reference operator[](const difference_type offset) const noexcept
663  {
664  return *(*this + offset);
665  }
666 
667  //============================================================================
668  // Method Description:
674  bool operator==(const self_type& rhs) const noexcept
675  {
676  return currPtr_ == rhs.currPtr_;
677  }
678 
679  //============================================================================
680  // Method Description:
686  bool operator!=(const self_type& rhs) const noexcept
687  {
688  return !(*this == rhs);
689  }
690 
691  //============================================================================
692  // Method Description:
698  bool operator<(const self_type& rhs) const noexcept
699  {
700  return *this - rhs < 0;
701  }
702 
703  //============================================================================
704  // Method Description:
710  bool operator>(const self_type& rhs) const noexcept
711  {
712  return *this - rhs > 0;
713  }
714 
715  //============================================================================
716  // Method Description:
722  bool operator<=(const self_type& rhs) const noexcept
723  {
724  return !(rhs < *this);
725  }
726 
727  //============================================================================
728  // Method Description:
734  bool operator>=(const self_type& rhs) const noexcept
735  {
736  return !(*this < rhs);
737  }
738 
739  private:
740  pointer ptr_{};
741  pointer currPtr_{};
742  difference_type numRows_{ 0 };
743  difference_type numCols_{ 0 };
744  difference_type size_{ 0 };
745 
746  //============================================================================
747  // Method Description:
753  difference_type ptr2ColIdx(pointer ptr) const noexcept
754  {
755  if (ptr == nullptr)
756  {
757  return size_;
758  }
759 
760  const auto rowIdx = ptr - ptr_;
761  if (rowIdx >= size_)
762  {
763  return size_;
764  }
765 
766  const auto row = rowIdx / numCols_;
767  const auto col = rowIdx % numCols_;
768  return row + col * numRows_;
769  }
770 
771  //============================================================================
772  // Method Description:
778  pointer colIdx2Ptr(difference_type colIdx) const noexcept
779  {
780  if (colIdx >= size_)
781  {
782  return nullptr;
783  }
784 
785  const auto row = colIdx % numRows_;
786  const auto col = colIdx / numRows_;
787  const auto rowIdx = col + row * numCols_;
788  return ptr_ + rowIdx;
789  }
790  };
791 
792  //============================================================================
793  // Method Description:
800  template<class dtype, typename SizeType, typename PointerType, typename DifferenceType>
804  {
805  return next += offset;
806  }
807 
808  //================================================================================
809  // Class Description:
811  template<typename dtype, typename SizeType, typename PointerType, typename DifferenceType>
812  class NdArrayColumnIterator : public NdArrayConstColumnIterator<dtype, SizeType, PointerType, DifferenceType>
813  {
814  private:
817 
818  public:
819  using iterator_category = std::random_access_iterator_tag;
820  using value_type = dtype;
821  using size_type = SizeType;
822  using pointer = PointerType;
824  using difference_type = DifferenceType;
825 
826  using MyBase::MyBase;
827 
828  //============================================================================
829  // Method Description:
834  reference operator*() const noexcept
835  {
836  return const_cast<reference>(MyBase::operator*());
837  }
838 
839  //============================================================================
840  // Method Description:
845  pointer operator->() const noexcept
846  {
847  return const_cast<pointer>(MyBase::operator->());
848  }
849 
850  //============================================================================
851  // Method Description:
856  self_type& operator++() noexcept
857  {
859  return *this;
860  }
861 
862  //============================================================================
863  // Method Description:
868  self_type operator++(int) noexcept
869  {
870  self_type tmp = *this;
872  return tmp;
873  }
874 
875  //============================================================================
876  // Method Description:
881  self_type& operator--() noexcept
882  {
884  return *this;
885  }
886 
887  //============================================================================
888  // Method Description:
893  self_type operator--(int) noexcept
894  {
895  self_type tmp = *this;
897  return tmp;
898  }
899 
900  //============================================================================
901  // Method Description:
907  self_type& operator+=(const difference_type offset) noexcept
908  {
909  MyBase::operator+=(offset);
910  return *this;
911  }
912 
913  //============================================================================
914  // Method Description:
920  self_type operator+(const difference_type offset) const noexcept
921  {
922  self_type tmp = *this;
923  return tmp += offset;
924  }
925 
926  //============================================================================
927  // Method Description:
933  self_type& operator-=(const difference_type offset) noexcept
934  {
935  MyBase::operator-=(offset);
936  return *this;
937  }
938 
939  using MyBase::operator-;
940 
941  //============================================================================
942  // Method Description:
948  self_type operator-(const difference_type offset) const noexcept
949  {
950  self_type tmp = *this;
951  return tmp -= offset;
952  }
953 
954  //============================================================================
955  // Method Description:
961  reference operator[](const difference_type offset) const noexcept
962  {
963  return const_cast<reference>(MyBase::operator[](offset));
964  }
965  };
966 
967  //============================================================================
968  // Method Description:
975  template<class dtype, typename SizeType, typename PointerType, typename DifferenceType>
976  NdArrayColumnIterator<dtype, SizeType, PointerType, DifferenceType>
979  {
980  return next += offset;
981  }
982 } // namespace nc
Custom column iterator for NdArray.
Definition: NdArrayIterators.hpp:813
self_type & operator--() noexcept
Definition: NdArrayIterators.hpp:881
self_type operator++(int) noexcept
Definition: NdArrayIterators.hpp:868
reference operator[](const difference_type offset) const noexcept
Definition: NdArrayIterators.hpp:961
self_type operator-(const difference_type offset) const noexcept
Definition: NdArrayIterators.hpp:948
self_type operator+(const difference_type offset) const noexcept
Definition: NdArrayIterators.hpp:920
self_type & operator-=(const difference_type offset) noexcept
Definition: NdArrayIterators.hpp:933
self_type operator--(int) noexcept
Definition: NdArrayIterators.hpp:893
self_type & operator++() noexcept
Definition: NdArrayIterators.hpp:856
self_type & operator+=(const difference_type offset) noexcept
Definition: NdArrayIterators.hpp:907
DifferenceType difference_type
Definition: NdArrayIterators.hpp:824
pointer operator->() const noexcept
Definition: NdArrayIterators.hpp:845
reference operator*() const noexcept
Definition: NdArrayIterators.hpp:834
Custom column const_iterator for NdArray.
Definition: NdArrayIterators.hpp:487
self_type operator+(const difference_type offset) const noexcept
Definition: NdArrayIterators.hpp:612
pointer operator->() const noexcept
Definition: NdArrayIterators.hpp:539
reference operator[](const difference_type offset) const noexcept
Definition: NdArrayIterators.hpp:662
dtype value_type
Definition: NdArrayIterators.hpp:493
std::random_access_iterator_tag iterator_category
Definition: NdArrayIterators.hpp:492
PointerType pointer
Definition: NdArrayIterators.hpp:495
self_type operator--(int) noexcept
Definition: NdArrayIterators.hpp:585
difference_type operator-(const self_type &rhs) const noexcept
Definition: NdArrayIterators.hpp:650
const value_type & reference
Definition: NdArrayIterators.hpp:496
self_type operator-(const difference_type offset) const noexcept
Definition: NdArrayIterators.hpp:637
bool operator>(const self_type &rhs) const noexcept
Definition: NdArrayIterators.hpp:710
self_type operator++(int) noexcept
Definition: NdArrayIterators.hpp:561
bool operator<=(const self_type &rhs) const noexcept
Definition: NdArrayIterators.hpp:722
self_type & operator--() noexcept
Definition: NdArrayIterators.hpp:574
bool operator>=(const self_type &rhs) const noexcept
Definition: NdArrayIterators.hpp:734
SizeType size_type
Definition: NdArrayIterators.hpp:494
self_type & operator+=(const difference_type offset) noexcept
Definition: NdArrayIterators.hpp:599
bool operator<(const self_type &rhs) const noexcept
Definition: NdArrayIterators.hpp:698
reference operator*() const noexcept
Definition: NdArrayIterators.hpp:528
DifferenceType difference_type
Definition: NdArrayIterators.hpp:497
self_type & operator++() noexcept
Definition: NdArrayIterators.hpp:550
bool operator!=(const self_type &rhs) const noexcept
Definition: NdArrayIterators.hpp:686
bool operator==(const self_type &rhs) const noexcept
Definition: NdArrayIterators.hpp:674
self_type & operator-=(const difference_type offset) noexcept
Definition: NdArrayIterators.hpp:625
NdArrayConstColumnIterator(pointer ptr, SizeType numRows, SizeType numCols) noexcept
Definition: NdArrayIterators.hpp:513
Custom const_iterator for NdArray.
Definition: NdArrayIterators.hpp:41
bool operator>=(const self_type &rhs) const noexcept
Definition: NdArrayIterators.hpp:283
DifferenceType difference_type
Definition: NdArrayIterators.hpp:50
bool operator<=(const self_type &rhs) const noexcept
Definition: NdArrayIterators.hpp:271
std::random_access_iterator_tag iterator_category
Definition: NdArrayIterators.hpp:46
pointer operator->() const noexcept
Definition: NdArrayIterators.hpp:86
self_type operator++(int) noexcept
Definition: NdArrayIterators.hpp:109
PointerType pointer
Definition: NdArrayIterators.hpp:48
self_type operator-(const difference_type offset) const noexcept
Definition: NdArrayIterators.hpp:186
self_type operator--(int) noexcept
Definition: NdArrayIterators.hpp:134
self_type operator+(const difference_type offset) const noexcept
Definition: NdArrayIterators.hpp:161
self_type & operator--() noexcept
Definition: NdArrayIterators.hpp:122
bool operator<(const self_type &rhs) const noexcept
Definition: NdArrayIterators.hpp:247
reference operator[](const difference_type offset) const noexcept
Definition: NdArrayIterators.hpp:211
bool operator>(const self_type &rhs) const noexcept
Definition: NdArrayIterators.hpp:259
bool operator!=(const self_type &rhs) const noexcept
Definition: NdArrayIterators.hpp:235
self_type & operator-=(const difference_type offset) noexcept
Definition: NdArrayIterators.hpp:174
difference_type operator-(const self_type &rhs) const noexcept
Definition: NdArrayIterators.hpp:199
NdArrayConstIterator(pointer ptr) noexcept
Definition: NdArrayIterators.hpp:64
const value_type & reference
Definition: NdArrayIterators.hpp:49
bool operator==(const self_type &rhs) const noexcept
Definition: NdArrayIterators.hpp:223
reference operator*() const noexcept
Definition: NdArrayIterators.hpp:75
self_type & operator++() noexcept
Definition: NdArrayIterators.hpp:97
self_type & operator+=(const difference_type offset) noexcept
Definition: NdArrayIterators.hpp:148
dtype value_type
Definition: NdArrayIterators.hpp:47
Custom iterator for NdArray.
Definition: NdArrayIterators.hpp:313
self_type operator++(int) noexcept
Definition: NdArrayIterators.hpp:367
self_type & operator-=(const difference_type offset) noexcept
Definition: NdArrayIterators.hpp:432
self_type & operator--() noexcept
Definition: NdArrayIterators.hpp:380
reference operator[](const difference_type offset) const noexcept
Definition: NdArrayIterators.hpp:460
DifferenceType difference_type
Definition: NdArrayIterators.hpp:323
self_type operator-(const difference_type offset) const noexcept
Definition: NdArrayIterators.hpp:447
pointer operator->() const noexcept
Definition: NdArrayIterators.hpp:344
self_type operator+(const difference_type offset) const noexcept
Definition: NdArrayIterators.hpp:419
self_type & operator++() noexcept
Definition: NdArrayIterators.hpp:355
self_type operator--(int) noexcept
Definition: NdArrayIterators.hpp:392
reference operator*() const noexcept
Definition: NdArrayIterators.hpp:333
self_type & operator+=(const difference_type offset) noexcept
Definition: NdArrayIterators.hpp:406
Definition: Cartesian.hpp:40
NdArrayConstIterator< dtype, PointerType, DifferenceType > operator+(typename NdArrayConstIterator< dtype, PointerType, DifferenceType >::difference_type offset, NdArrayConstIterator< dtype, PointerType, DifferenceType > next) noexcept
Definition: NdArrayIterators.hpp:302