|
||||
File indexing completed on 2025-01-30 10:25:47
0001 /* This file is part of the Vc library. {{{ 0002 Copyright © 2015 Matthias Kretz <kretz@kde.org> 0003 0004 Redistribution and use in source and binary forms, with or without 0005 modification, are permitted provided that the following conditions are met: 0006 * Redistributions of source code must retain the above copyright 0007 notice, this list of conditions and the following disclaimer. 0008 * Redistributions in binary form must reproduce the above copyright 0009 notice, this list of conditions and the following disclaimer in the 0010 documentation and/or other materials provided with the distribution. 0011 * Neither the names of contributing organizations nor the 0012 names of its contributors may be used to endorse or promote products 0013 derived from this software without specific prior written permission. 0014 0015 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 0016 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 0017 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 0018 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY 0019 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 0020 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 0021 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 0022 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 0023 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 0024 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 0025 0026 }}}*/ 0027 0028 #ifndef VC_COMMON_MASK_H_ 0029 #define VC_COMMON_MASK_H_ 0030 0031 #include "macros.h" 0032 0033 namespace Vc_VERSIONED_NAMESPACE 0034 { 0035 /** 0036 * \class Mask mask.h <Vc/vector.h> 0037 * \ingroup Masks 0038 * 0039 * The main SIMD mask class. 0040 */ 0041 template <typename T, typename Abi = VectorAbi::Best<T>> class Mask 0042 { 0043 public: 0044 /** 0045 * Returns the number of boolean components (\VSize{T}) in a mask of this type. 0046 * 0047 * The size of the mask. I.e. the number of boolean entries in the mask. Do not 0048 * make any assumptions about the size of masks. 0049 * 0050 * In addition, you can easily use if clauses that compare sizes. The compiler can 0051 * statically evaluate and fully optimize dead code away (very much like \#ifdef, but 0052 * with syntax checking). 0053 * 0054 * \returns The number of components (i.e. \VSize{T}) objects of this mask type store 0055 * and manipulate. 0056 */ 0057 static constexpr size_t size() { return VectorTraits<T, Abi>::size(); } 0058 ///\copydoc size 0059 ///\deprecated Use Vc::Mask::size instead. 0060 static constexpr size_t Size = VectorTraits<T, Abi>::size(); 0061 0062 /** 0063 * Specifies the alignment requirement for aligned load and store calls for objects of 0064 * this mask type. 0065 */ 0066 static constexpr size_t MemoryAlignment = VectorTraits<T, Abi>::maskMemoryAlignment(); 0067 0068 /// The ABI tag type of the current template instantiation. 0069 using abi = Abi; 0070 0071 /** 0072 * The \c EntryType of masks is always \c bool, independent of \c T. 0073 */ 0074 using EntryType = bool; 0075 /// \copydoc EntryType 0076 using value_type = EntryType; 0077 0078 /// The reference wrapper type used for accessing individual mask components. 0079 using EntryReference = typename VectorTraits<T, Abi>::EntryReference; 0080 /// \copydoc EntryReference 0081 using value_reference = EntryReference; 0082 0083 /** 0084 * The \c VectorEntryType, in contrast to \c EntryType, reveals information about the SIMD 0085 * implementation. 0086 * This type is useful for the \c sizeof operator in generic functions. 0087 */ 0088 using VectorEntryType = typename VectorTraits<T, Abi>::VectorEntryType; 0089 0090 /**\internal 0091 * The \c VectorType reveals the implementation-specific internal type used for the SIMD type. 0092 */ 0093 using VectorType = typename VectorTraits<T, Abi>::VectorType; 0094 /**\internal 0095 * \copydoc VectorType 0096 */ 0097 using vector_type = VectorType; 0098 0099 /* 0100 * The associated Vector<T> type. 0101 */ 0102 //using Vector = Vector<T, Abi>; 0103 0104 /// \name Generators 0105 ///@{ 0106 /** 0107 * Creates a new mask object initialized to zero/\c false. 0108 * 0109 * \returns A mask object with zero-initialized components. 0110 */ 0111 Vc_INTRINSIC static Mask Zero(); 0112 0113 /** 0114 * Creates a mask object initialized to one/\c true. 0115 * 0116 * \returns A mask object with components initialized to \c true. 0117 */ 0118 Vc_INTRINSIC static Mask One(); 0119 0120 /// Generate a mask object from booleans returned from the function \p gen. 0121 template <typename G> static Vc_INTRINSIC Mask generate(G &&gen); 0122 ///@} 0123 0124 /// \name Compile-Time Constant Initialization 0125 ///@{ 0126 /** 0127 * Construct a zero-initialized vector object. 0128 * 0129 * This constructor follows the behavior of the underlying \c bool type in that the 0130 * expression `bool()` zero-initializes the object (to \c false). On the other hand 0131 * the variable \c x in `bool x;` is uninitialized. 0132 * Since, for class types, both expressions call the default constructor `Mask<T> x` 0133 * must zero-initialize \c x as well. 0134 */ 0135 Vc_INTRINSIC Mask() = default; 0136 0137 /// Zero-initialize the new mask object (\c false). 0138 /// \see Vc::Zero, Zero() 0139 Vc_INTRINSIC explicit Mask(VectorSpecialInitializerZero); 0140 0141 /// Initialize the new mask object to one (\c true). 0142 /// \see Vc::One, One() 0143 Vc_INTRINSIC explicit Mask(VectorSpecialInitializerOne); 0144 ///@} 0145 0146 /// \name Conversion/Broadcast Constructors 0147 ///@{ 0148 /** 0149 * Broadcast constructor. 0150 * 0151 * Set all components of the new mask object to \p b. 0152 * 0153 * \param b Determines the initial state of the mask. 0154 */ 0155 Vc_INTRINSIC explicit Mask(bool b); 0156 0157 /** 0158 * Implicit conversion from a compatible (equal \VSize{T} on every platform) mask 0159 * object. 0160 * 0161 * \param otherMask The mask to be converted. 0162 */ 0163 template <typename U> 0164 Vc_INTRINSIC Mask(U &&otherMask, 0165 Common::enable_if_mask_converts_implicitly<Mask, T, U> = nullarg); 0166 0167 #if Vc_IS_VERSION_1 0168 /** 0169 * Explicit conversion (static_cast) from a mask object that potentially has a 0170 * different \VSize{T}. 0171 * 0172 * \param otherMask The mask to be converted. 0173 * 0174 * \internal This is implemented via simd_cast in scalar/simd_cast_caller.h 0175 */ 0176 template <typename U> 0177 Vc_DEPRECATED( 0178 "use simd_cast instead of explicit type casting to convert between mask types") 0179 Vc_INTRINSIC_L 0180 explicit Mask(U &&otherMask, Common::enable_if_mask_converts_explicitly<T, U> = 0181 nullarg) Vc_INTRINSIC_R; 0182 ///@} 0183 #endif 0184 0185 /** 0186 * \name Loads & Stores 0187 */ 0188 ///@{ 0189 /** 0190 * Load constructor from an array of \c bool. 0191 * 0192 * This constructor implements an explicit conversion from an array of booleans to a 0193 * mask object. It corresponds to a Vector load constructor. 0194 * 0195 * \param mem A pointer to the start of the array of booleans. 0196 * \see Mask(const bool *, Flags), load(const bool *) 0197 */ 0198 Vc_ALWAYS_INLINE explicit Mask(const bool *mem); 0199 /** 0200 * Overload of the above with a load/store flag argument. 0201 * 0202 * \param mem A pointer to the start of the array of booleans. 0203 * \param flags Choose a combination of flags such as Vc::Aligned, Vc::Streaming, 0204 * Vc::Unaligned, Vc::PrefetchDefault, ... 0205 * \see load(const bool *, Flags) 0206 */ 0207 template <typename Flags> Vc_ALWAYS_INLINE explicit Mask(const bool *mem, Flags flags); 0208 0209 /** 0210 * Load the components of the mask from an array of \c bool. 0211 * 0212 * \param mem A pointer to the start of the array of booleans. 0213 * \see load(const bool *, Flags), Mask(const bool *) 0214 */ 0215 Vc_ALWAYS_INLINE void load(const bool *mem); 0216 /** 0217 * Overload of the above with a load/store flag argument. 0218 * 0219 * \param mem A pointer to the start of the array of booleans. 0220 * \param flags Choose a combination of flags such as Vc::Aligned, Vc::Streaming, 0221 * Vc::Unaligned, Vc::PrefetchDefault, ... 0222 * \see Mask(const bool *, Flags) 0223 */ 0224 template <typename Flags> Vc_ALWAYS_INLINE void load(const bool *mem, Flags flags); 0225 0226 /** 0227 * Store the values of the mask to an array of \c bool. 0228 * 0229 * \param mem A pointer to the start of the array of booleans. 0230 * \see store(bool *, Flags) 0231 */ 0232 Vc_ALWAYS_INLINE void store(bool *mem) const; 0233 /** 0234 * Overload of the above with a load/store flag argument. 0235 * 0236 * \param mem A pointer to the start of the array of booleans. 0237 * \param flags Choose a combination of flags such as Vc::Aligned, Vc::Streaming, 0238 * Vc::Unaligned, Vc::PrefetchDefault, ... 0239 */ 0240 template <typename Flags> Vc_ALWAYS_INLINE void store(bool *mem, Flags flags) const; 0241 ///@} 0242 0243 /// \name Comparison Operators 0244 ///@{ 0245 /** 0246 * Returns whether the two masks are equal in all components. 0247 * 0248 * \param mask The other mask to compare against. 0249 * \returns A scalar boolean value that says whether all components of the two masks 0250 * are equal. 0251 * 0252 * \note If you expected a behavior similar to the compare operator of Vc::Vector, 0253 * consider that the bitwise operators already implement such functionality. There is 0254 * little use, typically, in having `a == b` return the same as `a ^ b`. In general, 0255 * it is more useful to query `all_of(a ^ b)` which is the same as this equality 0256 * operator. 0257 */ 0258 Vc_ALWAYS_INLINE bool operator==(const Mask &mask) const; 0259 0260 /** 0261 * Returns whether the two masks are different in at least one component. 0262 * 0263 * \param mask The other mask to compare against. 0264 * \returns A scalar boolean value that says whether at least one component of the two masks is different. 0265 * 0266 * \note `(a == b) == !(a != b)` holds 0267 * \see Mask::operator==(const Mask &) 0268 */ 0269 Vc_ALWAYS_INLINE bool operator!=(const Mask &mask) const; 0270 ///@} 0271 0272 /** 0273 * \name Logical and Binary Operators 0274 * 0275 * \brief Component-wise logical/binary operations on mask objects. 0276 * 0277 * The effect of logical and binary \c AND and \c OR is equivalent for mask types (as 0278 * it is for \c bool). 0279 */ 0280 ///@{ 0281 0282 /// Returns the component-wise application of a logical \c AND to \p mask. 0283 Vc_ALWAYS_INLINE Mask operator&&(const Mask &mask) const; 0284 /// Returns the component-wise application of a binary \c AND to \p mask. 0285 Vc_ALWAYS_INLINE Mask operator&(const Mask &mask) const; 0286 /// Returns the component-wise application of a logical \c OR to \p mask. 0287 Vc_ALWAYS_INLINE Mask operator||(const Mask &mask) const; 0288 /// Returns the component-wise application of a binary \c OR to \p mask. 0289 Vc_ALWAYS_INLINE Mask operator|(const Mask &mask) const; 0290 /// Returns the component-wise application of a binary \c XOR to \p mask. 0291 Vc_ALWAYS_INLINE Mask operator^(const Mask &mask) const; 0292 /// Returns a mask with inverted components. 0293 Vc_ALWAYS_INLINE Mask operator!() const; 0294 0295 /// Modifies the mask using an \c AND operation with \p mask. 0296 Vc_ALWAYS_INLINE Mask &operator&=(const Mask &mask); 0297 /// Modifies the mask using an \c OR operation with \p mask. 0298 Vc_ALWAYS_INLINE Mask &operator|=(const Mask &mask); 0299 /// Modifies the mask using an \c XOR operation with \p mask. 0300 Vc_ALWAYS_INLINE Mask &operator^=(const Mask &mask); 0301 ///@} 0302 0303 /** 0304 * \name Reductions 0305 * 0306 * \see any_of, all_of, none_of, some_of 0307 */ 0308 ///@{ 0309 0310 /// Returns a logical \c AND of all components. 0311 Vc_ALWAYS_INLINE bool isFull() const; 0312 /// Returns a logical \c OR of all components. 0313 Vc_ALWAYS_INLINE bool isNotEmpty() const; 0314 /// Returns \c true if components are \c false, \c false otherwise. 0315 Vc_ALWAYS_INLINE bool isEmpty() const; 0316 /// Returns `!isFull() && !isEmpty()`. 0317 Vc_ALWAYS_INLINE bool isMix() const; 0318 ///@} 0319 0320 /**\internal 0321 * \name Internal Data Access 0322 */ 0323 ///@{ 0324 Vc_ALWAYS_INLINE bool data() const; 0325 Vc_ALWAYS_INLINE bool dataI() const; 0326 Vc_ALWAYS_INLINE bool dataD() const; 0327 ///@} 0328 0329 /// \name Scalar Subscript Operators 0330 ///@{ 0331 /** 0332 * Lvalue-reference-like access to mask entries. 0333 * 0334 * \param index Determines the boolean to be accessed. 0335 * \return a temporary proxy object referencing the \p index th entry of the mask. 0336 * 0337 * \warning This operator does not return an lvalue reference (to \c bool), but rather 0338 * a temporary (rvalue) object that mimics an lvalue reference (as much as is possible 0339 * with C++11/14). 0340 */ 0341 Vc_ALWAYS_INLINE EntryReference operator[](size_t index); 0342 0343 /** 0344 * Read-only access to mask entries. 0345 * 0346 * \param index Determines the boolean to be accessed. 0347 * \return The \p index th entry of the mask as a \c bool (rvalue). 0348 * 0349 * \warning This operator does not return an lvalue reference (to `const bool`), but 0350 * rather a temporary (rvalue) \c bool. 0351 */ 0352 Vc_ALWAYS_INLINE EntryType operator[](size_t index) const; 0353 ///@} 0354 0355 /// Returns how many components of the mask are \c true. 0356 Vc_ALWAYS_INLINE int count() const; 0357 0358 /** 0359 * Returns the index of the first one in the mask. 0360 * 0361 * \returns the index of the first component that is \c true. 0362 * 0363 * \warning The return value is undefined if the mask is empty. 0364 * 0365 * Thus, unless `none_of(mask)`, `mask[mask.firstOne()] == true` holds and `mask[i] == 0366 * false` for all `i < mask.firstOne()`. 0367 */ 0368 Vc_ALWAYS_INLINE int firstOne() const; 0369 0370 /** 0371 * Convert the boolean components of the mask into bits of an integer. 0372 * 0373 * \return An \c int where each bit corresponds to the boolean value in the mask. 0374 * 0375 * For example, the mask `[true, false, false, true]` results in a `9` (in binary: `1001`). 0376 */ 0377 Vc_ALWAYS_INLINE int toInt() const; 0378 0379 /// Returns a mask with components shifted by \p amount places. 0380 Vc_INTRINSIC Vc_PURE Mask shifted(int amount) const; 0381 0382 Vc_FREE_STORE_OPERATORS_ALIGNED(alignof(Mask)); 0383 0384 private: 0385 VectorType d; 0386 }; 0387 0388 /** 0389 * \ingroup Utilities 0390 * 0391 * \name Boolean Reductions 0392 */ 0393 //@{ 0394 /** \ingroup Utilities 0395 * Returns whether all entries in the mask \p m are \c true. 0396 */ 0397 template<typename Mask> constexpr bool all_of(const Mask &m) { return m.isFull(); } 0398 /** \ingroup Utilities 0399 * Returns \p b 0400 */ 0401 constexpr bool all_of(bool b) { return b; } 0402 0403 /** \ingroup Utilities 0404 * Returns whether at least one entry in the mask \p m is \c true. 0405 */ 0406 template<typename Mask> constexpr bool any_of(const Mask &m) { return m.isNotEmpty(); } 0407 /** \ingroup Utilities 0408 * Returns \p b 0409 */ 0410 constexpr bool any_of(bool b) { return b; } 0411 0412 /** \ingroup Utilities 0413 * Returns whether all entries in the mask \p m are \c false. 0414 */ 0415 template<typename Mask> constexpr bool none_of(const Mask &m) { return m.isEmpty(); } 0416 /** \ingroup Utilities 0417 * Returns \p !b 0418 */ 0419 constexpr bool none_of(bool b) { return !b; } 0420 0421 /** \ingroup Utilities 0422 * Returns whether at least one entry in \p m is \c true and at least one entry in \p m is \c 0423 * false. 0424 */ 0425 template<typename Mask> constexpr bool some_of(const Mask &m) { return m.isMix(); } 0426 /** \ingroup Utilities 0427 * Returns \c false 0428 */ 0429 constexpr bool some_of(bool) { return false; } 0430 //@} 0431 } // namespace Vc 0432 0433 #endif // VC_COMMON_MASK_H_ 0434 0435 // vim: foldmethod=marker
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |