11#pragma once
22#include " ./concepts.hpp"
3+ #include " ./mem/alignment.hpp"
34
45#include < iterator>
56#include < utility>
7+ #include < tuple>
8+ #include < algorithm>
69
710namespace nda {
811 template <MemoryArray A>
@@ -24,9 +27,11 @@ namespace nda {
2427
2528 size_t index;
2629
27- packed_iterator ( const pointer data_ptr, const std:: size_t idx) : data(data_ptr), index(idx) {}
30+ size_t last_index;
2831
29- std::pair<simd_t , pointer> operator *() const {
32+ packed_iterator (const pointer data_ptr, const size_t idx, const size_t last_idx) : data(data_ptr), index(idx), last_index(last_idx) {}
33+
34+ std::tuple<simd_t , pointer, size_t > operator *() const noexcept {
3035 // Valid field counts= let j be the fastest dimension: let p be the padding. simd_size
3136 // (index + simd_size) % lengths[j] (index = 0 lengths[j] = 10, then valid_fields = 8;, index 8 lengtsah[j] = 10
3237 // ((lengths[j] - (index + simd_size + (lengths[j] / (index))^-1 * padding) % lengths[j]) % lengths[j])
@@ -35,64 +40,68 @@ namespace nda {
3540 // 8 + 8 - 10
3641 // 16 + 8 - 10 * 2 - 6
3742 if constexpr (aligned_and_padded) {
38- return {simd_t (data + index), data + index};
43+ return {simd_t (data + index), data + index, std::min ( simd_t::size (), last_index - index) };
3944 } else {
4045 simd_t tmp;
4146 tmp.load_unaligned (data + index);
42- return {tmp, data + index};
47+ return {tmp, data + index, std::min ( simd_t::size (), last_index - index) };
4348 }
4449 }
4550
46- pointer operator ->() const { return data + index; }
51+ pointer operator ->() const noexcept { return data + index; }
4752
48- packed_iterator &operator ++() {
53+ packed_iterator &operator ++() noexcept {
4954 index += simd_t::size ();
5055 return *this ;
5156 }
5257
53- packed_iterator operator ++(int ) {
58+ packed_iterator operator ++(int ) noexcept {
5459 packed_iterator tmp = *this ;
5560 index += simd_t::size ();
5661 return tmp;
5762 }
5863
59- packed_iterator &operator --() {
64+ packed_iterator &operator --() noexcept {
6065 index -= simd_t::size ();
6166 return *this ;
6267 }
6368
64- packed_iterator operator --(int ) {
69+ packed_iterator operator --(int ) noexcept {
6570 packed_iterator tmp = *this ;
6671 index -= simd_t::size ();
6772 return tmp;
6873 }
6974
70- packed_iterator &operator +=(std::ptrdiff_t n) {
75+ packed_iterator &operator +=(std::ptrdiff_t n) noexcept {
7176 index += n * simd_t::size ();
7277 return *this ;
7378 }
7479
75- packed_iterator &operator -=(std::ptrdiff_t n) {
80+ packed_iterator &operator -=(std::ptrdiff_t n) noexcept {
7681 index -= n * simd_t::size ();
7782 return *this ;
7883 }
7984
80- packed_iterator operator +(std::ptrdiff_t n) const { return packed_iterator (data, index + n * simd_t::size ()); }
81- packed_iterator operator -(std::ptrdiff_t n) const { return packed_iterator (data, index - n * simd_t::size ()); }
82- std::ptrdiff_t operator -(const packed_iterator &other) const { return (index - other.index ) / simd_t::size (); }
83- std::pair<simd_t , pointer> operator [](std::ptrdiff_t n) const {
84- return {simd_t (data + index + n * simd_t::size ()), data + index + n * simd_t::size ()};
85+ packed_iterator operator +(std::ptrdiff_t n) const noexcept { return packed_iterator (data, index + n * simd_t::size ()); }
86+ packed_iterator operator -(std::ptrdiff_t n) const noexcept { return packed_iterator (data, index - n * simd_t::size ()); }
87+ std::ptrdiff_t operator -(const packed_iterator &other) const noexcept { return (index - other.index ) / simd_t::size (); }
88+ std::tuple<simd_t , pointer, size_t > operator [](std::ptrdiff_t n) const noexcept {
89+ return {simd_t (data + index + n * simd_t::size ()), data + index + n * simd_t::size (),
90+ std::min (simd_t::size (), last_index - index + n * simd_t::size ())};
8591 }
8692
87- bool operator ==(const packed_iterator &other) const { return index == other.index ; }
88- bool operator !=(const packed_iterator &other) const { return !(*this == other); }
89- bool operator <(const packed_iterator &other) const { return index < other.index ; }
90- bool operator >(const packed_iterator &other) const { return index > other.index ; }
91- bool operator <=(const packed_iterator &other) const { return index <= other.index ; }
92- bool operator >=(const packed_iterator &other) const { return index >= other.index ; }
93+ bool operator ==(const packed_iterator &other) const noexcept { return index == other.index ; }
94+ bool operator !=(const packed_iterator &other) const noexcept { return !(*this == other); }
95+ bool operator <(const packed_iterator &other) const noexcept { return index < other.index ; }
96+ bool operator >(const packed_iterator &other) const noexcept { return index > other.index ; }
97+ bool operator <=(const packed_iterator &other) const noexcept { return index <= other.index ; }
98+ bool operator >=(const packed_iterator &other) const noexcept { return index >= other.index ; }
9399 };
94100
95- packed_iterator begin () { return packed_iterator (array.data (), 0 ); }
96- packed_iterator end () { return packed_iterator (array.data (), array.indexmap ().capacity ()); }
101+ packed_iterator begin () const noexcept { return packed_iterator (array.data (), 0 , array.indexmap ().capacity ()); }
102+ packed_iterator end () const noexcept {
103+ return packed_iterator (array.data (), mem::next_multiple (array.indexmap ().capacity (), native_simd<std::remove_cvref_t <get_value_t <A>>>::size ()),
104+ array.indexmap ().capacity ());
105+ }
97106 };
98107} // namespace nda
0 commit comments