20struct interleaved :
public std::ranges::view_interface<interleaved<Stride, ScalarType>> {
21 using intrinsic_type = simd::Vec128_t<ScalarType>;
22 static constexpr size_t lanes =
sizeof(intrinsic_type) /
sizeof(ScalarType);
23 static constexpr size_t vectorizeable_size(
size_t size) {
return size & ~(lanes - 1); }
27 using iterator_category = std::forward_iterator_tag;
29 using value_type = std::array<argon_type, Stride>;
30 using difference_type = std::ptrdiff_t;
33 Iterator(ScalarType* ptr) : ptr{ptr}, vec{argon_type::template LoadInterleaved<Stride>(ptr)} {}
35 value_type& operator*() {
return vec; }
36 value_type* operator->() {
return &vec; }
37 const value_type& operator*()
const {
return vec; }
38 const value_type* operator->()
const {
return &vec; }
39 Iterator& operator++() {
42 vec = argon_type::template LoadInterleaved<Stride>(ptr);
46 Iterator operator++(
int) {
52 friend bool operator==(
const Iterator& a,
const Iterator& b) {
return a.ptr == b.ptr; }
53 friend bool operator==(
const Iterator& a,
const ScalarType* ptr) {
return a.ptr == ptr; }
54 friend bool operator!=(
const Iterator& a,
const Iterator& b) {
return a.ptr != b.ptr; }
55 friend bool operator!=(
const Iterator& a,
const ScalarType* ptr) {
return a.ptr != ptr; }
58 ScalarType* ptr =
nullptr;
61 static_assert(std::input_or_output_iterator<Iterator>);
62 struct ConstIterator {
63 using iterator_category = std::forward_iterator_tag;
65 using value_type = std::array<argon_type, Stride>;
66 using difference_type = std::ptrdiff_t;
68 ConstIterator() =
default;
69 ConstIterator(
const ScalarType* ptr) : ptr{ptr}, vec{argon_type::template LoadInterleaved<Stride>(ptr)} {}
71 const value_type operator*()
const {
return vec; }
72 ConstIterator& operator++() {
74 vec = argon_type::template LoadInterleaved<Stride>(ptr);
77 ConstIterator operator++(
int) {
78 ConstIterator tmp = *
this;
82 friend bool operator==(
const ConstIterator& a,
const ConstIterator& b) {
return a.ptr == b.ptr; }
83 friend bool operator!=(
const ConstIterator& a,
const ConstIterator& b) {
return a.ptr != b.ptr; }
86 const ScalarType* ptr =
nullptr;
89 static_assert(std::input_iterator<ConstIterator>);
94 interleaved(ScalarType* start, ScalarType* end) : start_{start}, size_{vectorizeable_size(end - start)} {};
95 interleaved(ScalarType* start,
const size_t size) : start_{start}, size_{vectorizeable_size(size)} {};
96 interleaved(
const std::span<ScalarType> span) : start_{span.data()}, size_{vectorizeable_size(span.size())} {};
98 template <
size_t, std::ranges::contiguous_range R>
99 interleaved(R&& r) : start_{
std::ranges::begin(r)}, size_{vectorizeable_size(
std::ranges::size(r))} {}
101 iterator begin()
const {
return Iterator(start_); }
102 const ScalarType* end()
const {
return start_ + size_; }
103 const_iterator cbegin()
const {
return ConstIterator(start_); }
104 const ScalarType* cend()
const {
return start_ + size_; }
105 size_t size()
const {
return size_; }