Back to home page

EIC code displayed by LXR

 
 

    


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