28 #ifndef VC_COMMON_ITERATORS_H_
29 #define VC_COMMON_ITERATORS_H_
37 #include "elementreference.h"
40 namespace Vc_VERSIONED_NAMESPACE
46 template<
typename _V,
typename Flags>
class MemoryVectorIterator;
48 template <
typename V>
class Iterator;
49 template <
typename V,
bool>
class IteratorBase;
50 template <
typename V>
class IteratorBase<V, true>
53 using iterator_category = std::input_iterator_tag;
54 using value_type =
typename V::value_type;
55 using difference_type = int;
56 using reference = value_type;
57 Vc_ALWAYS_INLINE reference
operator*()
const {
return v()[i()]; }
58 Vc_ALWAYS_INLINE reference operator[](difference_type i2)
const {
return v()[i2]; }
61 Vc_INTRINSIC V &v()
const {
return *
static_cast<const Iterator<V> *
>(
this)->v; }
62 Vc_INTRINSIC difference_type i()
const
64 return static_cast<const Iterator<V> *
>(
this)->i;
68 template <
typename V>
class IteratorBase<V, false>
71 using iterator_category = std::input_iterator_tag;
72 using value_type =
typename V::value_type;
73 using difference_type = int;
74 using reference = Vc::Detail::ElementReference<V, IteratorBase>;
75 Vc_ALWAYS_INLINE reference
operator*()
const {
return {*v(), i()}; }
76 Vc_ALWAYS_INLINE reference operator[](difference_type i2)
const {
return {*v(), i2}; }
79 Vc_INTRINSIC V *v()
const {
return static_cast<const Iterator<V> *
>(
this)->v; }
80 Vc_INTRINSIC difference_type i()
const
82 return static_cast<const Iterator<V> *
>(
this)->i;
86 static Vc_INTRINSIC value_type
get(
const V &o,
int i)
90 template <
typename T>
static Vc_INTRINSIC
void set(V &o,
int i, T &&v)
92 o[i] = std::forward<T>(v);
97 template <
typename V>
class Iterator :
public IteratorBase<V, std::is_const<V>::value>
99 using Base = IteratorBase<V, std::is_const<V>::value>;
103 using typename Base::iterator_category;
104 using typename Base::value_type;
105 using typename Base::difference_type;
106 using pointer =
const Iterator *;
107 using typename Base::reference;
109 constexpr Iterator() =
default;
110 constexpr Iterator(V &_v, difference_type _i) : v(&_v), i(_i) {}
113 Vc_ALWAYS_INLINE pointer operator->()
const {
return this; }
114 using Base::operator*;
116 Vc_ALWAYS_INLINE Iterator &operator++() { ++i;
return *
this; }
117 Vc_ALWAYS_INLINE Iterator operator++(
int) { Iterator tmp = *
this; ++i;
return tmp; }
120 Vc_ALWAYS_INLINE Iterator &operator--() { --i;
return *
this; }
121 Vc_ALWAYS_INLINE Iterator operator--(
int) { Iterator tmp = *
this; --i;
return tmp; }
124 using Base::operator[];
125 Vc_ALWAYS_INLINE Iterator &operator+=(difference_type d) { i += d;
return *
this; }
126 Vc_ALWAYS_INLINE Iterator &operator-=(difference_type d) { i -= d;
return *
this; }
127 Vc_ALWAYS_INLINE Iterator
operator+(difference_type d)
const {
return {*v, i + d}; }
128 Vc_ALWAYS_INLINE Iterator
operator-(difference_type d)
const {
return {*v, i - d}; }
129 Vc_ALWAYS_INLINE difference_type
operator-(
const Iterator &rhs)
const {
return i - rhs.i; }
130 friend Vc_ALWAYS_INLINE Iterator
operator+(difference_type d,
const Iterator &rhs)
132 return {*rhs.v, rhs.i + d};
137 Vc_ALWAYS_INLINE
bool operator==(
const Iterator<V> &rhs)
const {
return v == rhs.v && i == rhs.i; }
138 Vc_ALWAYS_INLINE
bool operator!=(
const Iterator<V> &rhs)
const {
return v == rhs.v && i != rhs.i; }
139 Vc_ALWAYS_INLINE
bool operator< (const Iterator<V> &rhs)
const {
return v == rhs.v && i < rhs.i; }
140 Vc_ALWAYS_INLINE
bool operator<=(const Iterator<V> &rhs)
const {
return v == rhs.v && i <= rhs.i; }
141 Vc_ALWAYS_INLINE
bool operator> (
const Iterator<V> &rhs)
const {
return v == rhs.v && i > rhs.i; }
142 Vc_ALWAYS_INLINE
bool operator>=(
const Iterator<V> &rhs)
const {
return v == rhs.v && i >= rhs.i; }
146 difference_type i = 0;
149 template <
typename V>
using ConstIterator = Iterator<const V>;
152 class BitmaskIterator
157 Vc_ALWAYS_INLINE BitmaskIterator(
int m) : mask(m), bit(_mm_tzcnt_32(mask)) {}
158 Vc_ALWAYS_INLINE BitmaskIterator(
const BitmaskIterator &) =
default;
159 Vc_ALWAYS_INLINE BitmaskIterator(BitmaskIterator &&) =
default;
161 Vc_ALWAYS_INLINE
size_t operator->()
const {
return bit; }
162 Vc_ALWAYS_INLINE
size_t operator*()
const {
return bit; }
164 Vc_ALWAYS_INLINE BitmaskIterator &operator++() {
165 bit = _mm_tzcnti_32(bit, mask);
168 Vc_ALWAYS_INLINE BitmaskIterator operator++(
int) {
169 BitmaskIterator tmp = *
this;
170 bit = _mm_tzcnti_32(bit, mask);
174 Vc_ALWAYS_INLINE
bool operator==(
const BitmaskIterator &rhs)
const {
return bit == rhs.bit; }
175 Vc_ALWAYS_INLINE
bool operator!=(
const BitmaskIterator &rhs)
const {
return bit != rhs.bit; }
178 class BitmaskIterator
191 bit = __builtin_ctzl(mask);
192 #elif defined(Vc_MSVC)
193 _BitScanForward(&bit, mask);
195 #error "Not implemented yet. Please contact vc-devel@compeng.uni-frankfurt.de"
215 BitmaskIterator(decltype(mask) m) : mask(m) { nextBit(); }
216 BitmaskIterator(
const BitmaskIterator &) =
default;
217 BitmaskIterator(BitmaskIterator &&) =
default;
219 Vc_ALWAYS_INLINE
size_t operator->()
const {
return bit; }
220 Vc_ALWAYS_INLINE
size_t operator*()
const {
return bit; }
222 Vc_ALWAYS_INLINE BitmaskIterator &operator++() { resetLsb(); nextBit();
return *
this; }
223 Vc_ALWAYS_INLINE BitmaskIterator operator++(
int) { BitmaskIterator tmp = *
this; resetLsb(); nextBit();
return tmp; }
225 Vc_ALWAYS_INLINE
bool operator==(
const BitmaskIterator &rhs)
const {
return mask == rhs.mask; }
226 Vc_ALWAYS_INLINE
bool operator!=(
const BitmaskIterator &rhs)
const {
return mask != rhs.mask; }
230 template <
typename T>
232 enable_if<Traits::is_simd_vector<T>::value || Traits::is_simd_mask<T>::value,
233 Iterator<typename std::remove_reference<T>::type>>
236 return {std::forward<T>(x), 0};
239 template <
typename T>
241 enable_if<Traits::is_simd_vector<T>::value || Traits::is_simd_mask<T>::value,
242 Iterator<typename std::remove_reference<T>::type>>
245 using TT =
typename std::decay<T>::type;
246 return {std::forward<T>(x),
int(TT::size())};
249 template <
typename T>
250 Vc_ALWAYS_INLINE enable_if<
251 Traits::is_simd_mask<T>::value || Traits::is_simd_vector<T>::value, ConstIterator<T>>
257 template <
typename T>
258 Vc_ALWAYS_INLINE enable_if<
259 Traits::is_simd_mask<T>::value || Traits::is_simd_vector<T>::value, ConstIterator<T>>
262 return {v, int(T::size())};
265 template<
typename M> Vc_ALWAYS_INLINE BitmaskIterator begin(
const WhereImpl::WhereMask<M> &w)
267 return w.mask.toInt();
270 template<
typename M> Vc_ALWAYS_INLINE BitmaskIterator end(
const WhereImpl::WhereMask<M> &)
275 template<
typename V,
typename Flags,
typename T> Vc_ALWAYS_INLINE MemoryVectorIterator<V, Flags>
276 makeIterator(T *mem, Flags)
278 return new(mem) MemoryVector<V, Flags>;
281 template<
typename V,
typename Flags,
typename T> Vc_ALWAYS_INLINE MemoryVectorIterator<const V, Flags>
282 makeIterator(
const T *mem, Flags)
284 return new(
const_cast<T *
>(mem)) MemoryVector<const V, Flags>;
287 template<
typename V,
typename Flags,
typename FlagsX> Vc_ALWAYS_INLINE MemoryVectorIterator<V, Flags>
288 makeIterator(MemoryVector<V, FlagsX> &mv, Flags)
290 return new(&mv) MemoryVector<V, Flags>;
293 template<
typename V,
typename Flags,
typename FlagsX> Vc_ALWAYS_INLINE MemoryVectorIterator<const V, Flags>
294 makeIterator(MemoryVector<const V, FlagsX> &mv, Flags)
296 return new(&mv) MemoryVector<const V, Flags>;
303 using Common::cbegin;
305 using Common::makeIterator;
308 #endif // VC_COMMON_ITERATORS_H_
result_vector_type< L, R > operator-(L &&lhs, R &&rhs)
Applies - component-wise and concurrently.
result_vector_type< L, R >::mask_type operator!=(L &&lhs, R &&rhs)
Applies != component-wise and concurrently.
result_vector_type< L, R > operator*(L &&lhs, R &&rhs)
Applies * component-wise and concurrently.
Helper class for the Memory::vector(size_t) class of functions.
result_vector_type< L, R >::mask_type operator==(L &&lhs, R &&rhs)
Applies == component-wise and concurrently.
result_vector_type< L, R > operator+(L &&lhs, R &&rhs)
Applies + component-wise and concurrently.
result_vector_type< L, R >::mask_type operator>=(L &&lhs, R &&rhs)
Applies >= component-wise and concurrently.
result_vector_type< L, R >::mask_type operator>(L &&lhs, R &&rhs)
Applies > component-wise and concurrently.