8#include "arm_simd/helpers/vec128.hpp"
10#ifdef __ARM_FEATURE_MVE
16namespace argon::vectorize {
18template <
size_t Str
ide,
typename ScalarType>
19struct interleaved :
public std::ranges::view_interface<interleaved<Stride, ScalarType>> {
20 using intrinsic_type = simd::Vec128_t<ScalarType>;
21 static constexpr size_t lanes =
sizeof(intrinsic_type) /
sizeof(ScalarType);
23 static constexpr size_t vectorizeable_size(
size_t size) {
return size - (size % (lanes * Stride)); }
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++() {
40 argon::store_interleaved(ptr, vec);
41 ptr += lanes * Stride;
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++() {
73 ptr += lanes * Stride;
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 iterator begin()
const {
return Iterator(start_); }
99 const ScalarType* end()
const {
return start_ + size_; }
100 const_iterator cbegin()
const {
return ConstIterator(start_); }
101 const ScalarType* cend()
const {
return start_ + size_; }
102 size_t size()
const {
return size_; }
115#if !defined(_MSC_VER) || defined(__clang__)
116static_assert(std::ranges::range<interleaved<3, int32_t>>);
117static_assert(std::ranges::view<interleaved<3, int32_t>>);
118static_assert(std::movable<interleaved<3, int32_t>>);
119static_assert(std::ranges::viewable_range<interleaved<3, int32_t>>);
A 128-bit SIMD vector wrapping a scalar type, providing arithmetic, logical, and data-movement operat...
Definition argon_full.hpp:29
Definition interleaved.hpp:62
Definition interleaved.hpp:26
Definition interleaved.hpp:19