Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 10:25:52

0001 /*  This file is part of the Vc library. {{{
0002 Copyright © 2014-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_WRITEMASKEDVECTOR_H_
0029 #define VC_COMMON_WRITEMASKEDVECTOR_H_
0030 
0031 #include <utility>
0032 #include "macros.h"
0033 
0034 namespace Vc_VERSIONED_NAMESPACE
0035 {
0036 namespace Common
0037 {
0038 
0039 template <typename V, typename M = typename V::Mask> class WriteMaskedVector
0040 {
0041     static_assert(
0042         V::Size == M::Size,
0043         "incorrect use of Vc::Common::WriteMaskedVector<V, M>. V and M must have the same «Size».");
0044 
0045 public:
0046     typedef M Mask;
0047     static constexpr size_t Size = V::Size;
0048 
0049     Vc_FREE_STORE_OPERATORS_ALIGNED(alignof(Mask));
0050 
0051     // implicit (allows {vec, mask} in places where WriteMaskedVector is expected)
0052     Vc_INTRINSIC WriteMaskedVector(V &v, const Mask &k) : mask(k), vec(v)
0053     {
0054     }
0055 
0056     // prefix
0057     Vc_INTRINSIC V &operator++()
0058     {
0059         V one = V::One();
0060         one.setZeroInverted(mask);
0061         return vec += one;
0062     }
0063     Vc_INTRINSIC V &operator--()
0064     {
0065         V one = V::One();
0066         one.setZeroInverted(mask);
0067         return vec -= one;
0068     }
0069 
0070     // postfix
0071     Vc_INTRINSIC V operator++(int)
0072     {
0073         V ret(vec);
0074         operator++();
0075         return ret;
0076     }
0077     Vc_INTRINSIC V operator--(int)
0078     {
0079         V ret(vec);
0080         operator--();
0081         return ret;
0082     }
0083 
0084 #define Vc_OPERATOR_(op)                                                                 \
0085     template <typename U> Vc_ALWAYS_INLINE void operator op##=(U &&x)                    \
0086     {                                                                                    \
0087         operator=(static_cast<V>(vec op std::forward<U>(x)));                            \
0088     }
0089     Vc_ALL_BINARY(Vc_OPERATOR_);
0090     Vc_ALL_ARITHMETICS(Vc_OPERATOR_);
0091     Vc_ALL_SHIFTS(Vc_OPERATOR_);
0092 #undef Vc_OPERATOR_
0093 
0094     Vc_ALWAYS_INLINE void operator=(const V &x)
0095     {
0096         vec.assign(x, mask);
0097     }
0098 
0099     template <typename T, typename I, typename S>
0100     Vc_ALWAYS_INLINE void operator=(SubscriptOperation<T, I, S, true> &&x)
0101     {
0102         vec.gather(std::move(x).gatherArguments(), mask);
0103     }
0104 
0105     template <typename F> Vc_INTRINSIC void call(const F &f) const
0106     {
0107         return vec.call(f, mask);
0108     }
0109     template <typename F> Vc_INTRINSIC V apply(const F &f) const
0110     {
0111         return vec.apply(f, mask);
0112     }
0113     template <typename F> Vc_INTRINSIC void call(F &&f) const
0114     {
0115         return vec.call(std::forward<F>(f), mask);
0116     }
0117     template <typename F> Vc_INTRINSIC V apply(F &&f) const
0118     {
0119         return vec.apply(std::forward<F>(f), mask);
0120     }
0121 
0122 private:
0123 #ifdef Vc_ICC
0124     // If ICC gets a by-value copy of Mask here, it'll generate a lot of superfluous
0125     // stack-register copies.
0126     const Mask &mask;
0127 #else
0128     // If Clang gets a const-ref Mask here, it'll miscompile some of the masked assignment
0129     // statements.
0130     const Mask mask;
0131 #endif
0132     V &vec;
0133 };
0134 }  // namespace Common
0135 }  // namespace Vc
0136 
0137 #endif // VC_COMMON_WRITEMASKEDVECTOR_H_