File indexing completed on 2025-02-28 10:25:30
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_SCALAR_MASK_H_
0029 #define VC_SCALAR_MASK_H_
0030
0031 #include "types.h"
0032 #include "macros.h"
0033
0034 namespace Vc_VERSIONED_NAMESPACE
0035 {
0036 template <typename T> class Mask<T, VectorAbi::Scalar>
0037 {
0038 friend class Mask< double, VectorAbi::Scalar>;
0039 friend class Mask< float, VectorAbi::Scalar>;
0040 friend class Mask< int32_t, VectorAbi::Scalar>;
0041 friend class Mask<uint32_t, VectorAbi::Scalar>;
0042 friend class Mask< int16_t, VectorAbi::Scalar>;
0043 friend class Mask<uint16_t, VectorAbi::Scalar>;
0044
0045 public:
0046 using abi = VectorAbi::Scalar;
0047
0048 static constexpr size_t Size = 1;
0049 static constexpr size_t MemoryAlignment = 1;
0050 static constexpr std::size_t size() { return 1; }
0051
0052
0053
0054
0055 typedef bool EntryType;
0056 using value_type = EntryType;
0057
0058 using EntryReference = Vc::Detail::ElementReference<Mask>;
0059 using reference = EntryReference;
0060
0061
0062
0063
0064
0065 typedef bool VectorEntryType;
0066
0067
0068
0069
0070 using VectorType = bool;
0071
0072
0073
0074
0075 using Vector = Scalar::Vector<T>;
0076
0077 Vc_INTRINSIC Mask() = default;
0078 Vc_INTRINSIC explicit Mask(bool b) : m(b) {}
0079 Vc_INTRINSIC explicit Mask(VectorSpecialInitializerZero) : m(false) {}
0080 Vc_INTRINSIC explicit Mask(VectorSpecialInitializerOne) : m(true) {}
0081 Vc_INTRINSIC static Mask Zero() { return Mask(false); }
0082 Vc_INTRINSIC static Mask One() { return Mask(true); }
0083
0084
0085 template <typename U>
0086 Vc_INTRINSIC Mask(U &&rhs, Common::enable_if_mask_converts_implicitly<Mask, T, U> = nullarg)
0087 : m(rhs.m) {}
0088
0089 #if Vc_IS_VERSION_1
0090
0091 template <typename U>
0092 Vc_DEPRECATED(
0093 "use simd_cast instead of explicit type casting to convert between mask types")
0094 Vc_INTRINSIC_L
0095 explicit Mask(U &&rhs, Common::enable_if_mask_converts_explicitly<T, U> = nullarg)
0096 Vc_INTRINSIC_R;
0097 #endif
0098
0099 Vc_ALWAYS_INLINE explicit Mask(const bool *mem) : m(mem[0]) {}
0100 template<typename Flags> Vc_ALWAYS_INLINE explicit Mask(const bool *mem, Flags) : m(mem[0]) {}
0101
0102 Vc_ALWAYS_INLINE void load(const bool *mem) { m = mem[0]; }
0103 template<typename Flags> Vc_ALWAYS_INLINE void load(const bool *mem, Flags) { m = mem[0]; }
0104
0105 Vc_ALWAYS_INLINE void store(bool *mem) const { *mem = m; }
0106 template<typename Flags> Vc_ALWAYS_INLINE void store(bool *mem, Flags) const { *mem = m; }
0107
0108 Vc_ALWAYS_INLINE bool operator==(const Mask &rhs) const { return m == rhs.m; }
0109 Vc_ALWAYS_INLINE bool operator!=(const Mask &rhs) const { return m != rhs.m; }
0110
0111 Vc_ALWAYS_INLINE Mask operator&&(const Mask &rhs) const { return Mask(m && rhs.m); }
0112 Vc_ALWAYS_INLINE Mask operator& (const Mask &rhs) const { return Mask(m && rhs.m); }
0113 Vc_ALWAYS_INLINE Mask operator||(const Mask &rhs) const { return Mask(m || rhs.m); }
0114 Vc_ALWAYS_INLINE Mask operator| (const Mask &rhs) const { return Mask(m || rhs.m); }
0115 Vc_ALWAYS_INLINE Mask operator^ (const Mask &rhs) const { return Mask(m ^ rhs.m); }
0116 Vc_ALWAYS_INLINE Mask operator!() const { return Mask(!m); }
0117
0118 Vc_ALWAYS_INLINE Mask &operator&=(const Mask &rhs) { m &= rhs.m; return *this; }
0119 Vc_ALWAYS_INLINE Mask &operator|=(const Mask &rhs) { m |= rhs.m; return *this; }
0120 Vc_ALWAYS_INLINE Mask &operator^=(const Mask &rhs) { m ^= rhs.m; return *this; }
0121
0122 Vc_ALWAYS_INLINE bool isFull () const { return m; }
0123 Vc_ALWAYS_INLINE bool isNotEmpty() const { return m; }
0124 Vc_ALWAYS_INLINE bool isEmpty() const { return !m; }
0125 Vc_ALWAYS_INLINE bool isMix () const { return false; }
0126
0127 Vc_ALWAYS_INLINE bool data () const { return m; }
0128 Vc_ALWAYS_INLINE bool dataI() const { return m; }
0129 Vc_ALWAYS_INLINE bool dataD() const { return m; }
0130
0131 private:
0132 friend reference;
0133 static Vc_INTRINSIC bool get(const Mask &o, int) noexcept { return o.m; }
0134 template <typename U>
0135 static Vc_INTRINSIC void set(Mask &o, int, U &&v) noexcept(
0136 noexcept(std::declval<bool &>() = std::declval<U>()))
0137 {
0138 o.m = std::forward<U>(v);
0139 }
0140
0141 public:
0142
0143
0144
0145
0146
0147
0148 Vc_ALWAYS_INLINE reference operator[](size_t i) noexcept
0149 {
0150 Vc_ASSERT(i == 0); if (i) {}
0151 return {*this, 0};
0152 }
0153 Vc_ALWAYS_INLINE value_type operator[](size_t i) const noexcept
0154 {
0155 Vc_ASSERT(i == 0); if (i) {}
0156 return m;
0157 }
0158
0159 Vc_ALWAYS_INLINE int count() const { return m ? 1 : 0; }
0160
0161
0162
0163
0164
0165
0166 Vc_ALWAYS_INLINE int firstOne() const { return 0; }
0167 Vc_ALWAYS_INLINE int toInt() const { return m ? 1 : 0; }
0168
0169 template <typename G> static Vc_INTRINSIC Mask generate(G &&gen)
0170 {
0171 return Mask(gen(0));
0172 }
0173
0174 Vc_INTRINSIC Vc_PURE Mask shifted(int amount) const
0175 {
0176 if (amount == 0) {
0177 return *this;
0178 } else {
0179 return Zero();
0180 }
0181 }
0182
0183 private:
0184 bool m;
0185 };
0186 template <typename T> constexpr size_t Mask<T, VectorAbi::Scalar>::Size;
0187 template <typename T> constexpr size_t Mask<T, VectorAbi::Scalar>::MemoryAlignment;
0188
0189 }
0190
0191 #endif