Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-31 10:25:42

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_VECTOR_H_
0029 #define VC_SCALAR_VECTOR_H_
0030 
0031 #include <assert.h>
0032 #include <algorithm>
0033 #include <cmath>
0034 
0035 #ifdef _MSC_VER
0036 #include <float.h>
0037 #endif
0038 
0039 #include "types.h"
0040 #include "detail.h"
0041 #include "mask.h"
0042 
0043 #include "macros.h"
0044 
0045 namespace Vc_VERSIONED_NAMESPACE
0046 {
0047 #define Vc_CURRENT_CLASS_NAME Vector
0048 template <typename T> class Vector<T, VectorAbi::Scalar>
0049 {
0050     static_assert(std::is_arithmetic<T>::value,
0051                   "Vector<T> only accepts arithmetic builtin types as template parameter T.");
0052 
0053     public:
0054         using abi = VectorAbi::Scalar;
0055         using EntryType = T;
0056         using VectorEntryType = EntryType;
0057         using value_type = EntryType;
0058         using VectorType = EntryType;
0059         using vector_type = VectorType;
0060         using reference = Detail::ElementReference<Vector>;
0061 
0062     protected:
0063         VectorType m_data = VectorType();
0064         template <typename U> using V = Vector<U, abi>;
0065 
0066     public:
0067         typedef Scalar::Mask<T> Mask;
0068         using MaskType = Mask;
0069         using mask_type = Mask;
0070         typedef Mask MaskArgument;
0071         typedef Vector AsArg;
0072 
0073         Vc_ALWAYS_INLINE VectorType &data() { return m_data; }
0074         Vc_ALWAYS_INLINE const VectorType &data() const { return m_data; }
0075 
0076         static constexpr size_t Size = 1;
0077         static constexpr size_t MemoryAlignment = alignof(VectorType);
0078         using IndexType = fixed_size_simd<int, 1>;
0079         using index_type = IndexType;
0080 
0081 #include "../common/generalinterface.h"
0082 
0083         static Vc_INTRINSIC_L Vector Random() Vc_INTRINSIC_R;
0084 
0085         // implict conversion from compatible Vector<U, abi>
0086         template <typename U>
0087         Vc_INTRINSIC Vector(
0088             V<U> x, typename std::enable_if<Traits::is_implicit_cast_allowed<U, T>::value,
0089                                             void *>::type = nullptr)
0090             : m_data(static_cast<EntryType>(x.data()))
0091         {
0092         }
0093 
0094 #if Vc_IS_VERSION_1
0095         // static_cast from the remaining Vector<U, abi>
0096         template <typename U>
0097         Vc_DEPRECATED("use simd_cast instead of explicit type casting to convert between "
0098                       "vector types") Vc_INTRINSIC
0099             explicit Vector(
0100                 V<U> x,
0101                 typename std::enable_if<!Traits::is_implicit_cast_allowed<U, T>::value,
0102                                         void *>::type = nullptr)
0103             : m_data(static_cast<EntryType>(x.data()))
0104         {
0105         }
0106 #endif
0107 
0108         Vc_INTRINSIC explicit Vector(reference a) : Vector(static_cast<EntryType>(a)) {}
0109 
0110         ///////////////////////////////////////////////////////////////////////////////////////////
0111         // broadcast
0112         Vc_INTRINSIC Vector(EntryType a) : m_data(a) {}
0113         template <typename U>
0114         Vc_INTRINSIC Vector(U a,
0115                             typename std::enable_if<std::is_same<U, int>::value &&
0116                                                         !std::is_same<U, EntryType>::value,
0117                                                     void *>::type = nullptr)
0118             : Vector(static_cast<EntryType>(a))
0119         {
0120         }
0121 
0122 #include "../common/loadinterface.h"
0123 #include "../common/storeinterface.h"
0124 
0125         ///////////////////////////////////////////////////////////////////////////////////////////
0126         // zeroing
0127         Vc_ALWAYS_INLINE void setZero() { m_data = 0; }
0128         Vc_ALWAYS_INLINE void setZero(Mask k) { if (k.data()) m_data = 0; }
0129         Vc_ALWAYS_INLINE void setZeroInverted(Mask k) { if (!k.data()) m_data = 0; }
0130 
0131         Vc_INTRINSIC_L void setQnan() Vc_INTRINSIC_R;
0132         Vc_INTRINSIC_L void setQnan(Mask m) Vc_INTRINSIC_R;
0133 
0134 #include "../common/gatherinterface.h"
0135 #include "../common/scatterinterface.h"
0136 
0137         //prefix
0138         Vc_ALWAYS_INLINE Vector &operator++() { ++m_data; return *this; }
0139         Vc_ALWAYS_INLINE Vector &operator--() { --m_data; return *this; }
0140         //postfix
0141         Vc_ALWAYS_INLINE Vector operator++(int) { return m_data++; }
0142         Vc_ALWAYS_INLINE Vector operator--(int) { return m_data--; }
0143 
0144     private:
0145         friend reference;
0146         Vc_INTRINSIC static value_type get(const Vector &o, int i) noexcept
0147         {
0148             Vc_ASSERT(i == 0); if (i) {}
0149             return o.m_data;
0150         }
0151         template <typename U>
0152         Vc_INTRINSIC static void set(Vector &o, int i, U &&v) noexcept(
0153             noexcept(std::declval<value_type &>() = v))
0154         {
0155             Vc_ASSERT(i == 0); if (i) {}
0156             o.m_data = v;
0157         }
0158 
0159     public:
0160         /**
0161          * \note the returned object models the concept of a reference and
0162          * as such it can exist longer than the data it is referencing.
0163          * \note to avoid lifetime issues, we strongly advice not to store
0164          * any reference objects.
0165          */
0166         Vc_ALWAYS_INLINE reference operator[](size_t index) noexcept
0167         {
0168             static_assert(noexcept(reference{std::declval<Vector &>(), int()}), "");
0169             return {*this, int(index)};
0170         }
0171         Vc_ALWAYS_INLINE value_type operator[](size_t index) const noexcept
0172         {
0173             Vc_ASSERT(index == 0); if (index) {}
0174             return m_data;
0175         }
0176 
0177         Vc_ALWAYS_INLINE Mask operator!() const
0178         {
0179             return Mask(!m_data);
0180         }
0181         Vc_ALWAYS_INLINE Vector operator~() const
0182         {
0183 #ifndef Vc_ENABLE_FLOAT_BIT_OPERATORS
0184             static_assert(std::is_integral<T>::value, "bit-complement can only be used with Vectors of integral type");
0185 #endif
0186             return Vector(~m_data);
0187         }
0188 
0189         Vc_ALWAYS_INLINE Vector operator-() const
0190         {
0191             return -m_data;
0192         }
0193         Vc_INTRINSIC Vector Vc_PURE operator+() const { return *this; }
0194 
0195 #define Vc_OP(symbol) \
0196         Vc_ALWAYS_INLINE Vc_PURE Vector operator symbol(const Vector &x) const { return Vector(m_data symbol x.m_data); }
0197         Vc_ALL_SHIFTS(Vc_OP);
0198 #undef Vc_OP
0199 
0200         Vc_DEPRECATED("use isnegative(x) instead") Vc_INTRINSIC Vc_PURE Mask
0201             isNegative() const
0202         {
0203             return Vc::isnegative(*this);
0204         }
0205 
0206         Vc_ALWAYS_INLINE void assign(const Vector &v, const Mask &m) {
0207           if (m.data()) m_data = v.m_data;
0208         }
0209 
0210         template <typename V2>
0211         Vc_DEPRECATED("Use simd_cast instead of Vector::staticCast") Vc_ALWAYS_INLINE V2
0212             staticCast() const
0213         {
0214             return V2(static_cast<typename V2::EntryType>(m_data));
0215         }
0216 //        template <typename V2>
0217 //        Vc_DEPRECATED("use reinterpret_components_cast instead") Vc_ALWAYS_INLINE V2
0218 //            reinterpretCast() const
0219 //        {
0220 //            typedef typename V2::EntryType AliasT2 Vc_MAY_ALIAS;
0221 //            return V2(*reinterpret_cast<const AliasT2 *>(&m_data));
0222 //        }
0223 
0224         Vc_ALWAYS_INLINE Common::WriteMaskedVector<Vector, Mask> operator()(Mask m)
0225         {
0226             return {*this, m};
0227         }
0228 
0229         Vc_ALWAYS_INLINE EntryType min() const { return m_data; }
0230         Vc_ALWAYS_INLINE EntryType max() const { return m_data; }
0231         Vc_ALWAYS_INLINE EntryType product() const { return m_data; }
0232         Vc_ALWAYS_INLINE EntryType sum() const { return m_data; }
0233         Vc_ALWAYS_INLINE Vector partialSum() const { return *this; }
0234         Vc_ALWAYS_INLINE EntryType min(Mask) const { return m_data; }
0235         Vc_ALWAYS_INLINE EntryType max(Mask) const { return m_data; }
0236         Vc_ALWAYS_INLINE EntryType product(Mask m) const
0237         {
0238             if (m.data()) {
0239                 return m_data;
0240             } else {
0241                 return EntryType(1);
0242             }
0243         }
0244         Vc_ALWAYS_INLINE EntryType sum(Mask m) const { if (m.data()) return m_data; return static_cast<EntryType>(0); }
0245 
0246         Vc_INTRINSIC Vector Vc_VDECL shifted(int amount, Vector shiftIn) const {
0247             Vc_ASSERT(amount >= -1 && amount <= 1);
0248             return amount == 0 ? *this : shiftIn;
0249         }
0250         Vc_INTRINSIC Vector shifted(int amount) const { return amount == 0 ? *this : Zero(); }
0251         Vc_INTRINSIC Vector rotated(int) const { return *this; }
0252         Vc_INTRINSIC Vector reversed() const { return *this; }
0253         Vc_INTRINSIC Vector sorted() const { return *this; }
0254 
0255         template <typename F> void callWithValuesSorted(F &&f) { f(m_data); }
0256 
0257         template <typename F> Vc_INTRINSIC void call(F &&f) const { f(m_data); }
0258 
0259         template <typename F> Vc_INTRINSIC void call(F &&f, Mask mask) const
0260         {
0261             if (mask.data()) {
0262                 f(m_data);
0263             }
0264         }
0265 
0266         template <typename F> Vc_INTRINSIC Vector apply(F &&f) const { return Vector(f(m_data)); }
0267 
0268         template <typename F> Vc_INTRINSIC Vector apply(F &&f, Mask mask) const
0269         {
0270             if (mask.data()) {
0271                 return Vector(f(m_data));
0272             } else {
0273                 return *this;
0274             }
0275         }
0276 
0277         template<typename IndexT> Vc_INTRINSIC void fill(EntryType (&f)(IndexT)) {
0278             m_data = f(0);
0279         }
0280         Vc_INTRINSIC void fill(EntryType (&f)()) {
0281             m_data = f();
0282         }
0283 
0284         template <typename G> static Vc_INTRINSIC Vector generate(G gen)
0285         {
0286             return gen(0);
0287         }
0288 
0289         Vc_DEPRECATED("use copysign(x, y) instead") Vc_INTRINSIC Vector Vc_VDECL
0290             copySign(Vector x) const
0291         {
0292             return Vc::copysign(*this, x);
0293         }
0294 
0295         Vc_DEPRECATED("use exponent(x) instead") Vc_INTRINSIC Vector exponent() const
0296         {
0297             return Vc::exponent(*this);
0298         }
0299 
0300         Vc_INTRINSIC Vector Vc_VDECL interleaveLow(Vector) const { return *this; }
0301         Vc_INTRINSIC Vector Vc_VDECL interleaveHigh(Vector x) const { return x; }
0302 };
0303 #undef Vc_CURRENT_CLASS_NAME
0304 template <typename T> constexpr size_t Vector<T, VectorAbi::Scalar>::Size;
0305 template <typename T> constexpr size_t Vector<T, VectorAbi::Scalar>::MemoryAlignment;
0306 
0307 #define Vc_OP(symbol)                                                                    \
0308     template <typename T, typename U,                                                    \
0309               typename = decltype(std::declval<T &>() symbol## = std::declval<T>())>     \
0310     Vc_INTRINSIC enable_if<std::is_convertible<U, Vector<T, VectorAbi::Scalar>>::value,  \
0311                            Vector<T, VectorAbi::Scalar>>                                 \
0312         &operator symbol##=(Vector<T, VectorAbi::Scalar> &lhs, U &&rhs)                  \
0313     {                                                                                    \
0314         lhs.data() symbol## = Vector<T, VectorAbi::Scalar>(std::forward<U>(rhs)).data(); \
0315         return lhs;                                                                      \
0316     }
0317 Vc_ALL_SHIFTS(Vc_OP);
0318 #undef Vc_OP
0319 
0320 #define Vc_CONDITIONAL_ASSIGN(name_, op_)                                                \
0321     template <Operator O, typename T, typename M, typename U>                            \
0322     Vc_INTRINSIC enable_if<O == Operator::name_, void> conditional_assign(               \
0323         Vector<T, VectorAbi::Scalar> &lhs, M &&mask, U &&rhs)                            \
0324     {                                                                                    \
0325         if (mask.isFull()) {                                                             \
0326             lhs op_ std::forward<U>(rhs);                                                \
0327         }                                                                                \
0328     }                                                                                    \
0329     Vc_NOTHING_EXPECTING_SEMICOLON
0330 Vc_CONDITIONAL_ASSIGN(          Assign,  =);
0331 Vc_CONDITIONAL_ASSIGN(      PlusAssign, +=);
0332 Vc_CONDITIONAL_ASSIGN(     MinusAssign, -=);
0333 Vc_CONDITIONAL_ASSIGN(  MultiplyAssign, *=);
0334 Vc_CONDITIONAL_ASSIGN(    DivideAssign, /=);
0335 Vc_CONDITIONAL_ASSIGN( RemainderAssign, %=);
0336 Vc_CONDITIONAL_ASSIGN(       XorAssign, ^=);
0337 Vc_CONDITIONAL_ASSIGN(       AndAssign, &=);
0338 Vc_CONDITIONAL_ASSIGN(        OrAssign, |=);
0339 Vc_CONDITIONAL_ASSIGN( LeftShiftAssign,<<=);
0340 Vc_CONDITIONAL_ASSIGN(RightShiftAssign,>>=);
0341 #undef Vc_CONDITIONAL_ASSIGN
0342 
0343 #define Vc_CONDITIONAL_ASSIGN(name_, expr_)                                              \
0344     template <Operator O, typename T, typename M>                                        \
0345     Vc_INTRINSIC enable_if<O == Operator::name_, Vector<T, VectorAbi::Scalar>>           \
0346     conditional_assign(Vector<T, VectorAbi::Scalar> &lhs, M &&mask)                      \
0347     {                                                                                    \
0348         return mask.isFull() ? (expr_) : lhs;                                            \
0349     }                                                                                    \
0350     Vc_NOTHING_EXPECTING_SEMICOLON
0351 Vc_CONDITIONAL_ASSIGN(PostIncrement, lhs++);
0352 Vc_CONDITIONAL_ASSIGN( PreIncrement, ++lhs);
0353 Vc_CONDITIONAL_ASSIGN(PostDecrement, lhs--);
0354 Vc_CONDITIONAL_ASSIGN( PreDecrement, --lhs);
0355 #undef Vc_CONDITIONAL_ASSIGN
0356 
0357 }  // namespace Vc
0358 
0359 #include "vector.tcc"
0360 #include "simd_cast.h"
0361 
0362 #endif // VC_SCALAR_VECTOR_H_