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.