File indexing completed on 2025-01-30 10:25:52
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 #ifndef VC_COMMON_VECTORTUPLE_H_
0029 #define VC_COMMON_VECTORTUPLE_H_
0030
0031 #include "transpose.h"
0032 #include "macros.h"
0033
0034 namespace Vc_VERSIONED_NAMESPACE
0035 {
0036 namespace Common
0037 {
0038
0039 template<size_t StructSize, typename V, typename I, bool Readonly = true> struct InterleavedMemoryReadAccess;
0040
0041 template <int Length, typename V> class VectorReferenceArray
0042 {
0043 typedef typename V::EntryType T;
0044 typedef V &Vc_RESTRICT Reference;
0045 std::array<V * Vc_RESTRICT, Length> r;
0046
0047 typedef make_index_sequence<Length> IndexSequence;
0048
0049 template <typename VV, std::size_t... Indexes>
0050 constexpr VectorReferenceArray<Length + 1, VV> appendOneReference(
0051 VV &a, index_sequence<Indexes...>) const
0052 {
0053 return {*r[Indexes]..., a};
0054 }
0055
0056 template <typename A, std::size_t... Indexes>
0057 Vc_INTRINSIC void callDeinterleave(const A &access, index_sequence<Indexes...>) const
0058 {
0059 access.deinterleave(*r[Indexes]...);
0060 }
0061
0062 public:
0063 template <typename... Us, typename = enable_if<(sizeof...(Us) == Length)>>
0064 constexpr VectorReferenceArray(Us &&... args)
0065 : r{{std::addressof(std::forward<Us>(args))...}}
0066 {
0067 }
0068
0069 template <typename VV, typename = enable_if<!std::is_const<V>::value &&
0070 std::is_same<VV, V>::value>>
0071 Vc_DEPRECATED("build the tuple with Vc::tie instead") constexpr VectorReferenceArray<
0072 Length + 1, V>
0073 operator,(VV &a) const &&
0074 {
0075 return appendOneReference(a, IndexSequence());
0076 }
0077
0078 Vc_DEPRECATED("build the tuple with Vc::tie instead") constexpr VectorReferenceArray<
0079 Length + 1, const V>
0080 operator,(const V &a) const &&
0081 {
0082 return appendOneReference(a, IndexSequence());
0083 }
0084
0085 template <size_t StructSize, typename I, bool RO>
0086 Vc_ALWAYS_INLINE enable_if<(Length <= StructSize), void> operator=(
0087 const InterleavedMemoryReadAccess<StructSize, V, I, RO> &access) &&
0088 {
0089 callDeinterleave(access, IndexSequence());
0090 }
0091
0092 template <size_t StructSize, typename I, bool RO>
0093 enable_if<(Length > StructSize), void> operator=(
0094 const InterleavedMemoryReadAccess<StructSize, V, I, RO> &access) && =
0095 delete;
0096
0097 template <typename... Inputs> void operator=(TransposeProxy<Inputs...> &&proxy) &&
0098 {
0099 transpose_impl(TransposeTag<Length, sizeof...(Inputs)>(), &r[0], proxy);
0100 }
0101
0102 template <typename T, typename IndexVector, typename Scale, bool Flag>
0103 void operator=(SubscriptOperation<T, IndexVector, Scale, Flag> &&sub) &&
0104 {
0105 const auto &args = std::move(sub).gatherArguments();
0106
0107
0108 Common::InterleavedMemoryReadAccess<1, V, Traits::decay<decltype(args.indexes)>>
0109 deinterleaver(args.address, args.indexes);
0110 callDeinterleave(deinterleaver, IndexSequence());
0111 }
0112
0113 Vc_ALWAYS_INLINE Reference operator[](std::size_t i) { return *r[i]; }
0114 };
0115
0116 }
0117
0118 template <typename T, typename Abi>
0119 Vc_DEPRECATED("build the tuple with Vc::tie instead")
0120 constexpr Common::VectorReferenceArray<2, Vc::Vector<T, Abi>>
0121 operator,(Vc::Vector<T, Abi> &a, Vc::Vector<T, Abi> &b)
0122 {
0123 return {a, b};
0124 }
0125
0126 template <typename T, typename Abi>
0127 Vc_DEPRECATED("build the tuple with Vc::tie instead")
0128 constexpr Common::VectorReferenceArray<2, const Vc::Vector<T, Abi>>
0129 operator,(const Vc::Vector<T, Abi> &a, const Vc::Vector<T, Abi> &b)
0130 {
0131 return {a, b};
0132 }
0133
0134 template <typename V, typename... Vs>
0135 constexpr Common::VectorReferenceArray<sizeof...(Vs) + 1,
0136 typename std::remove_reference<V>::type>
0137 tie(V &&a, Vs &&... b)
0138 {
0139 return {std::forward<V>(a), std::forward<Vs>(b)...};
0140 }
0141
0142 }
0143
0144 #endif