Warning, file /include/Vc/avx/mask.h was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 #ifndef VC_AVX_MASK_H_
0029 #define VC_AVX_MASK_H_
0030
0031 #include <array>
0032
0033 #include "intrinsics.h"
0034 #include "../common/storage.h"
0035 #include "../common/bitscanintrinsics.h"
0036 #include "../common/maskbool.h"
0037 #include "detail.h"
0038 #include "macros.h"
0039
0040 namespace Vc_VERSIONED_NAMESPACE
0041 {
0042 template <typename T> class Mask<T, VectorAbi::Avx>
0043 {
0044 public:
0045 using abi = VectorAbi::Avx;
0046
0047
0048
0049
0050 typedef bool EntryType;
0051 using value_type = EntryType;
0052
0053 using MaskBool = Common::MaskBool<sizeof(T)>;
0054
0055
0056
0057
0058 using VectorEntryType = MaskBool;
0059
0060
0061
0062
0063 using Vector = AVX2::Vector<T>;
0064
0065
0066 using VectorTypeF = AVX::FloatVectorType<typename AVX::VectorTypeHelper<T>::Type>;
0067
0068 using VectorTypeD = AVX::DoubleVectorType<VectorTypeF>;
0069
0070 using VectorTypeI = AVX::IntegerVectorType<VectorTypeF>;
0071
0072 private:
0073 typedef const VectorTypeF VArg;
0074 typedef const VectorTypeD VdArg;
0075 typedef const VectorTypeI ViArg;
0076
0077 public:
0078 static constexpr size_t Size = sizeof(VectorTypeF) / sizeof(T);
0079 static constexpr size_t MemoryAlignment = Size;
0080 static constexpr std::size_t size() { return Size; }
0081 Vc_FREE_STORE_OPERATORS_ALIGNED(alignof(VectorType));
0082
0083 private:
0084 typedef Common::Storage<T, Size> Storage;
0085
0086 public:
0087
0088
0089
0090
0091 using VectorType = typename Storage::VectorType;
0092
0093 using EntryReference = Vc::Detail::ElementReference<Mask>;
0094 using reference = EntryReference;
0095
0096
0097 #if defined Vc_MSVC && defined _WIN32
0098 typedef const Mask &AsArg;
0099 #else
0100 typedef const Mask AsArg;
0101 #endif
0102
0103 Vc_INTRINSIC Mask() {}
0104 Vc_INTRINSIC Mask(VArg x) : d(AVX::avx_cast<VectorType>(x)) {}
0105 Vc_INTRINSIC Mask(VdArg x) : d(AVX::avx_cast<VectorType>(x)) {}
0106 Vc_INTRINSIC Mask(ViArg x) : d(AVX::avx_cast<VectorType>(x)) {}
0107 Vc_INTRINSIC explicit Mask(VectorSpecialInitializerZero) : d(Detail::zero<VectorType>()) {}
0108 Vc_INTRINSIC explicit Mask(VectorSpecialInitializerOne) : d(Detail::allone<VectorType>()) {}
0109 Vc_INTRINSIC explicit Mask(bool b)
0110 : d(b ? Detail::allone<VectorType>() : Detail::zero<VectorType>())
0111 {
0112 }
0113 Vc_INTRINSIC static Mask Zero() { return Mask{Vc::Zero}; }
0114 Vc_INTRINSIC static Mask One() { return Mask{Vc::One}; }
0115
0116
0117 template <typename U>
0118 Vc_INTRINSIC Mask(
0119 U &&rhs, Common::enable_if_mask_converts_implicitly<Mask, T, U> = nullarg)
0120 : d(AVX::avx_cast<VectorType>(
0121 Detail::mask_cast<Traits::decay<U>::Size, Size, VectorTypeF>(
0122 rhs.dataI())))
0123 {
0124 }
0125
0126 #if Vc_IS_VERSION_1
0127
0128 template <typename U>
0129 Vc_DEPRECATED("use simd_cast instead of explicit type casting to convert between "
0130 "mask types") Vc_INTRINSIC
0131 explicit Mask(U &&rhs,
0132 Common::enable_if_mask_converts_explicitly<T, U> = nullarg);
0133 #endif
0134
0135 template<typename Flags = DefaultLoadTag> Vc_INTRINSIC explicit Mask(const bool *mem, Flags f = Flags()) { load(mem, f); }
0136
0137 template<typename Flags = DefaultLoadTag> Vc_INTRINSIC void load(const bool *mem, Flags = Flags());
0138
0139 template<typename Flags = DefaultLoadTag> Vc_INTRINSIC void store(bool *mem, Flags = Flags()) const;
0140
0141 Vc_INTRINSIC Mask &operator=(const Mask &) = default;
0142 Vc_INTRINSIC_L Mask &operator=(const std::array<bool, Size> &values) Vc_INTRINSIC_R;
0143 Vc_INTRINSIC_L operator std::array<bool, Size>() const Vc_INTRINSIC_R;
0144
0145
0146 Vc_INTRINSIC Vc_PURE bool operator==(const Mask &rhs) const
0147 { return Detail::movemask(d.v()) == Detail::movemask(rhs.d.v()); }
0148
0149 Vc_INTRINSIC Vc_PURE bool operator!=(const Mask &rhs) const
0150 { return !operator==(rhs); }
0151
0152 Vc_INTRINSIC Mask operator!() const
0153 {
0154 #ifdef Vc_GCC
0155 return ~dataI();
0156 #else
0157 return Detail::andnot_(dataF(), Detail::allone<VectorTypeF>());
0158 #endif
0159 }
0160
0161 Vc_INTRINSIC Mask &operator&=(const Mask &rhs) { d.v() = AVX::avx_cast<VectorType>(Detail::and_(data(), rhs.data())); return *this; }
0162 Vc_INTRINSIC Mask &operator|=(const Mask &rhs) { d.v() = AVX::avx_cast<VectorType>(Detail::or_ (data(), rhs.data())); return *this; }
0163 Vc_INTRINSIC Mask &operator^=(const Mask &rhs) { d.v() = AVX::avx_cast<VectorType>(Detail::xor_(data(), rhs.data())); return *this; }
0164
0165 Vc_INTRINSIC Vc_PURE Mask operator&(const Mask &rhs) const { return Detail::and_(data(), rhs.data()); }
0166 Vc_INTRINSIC Vc_PURE Mask operator|(const Mask &rhs) const { return Detail::or_(data(), rhs.data()); }
0167 Vc_INTRINSIC Vc_PURE Mask operator^(const Mask &rhs) const { return Detail::xor_(data(), rhs.data()); }
0168
0169 Vc_INTRINSIC Vc_PURE Mask operator&&(const Mask &rhs) const { return Detail::and_(data(), rhs.data()); }
0170 Vc_INTRINSIC Vc_PURE Mask operator||(const Mask &rhs) const { return Detail::or_(data(), rhs.data()); }
0171
0172
0173
0174 Vc_INTRINSIC_L bool isNotEmpty() const Vc_INTRINSIC_R;
0175 Vc_INTRINSIC_L bool isEmpty() const Vc_INTRINSIC_R;
0176 Vc_INTRINSIC_L bool isFull() const Vc_INTRINSIC_R;
0177 Vc_INTRINSIC_L bool isMix() const Vc_INTRINSIC_R;
0178
0179 Vc_INTRINSIC Vc_PURE int shiftMask() const { return Detail::movemask(dataI()); }
0180 Vc_INTRINSIC Vc_PURE int toInt() const { return Detail::mask_to_int<Size>(dataI()); }
0181
0182 Vc_INTRINSIC VectorType data () const { return d.v(); }
0183 Vc_INTRINSIC VectorTypeF dataF() const { return AVX::avx_cast<VectorTypeF>(d.v()); }
0184 Vc_INTRINSIC VectorTypeI dataI() const { return AVX::avx_cast<VectorTypeI>(d.v()); }
0185 Vc_INTRINSIC VectorTypeD dataD() const { return AVX::avx_cast<VectorTypeD>(d.v()); }
0186
0187 private:
0188 friend reference;
0189 static Vc_INTRINSIC Vc_PURE value_type get(const Mask &m, int i) noexcept
0190 {
0191 return m.toInt() & (1 << i);
0192 }
0193 template <typename U>
0194 static Vc_INTRINSIC void set(Mask &m, int i,
0195 U &&v) noexcept(noexcept(MaskBool(std::declval<U>())))
0196 {
0197 m.d.set(i, MaskBool(std::forward<U>(v)));
0198 }
0199
0200 public:
0201
0202
0203
0204
0205
0206
0207 Vc_ALWAYS_INLINE reference operator[](size_t index) noexcept
0208 {
0209 return {*this, int(index)};
0210 }
0211 Vc_ALWAYS_INLINE Vc_PURE value_type operator[](size_t index) const noexcept
0212 {
0213 return get(*this, index);
0214 }
0215
0216 Vc_INTRINSIC Vc_PURE int count() const { return Detail::popcnt16(toInt()); }
0217 Vc_INTRINSIC Vc_PURE int firstOne() const { return _bit_scan_forward(toInt()); }
0218
0219 template <typename G> static Vc_INTRINSIC_L Mask generate(G &&gen) Vc_INTRINSIC_R;
0220 Vc_INTRINSIC_L Vc_PURE_L Mask shifted(int amount) const Vc_INTRINSIC_R Vc_PURE_R;
0221
0222 private:
0223 #ifdef Vc_COMPILE_BENCHMARKS
0224 public:
0225 #endif
0226 Storage d;
0227 };
0228 template <typename T> constexpr size_t Mask<T, VectorAbi::Avx>::Size;
0229 template <typename T> constexpr size_t Mask<T, VectorAbi::Avx>::MemoryAlignment;
0230
0231 }
0232
0233 #include "mask.tcc"
0234
0235 #endif