Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-28 10:25:30

0001 /*  This file is part of the Vc library. {{{
0002 Copyright © 2009-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_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      * The \c EntryType of masks is always bool, independent of \c T.
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      * The \c VectorEntryType, in contrast to \c EntryType, reveals information about the SIMD
0063      * implementation. This type is useful for the \c sizeof operator in generic functions.
0064      */
0065     typedef bool VectorEntryType;
0066 
0067     /**
0068      * The \c VectorType reveals the implementation-specific internal type used for the SIMD type.
0069      */
0070     using VectorType = bool;
0071 
0072     /**
0073      * The associated Vector<T> type.
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     // implicit cast
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     // explicit cast, implemented via simd_cast (in scalar/simd_cast_caller.h)
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      * \note the returned object models the concept of a reference and
0144      * as such it can exist longer than the data it is referencing.
0145      * \note to avoid lifetime issues, we strongly advice not to store
0146      * any reference objects.
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          * Returns the index of the first one in the mask.
0163          *
0164          * The return value is undefined if the mask is empty.
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 }  // namespace Vc
0190 
0191 #endif // VC_SCALAR_MASK_H_