cortexlib  v0.2.0
normal.hxx
Go to the documentation of this file.
1 // -*- C++ -*- Header compatibility <normal.hxx>
2 
16 
17 #ifndef CORTEX_NORMAL_ITERATOR
18 # define CORTEX_NORMAL_ITERATOR
19 
20 #include <iterator>
21 #include <ranges>
22 #include <type_traits>
23 #include <utility>
24 
25 #if __cpp_lib_three_way_comparison
26 # include <compare>
27 #endif //< __cpp_lib_three_way_comparison
28 
29 #if __cpp_concepts >= 201907L
30 # include <concepts>
31 #endif //< __cpp_concepts >= 201907L
32 
33 namespace cxl
34 {
46  template<typename Iterator, typename Container>
48  {
49  protected:
50  Iterator current;
51 
52  using iter_traits_type = std::iterator_traits<Iterator>;
53 
54  public:
55  using iterator_type = Iterator;
56  using iterator_category = typename iter_traits_type::iterator_category;
57 
58 # if __cpp_concepts >= 201907L
59  using iterator_concept = std::conditional_t<
60  std::random_access_iterator<Iterator>,
61  std::random_access_iterator_tag,
62  std::conditional_t<
63  std::bidirectional_iterator<Iterator>,
64  std::bidirectional_iterator_tag,
65  std::conditional_t<
66  std::forward_iterator<Iterator>,
67  std::forward_iterator_tag,
68  std::conditional_t<std::input_iterator<Iterator>,
69  std::input_iterator_tag,
70  std::output_iterator_tag>>>>;
71 # endif //< __cpp_concepts >= 201907L
72 
73  using value_type = typename iter_traits_type::value_type;
74  using difference_type = typename iter_traits_type::difference_type;
75  using pointer = typename iter_traits_type::pointer;
76  using reference = typename iter_traits_type::reference;
77 
78 public:
83  constexpr
84  normal_iterator() noexcept
85  : current{ Iterator{} }
86  { }
87 
97  template<typename Iter>
98  requires std::convertible_to<Iter, Iterator>
99  constexpr
101  : current{ other.base() }
102  { }
103 
112  constexpr
113  normal_iterator(const iterator_type& other) noexcept
114  : current{ other }
115  { }
116 
117 
124  constexpr auto
125  operator* () noexcept -> reference
126  { return *current; }
127 
134  constexpr auto
135  operator* () const noexcept -> reference
136  { return *current; }
137 
146  constexpr auto
147  operator->() noexcept -> pointer
148 # if __cplusplus > 201703L && __cpp_concepts >= 201907L
149  requires std::is_pointer_v<iterator_type> ||
150  requires (const iterator_type i) { i.operator->(); }
151 # endif //< __cplusplus > 201703L && __cpp_concepts >= 201907L
152  { return _S_to_pointer(current); }
153 
162  constexpr auto
163  operator->() const noexcept -> pointer
164 # if __cplusplus > 201703L && __cpp_concepts >= 201907L
165  requires std::is_pointer_v<iterator_type> ||
166  requires (const iterator_type i) { i.operator->(); }
167 # endif //< __cplusplus > 201703L && __cpp_concepts >= 201907L
168  { return _S_to_pointer(current); }
169 
176  constexpr auto
177  operator++ () noexcept -> normal_iterator&
178  {
179  ++current;
180  return *this;
181  }
182 
192  constexpr auto
193  operator++ (int) noexcept -> normal_iterator
194  { return normal_iterator(current++); }
195 
202  constexpr auto
203  operator-- () noexcept -> normal_iterator&
204  {
205  --current;
206  return *this;
207  }
208 
218  constexpr auto
219  operator-- (int) noexcept -> normal_iterator
220  { return normal_iterator(current--); }
221 
230  constexpr auto
232  { return current[n]; }
233 
242  constexpr auto
244  -> normal_iterator&
245  {
246  current += step;
247  return *this;
248  }
249 
258  constexpr auto
260  -> normal_iterator&
261  {
262  current -= step;
263  return *this;
264  }
265 
273  constexpr auto
274  operator+ (difference_type step) const noexcept
275  -> normal_iterator
276  { return normal_iterator(current + step); }
277 
285  constexpr auto
286  operator- (difference_type step) const noexcept
287  -> normal_iterator
288  { return normal_iterator(current - step); }
289 
295  constexpr auto
296  base() const noexcept -> iterator_type
297  { return current; }
298 
299  private:
313  template<typename P>
314  static constexpr auto
315  _S_to_pointer(P* ptr) -> P*
316  { return ptr; }
317 
330  template<typename P>
331  static constexpr auto
332  _S_to_pointer(P obj) -> pointer
333  { return obj.operator->(); }
334 
335  }; //< class normal_iterator
336 
337 # if __cpp_lib_three_way_comparison //< C++20
338 
354  template<typename IterL, typename IterR, typename Container>
355  requires requires (IterL lhsI, IterR rhsI)
356  { { lhsI == rhsI } -> std::convertible_to<bool>; }
357  constexpr auto
358  operator== (const normal_iterator<IterL, Container>& lhs,
359  const normal_iterator<IterR, Container>& rhs)
360  noexcept(noexcept(lhs.base() == rhs.base())) -> bool
361  { return lhs.base() == rhs.base(); }
362 
379  template<typename IterL, typename IterR, typename Container>
380  requires std::three_way_comparable_with<IterL, IterR, std::weak_ordering>
381  constexpr auto
382  operator<=> (const normal_iterator<IterL, Container>& lhs,
383  const normal_iterator<IterR, Container>& rhs)
384  noexcept(noexcept(lhs.base() <=> rhs.base())) -> std::weak_ordering
385  { return lhs.base() <=> rhs.base(); }
386 
387 # else //< __cpp_lib_three_way_comparison -> C++20
388 
403  template<typename IterL, typename IterR, typename Container>
404  constexpr inline auto
407  noexcept(noexcept(lhs.base() == rhs.base())) -> bool
408  { return lhs.base() == rhs.base(); }
409 
422  template<typename Iterator, typename Container>
423  constexpr inline auto
426  noexcept(noexcept(lhs.base() == rhs.base())) -> bool
427  { return lhs.base() == rhs.base(); }
428 
443  template<typename IterL, typename IterR, typename Container>
444  constexpr inline auto
447  noexcept(noexcept(lhs.base() != rhs.base())) -> bool
448  { return lhs.base() != rhs.base(); }
449 
462  template<typename Iterator, typename Container>
463  constexpr inline auto
466  noexcept(noexcept(lhs.base() != rhs.base())) -> bool
467  { return lhs.base() != rhs.base(); }
468 
483  template<typename IterL, typename IterR, typename Container>
484  constexpr inline auto
487  noexcept(noexcept(lhs.base() < rhs.base())) -> bool
488  { return lhs.base() < rhs.base(); }
489 
502  template<typename Iterator, typename Container>
503  constexpr inline auto
506  noexcept(noexcept(lhs.base() < rhs.base())) -> bool
507  { return lhs.base() < rhs.base(); }
508 
523  template<typename IterL, typename IterR, typename Container>
524  constexpr inline auto
527  noexcept(noexcept(lhs.base() > rhs.base())) -> bool
528  { return lhs.base() > rhs.base(); }
529 
542  template<typename Iterator, typename Container>
543  constexpr inline auto
546  noexcept(noexcept(lhs.base() > rhs.base())) -> bool
547  { return lhs.base() > rhs.base(); }
548 
563  template<typename IterL, typename IterR, typename Container>
564  constexpr inline auto
567  noexcept(noexcept(lhs.base() <= rhs.base())) -> bool
568  { return lhs.base() <= rhs.base(); }
569 
582  template<typename Iterator, typename Container>
583  constexpr inline auto
586  noexcept(noexcept(lhs.base() <= rhs.base())) -> bool
587  { return lhs.base() <= rhs.base(); }
588 
603  template<typename IterL, typename IterR, typename Container>
604  constexpr inline auto
607  noexcept(noexcept(lhs.base() >= rhs.base())) -> bool
608  { return lhs.base() >= rhs.base(); }
609 
622  template<typename Iterator, typename Container>
623  constexpr inline bool
626  noexcept(noexcept(lhs.base() >= rhs.base())) ->bool
627  { return lhs.base() >= rhs.base(); }
628 
629 # endif //< __cpp_lib_three_way_comparison
630 
648  template<typename IterL, typename IterR, typename Container>
649 # if __cplusplus >= 201103L
650  constexpr inline auto
651  operator- (const normal_iterator<IterL, Container>& lhs,
652  const normal_iterator<IterR, Container>& rhs)
653  noexcept(noexcept(lhs.base() - rhs.base()))
654  -> decltype(lhs.base() - rhs.base())
655 # else
659 # endif //< __cplusplus >= 201103L
660  { return lhs.base() - rhs.base(); }
661 
674  template<typename Iterator, typename Container>
675 # if __cplusplus >= 201103L
676  constexpr inline auto
677  operator- (const normal_iterator<Iterator, Container>& lhs,
678  const normal_iterator<Iterator, Container>& rhs)
679  noexcept(noexcept(lhs.base() - rhs.base()))
680  -> decltype(lhs.base() - rhs.base())
681 # else //< ! C++11
682  inline
686 # endif //< __cplusplus >= 201103L
687  { return lhs.base() - rhs.base(); }
688 
701  template<typename Iterator, typename Container>
702  constexpr inline auto
704  const normal_iterator<Iterator, Container>& i) noexcept
706  { return normal_iterator<Iterator, Container>(i.base() + n); }
707 
718  template<typename Container>
719  constexpr auto
720  make_normal_iterator(typename Container::iterator i) noexcept
723 
734  template<typename Iterator, typename Container>
735  constexpr auto
736  make_normal_iterator(Iterator i) noexcept
739 
740 } //< namespace cxl
741 
742 namespace std
743 {
744 
753  template<typename Iterator, typename Container>
754  constexpr auto
756  noexcept(
757  is_nothrow_copy_constructible_v<Iterator>
758  && noexcept(ranges::iter_move(declval<Iterator&>()))
759  ) -> iter_rvalue_reference_t<Iterator>
760  { return ranges::iter_move(i.base()); }
761 
773  template<typename Iterator, std::indirectly_swappable<Iterator> Iter2, typename Container>
774  constexpr auto
777  noexcept(
778  std::is_nothrow_copy_constructible_v<Iterator>
779  && std::is_nothrow_copy_constructible_v<Iter2>
780  && noexcept(ranges::iter_swap(std::declval<Iterator&>(), std::declval<Iter2&>()))
781  ) -> void
782  { ranges::iter_swap(x.base(), y.base()); }
783 
784 } //< namespace std
785 
786 #endif //< CORTEX_NORMAL_ITERATOR
Normal Iterator.
Definition: normal.hxx:48
constexpr auto operator+(difference_type step) const noexcept -> normal_iterator
Addition Operator Overload.
Definition: normal.hxx:274
constexpr auto operator->() const noexcept -> pointer
Arrow Deference Operator Overload.
Definition: normal.hxx:163
typename iter_traits_type::iterator_category iterator_category
Definition: normal.hxx:56
constexpr auto operator*() noexcept -> reference
Dereference Operator Overload.
Definition: normal.hxx:125
constexpr auto operator-=(difference_type step) noexcept -> normal_iterator &
Subtraction Assignment Operator Overload.
Definition: normal.hxx:259
typename iter_traits_type::difference_type difference_type
Definition: normal.hxx:74
requires constexpr std::convertible_to< Iter, Iterator > normal_iterator(const normal_iterator< Iter, Container > &other) noexcept
Converting Copy Constructor.
Definition: normal.hxx:100
std::iterator_traits< Iterator > iter_traits_type
Definition: normal.hxx:52
Iterator current
Definition: normal.hxx:50
constexpr auto operator[](difference_type n) noexcept -> reference
Subscript Operator Overload.
Definition: normal.hxx:231
constexpr auto operator->() noexcept -> pointer
Arrow Deference Operator Overload.
Definition: normal.hxx:147
constexpr auto operator-(difference_type step) const noexcept -> normal_iterator
Subtraction Operator Overload.
Definition: normal.hxx:286
constexpr auto operator++() noexcept -> normal_iterator &
Prefix Increment Operator Overload.
Definition: normal.hxx:177
typename iter_traits_type::value_type value_type
Definition: normal.hxx:73
constexpr auto operator+=(difference_type step) noexcept -> normal_iterator &
Additive Assignment Operator Overload.
Definition: normal.hxx:243
constexpr normal_iterator() noexcept
Default Constructor.
Definition: normal.hxx:84
typename iter_traits_type::pointer pointer
Definition: normal.hxx:75
typename iter_traits_type::reference reference
Definition: normal.hxx:76
constexpr auto operator--() noexcept -> normal_iterator &
Prefix Decrement Operator Overload.
Definition: normal.hxx:203
Iterator iterator_type
Definition: normal.hxx:55
constexpr auto base() const noexcept -> iterator_type
Base Member Access.
Definition: normal.hxx:296
constexpr normal_iterator(const iterator_type &other) noexcept
Iterator Copy Constructor.
Definition: normal.hxx:113
Definition: matrix.hxx:30
constexpr auto operator+(typename normal_iterator< Iterator, Container >::difference_type n, const normal_iterator< Iterator, Container > &i) noexcept -> normal_iterator< Iterator, Container >
Addition Operator Overload.
Definition: normal.hxx:703
requires requires(ElemL lhsE, ElemR rhsE)
Compares two Matrices for equality.
Definition: matrix.hxx:1262
constexpr auto operator<(const normal_iterator< IterL, Container > &lhs, const normal_iterator< IterR, Container > &rhs) noexcept(noexcept(lhs.base()< rhs.base())) -> bool
Less-than Operator Overload.
Definition: normal.hxx:485
constexpr auto operator!=(const normal_iterator< IterL, Container > &lhs, const normal_iterator< IterR, Container > &rhs) noexcept(noexcept(lhs.base() !=rhs.base())) -> bool
Inequality Operator Overload.
Definition: normal.hxx:445
normal_iterator< IterL, Container >::difference_type operator-(const normal_iterator< IterL, Container > &lhs, const normal_iterator< IterR, Container > &rhs)
Difference Operator Overload.
Definition: normal.hxx:657
constexpr auto operator<=>(const matrix< ElemL > &lhs, const matrix< ElemR > &rhs)
Spaceship Operator for matrix.
Definition: matrix.hxx:1288
constexpr auto operator==(const matrix< ElemL > &lhs, const matrix< ElemR > &rhs) noexcept(noexcept(std::declval< ElemL >()==std::declval< ElemR >()) &&noexcept(std::ranges::equal(lhs, rhs))) -> bool
Definition: matrix.hxx:1266
constexpr auto make_normal_iterator(typename Container::iterator i) noexcept -> normal_iterator< typename Container::iterator, Container >
Makes a new normal_iterator.
Definition: normal.hxx:720
constexpr auto operator>=(const normal_iterator< IterL, Container > &lhs, const normal_iterator< IterR, Container > &rhs) noexcept(noexcept(lhs.base() >=rhs.base())) -> bool
Greater-than-or-Equal Operator Overload.
Definition: normal.hxx:605
constexpr auto operator>(const normal_iterator< IterL, Container > &lhs, const normal_iterator< IterR, Container > &rhs) noexcept(noexcept(lhs.base() > rhs.base())) -> bool
Greater-than Operator Overload.
Definition: normal.hxx:525
constexpr auto operator<=(const normal_iterator< IterL, Container > &lhs, const normal_iterator< IterR, Container > &rhs) noexcept(noexcept(lhs.base()<=rhs.base())) -> bool
Less-than-or-Equal Operator Overload.
Definition: normal.hxx:565
Definition: matrix.hxx:1310
constexpr auto iter_swap(const cxl::normal_iterator< Iterator, Container > &x, const cxl::normal_iterator< Iter2, Container > &y) noexcept(std::is_nothrow_copy_constructible_v< Iterator > &&std::is_nothrow_copy_constructible_v< Iter2 > &&noexcept(ranges::iter_swap(std::declval< Iterator & >(), std::declval< Iter2 & >()))) -> void
Swaps iterator objects.
Definition: normal.hxx:775
constexpr auto iter_move(const cxl::normal_iterator< Iterator, Container > &i) noexcept(is_nothrow_copy_constructible_v< Iterator > &&noexcept(ranges::iter_move(declval< Iterator & >()))) -> iter_rvalue_reference_t< Iterator >
rvalue cast
Definition: normal.hxx:755