NumCpp  2.5.1
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 "NumCpp/Core/Types.hpp"
32 
33 #include <iterator>
34 
35 namespace nc
36 {
37  //================================================================================
38  // Class Description:
40  template<typename dtype,
41  typename PointerType,
42  typename DifferenceType>
44  {
45  private:
47 
48  public:
49  using iterator_category = std::random_access_iterator_tag;
50  using value_type = dtype;
51  using pointer = PointerType;
52  using reference = const value_type&;
53  using difference_type = DifferenceType;
54 
55  //============================================================================
56  // Method Description:
59  NdArrayConstIterator() = default;
60 
61  //============================================================================
62  // Method Description:
67  explicit NdArrayConstIterator(pointer ptr) :
68  ptr_(ptr)
69  {
70  if (ptr == nullptr)
71  {
72  THROW_RUNTIME_ERROR("NdArray has not been initialized.");
73  }
74  }
75 
76  //============================================================================
77  // Method Description:
82  reference operator*() const noexcept
83  {
84  return *ptr_;
85  }
86 
87  //============================================================================
88  // Method Description:
93  pointer operator->() const noexcept
94  {
95  return ptr_;
96  }
97 
98  //============================================================================
99  // Method Description:
104  self_type& operator++() noexcept
105  {
106  ++ptr_;
107  return *this;
108  }
109 
110  //============================================================================
111  // Method Description:
116  self_type operator++(int) noexcept
117  {
118  self_type tmp = *this;
119  ++*this;
120  return tmp;
121  }
122 
123  //============================================================================
124  // Method Description:
129  self_type& operator--() noexcept
130  {
131  --ptr_;
132  return *this;
133  }
134 
135  //============================================================================
136  // Method Description:
141  self_type operator--(int) noexcept
142  {
143  self_type tmp = *this;
144  --*this;
145  return tmp;
146  }
147 
148  //============================================================================
149  // Method Description:
155  self_type& operator+=(const difference_type offset) noexcept
156  {
157  ptr_ += offset;
158  return *this;
159  }
160 
161  //============================================================================
162  // Method Description:
168  self_type operator+(const difference_type offset) const noexcept
169  {
170  self_type tmp = *this;
171  return tmp += offset;
172  }
173 
174  //============================================================================
175  // Method Description:
181  self_type& operator-=(const difference_type offset) noexcept
182  {
183  return *this += -offset;
184  }
185 
186  //============================================================================
187  // Method Description:
193  self_type operator-(const difference_type offset) const noexcept
194  {
195  self_type tmp = *this;
196  return tmp -= offset;
197  }
198 
199  //============================================================================
200  // Method Description:
206  difference_type operator-(const self_type& rhs) const noexcept
207  {
208  return ptr_ - rhs.ptr_;
209  }
210 
211  //============================================================================
212  // Method Description:
218  reference operator[](const difference_type offset) const noexcept
219  {
220  return *(*this + offset);
221  }
222 
223  //============================================================================
224  // Method Description:
230  bool operator==(const self_type& rhs) const noexcept
231  {
232  return ptr_ == rhs.ptr_;
233  }
234 
235  //============================================================================
236  // Method Description:
242  bool operator!=(const self_type& rhs) const noexcept
243  {
244  return !(*this == rhs);
245  }
246 
247  //============================================================================
248  // Method Description:
254  bool operator<(const self_type& rhs) const noexcept
255  {
256  return ptr_ < rhs.ptr_;
257  }
258 
259  //============================================================================
260  // Method Description:
266  bool operator>(const self_type& rhs) const noexcept
267  {
268  return rhs < *this;
269  }
270 
271  //============================================================================
272  // Method Description:
278  bool operator<=(const self_type& rhs) const noexcept
279  {
280  return !(rhs < *this);
281  }
282 
283  //============================================================================
284  // Method Description:
290  bool operator>=(const self_type& rhs) const noexcept
291  {
292  return !(*this < rhs);
293  }
294 
295  private:
296  pointer ptr_{nullptr};
297  };
298 
299  //============================================================================
300  // Method Description:
307  template <class dtype,
308  typename PointerType,
309  typename DifferenceType>
313  {
314  return next += offset;
315  }
316 
317  //================================================================================
318  // Class Description:
320  template<typename dtype,
321  typename PointerType,
322  typename DifferenceType>
323  class NdArrayIterator : public NdArrayConstIterator<dtype, PointerType, DifferenceType>
324  {
325  private:
328 
329  public:
330  using iterator_category = std::random_access_iterator_tag;
331  using value_type = dtype;
332  using pointer = PointerType;
334  using difference_type = DifferenceType;
335 
336  using MyBase::MyBase;
337 
338  //============================================================================
339  // Method Description:
344  reference operator*() const noexcept
345  {
346  return const_cast<reference>(MyBase::operator*());
347  }
348 
349  //============================================================================
350  // Method Description:
355  pointer operator->() const noexcept
356  {
357  return const_cast<pointer>(MyBase::operator->());
358  }
359 
360  //============================================================================
361  // Method Description:
366  self_type& operator++() noexcept
367  {
369  return *this;
370  }
371 
372  //============================================================================
373  // Method Description:
378  self_type operator++(int) noexcept
379  {
380  self_type tmp = *this;
382  return tmp;
383  }
384 
385  //============================================================================
386  // Method Description:
391  self_type& operator--() noexcept
392  {
394  return *this;
395  }
396 
397  //============================================================================
398  // Method Description:
403  self_type operator--(int) noexcept
404  {
405  self_type tmp = *this;
407  return tmp;
408  }
409 
410  //============================================================================
411  // Method Description:
417  self_type& operator+=(const difference_type offset) noexcept
418  {
419  MyBase::operator+=(offset);
420  return *this;
421  }
422 
423  //============================================================================
424  // Method Description:
430  self_type operator+(const difference_type offset) const noexcept
431  {
432  self_type tmp = *this;
433  return tmp += offset;
434  }
435 
436  //============================================================================
437  // Method Description:
443  self_type& operator-=(const difference_type offset) noexcept
444  {
445  MyBase::operator-=(offset);
446  return *this;
447  }
448 
449  using MyBase::operator-;
450 
451  //============================================================================
452  // Method Description:
458  self_type operator-(const difference_type offset) const noexcept
459  {
460  self_type tmp = *this;
461  return tmp -= offset;
462  }
463 
464  //============================================================================
465  // Method Description:
471  reference operator[](const difference_type offset) const noexcept
472  {
473  return const_cast<reference>(MyBase::operator[](offset));
474  }
475  };
476 
477  //============================================================================
478  // Method Description:
485  template <class dtype,
486  typename PointerType,
487  typename DifferenceType>
491  {
492  return next += offset;
493  }
494 
495  //================================================================================
496  // Class Description:
498  template<typename dtype,
499  typename SizeType,
500  typename PointerType,
501  typename DifferenceType>
503  {
504  private:
506 
507  public:
508  using iterator_category = std::random_access_iterator_tag;
509  using value_type = dtype;
510  using size_type = SizeType;
511  using pointer = PointerType;
512  using reference = const value_type&;
513  using difference_type = DifferenceType;
514 
515  //============================================================================
516  // Method Description:
520 
521  //============================================================================
522  // Method Description:
529  NdArrayConstColumnIterator(pointer ptr, SizeType numRows, SizeType numCols) noexcept :
530  ptr_(ptr),
531  currPtr_(ptr),
532  numRows_(static_cast<difference_type>(numRows)),
533  numCols_(static_cast<difference_type>(numCols)),
534  size_(numRows_ * numCols_)
535  {}
536 
537  //============================================================================
538  // Method Description:
543  reference operator*() const noexcept
544  {
545  return *currPtr_;
546  }
547 
548  //============================================================================
549  // Method Description:
554  pointer operator->() const noexcept
555  {
556  return currPtr_;
557  }
558 
559  //============================================================================
560  // Method Description:
565  self_type& operator++() noexcept
566  {
567  return *this += 1;
568  }
569 
570  //============================================================================
571  // Method Description:
576  self_type operator++(int) noexcept
577  {
578  self_type tmp = *this;
579  ++*this;
580  return tmp;
581  }
582 
583  //============================================================================
584  // Method Description:
589  self_type& operator--() noexcept
590  {
591  return *this -= 1;
592  }
593 
594  //============================================================================
595  // Method Description:
600  self_type operator--(int) noexcept
601  {
602  self_type tmp = *this;
603  --*this;
604  return tmp;
605  }
606 
607  //============================================================================
608  // Method Description:
614  self_type& operator+=(const difference_type offset) noexcept
615  {
616  currPtr_ = colIdx2Ptr(ptr2ColIdx(currPtr_) + offset);
617  return *this;
618  }
619 
620  //============================================================================
621  // Method Description:
627  self_type operator+(const difference_type offset) const noexcept
628  {
629  self_type tmp = *this;
630  return tmp += offset;
631  }
632 
633  //============================================================================
634  // Method Description:
640  self_type& operator-=(const difference_type offset) noexcept
641  {
642  return *this += -offset;
643  }
644 
645  //============================================================================
646  // Method Description:
652  self_type operator-(const difference_type offset) const noexcept
653  {
654  self_type tmp = *this;
655  return tmp -= offset;
656  }
657 
658  //============================================================================
659  // Method Description:
665  difference_type operator-(const self_type& rhs) const noexcept
666  {
667  return ptr2ColIdx(currPtr_) - ptr2ColIdx(rhs.currPtr_);
668  }
669 
670  //============================================================================
671  // Method Description:
677  reference operator[](const difference_type offset) const noexcept
678  {
679  return *(*this + offset);
680  }
681 
682  //============================================================================
683  // Method Description:
689  bool operator==(const self_type& rhs) const noexcept
690  {
691  return currPtr_ == rhs.currPtr_;
692  }
693 
694  //============================================================================
695  // Method Description:
701  bool operator!=(const self_type& rhs) const noexcept
702  {
703  return !(*this == rhs);
704  }
705 
706  //============================================================================
707  // Method Description:
713  bool operator<(const self_type& rhs) const noexcept
714  {
715  return *this - rhs < 0;
716  }
717 
718  //============================================================================
719  // Method Description:
725  bool operator>(const self_type& rhs) const noexcept
726  {
727  return *this - rhs > 0;
728  }
729 
730  //============================================================================
731  // Method Description:
737  bool operator<=(const self_type& rhs) const noexcept
738  {
739  return !(rhs < *this);
740  }
741 
742  //============================================================================
743  // Method Description:
749  bool operator>=(const self_type& rhs) const noexcept
750  {
751  return !(*this < rhs);
752  }
753 
754  private:
755  pointer ptr_{};
756  pointer currPtr_{};
757  difference_type numRows_{ 0 };
758  difference_type numCols_{ 0 };
759  difference_type size_{ 0 };
760 
761  //============================================================================
762  // Method Description:
768  difference_type ptr2ColIdx(pointer ptr) const noexcept
769  {
770  if (ptr == nullptr)
771  {
772  return size_;
773  }
774 
775  const auto rowIdx = ptr - ptr_;
776  if (rowIdx >= size_)
777  {
778  return size_;
779  }
780 
781  const auto row = rowIdx / numCols_;
782  const auto col = rowIdx % numCols_;
783  return row + col * numRows_;
784  }
785 
786  //============================================================================
787  // Method Description:
793  pointer colIdx2Ptr(difference_type colIdx) const noexcept
794  {
795  if (colIdx >= size_)
796  {
797  return nullptr;
798  }
799 
800  const auto row = colIdx % numRows_;
801  const auto col = colIdx / numRows_;
802  const auto rowIdx = col + row * numCols_;
803  return ptr_ + rowIdx;
804  }
805  };
806 
807  //============================================================================
808  // Method Description:
815  template <class dtype,
816  typename SizeType,
817  typename PointerType,
818  typename DifferenceType>
822  {
823  return next += offset;
824  }
825 
826  //================================================================================
827  // Class Description:
829  template<typename dtype,
830  typename SizeType,
831  typename PointerType,
832  typename DifferenceType>
833  class NdArrayColumnIterator : public NdArrayConstColumnIterator<dtype, SizeType, PointerType, DifferenceType>
834  {
835  private:
838 
839  public:
840  using iterator_category = std::random_access_iterator_tag;
841  using value_type = dtype;
842  using size_type = SizeType;
843  using pointer = PointerType;
845  using difference_type = DifferenceType;
846 
847  using MyBase::MyBase;
848 
849  //============================================================================
850  // Method Description:
855  reference operator*() const noexcept
856  {
857  return const_cast<reference>(MyBase::operator*());
858  }
859 
860  //============================================================================
861  // Method Description:
866  pointer operator->() const noexcept
867  {
868  return const_cast<pointer>(MyBase::operator->());
869  }
870 
871  //============================================================================
872  // Method Description:
877  self_type& operator++() noexcept
878  {
880  return *this;
881  }
882 
883  //============================================================================
884  // Method Description:
889  self_type operator++(int) noexcept
890  {
891  self_type tmp = *this;
893  return tmp;
894  }
895 
896  //============================================================================
897  // Method Description:
902  self_type& operator--() noexcept
903  {
905  return *this;
906  }
907 
908  //============================================================================
909  // Method Description:
914  self_type operator--(int) noexcept
915  {
916  self_type tmp = *this;
918  return tmp;
919  }
920 
921  //============================================================================
922  // Method Description:
928  self_type& operator+=(const difference_type offset) noexcept
929  {
930  MyBase::operator+=(offset);
931  return *this;
932  }
933 
934  //============================================================================
935  // Method Description:
941  self_type operator+(const difference_type offset) const noexcept
942  {
943  self_type tmp = *this;
944  return tmp += offset;
945  }
946 
947  //============================================================================
948  // Method Description:
954  self_type& operator-=(const difference_type offset) noexcept
955  {
956  MyBase::operator-=(offset);
957  return *this;
958  }
959 
960  using MyBase::operator-;
961 
962  //============================================================================
963  // Method Description:
969  self_type operator-(const difference_type offset) const noexcept
970  {
971  self_type tmp = *this;
972  return tmp -= offset;
973  }
974 
975  //============================================================================
976  // Method Description:
982  reference operator[](const difference_type offset) const noexcept
983  {
984  return const_cast<reference>(MyBase::operator[](offset));
985  }
986  };
987 
988  //============================================================================
989  // Method Description:
996  template <class dtype,
997  typename SizeType,
998  typename PointerType,
999  typename DifferenceType>
1003  {
1004  return next += offset;
1005  }
1006 } // namespace nc
#define THROW_RUNTIME_ERROR(msg)
Definition: Error.hpp:37
Custom column iterator for NdArray.
Definition: NdArrayIterators.hpp:834
self_type & operator--() noexcept
Definition: NdArrayIterators.hpp:902
self_type operator++(int) noexcept
Definition: NdArrayIterators.hpp:889
reference operator[](const difference_type offset) const noexcept
Definition: NdArrayIterators.hpp:982
self_type operator-(const difference_type offset) const noexcept
Definition: NdArrayIterators.hpp:969
self_type operator+(const difference_type offset) const noexcept
Definition: NdArrayIterators.hpp:941
self_type & operator-=(const difference_type offset) noexcept
Definition: NdArrayIterators.hpp:954
self_type operator--(int) noexcept
Definition: NdArrayIterators.hpp:914
self_type & operator++() noexcept
Definition: NdArrayIterators.hpp:877
self_type & operator+=(const difference_type offset) noexcept
Definition: NdArrayIterators.hpp:928
DifferenceType difference_type
Definition: NdArrayIterators.hpp:845
pointer operator->() const noexcept
Definition: NdArrayIterators.hpp:866
reference operator*() const noexcept
Definition: NdArrayIterators.hpp:855
Custom column const_iterator for NdArray.
Definition: NdArrayIterators.hpp:503
self_type operator+(const difference_type offset) const noexcept
Definition: NdArrayIterators.hpp:627
pointer operator->() const noexcept
Definition: NdArrayIterators.hpp:554
reference operator[](const difference_type offset) const noexcept
Definition: NdArrayIterators.hpp:677
dtype value_type
Definition: NdArrayIterators.hpp:509
std::random_access_iterator_tag iterator_category
Definition: NdArrayIterators.hpp:508
PointerType pointer
Definition: NdArrayIterators.hpp:511
self_type operator--(int) noexcept
Definition: NdArrayIterators.hpp:600
difference_type operator-(const self_type &rhs) const noexcept
Definition: NdArrayIterators.hpp:665
const value_type & reference
Definition: NdArrayIterators.hpp:512
self_type operator-(const difference_type offset) const noexcept
Definition: NdArrayIterators.hpp:652
bool operator>(const self_type &rhs) const noexcept
Definition: NdArrayIterators.hpp:725
self_type operator++(int) noexcept
Definition: NdArrayIterators.hpp:576
bool operator<=(const self_type &rhs) const noexcept
Definition: NdArrayIterators.hpp:737
self_type & operator--() noexcept
Definition: NdArrayIterators.hpp:589
bool operator>=(const self_type &rhs) const noexcept
Definition: NdArrayIterators.hpp:749
SizeType size_type
Definition: NdArrayIterators.hpp:510
self_type & operator+=(const difference_type offset) noexcept
Definition: NdArrayIterators.hpp:614
bool operator<(const self_type &rhs) const noexcept
Definition: NdArrayIterators.hpp:713
reference operator*() const noexcept
Definition: NdArrayIterators.hpp:543
DifferenceType difference_type
Definition: NdArrayIterators.hpp:513
self_type & operator++() noexcept
Definition: NdArrayIterators.hpp:565
bool operator!=(const self_type &rhs) const noexcept
Definition: NdArrayIterators.hpp:701
bool operator==(const self_type &rhs) const noexcept
Definition: NdArrayIterators.hpp:689
self_type & operator-=(const difference_type offset) noexcept
Definition: NdArrayIterators.hpp:640
NdArrayConstColumnIterator(pointer ptr, SizeType numRows, SizeType numCols) noexcept
Definition: NdArrayIterators.hpp:529
Custom const_iterator for NdArray.
Definition: NdArrayIterators.hpp:44
bool operator>=(const self_type &rhs) const noexcept
Definition: NdArrayIterators.hpp:290
DifferenceType difference_type
Definition: NdArrayIterators.hpp:53
bool operator<=(const self_type &rhs) const noexcept
Definition: NdArrayIterators.hpp:278
std::random_access_iterator_tag iterator_category
Definition: NdArrayIterators.hpp:49
pointer operator->() const noexcept
Definition: NdArrayIterators.hpp:93
self_type operator++(int) noexcept
Definition: NdArrayIterators.hpp:116
PointerType pointer
Definition: NdArrayIterators.hpp:51
self_type operator-(const difference_type offset) const noexcept
Definition: NdArrayIterators.hpp:193
self_type operator--(int) noexcept
Definition: NdArrayIterators.hpp:141
self_type operator+(const difference_type offset) const noexcept
Definition: NdArrayIterators.hpp:168
self_type & operator--() noexcept
Definition: NdArrayIterators.hpp:129
bool operator<(const self_type &rhs) const noexcept
Definition: NdArrayIterators.hpp:254
reference operator[](const difference_type offset) const noexcept
Definition: NdArrayIterators.hpp:218
bool operator>(const self_type &rhs) const noexcept
Definition: NdArrayIterators.hpp:266
NdArrayConstIterator(pointer ptr)
Definition: NdArrayIterators.hpp:67
bool operator!=(const self_type &rhs) const noexcept
Definition: NdArrayIterators.hpp:242
self_type & operator-=(const difference_type offset) noexcept
Definition: NdArrayIterators.hpp:181
difference_type operator-(const self_type &rhs) const noexcept
Definition: NdArrayIterators.hpp:206
const value_type & reference
Definition: NdArrayIterators.hpp:52
bool operator==(const self_type &rhs) const noexcept
Definition: NdArrayIterators.hpp:230
reference operator*() const noexcept
Definition: NdArrayIterators.hpp:82
self_type & operator++() noexcept
Definition: NdArrayIterators.hpp:104
self_type & operator+=(const difference_type offset) noexcept
Definition: NdArrayIterators.hpp:155
dtype value_type
Definition: NdArrayIterators.hpp:50
Custom iterator for NdArray.
Definition: NdArrayIterators.hpp:324
self_type operator++(int) noexcept
Definition: NdArrayIterators.hpp:378
self_type & operator-=(const difference_type offset) noexcept
Definition: NdArrayIterators.hpp:443
self_type & operator--() noexcept
Definition: NdArrayIterators.hpp:391
reference operator[](const difference_type offset) const noexcept
Definition: NdArrayIterators.hpp:471
DifferenceType difference_type
Definition: NdArrayIterators.hpp:334
self_type operator-(const difference_type offset) const noexcept
Definition: NdArrayIterators.hpp:458
pointer operator->() const noexcept
Definition: NdArrayIterators.hpp:355
self_type operator+(const difference_type offset) const noexcept
Definition: NdArrayIterators.hpp:430
self_type & operator++() noexcept
Definition: NdArrayIterators.hpp:366
self_type operator--(int) noexcept
Definition: NdArrayIterators.hpp:403
reference operator*() const noexcept
Definition: NdArrayIterators.hpp:344
self_type & operator+=(const difference_type offset) noexcept
Definition: NdArrayIterators.hpp:417
Definition: Coordinate.hpp:45
NdArrayConstIterator< dtype, PointerType, DifferenceType > operator+(typename NdArrayConstIterator< dtype, PointerType, DifferenceType >::difference_type offset, NdArrayConstIterator< dtype, PointerType, DifferenceType > next) noexcept
Definition: NdArrayIterators.hpp:310