NumCpp  2.9.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 
33 #include "NumCpp/Core/Types.hpp"
34 
35 namespace nc
36 {
37  //================================================================================
38  // Class Description:
40  template<typename dtype, typename PointerType, typename DifferenceType>
42  {
43  private:
45 
46  public:
47  using iterator_category = std::random_access_iterator_tag;
48  using value_type = dtype;
49  using pointer = PointerType;
50  using reference = const value_type&;
51  using difference_type = DifferenceType;
52 
53  //============================================================================
54  // Method Description:
57  NdArrayConstIterator() = default;
58 
59  //============================================================================
60  // Method Description:
65  explicit NdArrayConstIterator(pointer ptr) :
66  ptr_(ptr)
67  {
68  if (ptr == nullptr)
69  {
70  THROW_RUNTIME_ERROR("NdArray has not been initialized.");
71  }
72  }
73 
74  //============================================================================
75  // Method Description:
80  reference operator*() const noexcept
81  {
82  return *ptr_;
83  }
84 
85  //============================================================================
86  // Method Description:
91  pointer operator->() const noexcept
92  {
93  return ptr_;
94  }
95 
96  //============================================================================
97  // Method Description:
102  self_type& operator++() noexcept
103  {
104  ++ptr_;
105  return *this;
106  }
107 
108  //============================================================================
109  // Method Description:
114  self_type operator++(int) noexcept
115  {
116  self_type tmp = *this;
117  ++*this;
118  return tmp;
119  }
120 
121  //============================================================================
122  // Method Description:
127  self_type& operator--() noexcept
128  {
129  --ptr_;
130  return *this;
131  }
132 
133  //============================================================================
134  // Method Description:
139  self_type operator--(int) noexcept
140  {
141  self_type tmp = *this;
142  --*this;
143  return tmp;
144  }
145 
146  //============================================================================
147  // Method Description:
153  self_type& operator+=(const difference_type offset) noexcept
154  {
155  ptr_ += offset;
156  return *this;
157  }
158 
159  //============================================================================
160  // Method Description:
166  self_type operator+(const difference_type offset) const noexcept
167  {
168  self_type tmp = *this;
169  return tmp += offset;
170  }
171 
172  //============================================================================
173  // Method Description:
179  self_type& operator-=(const difference_type offset) noexcept
180  {
181  return *this += -offset;
182  }
183 
184  //============================================================================
185  // Method Description:
191  self_type operator-(const difference_type offset) const noexcept
192  {
193  self_type tmp = *this;
194  return tmp -= offset;
195  }
196 
197  //============================================================================
198  // Method Description:
204  difference_type operator-(const self_type& rhs) const noexcept
205  {
206  return ptr_ - rhs.ptr_;
207  }
208 
209  //============================================================================
210  // Method Description:
216  reference operator[](const difference_type offset) const noexcept
217  {
218  return *(*this + offset);
219  }
220 
221  //============================================================================
222  // Method Description:
228  bool operator==(const self_type& rhs) const noexcept
229  {
230  return ptr_ == rhs.ptr_;
231  }
232 
233  //============================================================================
234  // Method Description:
240  bool operator!=(const self_type& rhs) const noexcept
241  {
242  return !(*this == rhs);
243  }
244 
245  //============================================================================
246  // Method Description:
252  bool operator<(const self_type& rhs) const noexcept
253  {
254  return ptr_ < rhs.ptr_;
255  }
256 
257  //============================================================================
258  // Method Description:
264  bool operator>(const self_type& rhs) const noexcept
265  {
266  return rhs < *this;
267  }
268 
269  //============================================================================
270  // Method Description:
276  bool operator<=(const self_type& rhs) const noexcept
277  {
278  return !(rhs < *this);
279  }
280 
281  //============================================================================
282  // Method Description:
288  bool operator>=(const self_type& rhs) const noexcept
289  {
290  return !(*this < rhs);
291  }
292 
293  private:
294  pointer ptr_{ nullptr };
295  };
296 
297  //============================================================================
298  // Method Description:
305  template<class dtype, typename PointerType, typename DifferenceType>
306  NdArrayConstIterator<dtype, PointerType, DifferenceType>
309  {
310  return next += offset;
311  }
312 
313  //================================================================================
314  // Class Description:
316  template<typename dtype, typename PointerType, typename DifferenceType>
317  class NdArrayIterator : public NdArrayConstIterator<dtype, PointerType, DifferenceType>
318  {
319  private:
322 
323  public:
324  using iterator_category = std::random_access_iterator_tag;
325  using value_type = dtype;
326  using pointer = PointerType;
328  using difference_type = DifferenceType;
329 
330  using MyBase::MyBase;
331 
332  //============================================================================
333  // Method Description:
338  reference operator*() const noexcept
339  {
340  return const_cast<reference>(MyBase::operator*());
341  }
342 
343  //============================================================================
344  // Method Description:
349  pointer operator->() const noexcept
350  {
351  return const_cast<pointer>(MyBase::operator->());
352  }
353 
354  //============================================================================
355  // Method Description:
360  self_type& operator++() noexcept
361  {
363  return *this;
364  }
365 
366  //============================================================================
367  // Method Description:
372  self_type operator++(int) noexcept
373  {
374  self_type tmp = *this;
376  return tmp;
377  }
378 
379  //============================================================================
380  // Method Description:
385  self_type& operator--() noexcept
386  {
388  return *this;
389  }
390 
391  //============================================================================
392  // Method Description:
397  self_type operator--(int) noexcept
398  {
399  self_type tmp = *this;
401  return tmp;
402  }
403 
404  //============================================================================
405  // Method Description:
411  self_type& operator+=(const difference_type offset) noexcept
412  {
413  MyBase::operator+=(offset);
414  return *this;
415  }
416 
417  //============================================================================
418  // Method Description:
424  self_type operator+(const difference_type offset) const noexcept
425  {
426  self_type tmp = *this;
427  return tmp += offset;
428  }
429 
430  //============================================================================
431  // Method Description:
437  self_type& operator-=(const difference_type offset) noexcept
438  {
439  MyBase::operator-=(offset);
440  return *this;
441  }
442 
443  using MyBase::operator-;
444 
445  //============================================================================
446  // Method Description:
452  self_type operator-(const difference_type offset) const noexcept
453  {
454  self_type tmp = *this;
455  return tmp -= offset;
456  }
457 
458  //============================================================================
459  // Method Description:
465  reference operator[](const difference_type offset) const noexcept
466  {
467  return const_cast<reference>(MyBase::operator[](offset));
468  }
469  };
470 
471  //============================================================================
472  // Method Description:
479  template<class dtype, typename PointerType, typename DifferenceType>
480  NdArrayIterator<dtype, PointerType, DifferenceType>
483  {
484  return next += offset;
485  }
486 
487  //================================================================================
488  // Class Description:
490  template<typename dtype, typename SizeType, typename PointerType, typename DifferenceType>
492  {
493  private:
495 
496  public:
497  using iterator_category = std::random_access_iterator_tag;
498  using value_type = dtype;
499  using size_type = SizeType;
500  using pointer = PointerType;
501  using reference = const value_type&;
502  using difference_type = DifferenceType;
503 
504  //============================================================================
505  // Method Description:
509 
510  //============================================================================
511  // Method Description:
518  NdArrayConstColumnIterator(pointer ptr, SizeType numRows, SizeType numCols) noexcept :
519  ptr_(ptr),
520  currPtr_(ptr),
521  numRows_(static_cast<difference_type>(numRows)),
522  numCols_(static_cast<difference_type>(numCols)),
523  size_(numRows_ * numCols_)
524  {
525  }
526 
527  //============================================================================
528  // Method Description:
533  reference operator*() const noexcept
534  {
535  return *currPtr_;
536  }
537 
538  //============================================================================
539  // Method Description:
544  pointer operator->() const noexcept
545  {
546  return currPtr_;
547  }
548 
549  //============================================================================
550  // Method Description:
555  self_type& operator++() noexcept
556  {
557  return *this += 1;
558  }
559 
560  //============================================================================
561  // Method Description:
566  self_type operator++(int) noexcept
567  {
568  self_type tmp = *this;
569  ++*this;
570  return tmp;
571  }
572 
573  //============================================================================
574  // Method Description:
579  self_type& operator--() noexcept
580  {
581  return *this -= 1;
582  }
583 
584  //============================================================================
585  // Method Description:
590  self_type operator--(int) noexcept
591  {
592  self_type tmp = *this;
593  --*this;
594  return tmp;
595  }
596 
597  //============================================================================
598  // Method Description:
604  self_type& operator+=(const difference_type offset) noexcept
605  {
606  currPtr_ = colIdx2Ptr(ptr2ColIdx(currPtr_) + offset);
607  return *this;
608  }
609 
610  //============================================================================
611  // Method Description:
617  self_type operator+(const difference_type offset) const noexcept
618  {
619  self_type tmp = *this;
620  return tmp += offset;
621  }
622 
623  //============================================================================
624  // Method Description:
630  self_type& operator-=(const difference_type offset) noexcept
631  {
632  return *this += -offset;
633  }
634 
635  //============================================================================
636  // Method Description:
642  self_type operator-(const difference_type offset) const noexcept
643  {
644  self_type tmp = *this;
645  return tmp -= offset;
646  }
647 
648  //============================================================================
649  // Method Description:
655  difference_type operator-(const self_type& rhs) const noexcept
656  {
657  return ptr2ColIdx(currPtr_) - ptr2ColIdx(rhs.currPtr_);
658  }
659 
660  //============================================================================
661  // Method Description:
667  reference operator[](const difference_type offset) const noexcept
668  {
669  return *(*this + offset);
670  }
671 
672  //============================================================================
673  // Method Description:
679  bool operator==(const self_type& rhs) const noexcept
680  {
681  return currPtr_ == rhs.currPtr_;
682  }
683 
684  //============================================================================
685  // Method Description:
691  bool operator!=(const self_type& rhs) const noexcept
692  {
693  return !(*this == rhs);
694  }
695 
696  //============================================================================
697  // Method Description:
703  bool operator<(const self_type& rhs) const noexcept
704  {
705  return *this - rhs < 0;
706  }
707 
708  //============================================================================
709  // Method Description:
715  bool operator>(const self_type& rhs) const noexcept
716  {
717  return *this - rhs > 0;
718  }
719 
720  //============================================================================
721  // Method Description:
727  bool operator<=(const self_type& rhs) const noexcept
728  {
729  return !(rhs < *this);
730  }
731 
732  //============================================================================
733  // Method Description:
739  bool operator>=(const self_type& rhs) const noexcept
740  {
741  return !(*this < rhs);
742  }
743 
744  private:
745  pointer ptr_{};
746  pointer currPtr_{};
747  difference_type numRows_{ 0 };
748  difference_type numCols_{ 0 };
749  difference_type size_{ 0 };
750 
751  //============================================================================
752  // Method Description:
758  difference_type ptr2ColIdx(pointer ptr) const noexcept
759  {
760  if (ptr == nullptr)
761  {
762  return size_;
763  }
764 
765  const auto rowIdx = ptr - ptr_;
766  if (rowIdx >= size_)
767  {
768  return size_;
769  }
770 
771  const auto row = rowIdx / numCols_;
772  const auto col = rowIdx % numCols_;
773  return row + col * numRows_;
774  }
775 
776  //============================================================================
777  // Method Description:
783  pointer colIdx2Ptr(difference_type colIdx) const noexcept
784  {
785  if (colIdx >= size_)
786  {
787  return nullptr;
788  }
789 
790  const auto row = colIdx % numRows_;
791  const auto col = colIdx / numRows_;
792  const auto rowIdx = col + row * numCols_;
793  return ptr_ + rowIdx;
794  }
795  };
796 
797  //============================================================================
798  // Method Description:
805  template<class dtype, typename SizeType, typename PointerType, typename DifferenceType>
809  {
810  return next += offset;
811  }
812 
813  //================================================================================
814  // Class Description:
816  template<typename dtype, typename SizeType, typename PointerType, typename DifferenceType>
817  class NdArrayColumnIterator : public NdArrayConstColumnIterator<dtype, SizeType, PointerType, DifferenceType>
818  {
819  private:
822 
823  public:
824  using iterator_category = std::random_access_iterator_tag;
825  using value_type = dtype;
826  using size_type = SizeType;
827  using pointer = PointerType;
829  using difference_type = DifferenceType;
830 
831  using MyBase::MyBase;
832 
833  //============================================================================
834  // Method Description:
839  reference operator*() const noexcept
840  {
841  return const_cast<reference>(MyBase::operator*());
842  }
843 
844  //============================================================================
845  // Method Description:
850  pointer operator->() const noexcept
851  {
852  return const_cast<pointer>(MyBase::operator->());
853  }
854 
855  //============================================================================
856  // Method Description:
861  self_type& operator++() noexcept
862  {
864  return *this;
865  }
866 
867  //============================================================================
868  // Method Description:
873  self_type operator++(int) noexcept
874  {
875  self_type tmp = *this;
877  return tmp;
878  }
879 
880  //============================================================================
881  // Method Description:
886  self_type& operator--() noexcept
887  {
889  return *this;
890  }
891 
892  //============================================================================
893  // Method Description:
898  self_type operator--(int) noexcept
899  {
900  self_type tmp = *this;
902  return tmp;
903  }
904 
905  //============================================================================
906  // Method Description:
912  self_type& operator+=(const difference_type offset) noexcept
913  {
914  MyBase::operator+=(offset);
915  return *this;
916  }
917 
918  //============================================================================
919  // Method Description:
925  self_type operator+(const difference_type offset) const noexcept
926  {
927  self_type tmp = *this;
928  return tmp += offset;
929  }
930 
931  //============================================================================
932  // Method Description:
938  self_type& operator-=(const difference_type offset) noexcept
939  {
940  MyBase::operator-=(offset);
941  return *this;
942  }
943 
944  using MyBase::operator-;
945 
946  //============================================================================
947  // Method Description:
953  self_type operator-(const difference_type offset) const noexcept
954  {
955  self_type tmp = *this;
956  return tmp -= offset;
957  }
958 
959  //============================================================================
960  // Method Description:
966  reference operator[](const difference_type offset) const noexcept
967  {
968  return const_cast<reference>(MyBase::operator[](offset));
969  }
970  };
971 
972  //============================================================================
973  // Method Description:
980  template<class dtype, typename SizeType, typename PointerType, typename DifferenceType>
981  NdArrayColumnIterator<dtype, SizeType, PointerType, DifferenceType>
984  {
985  return next += offset;
986  }
987 } // namespace nc
#define THROW_RUNTIME_ERROR(msg)
Definition: Error.hpp:38
Custom column iterator for NdArray.
Definition: NdArrayIterators.hpp:818
self_type & operator--() noexcept
Definition: NdArrayIterators.hpp:886
self_type operator++(int) noexcept
Definition: NdArrayIterators.hpp:873
reference operator[](const difference_type offset) const noexcept
Definition: NdArrayIterators.hpp:966
self_type operator-(const difference_type offset) const noexcept
Definition: NdArrayIterators.hpp:953
self_type operator+(const difference_type offset) const noexcept
Definition: NdArrayIterators.hpp:925
self_type & operator-=(const difference_type offset) noexcept
Definition: NdArrayIterators.hpp:938
self_type operator--(int) noexcept
Definition: NdArrayIterators.hpp:898
self_type & operator++() noexcept
Definition: NdArrayIterators.hpp:861
self_type & operator+=(const difference_type offset) noexcept
Definition: NdArrayIterators.hpp:912
DifferenceType difference_type
Definition: NdArrayIterators.hpp:829
pointer operator->() const noexcept
Definition: NdArrayIterators.hpp:850
reference operator*() const noexcept
Definition: NdArrayIterators.hpp:839
Custom column const_iterator for NdArray.
Definition: NdArrayIterators.hpp:492
self_type operator+(const difference_type offset) const noexcept
Definition: NdArrayIterators.hpp:617
pointer operator->() const noexcept
Definition: NdArrayIterators.hpp:544
reference operator[](const difference_type offset) const noexcept
Definition: NdArrayIterators.hpp:667
dtype value_type
Definition: NdArrayIterators.hpp:498
std::random_access_iterator_tag iterator_category
Definition: NdArrayIterators.hpp:497
PointerType pointer
Definition: NdArrayIterators.hpp:500
self_type operator--(int) noexcept
Definition: NdArrayIterators.hpp:590
difference_type operator-(const self_type &rhs) const noexcept
Definition: NdArrayIterators.hpp:655
const value_type & reference
Definition: NdArrayIterators.hpp:501
self_type operator-(const difference_type offset) const noexcept
Definition: NdArrayIterators.hpp:642
bool operator>(const self_type &rhs) const noexcept
Definition: NdArrayIterators.hpp:715
self_type operator++(int) noexcept
Definition: NdArrayIterators.hpp:566
bool operator<=(const self_type &rhs) const noexcept
Definition: NdArrayIterators.hpp:727
self_type & operator--() noexcept
Definition: NdArrayIterators.hpp:579
bool operator>=(const self_type &rhs) const noexcept
Definition: NdArrayIterators.hpp:739
SizeType size_type
Definition: NdArrayIterators.hpp:499
self_type & operator+=(const difference_type offset) noexcept
Definition: NdArrayIterators.hpp:604
bool operator<(const self_type &rhs) const noexcept
Definition: NdArrayIterators.hpp:703
reference operator*() const noexcept
Definition: NdArrayIterators.hpp:533
DifferenceType difference_type
Definition: NdArrayIterators.hpp:502
self_type & operator++() noexcept
Definition: NdArrayIterators.hpp:555
bool operator!=(const self_type &rhs) const noexcept
Definition: NdArrayIterators.hpp:691
bool operator==(const self_type &rhs) const noexcept
Definition: NdArrayIterators.hpp:679
self_type & operator-=(const difference_type offset) noexcept
Definition: NdArrayIterators.hpp:630
NdArrayConstColumnIterator(pointer ptr, SizeType numRows, SizeType numCols) noexcept
Definition: NdArrayIterators.hpp:518
Custom const_iterator for NdArray.
Definition: NdArrayIterators.hpp:42
bool operator>=(const self_type &rhs) const noexcept
Definition: NdArrayIterators.hpp:288
DifferenceType difference_type
Definition: NdArrayIterators.hpp:51
bool operator<=(const self_type &rhs) const noexcept
Definition: NdArrayIterators.hpp:276
std::random_access_iterator_tag iterator_category
Definition: NdArrayIterators.hpp:47
pointer operator->() const noexcept
Definition: NdArrayIterators.hpp:91
self_type operator++(int) noexcept
Definition: NdArrayIterators.hpp:114
PointerType pointer
Definition: NdArrayIterators.hpp:49
self_type operator-(const difference_type offset) const noexcept
Definition: NdArrayIterators.hpp:191
self_type operator--(int) noexcept
Definition: NdArrayIterators.hpp:139
self_type operator+(const difference_type offset) const noexcept
Definition: NdArrayIterators.hpp:166
self_type & operator--() noexcept
Definition: NdArrayIterators.hpp:127
bool operator<(const self_type &rhs) const noexcept
Definition: NdArrayIterators.hpp:252
reference operator[](const difference_type offset) const noexcept
Definition: NdArrayIterators.hpp:216
bool operator>(const self_type &rhs) const noexcept
Definition: NdArrayIterators.hpp:264
NdArrayConstIterator(pointer ptr)
Definition: NdArrayIterators.hpp:65
bool operator!=(const self_type &rhs) const noexcept
Definition: NdArrayIterators.hpp:240
self_type & operator-=(const difference_type offset) noexcept
Definition: NdArrayIterators.hpp:179
difference_type operator-(const self_type &rhs) const noexcept
Definition: NdArrayIterators.hpp:204
const value_type & reference
Definition: NdArrayIterators.hpp:50
bool operator==(const self_type &rhs) const noexcept
Definition: NdArrayIterators.hpp:228
reference operator*() const noexcept
Definition: NdArrayIterators.hpp:80
self_type & operator++() noexcept
Definition: NdArrayIterators.hpp:102
self_type & operator+=(const difference_type offset) noexcept
Definition: NdArrayIterators.hpp:153
dtype value_type
Definition: NdArrayIterators.hpp:48
Custom iterator for NdArray.
Definition: NdArrayIterators.hpp:318
self_type operator++(int) noexcept
Definition: NdArrayIterators.hpp:372
self_type & operator-=(const difference_type offset) noexcept
Definition: NdArrayIterators.hpp:437
self_type & operator--() noexcept
Definition: NdArrayIterators.hpp:385
reference operator[](const difference_type offset) const noexcept
Definition: NdArrayIterators.hpp:465
DifferenceType difference_type
Definition: NdArrayIterators.hpp:328
self_type operator-(const difference_type offset) const noexcept
Definition: NdArrayIterators.hpp:452
pointer operator->() const noexcept
Definition: NdArrayIterators.hpp:349
self_type operator+(const difference_type offset) const noexcept
Definition: NdArrayIterators.hpp:424
self_type & operator++() noexcept
Definition: NdArrayIterators.hpp:360
self_type operator--(int) noexcept
Definition: NdArrayIterators.hpp:397
reference operator*() const noexcept
Definition: NdArrayIterators.hpp:338
self_type & operator+=(const difference_type offset) noexcept
Definition: NdArrayIterators.hpp:411
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:307