Vc  1.0.0-dev
SIMD Vector Classes for C++
vectortuple.h
1 /* This file is part of the Vc library. {{{
2 Copyright © 2012-2015 Matthias Kretz <kretz@kde.org>
3 All rights reserved.
4 
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7  * Redistributions of source code must retain the above copyright
8  notice, this list of conditions and the following disclaimer.
9  * Redistributions in binary form must reproduce the above copyright
10  notice, this list of conditions and the following disclaimer in the
11  documentation and/or other materials provided with the distribution.
12  * Neither the names of contributing organizations nor the
13  names of its contributors may be used to endorse or promote products
14  derived from this software without specific prior written permission.
15 
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
20 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 
27 }}}*/
28 
29 #ifndef VC_COMMON_VECTORTUPLE_H_
30 #define VC_COMMON_VECTORTUPLE_H_
31 
32 #include "transpose.h"
33 #include "macros.h"
34 
35 namespace Vc_VERSIONED_NAMESPACE
36 {
37 namespace Common
38 {
39 
40 template<size_t StructSize, typename V, typename I, bool Readonly = true> struct InterleavedMemoryReadAccess;
41 
42 template <int Length, typename V> class VectorReferenceArray
43 {
44  typedef typename V::EntryType T;
45  typedef V &Vc_RESTRICT Reference;
46  std::array<V * Vc_RESTRICT, Length> r;
47 
48  typedef make_index_sequence<Length> IndexSequence;
49 
50  template <typename VV, std::size_t... Indexes>
51  constexpr VectorReferenceArray<Length + 1, VV> appendOneReference(
52  VV &a, index_sequence<Indexes...>) const
53  {
54  return {*r[Indexes]..., a};
55  }
56 
57  template <typename A, std::size_t... Indexes>
58  Vc_INTRINSIC void callDeinterleave(const A &access, index_sequence<Indexes...>) const
59  {
60  access.deinterleave(*r[Indexes]...);
61  }
62 
63 public:
64  template <typename... Us, typename = enable_if<(sizeof...(Us) == Length)>>
65  constexpr VectorReferenceArray(Us &&... args)
66  : r{{std::addressof(std::forward<Us>(args))...}}
67  {
68  }
69 
70  template <typename VV, typename = enable_if<!std::is_const<V>::value &&
71  std::is_same<VV, V>::value>>
72  Vc_DEPRECATED("build the tuple with Vc::tie instead")
73  constexpr VectorReferenceArray<Length + 1, V> operator, (VV & a) const
74  {
75  return appendOneReference(a, IndexSequence());
76  }
77 
78  Vc_DEPRECATED("build the tuple with Vc::tie instead")
79  constexpr VectorReferenceArray<Length + 1, const V> operator, (const V &a) const
80  {
81  return appendOneReference(a, IndexSequence());
82  }
83 
84  template <size_t StructSize, typename I, bool RO>
85  Vc_ALWAYS_INLINE enable_if<(Length <= StructSize), void> operator=(
86  const InterleavedMemoryReadAccess<StructSize, V, I, RO> &access)
87  {
88  callDeinterleave(access, IndexSequence());
89  }
90 
91  template <size_t StructSize, typename I, bool RO>
92  enable_if<(Length > StructSize), void> operator=(
93  const InterleavedMemoryReadAccess<StructSize, V, I, RO> &access) =
94  delete; //("You are trying to extract more data from the struct than it has");
95 
96  template <typename... Inputs> void operator=(TransposeProxy<Inputs...> &&proxy)
97  {
98  transpose_impl<Length>(&r[0], proxy);
99  }
100 
101  template <typename T, typename IndexVector, typename Scale, bool Flag>
102  void operator=(const SubscriptOperation<T, IndexVector, Scale, Flag> &sub)
103  {
104  const auto &args = sub.gatherArguments();
105  //const IndexVector args.indexes;
106  //const T *const args.address;
107  Common::InterleavedMemoryReadAccess<1, V, Traits::decay<decltype(args.indexes)>>
108  deinterleaver(args.address, args.indexes);
109  callDeinterleave(deinterleaver, IndexSequence());
110  }
111 
112  Vc_ALWAYS_INLINE Reference operator[](std::size_t i) { return *r[i]; }
113 };
114 
115 } // namespace Common
116 
117 template <typename T, typename Abi>
118 Vc_DEPRECATED("build the tuple with Vc::tie instead")
119 constexpr Common::VectorReferenceArray<2, Vc::Vector<T, Abi>>
120 operator,(Vc::Vector<T, Abi> &a, Vc::Vector<T, Abi> &b)
121 {
122  return {a, b};
123 }
124 
125 template <typename T, typename Abi>
126 Vc_DEPRECATED("build the tuple with Vc::tie instead")
127 constexpr Common::VectorReferenceArray<2, const Vc::Vector<T, Abi>>
128 operator,(const Vc::Vector<T, Abi> &a, const Vc::Vector<T, Abi> &b)
129 {
130  return {a, b};
131 }
132 
133 template <typename V, typename... Vs>
134 constexpr Common::VectorReferenceArray<sizeof...(Vs) + 1,
135  typename std::remove_reference<V>::type>
136  tie(V &&a, Vs &&... b)
137 {
138  return {std::forward<V>(a), std::forward<Vs>(b)...};
139 }
140 
141 } // namespace Vc
142 
143 #endif // VC_COMMON_VECTORTUPLE_H_
Vector Classes Namespace.
Definition: cpuid.h:33